@eyeauras/insight-cli 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cli-package-build.json +1 -1
- package/README.md +25 -0
- package/SKILL.md +38 -54
- package/dist/src/binary.d.ts +3 -0
- package/dist/src/binary.js +74 -0
- package/dist/src/capture.d.ts +3 -0
- package/dist/src/capture.js +220 -0
- package/dist/src/cli.js +57 -12
- package/dist/src/contexts.d.ts +5 -0
- package/dist/src/contexts.js +42 -16
- package/dist/src/debugger-caller.d.ts +17 -0
- package/dist/src/debugger-caller.js +129 -0
- package/dist/src/debugger-launch.d.ts +2 -0
- package/dist/src/debugger-launch.js +17 -0
- package/dist/src/debugger-results.d.ts +1 -0
- package/dist/src/debugger-results.js +8 -0
- package/dist/src/debugger-supervisor.js +56 -13
- package/dist/src/debugger.js +16 -7
- package/dist/src/die.d.ts +12 -0
- package/dist/src/die.js +127 -0
- package/dist/src/dnspy-runtime.d.ts +8 -0
- package/dist/src/dnspy-runtime.js +46 -0
- package/dist/src/dnspy.d.ts +22 -0
- package/dist/src/dnspy.js +160 -0
- package/dist/src/dotnet-diagnostics.d.ts +13 -0
- package/dist/src/dotnet-diagnostics.js +101 -0
- package/dist/src/frida-worker.d.ts +1 -0
- package/dist/src/frida-worker.js +125 -0
- package/dist/src/frida.d.ts +16 -0
- package/dist/src/frida.js +125 -0
- package/dist/src/ghidra-debugger-runtime.d.ts +7 -0
- package/dist/src/ghidra-debugger-runtime.js +31 -0
- package/dist/src/ghidra-processes.d.ts +6 -0
- package/dist/src/ghidra-processes.js +121 -0
- package/dist/src/ghidra.js +6 -6
- package/dist/src/ilspy.d.ts +7 -0
- package/dist/src/ilspy.js +122 -0
- package/dist/src/lldb.d.ts +10 -0
- package/dist/src/lldb.js +99 -0
- package/dist/src/llvm.d.ts +6 -0
- package/dist/src/llvm.js +133 -0
- package/dist/src/managed-heap.d.ts +4 -0
- package/dist/src/managed-heap.js +73 -0
- package/dist/src/managed-metadata.d.ts +11 -0
- package/dist/src/managed-metadata.js +66 -0
- package/dist/src/mitmproxy.d.ts +55 -0
- package/dist/src/mitmproxy.js +172 -0
- package/dist/src/native-inputs.d.ts +3 -2
- package/dist/src/native-inputs.js +9 -4
- package/dist/src/package-version.d.ts +1 -0
- package/dist/src/package-version.js +3 -0
- package/dist/src/procmon-config.d.ts +2 -0
- package/dist/src/procmon-config.js +15 -0
- package/dist/src/procmon-events.d.ts +13 -0
- package/dist/src/procmon-events.js +82 -0
- package/dist/src/procmon.d.ts +4 -0
- package/dist/src/procmon.js +107 -0
- package/dist/src/research.d.ts +11 -2
- package/dist/src/research.js +5 -3
- package/dist/src/runtime-catalog.d.ts +5 -10
- package/dist/src/runtime-catalog.js +4 -5
- package/dist/src/runtime-manager.d.ts +27 -3
- package/dist/src/runtime-manager.js +100 -159
- package/dist/src/runtime-selection.js +21 -4
- package/dist/src/server.d.ts +13 -0
- package/dist/src/server.js +21 -45
- package/dist/src/sevenzip.d.ts +15 -0
- package/dist/src/sevenzip.js +119 -0
- package/dist/src/strace.d.ts +10 -0
- package/dist/src/strace.js +71 -0
- package/dist/src/text-window.d.ts +11 -0
- package/dist/src/text-window.js +6 -0
- package/dist/src/tool-runtime/archives.d.ts +10 -0
- package/dist/src/{runtime-archives.js → tool-runtime/archives.js} +91 -24
- package/dist/src/tool-runtime/catalog.d.ts +3 -0
- package/dist/src/tool-runtime/catalog.js +13 -0
- package/dist/src/tool-runtime/commands.d.ts +9 -0
- package/dist/src/tool-runtime/commands.js +39 -0
- package/dist/src/tool-runtime/deadline.d.ts +11 -0
- package/dist/src/tool-runtime/deadline.js +32 -0
- package/dist/src/tool-runtime/definition.d.ts +73 -0
- package/dist/src/tool-runtime/definition.js +49 -0
- package/dist/src/tool-runtime/dotnet.d.ts +4 -0
- package/dist/src/tool-runtime/dotnet.js +22 -0
- package/dist/src/tool-runtime/identity.d.ts +6 -0
- package/dist/src/tool-runtime/identity.js +50 -0
- package/dist/src/tool-runtime/installer.d.ts +101 -0
- package/dist/src/tool-runtime/installer.js +180 -0
- package/dist/src/tool-runtime/launch-worker.d.ts +1 -0
- package/dist/src/tool-runtime/launch-worker.js +58 -0
- package/dist/src/tool-runtime/run.d.ts +51 -0
- package/dist/src/tool-runtime/run.js +159 -0
- package/dist/src/tool-runtime/store.d.ts +15 -0
- package/dist/src/tool-runtime/store.js +219 -0
- package/dist/src/tool-runtime/supervisor.d.ts +57 -0
- package/dist/src/tool-runtime/supervisor.js +266 -0
- package/dist/src/tool-runtime/windows-job.d.ts +22 -0
- package/dist/src/tool-runtime/windows-job.js +43 -0
- package/dist/src/toolbox.d.ts +84 -0
- package/dist/src/toolbox.js +35 -0
- package/dist/src/tshark.d.ts +23 -0
- package/dist/src/tshark.js +174 -0
- package/dist/src/windbg.d.ts +14 -0
- package/dist/src/windbg.js +119 -0
- package/dist/src/workspace.d.ts +1 -0
- package/dist/src/workspace.js +6 -0
- package/package.json +5 -4
- package/references/agent-execution.md +36 -0
- package/references/agent-setup.md +61 -0
- package/references/artifacts.md +5 -0
- package/references/debugger.md +22 -0
- package/references/ilspy.md +33 -0
- package/references/managed-runtime.md +48 -7
- package/references/native/InsightPythonWheels.java +283 -2
- package/references/native/InsightTraceState.java +28 -13
- package/references/setup.md +2 -1
- package/runtime/managed/insight-heap/Azure.Core.dll +0 -0
- package/runtime/managed/insight-heap/Azure.Identity.dll +0 -0
- package/runtime/managed/insight-heap/Insight.Heap.csproj +1 -0
- package/runtime/managed/insight-heap/Insight.Heap.deps.json +391 -0
- package/runtime/managed/insight-heap/Insight.Heap.dll +0 -0
- package/runtime/managed/insight-heap/Insight.Heap.runtimeconfig.json +13 -0
- package/runtime/managed/insight-heap/Microsoft.Bcl.AsyncInterfaces.dll +0 -0
- package/runtime/managed/insight-heap/Microsoft.Diagnostics.NETCore.Client.dll +0 -0
- package/runtime/managed/insight-heap/Microsoft.Diagnostics.Runtime.dll +0 -0
- package/runtime/managed/insight-heap/Microsoft.Extensions.Configuration.Abstractions.dll +0 -0
- package/runtime/managed/insight-heap/Microsoft.Extensions.DependencyInjection.Abstractions.dll +0 -0
- package/runtime/managed/insight-heap/Microsoft.Extensions.Diagnostics.Abstractions.dll +0 -0
- package/runtime/managed/insight-heap/Microsoft.Extensions.FileProviders.Abstractions.dll +0 -0
- package/runtime/managed/insight-heap/Microsoft.Extensions.Hosting.Abstractions.dll +0 -0
- package/runtime/managed/insight-heap/Microsoft.Extensions.Logging.Abstractions.dll +0 -0
- package/runtime/managed/insight-heap/Microsoft.Extensions.Options.dll +0 -0
- package/runtime/managed/insight-heap/Microsoft.Extensions.Primitives.dll +0 -0
- package/runtime/managed/insight-heap/Microsoft.Identity.Client.Extensions.Msal.dll +0 -0
- package/runtime/managed/insight-heap/Microsoft.Identity.Client.dll +0 -0
- package/runtime/managed/insight-heap/Microsoft.IdentityModel.Abstractions.dll +0 -0
- package/runtime/managed/insight-heap/Microsoft.Security.AntiSSRF.dll +0 -0
- package/runtime/managed/insight-heap/NuGet.Config +1 -0
- package/runtime/managed/insight-heap/Program.cs +20 -0
- package/runtime/managed/insight-heap/README.md +16 -0
- package/runtime/managed/insight-heap/System.ClientModel.dll +0 -0
- package/runtime/managed/insight-heap/System.Memory.Data.dll +0 -0
- package/runtime/managed/insight-heap/System.Security.Cryptography.ProtectedData.dll +0 -0
- package/runtime/managed/insight-heap/dependencies.json +436 -0
- package/runtime/managed/insight-heap/notices/Azure.Core-LICENSE.txt +21 -0
- package/runtime/managed/insight-heap/notices/Azure.Identity-LICENSE.txt +21 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Bcl.AsyncInterfaces-LICENSE.txt +23 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Bcl.AsyncInterfaces-THIRD-PARTY-NOTICES.TXT +1418 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Diagnostics.NETCore.Client-LICENSE.txt +23 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Diagnostics.Runtime-LICENSE.txt +23 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Configuration.Abstractions-LICENSE.txt +23 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Configuration.Abstractions-THIRD-PARTY-NOTICES.TXT +1418 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Extensions.DependencyInjection.Abstractions-LICENSE.txt +23 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Extensions.DependencyInjection.Abstractions-THIRD-PARTY-NOTICES.TXT +1418 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Diagnostics.Abstractions-LICENSE.txt +23 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Diagnostics.Abstractions-THIRD-PARTY-NOTICES.TXT +1418 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Extensions.FileProviders.Abstractions-LICENSE.txt +23 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Extensions.FileProviders.Abstractions-THIRD-PARTY-NOTICES.TXT +1418 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Hosting.Abstractions-LICENSE.txt +23 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Hosting.Abstractions-THIRD-PARTY-NOTICES.TXT +1418 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Logging.Abstractions-LICENSE.txt +23 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Logging.Abstractions-THIRD-PARTY-NOTICES.TXT +1418 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Options-LICENSE.txt +23 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Options-THIRD-PARTY-NOTICES.TXT +1418 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Primitives-LICENSE.txt +23 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Primitives-THIRD-PARTY-NOTICES.TXT +1418 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Identity.Client-LICENSE.txt +21 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Identity.Client.Extensions.Msal-LICENSE.txt +21 -0
- package/runtime/managed/insight-heap/notices/Microsoft.IdentityModel.Abstractions-LICENSE.txt +21 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Security.AntiSSRF-LICENSE.txt +21 -0
- package/runtime/managed/insight-heap/notices/System.ClientModel-LICENSE.txt +21 -0
- package/runtime/managed/insight-heap/notices/System.Memory.Data-LICENSE.txt +23 -0
- package/runtime/managed/insight-heap/notices/System.Memory.Data-THIRD-PARTY-NOTICES.TXT +1418 -0
- package/runtime/managed/insight-heap/notices/System.Security.Cryptography.ProtectedData-LICENSE.TXT +23 -0
- package/runtime/managed/insight-heap/notices/System.Security.Cryptography.ProtectedData-THIRD-PARTY-NOTICES.TXT +309 -0
- package/runtime/managed/insight-heap/packages.lock.json +165 -0
- package/runtime/managed/insight-heap/provenance.json +146 -0
- package/runtime/managed/insight-heap/runtimes/win/lib/netstandard2.0/System.Security.Cryptography.ProtectedData.dll +0 -0
- package/runtime/managed/insight-managed/Insight.Managed.csproj +4 -0
- package/runtime/managed/insight-managed/Insight.Managed.deps.json +41 -0
- package/runtime/managed/insight-managed/Insight.Managed.dll +0 -0
- package/runtime/managed/insight-managed/Insight.Managed.runtimeconfig.json +13 -0
- package/runtime/managed/insight-managed/LICENSE.dnlib.txt +20 -0
- package/runtime/managed/insight-managed/NuGet.Config +1 -0
- package/runtime/managed/insight-managed/Program.cs +31 -0
- package/runtime/managed/insight-managed/README.md +16 -0
- package/runtime/managed/insight-managed/dnlib.dll +0 -0
- package/runtime/managed/insight-managed/packages.lock.json +13 -0
- package/runtime/managed/insight-managed/provenance.json +40 -0
- package/runtime/native/binary/README.md +22 -0
- package/runtime/native/binary/dependencies.json +166 -0
- package/runtime/native/binary/helper.cpp +44 -0
- package/runtime/native/binary/insight-binary-darwin-arm64 +0 -0
- package/runtime/native/binary/notices/Catch2-3.12.0--Catch2-3.12.0__LICENSE.txt +23 -0
- package/runtime/native/binary/notices/LIEF-LICENSE.txt +202 -0
- package/runtime/native/binary/notices/LIEF-attribution.txt +37 -0
- package/runtime/native/binary/notices/Melkor_ELF_Fuzzer-ac2495b--elf_fuzzer-master__LICENSE.txt +674 -0
- package/runtime/native/binary/notices/expected-1.3.1--expected-1.3.1__COPYING +121 -0
- package/runtime/native/binary/notices/frozen-61dce5a--frozen-61dce5ae18ca59931e27675c468e64118aba8744__AUTHORS +3 -0
- package/runtime/native/binary/notices/frozen-61dce5a--frozen-61dce5ae18ca59931e27675c468e64118aba8744__LICENSE +202 -0
- package/runtime/native/binary/notices/json-LICENSE.MIT +21 -0
- package/runtime/native/binary/notices/mbedtls-4.0.0.r0.gec4044008d--LICENSE +553 -0
- package/runtime/native/binary/notices/mbedtls-4.0.0.r0.gec4044008d--framework__LICENSE +553 -0
- package/runtime/native/binary/notices/mbedtls-4.0.0.r0.gec4044008d--tf-psa-crypto__LICENSE +552 -0
- package/runtime/native/binary/notices/mbedtls-4.0.0.r0.gec4044008d--tf-psa-crypto__framework__LICENSE +553 -0
- package/runtime/native/binary/notices/nanobind-2.13.0.r18.g4db9ed3f--LICENSE +26 -0
- package/runtime/native/binary/notices/nanobind-2.13.0.r18.g4db9ed3f--ext__robin_map__LICENSE +21 -0
- package/runtime/native/binary/notices/span-LICENSE_1_0.txt +23 -0
- package/runtime/native/binary/notices/span-attribution.txt +11 -0
- package/runtime/native/binary/notices/spdlog-1.17.0--spdlog-1.17.0__LICENSE +25 -0
- package/runtime/native/binary/notices/utfcpp-4.0.9--utfcpp-4.0.9__LICENSE +23 -0
- package/runtime/native/binary/provenance.json +48 -0
- package/runtime/native/child-deadline-linux-x64 +0 -0
- package/runtime/native/child-deadline-linux.c +24 -0
- package/runtime/native/child-deadline-linux.provenance.json +17 -0
- package/runtime/native/deadline-alarm-darwin-universal.dylib +0 -0
- package/runtime/native/deadline-alarm.c +33 -0
- package/runtime/native/deadline-alarm.provenance.json +22 -0
- package/runtime/native/deadline-exec-darwin-arm64 +0 -0
- package/runtime/native/deadline-exec.c +24 -0
- package/runtime/native/deadline-exec.provenance.json +17 -0
- package/runtime/native/dnspy-extension/Bridge.cs +58 -0
- package/runtime/native/dnspy-extension/Insight.DnSpy.csproj +13 -0
- package/runtime/native/dnspy-extension/Insight.DnSpy.x.dll +0 -0
- package/runtime/native/dnspy-extension/NuGet.Config +1 -0
- package/runtime/native/dnspy-extension/UNICODE-LOADER.md +26 -0
- package/runtime/native/dnspy-extension/packages.lock.json +6 -0
- package/runtime/native/dnspy-extension/provenance.json +27 -0
- package/runtime/native/dnspy-extension/upstream-public-build.snk +0 -0
- package/runtime/native/dnspy-extension/vendor-files.json +4341 -0
- package/runtime/native/file-version.ps1 +7 -0
- package/runtime/native/insight-registry-win-x64.dll +0 -0
- package/runtime/native/mitmproxy/bridge.py +180 -0
- package/runtime/native/mitmproxy/notices.json +476 -0
- package/runtime/native/sources/detours-LICENSE.md +23 -0
- package/runtime/native/sources/detours-e4bfd6b.tar.gz +0 -0
- package/runtime/native/sources/detours-provenance.json +10 -0
- package/runtime/native/tshark-layout.json +2247 -0
- package/runtime/native/windows-job/DirectoryAlias.cs +24 -0
- package/runtime/native/windows-job/Insight.WindowsJob.csproj +1 -0
- package/runtime/native/windows-job/Insight.WindowsJob.dll +0 -0
- package/runtime/native/windows-job/NuGet.Config +1 -0
- package/runtime/native/windows-job/OwnedJob.cs +79 -0
- package/runtime/native/windows-job/RegistryRedirect.cs +45 -0
- package/runtime/native/windows-job/packages.lock.json +21 -0
- package/runtime/native/windows-job/provenance.json +16 -0
- package/runtime/native/windows-job/windows-job.ps1 +8 -0
- package/runtime/native/windows-registry.c +21 -0
- package/runtime/native/windows-registry.def +3 -0
- package/runtime/native/windows-registry.provenance.json +14 -0
- package/runtime/notices/diagnostics-10.0.750501.txt +23 -0
- package/runtime/tool-catalog.json +290 -0
- package/runtime/toolbox.json +1401 -0
- package/skill-bundle/insight-artifacts/SKILL.md +30 -0
- package/skill-bundle/insight-artifacts/references/agent-execution.md +36 -0
- package/skill-bundle/insight-artifacts/references/artifacts.md +52 -0
- package/skill-bundle/insight-binary/SKILL.md +46 -0
- package/skill-bundle/insight-binary/references/agent-execution.md +36 -0
- package/skill-bundle/insight-capture/SKILL.md +56 -0
- package/skill-bundle/insight-capture/references/agent-execution.md +36 -0
- package/skill-bundle/insight-cli/SKILL.md +42 -0
- package/skill-bundle/insight-cli/references/agent-execution.md +36 -0
- package/skill-bundle/insight-cli/references/agent-setup.md +61 -0
- package/skill-bundle/insight-die/SKILL.md +49 -0
- package/skill-bundle/insight-die/references/agent-execution.md +36 -0
- package/skill-bundle/insight-dnspy/SKILL.md +65 -0
- package/skill-bundle/insight-dnspy/references/agent-execution.md +36 -0
- package/skill-bundle/insight-dotnet-dump/SKILL.md +46 -0
- package/skill-bundle/insight-dotnet-dump/references/agent-execution.md +36 -0
- package/skill-bundle/insight-dotnet-stack/SKILL.md +39 -0
- package/skill-bundle/insight-dotnet-stack/references/agent-execution.md +36 -0
- package/skill-bundle/insight-dotnet-trace/SKILL.md +45 -0
- package/skill-bundle/insight-dotnet-trace/references/agent-execution.md +36 -0
- package/skill-bundle/insight-frida/SKILL.md +67 -0
- package/skill-bundle/insight-frida/references/agent-execution.md +36 -0
- package/skill-bundle/insight-ghidra/SKILL.md +91 -0
- package/skill-bundle/insight-ghidra/references/administration.md +34 -0
- package/skill-bundle/insight-ghidra/references/agent-execution.md +36 -0
- package/skill-bundle/insight-ghidra/references/archive.md +32 -0
- package/skill-bundle/insight-ghidra/references/artifacts.md +52 -0
- package/skill-bundle/insight-ghidra/references/debugger.md +62 -0
- package/skill-bundle/insight-ghidra/references/extensions-and-sync.md +124 -0
- package/skill-bundle/insight-ghidra/references/managed-runtime.md +157 -0
- package/skill-bundle/insight-ghidra/references/native-workflows.md +112 -0
- package/skill-bundle/insight-ghidra/references/query-semantics.md +96 -0
- package/skill-bundle/insight-ghidra/references/recovery.md +53 -0
- package/skill-bundle/insight-ghidra/references/research.md +101 -0
- package/skill-bundle/insight-ghidra/references/setup.md +50 -0
- package/skill-bundle/insight-ilspy/SKILL.md +45 -0
- package/skill-bundle/insight-ilspy/references/agent-execution.md +36 -0
- package/skill-bundle/insight-ilspy/references/ilspy.md +33 -0
- package/skill-bundle/insight-interop/SKILL.md +54 -0
- package/skill-bundle/insight-interop/references/agent-execution.md +36 -0
- package/skill-bundle/insight-lldb/SKILL.md +54 -0
- package/skill-bundle/insight-lldb/references/agent-execution.md +36 -0
- package/skill-bundle/insight-llvm/SKILL.md +56 -0
- package/skill-bundle/insight-llvm/references/agent-execution.md +36 -0
- package/skill-bundle/insight-managed-heap/SKILL.md +43 -0
- package/skill-bundle/insight-managed-heap/references/agent-execution.md +36 -0
- package/skill-bundle/insight-managed-metadata/SKILL.md +52 -0
- package/skill-bundle/insight-managed-metadata/references/agent-execution.md +36 -0
- package/skill-bundle/insight-mitmproxy/SKILL.md +62 -0
- package/skill-bundle/insight-mitmproxy/references/agent-execution.md +36 -0
- package/skill-bundle/insight-overview/SKILL.md +79 -0
- package/skill-bundle/insight-overview/references/agent-execution.md +36 -0
- package/skill-bundle/insight-procmon/SKILL.md +49 -0
- package/skill-bundle/insight-procmon/references/agent-execution.md +36 -0
- package/skill-bundle/insight-re/SKILL.md +121 -0
- package/skill-bundle/insight-re/references/agent-execution.md +36 -0
- package/skill-bundle/insight-re/references/artifacts.md +52 -0
- package/skill-bundle/insight-re/references/recovery.md +53 -0
- package/skill-bundle/insight-sevenzip/SKILL.md +42 -0
- package/skill-bundle/insight-sevenzip/references/agent-execution.md +36 -0
- package/skill-bundle/insight-strace/SKILL.md +46 -0
- package/skill-bundle/insight-strace/references/agent-execution.md +36 -0
- package/skill-bundle/insight-tshark/SKILL.md +49 -0
- package/skill-bundle/insight-tshark/references/agent-execution.md +36 -0
- package/skill-bundle/insight-windbg/SKILL.md +46 -0
- package/skill-bundle/insight-windbg/references/agent-execution.md +36 -0
- package/skill-bundle/manifest.json +32 -0
- package/skills/insight-artifacts/SKILL.md +30 -0
- package/skills/insight-artifacts/references/agent-execution.md +36 -0
- package/skills/insight-artifacts/references/artifacts.md +52 -0
- package/skills/insight-binary/SKILL.md +46 -0
- package/skills/insight-binary/references/agent-execution.md +36 -0
- package/skills/insight-capture/SKILL.md +56 -0
- package/skills/insight-capture/references/agent-execution.md +36 -0
- package/skills/insight-die/SKILL.md +49 -0
- package/skills/insight-die/references/agent-execution.md +36 -0
- package/skills/insight-dnspy/SKILL.md +65 -0
- package/skills/insight-dnspy/references/agent-execution.md +36 -0
- package/skills/insight-dotnet-dump/SKILL.md +46 -0
- package/skills/insight-dotnet-dump/references/agent-execution.md +36 -0
- package/skills/insight-dotnet-stack/SKILL.md +39 -0
- package/skills/insight-dotnet-stack/references/agent-execution.md +36 -0
- package/skills/insight-dotnet-trace/SKILL.md +45 -0
- package/skills/insight-dotnet-trace/references/agent-execution.md +36 -0
- package/skills/insight-frida/SKILL.md +67 -0
- package/skills/insight-frida/references/agent-execution.md +36 -0
- package/skills/insight-ghidra/SKILL.md +91 -0
- package/skills/insight-ghidra/references/administration.md +34 -0
- package/skills/insight-ghidra/references/agent-execution.md +36 -0
- package/skills/insight-ghidra/references/archive.md +32 -0
- package/skills/insight-ghidra/references/artifacts.md +52 -0
- package/skills/insight-ghidra/references/debugger.md +62 -0
- package/skills/insight-ghidra/references/extensions-and-sync.md +124 -0
- package/skills/insight-ghidra/references/managed-runtime.md +157 -0
- package/skills/insight-ghidra/references/native-workflows.md +112 -0
- package/skills/insight-ghidra/references/query-semantics.md +96 -0
- package/skills/insight-ghidra/references/recovery.md +53 -0
- package/skills/insight-ghidra/references/research.md +101 -0
- package/skills/insight-ghidra/references/setup.md +50 -0
- package/skills/insight-ilspy/SKILL.md +45 -0
- package/skills/insight-ilspy/references/agent-execution.md +36 -0
- package/skills/insight-ilspy/references/ilspy.md +33 -0
- package/skills/insight-interop/SKILL.md +54 -0
- package/skills/insight-interop/references/agent-execution.md +36 -0
- package/skills/insight-lldb/SKILL.md +54 -0
- package/skills/insight-lldb/references/agent-execution.md +36 -0
- package/skills/insight-llvm/SKILL.md +56 -0
- package/skills/insight-llvm/references/agent-execution.md +36 -0
- package/skills/insight-managed-heap/SKILL.md +43 -0
- package/skills/insight-managed-heap/references/agent-execution.md +36 -0
- package/skills/insight-managed-metadata/SKILL.md +52 -0
- package/skills/insight-managed-metadata/references/agent-execution.md +36 -0
- package/skills/insight-mitmproxy/SKILL.md +62 -0
- package/skills/insight-mitmproxy/references/agent-execution.md +36 -0
- package/skills/insight-overview/SKILL.md +79 -0
- package/skills/insight-overview/references/agent-execution.md +36 -0
- package/skills/insight-procmon/SKILL.md +49 -0
- package/skills/insight-procmon/references/agent-execution.md +36 -0
- package/skills/insight-re/SKILL.md +22 -9
- package/skills/insight-re/references/agent-execution.md +36 -0
- package/skills/insight-re/references/artifacts.md +52 -0
- package/skills/insight-re/references/recovery.md +53 -0
- package/skills/insight-sevenzip/SKILL.md +42 -0
- package/skills/insight-sevenzip/references/agent-execution.md +36 -0
- package/skills/insight-strace/SKILL.md +46 -0
- package/skills/insight-strace/references/agent-execution.md +36 -0
- package/skills/insight-tshark/SKILL.md +49 -0
- package/skills/insight-tshark/references/agent-execution.md +36 -0
- package/skills/insight-windbg/SKILL.md +46 -0
- package/skills/insight-windbg/references/agent-execution.md +36 -0
- package/dist/src/runtime-archives.d.ts +0 -5
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type CommandContext, type CommandDefinition } from '@eyeauras/cli-factory';
|
|
2
|
+
import { ToolInstaller } from './tool-runtime/installer.js';
|
|
3
|
+
import type { Workspace } from './workspace.js';
|
|
4
|
+
export interface ArchiveEntry {
|
|
5
|
+
path: string;
|
|
6
|
+
directory: boolean;
|
|
7
|
+
size: number;
|
|
8
|
+
encrypted: boolean;
|
|
9
|
+
attributes: string;
|
|
10
|
+
}
|
|
11
|
+
/** Technical listing is bounded, not a general line-escaping format. Extraction never trusts native paths. */
|
|
12
|
+
export declare function parseArchiveListing(content: string): ArchiveEntry[];
|
|
13
|
+
export declare function safeArchivePath(path: string): string;
|
|
14
|
+
export declare function sevenzipInstaller(c: CommandContext): ToolInstaller;
|
|
15
|
+
export declare function sevenzipCommands(workspace: (c: CommandContext) => Workspace): CommandDefinition[];
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { command, Permission } from '@eyeauras/cli-factory';
|
|
2
|
+
import { join, resolve, dirname } from 'node:path';
|
|
3
|
+
import { mkdir, lstat } from 'node:fs/promises';
|
|
4
|
+
import { ToolInstaller } from './tool-runtime/installer.js';
|
|
5
|
+
import { defineTool, lifecycleCommands } from './tool-runtime/definition.js';
|
|
6
|
+
import { catalogArtifact } from './tool-runtime/catalog.js';
|
|
7
|
+
import { runTool } from './tool-runtime/run.js';
|
|
8
|
+
import { fail, text, id } from './model.js';
|
|
9
|
+
import { number } from './research.js';
|
|
10
|
+
const archiveSha = '7bb52641f2e0dc9b8f5b180be4b0ab46b6d3127361a4e817938175603850c714';
|
|
11
|
+
/** Technical listing is bounded, not a general line-escaping format. Extraction never trusts native paths. */
|
|
12
|
+
export function parseArchiveListing(content) {
|
|
13
|
+
const entries = [];
|
|
14
|
+
for (const block of content.replaceAll('\r\n', '\n').trim().split(/\n\n+/)) {
|
|
15
|
+
if (!block)
|
|
16
|
+
continue;
|
|
17
|
+
const fields = new Map();
|
|
18
|
+
for (const line of block.split('\n')) {
|
|
19
|
+
const at = line.indexOf(' = ');
|
|
20
|
+
if (at < 1)
|
|
21
|
+
fail('unsupported', 'Archive listing contains a multiline or unsupported field.');
|
|
22
|
+
const key = line.slice(0, at);
|
|
23
|
+
if (fields.has(key))
|
|
24
|
+
fail('unsupported', 'Archive listing contains ambiguous fields.');
|
|
25
|
+
fields.set(key, line.slice(at + 3));
|
|
26
|
+
}
|
|
27
|
+
if (['Symbolic Link', 'Hard Link', 'Reparse'].some(key => fields.has(key)))
|
|
28
|
+
fail('unsupported', 'Archive links are not supported for ordinary-file recovery.');
|
|
29
|
+
const path = fields.get('Path'), size = Number(fields.get('Size'));
|
|
30
|
+
if (!path || !Number.isSafeInteger(size) || size < 0 || !['+', '-'].includes(fields.get('Folder') ?? ''))
|
|
31
|
+
fail('unsupported', 'Archive entry omitted its path, size or kind.');
|
|
32
|
+
if (entries.length >= 10000)
|
|
33
|
+
fail('limit', 'Archive inventory exceeds 10000 entries.');
|
|
34
|
+
entries.push({ path, size, directory: fields.get('Folder') === '+', encrypted: fields.get('Encrypted') === '+', attributes: fields.get('Attributes') ?? '' });
|
|
35
|
+
}
|
|
36
|
+
return entries;
|
|
37
|
+
}
|
|
38
|
+
export function safeArchivePath(path) {
|
|
39
|
+
if (!path || /[\\\x00-\x1f\x7f:]/.test(path) || path.startsWith('/') || path.split('/').some(p => !p || p === '.' || p === '..') || path.length > 2048)
|
|
40
|
+
fail('invalid', 'Archive entry has an unsafe or unsupported output path.');
|
|
41
|
+
return path;
|
|
42
|
+
}
|
|
43
|
+
export function sevenzipInstaller(c) {
|
|
44
|
+
return new ToolInstaller(c, { id: 'sevenzip', primary: 'sevenzip', components: () => {
|
|
45
|
+
if (process.platform !== 'darwin' || !['arm64', 'x64'].includes(process.arch))
|
|
46
|
+
fail('unsupported', 'Managed 7-Zip is currently provided for macOS ARM64/x64; select an external 7zz 26.04 on another host.');
|
|
47
|
+
return { sevenzip: catalogArtifact(archiveSha) };
|
|
48
|
+
}, launch: roots => ({ executable: join(roots.sevenzip, '7zz'), arguments: [], environment: {} }),
|
|
49
|
+
probe: async (launch, context) => {
|
|
50
|
+
const r = await runTool(context, { tool: 'sevenzip', role: 'version', executable: launch.executable, arguments: [...launch.arguments, 'i'], environment: launch.environment, maxOutputBytes: 65536, timeoutMs: 30000 });
|
|
51
|
+
if (!/7-Zip \(z\) 26\.04 /.test(r.stdout))
|
|
52
|
+
fail('configuration', 'The selected executable must provide 7zz 26.04.');
|
|
53
|
+
return { version: '26.04' };
|
|
54
|
+
} });
|
|
55
|
+
}
|
|
56
|
+
export function sevenzipCommands(workspace) {
|
|
57
|
+
const definition = defineTool({ id: 'sevenzip', description: 'Inventory, verify and recover files from containers', components: [{ id: 'sevenzip', version: '26.04', artifacts: [] }], lifecycle: {
|
|
58
|
+
download: (o, c) => sevenzipInstaller(c).download(Boolean(o.offline)), install: (o, c) => sevenzipInstaller(c).install(o), uninstall: (o, c) => sevenzipInstaller(c).uninstall(Boolean(o.purgeCache)), doctor: (_o, c) => sevenzipInstaller(c).doctor(), status: (_o, c) => sevenzipInstaller(c).status()
|
|
59
|
+
} });
|
|
60
|
+
const common = [{ flags: '--target <id>', description: 'Reuse an immutable input target' }, { flags: '--timeout-seconds <seconds>', description: 'Per-process deadline (1–600)', defaultValue: 120 }];
|
|
61
|
+
const operation = (name) => command(name + ' [input]', name === 'list' ? 'Inspect a bounded archive inventory' : name === 'test' ? 'Check container integrity without extracting' : 'Recover regular files into a new ordinary directory', async ({ args, options: o }, c) => {
|
|
62
|
+
if (Boolean(args.input) === Boolean(o.target))
|
|
63
|
+
fail('invalid', 'Supply exactly one input path or --target.');
|
|
64
|
+
const w = workspace(c), target = args.input ? await w.importTarget(resolve(c.cwd, text(args.input, 4096))) : w.target(id(o.target));
|
|
65
|
+
const input = await w.artifacts.verify(target.input), timeoutMs = number(o.timeoutSeconds, 600, 1) * 1000;
|
|
66
|
+
return sevenzipInstaller(c).use(async (selected) => {
|
|
67
|
+
const invoke = (role, parameters, extra = {}) => runTool(c, { tool: 'sevenzip', role, installation: selected.id, executable: selected.executable, arguments: [...selected.arguments, ...parameters], environment: selected.environment, target: target.id, timeoutMs, ...extra });
|
|
68
|
+
if (name === 'test') {
|
|
69
|
+
const result = await invoke('test', ['t', '-bd', '-y', '-p', '--', input]);
|
|
70
|
+
return { state: 'verified', target: target.id, inputSha256: target.binarySha256, process: result.process, elapsedMs: result.elapsedMs, diagnostics: result.diagnostics, content: result.stdout };
|
|
71
|
+
}
|
|
72
|
+
const listing = await invoke('inventory', ['l', '-slt', '-ba', '-sccUTF-8', '-p', '--', input]);
|
|
73
|
+
const entries = parseArchiveListing(listing.stdout);
|
|
74
|
+
const base = { target: target.id, inputSha256: target.binarySha256, process: listing.process, diagnostics: listing.diagnostics, total: entries.length };
|
|
75
|
+
if (name === 'list') {
|
|
76
|
+
const limit = number(o.limit, 100, 1), offset = number(o.offset, 10000, 0);
|
|
77
|
+
return { ...base, items: entries.slice(offset, offset + limit), limit, offset, truncated: offset + limit < entries.length };
|
|
78
|
+
}
|
|
79
|
+
const chosen = o.entry ? entries.filter(e => e.path === text(o.entry, 2048)) : entries;
|
|
80
|
+
if (!chosen.length)
|
|
81
|
+
fail('notFound', 'No matching archive entry.');
|
|
82
|
+
if (chosen.length > 512)
|
|
83
|
+
fail('limit', 'Select an entry; bulk recovery is limited to 512 entries.');
|
|
84
|
+
const paths = new Set();
|
|
85
|
+
let bytes = 0;
|
|
86
|
+
for (const entry of chosen) {
|
|
87
|
+
safeArchivePath(entry.path);
|
|
88
|
+
const key = entry.path.normalize('NFC').toLowerCase();
|
|
89
|
+
if (paths.has(key))
|
|
90
|
+
fail('unsupported', 'Archive output paths collide.');
|
|
91
|
+
paths.add(key);
|
|
92
|
+
if (entry.encrypted)
|
|
93
|
+
fail('unsupported', 'Encrypted recovery is not supported by this adapter.');
|
|
94
|
+
if (entry.size > 64 * 1024 ** 2 || (bytes += entry.size) > 256 * 1024 ** 2)
|
|
95
|
+
fail('limit', 'Recovery exceeds its 64-MiB per-file/256-MiB total bound.');
|
|
96
|
+
if (/(?:^|\s)[bclps][rwx-]{9}/.test(entry.attributes))
|
|
97
|
+
fail('unsupported', 'Only ordinary archive files and directories can be recovered.');
|
|
98
|
+
}
|
|
99
|
+
const output = resolve(c.cwd, text(o.output, 4096));
|
|
100
|
+
await mkdir(dirname(output), { recursive: true, mode: 0o700 });
|
|
101
|
+
await mkdir(output, { mode: 0o700 });
|
|
102
|
+
const files = [];
|
|
103
|
+
for (const entry of chosen) {
|
|
104
|
+
const destination = join(output, entry.path);
|
|
105
|
+
if (entry.directory) {
|
|
106
|
+
await mkdir(destination, { recursive: true, mode: 0o700 });
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
await mkdir(dirname(destination), { recursive: true, mode: 0o700 });
|
|
110
|
+
const result = await invoke('recover', ['x', '-so', '-spd', '-bd', '-y', '-p', '--', input, entry.path], { maxOutputBytes: Math.max(65536, entry.size + 65536), outputFile: destination });
|
|
111
|
+
if ((await lstat(destination)).size !== entry.size)
|
|
112
|
+
fail('binding', 'Recovered file size differs from the inventory; retained partial output requires inspection.');
|
|
113
|
+
files.push({ path: entry.path, size: entry.size, process: result.process });
|
|
114
|
+
}
|
|
115
|
+
return { ...base, state: 'extracted', outputDirectory: output, files, bytes, publication: 'ordinary files; no shared analysis merge' };
|
|
116
|
+
});
|
|
117
|
+
}, { permission: Permission.Update, options: [...common, ...(name === 'list' ? [{ flags: '--limit <count>', description: 'Page size (1–100)', defaultValue: 50 }, { flags: '--offset <count>', description: 'Skip entries', defaultValue: 0 }] : name === 'extract' ? [{ flags: '--entry <path>', description: 'Recover one exact regular entry' }, { flags: '--output <directory>', description: 'New output directory', required: true }] : [])] });
|
|
118
|
+
return [command('sevenzip', definition.description, [...lifecycleCommands(definition), operation('list'), operation('test'), operation('extract')])];
|
|
119
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type CommandContext, type CommandDefinition } from '@eyeauras/cli-factory';
|
|
2
|
+
import { ToolInstaller } from './tool-runtime/installer.js';
|
|
3
|
+
import type { Workspace } from './workspace.js';
|
|
4
|
+
export declare function straceInstaller(c: CommandContext): ToolInstaller;
|
|
5
|
+
export declare function stracePlan(o: Record<string, unknown>): {
|
|
6
|
+
events: string[];
|
|
7
|
+
arguments: string[];
|
|
8
|
+
programArguments: string[];
|
|
9
|
+
};
|
|
10
|
+
export declare function straceCommands(workspace: (c: CommandContext) => Workspace): CommandDefinition[];
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { command, Permission } from '@eyeauras/cli-factory';
|
|
2
|
+
import { dirname, join, resolve } from 'node:path';
|
|
3
|
+
import { mkdir, writeFile, open, copyFile, chmod } from 'node:fs/promises';
|
|
4
|
+
import { constants } from 'node:fs';
|
|
5
|
+
import { randomUUID } from 'node:crypto';
|
|
6
|
+
import { ToolInstaller } from './tool-runtime/installer.js';
|
|
7
|
+
import { defineTool, lifecycleCommands } from './tool-runtime/definition.js';
|
|
8
|
+
import { catalogArtifact } from './tool-runtime/catalog.js';
|
|
9
|
+
import { runTool } from './tool-runtime/run.js';
|
|
10
|
+
import { fileSha256 } from './tool-runtime/archives.js';
|
|
11
|
+
import { fail, text, id } from './model.js';
|
|
12
|
+
import { number } from './research.js';
|
|
13
|
+
// Exact binary from the reviewed reproducible Linux source build.
|
|
14
|
+
const archiveSha = '3f01b360952f9c81dee07b640916115f937685df6d3004f5a3227cb0582d8ca3';
|
|
15
|
+
function supported() { if (process.platform !== 'linux' || process.arch !== 'x64')
|
|
16
|
+
fail('unsupported', 'The strace facade requires Linux x64, glibc 2.35+ and permission to trace its owned child.'); }
|
|
17
|
+
export function straceInstaller(c) {
|
|
18
|
+
return new ToolInstaller(c, { id: 'strace', primary: 'strace', components: () => { supported(); return { strace: catalogArtifact(archiveSha) }; }, launch: roots => ({ executable: join(roots.strace, 'bin/strace'), arguments: [], environment: {} }), probe: async (launch, context) => {
|
|
19
|
+
supported();
|
|
20
|
+
const r = await runTool(context, { tool: 'strace', role: 'version', executable: launch.executable, arguments: ['--version'], maxOutputBytes: 65536, timeoutMs: 10000, nativeDeadline: true });
|
|
21
|
+
if (!/strace -- version 7\.2\b/.test(r.stdout + '\n' + r.stderr))
|
|
22
|
+
fail('configuration', 'Select strace 7.2 with --kill-on-exit support.');
|
|
23
|
+
return { version: '7.2', ownedChildOnly: true, killOnExit: true, kernelOwnerDeadline: true };
|
|
24
|
+
} });
|
|
25
|
+
}
|
|
26
|
+
export function stracePlan(o) {
|
|
27
|
+
const requested = text(o.events ?? 'file,process,io', 128).split(','), groups = { file: '%file', process: '%process', network: '%network', io: 'read,write,readv,writev' };
|
|
28
|
+
if (!requested.length || requested.length > 4 || requested.some(x => !groups[x]) || new Set(requested).size !== requested.length)
|
|
29
|
+
fail('invalid', '--events must contain unique file, process, network or io categories.');
|
|
30
|
+
const args = o.arg === undefined ? [] : Array.isArray(o.arg) ? o.arg : [o.arg];
|
|
31
|
+
if (args.length > 64)
|
|
32
|
+
fail('limit', 'At most 64 literal program arguments are supported.');
|
|
33
|
+
return { events: requested, arguments: ['--kill-on-exit', '-f', '-yy', '-s', String(number(o.stringBytes ?? 128, 1024, 1)), '-e', 'trace=' + requested.map(x => groups[x]).join(','), ...(o.path ? ['-P', resolve(text(o.path, 4096))] : [])], programArguments: args.map(v => text(v, 4096)) };
|
|
34
|
+
}
|
|
35
|
+
export function straceCommands(workspace) {
|
|
36
|
+
const definition = defineTool({ id: 'strace', description: 'Observe file, process, I/O and network syscalls in an owned native Linux launch', components: [{ id: 'strace', version: '7.2', artifacts: [] }], lifecycle: { download: (o, c) => straceInstaller(c).download(Boolean(o.offline)), install: (o, c) => straceInstaller(c).install(o), uninstall: (o, c) => straceInstaller(c).uninstall(Boolean(o.purgeCache)), doctor: (_o, c) => straceInstaller(c).doctor(), status: (_o, c) => straceInstaller(c).status() } });
|
|
37
|
+
return [command('strace', definition.description, [...lifecycleCommands(definition), command('trace [input]', 'Run an authorized owned ELF copy and retain bounded syscall observations', async ({ args, options: o }, c) => {
|
|
38
|
+
supported();
|
|
39
|
+
if (Boolean(args.input) === Boolean(o.target))
|
|
40
|
+
fail('invalid', 'Supply exactly one executable input or --target.');
|
|
41
|
+
if (o.path)
|
|
42
|
+
o = { ...o, path: resolve(c.cwd, text(o.path, 4096)) };
|
|
43
|
+
const plan = stracePlan(o), limit = number(o.limit ?? 200, 1000, 1), offset = number(o.offset ?? 0, 1000000), timeoutMs = number(o.timeoutSeconds ?? 30, 600, 1) * 1000;
|
|
44
|
+
const w = workspace(c), target = args.input ? await w.importTarget(resolve(c.cwd, text(args.input, 4096))) : w.target(id(o.target)), input = await w.artifacts.verify(target.input), header = Buffer.alloc(64), handle = await open(input, 'r');
|
|
45
|
+
try {
|
|
46
|
+
const { bytesRead } = await handle.read(header, 0, 64, 0);
|
|
47
|
+
if (bytesRead < 64 || header.subarray(0, 4).toString('hex') !== '7f454c46' || header[4] !== 2 || header[5] !== 1 || header.readUInt16LE(18) !== 62)
|
|
48
|
+
fail('unsupported', 'An owned launch requires a native little-endian x64 ELF executable.');
|
|
49
|
+
}
|
|
50
|
+
finally {
|
|
51
|
+
await handle.close();
|
|
52
|
+
}
|
|
53
|
+
const directory = join(c.appArguments.AppDataDirectory, 'runtime/strace/subjects', randomUUID()), subject = join(directory, 'subject');
|
|
54
|
+
await mkdir(directory, { recursive: true, mode: 0o700 });
|
|
55
|
+
await copyFile(input, subject, constants.COPYFILE_EXCL);
|
|
56
|
+
await chmod(subject, 0o700);
|
|
57
|
+
if (await fileSha256(subject) !== target.binarySha256)
|
|
58
|
+
fail('binding', 'Owned ELF bytes differ from the immutable target.');
|
|
59
|
+
return straceInstaller(c).use(async (selected) => {
|
|
60
|
+
const result = await runTool(c, { tool: 'strace', role: 'trace', installation: selected.id, executable: selected.executable, arguments: [...plan.arguments, '--', subject, ...plan.programArguments], cwd: c.cwd, target: target.id, timeoutMs, nativeDeadline: true, metadata: { inputSha256: target.binarySha256, events: plan.events } }), lines = result.stderr.trimEnd().split(/\r?\n/);
|
|
61
|
+
const base = { state: 'completed', target: target.id, inputSha256: target.binarySha256, process: result.process, elapsedMs: result.elapsedMs, diagnostics: result.diagnostics, events: plan.events, programStdout: result.stdout, coverage: 'Observed syscalls from one owned launch and its traced descendants. Native trace and program stderr share the stderr stream. Strings and category/path filters are bounded; unobserved operations are unknown. Application side effects require authorization; adjacent executable sidecars are not copied.' };
|
|
62
|
+
if (o.output) {
|
|
63
|
+
const output = resolve(c.cwd, text(o.output, 4096)), content = JSON.stringify({ ...base, lines }, null, 2) + '\n';
|
|
64
|
+
await mkdir(dirname(output), { recursive: true, mode: 0o700 });
|
|
65
|
+
await writeFile(output, content, { flag: 'wx', mode: 0o600 });
|
|
66
|
+
return { ...base, output, bytes: Buffer.byteLength(content), totalLines: lines.length };
|
|
67
|
+
}
|
|
68
|
+
return { ...base, lines: lines.slice(offset, offset + limit), offset, limit, totalLines: lines.length, truncated: offset + limit < lines.length };
|
|
69
|
+
});
|
|
70
|
+
}, { permission: Permission.Update, options: [{ flags: '--target <id>', description: 'Reuse an immutable captured native ELF' }, { flags: '--arg <literal...>', description: 'Literal arguments, without shell expansion' }, { flags: '--events <categories>', description: 'Comma-separated file, process, io or network', defaultValue: 'file,process,io' }, { flags: '--path <path>', description: 'Optional literal path filter; combines with selected categories' }, { flags: '--string-bytes <bytes>', description: 'Maximum native string bytes (1–1024)', defaultValue: 128 }, { flags: '--output <file>', description: 'Save bounded trace and program stdout to a new ordinary JSON file' }, { flags: '--limit <count>', description: 'Maximum trace lines (1–1000)', defaultValue: 200 }, { flags: '--offset <count>', description: 'Skip trace lines', defaultValue: 0 }, { flags: '--timeout-seconds <seconds>', description: 'Owned launch deadline (1–600)', defaultValue: 30 }] })])];
|
|
71
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Public text coordinates are Unicode code points, never native bytes or UTF-16 halves. */
|
|
2
|
+
export declare function textWindow(source: string, limit: number, offset: number, sourceTruncated?: boolean): {
|
|
3
|
+
content: string;
|
|
4
|
+
textSha256: string;
|
|
5
|
+
totalCharacters: number;
|
|
6
|
+
limit: number;
|
|
7
|
+
offset: number;
|
|
8
|
+
sourceTruncated: boolean;
|
|
9
|
+
truncated: boolean;
|
|
10
|
+
coordinates: string;
|
|
11
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
/** Public text coordinates are Unicode code points, never native bytes or UTF-16 halves. */
|
|
3
|
+
export function textWindow(source, limit, offset, sourceTruncated = false) {
|
|
4
|
+
const characters = Array.from(source);
|
|
5
|
+
return { content: characters.slice(offset, offset + limit).join(''), textSha256: createHash('sha256').update(source).digest('hex'), totalCharacters: characters.length, limit, offset, sourceTruncated, truncated: sourceTruncated || offset + limit < characters.length, coordinates: 'Unicode characters in the returned native text; hash binds that text, which may itself be a truncated prefix' };
|
|
6
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ToolArtifact } from './definition.js';
|
|
2
|
+
export declare function fileSha256(path: string, signal?: AbortSignal): Promise<string>;
|
|
3
|
+
export declare function archiveName(name: string): string;
|
|
4
|
+
export declare function extractArchive(file: string, destination: string, format: 'tgz' | 'zip', signal?: AbortSignal): Promise<void>;
|
|
5
|
+
export declare function cacheArtifact(artifact: ToolArtifact, cache: string, fetcher: typeof fetch, signal: AbortSignal, offline?: boolean, vendorDirect?: boolean): Promise<string>;
|
|
6
|
+
/** Consume local input once; extraction never races later edits to the caller's archive. */
|
|
7
|
+
export declare function consumeArchive(path: string, cache: string, artifact: ToolArtifact, checksum?: string, signal?: AbortSignal): Promise<{
|
|
8
|
+
path: string;
|
|
9
|
+
artifact: ToolArtifact;
|
|
10
|
+
}>;
|
|
@@ -1,26 +1,27 @@
|
|
|
1
1
|
import { createHash, randomUUID } from 'node:crypto';
|
|
2
|
-
import { createReadStream, createWriteStream } from 'node:fs';
|
|
3
|
-
import { mkdir, open, rename, rm,
|
|
2
|
+
import { createReadStream, createWriteStream, constants } from 'node:fs';
|
|
3
|
+
import { mkdir, open, rename, rm, lstat } from 'node:fs/promises';
|
|
4
4
|
import { dirname, join, posix } from 'node:path';
|
|
5
5
|
import { pipeline } from 'node:stream/promises';
|
|
6
6
|
import * as tar from 'tar';
|
|
7
7
|
import * as zip from 'yauzl';
|
|
8
|
-
import { fail } from '
|
|
9
|
-
export async function fileSha256(path) { const hash = createHash('sha256'); for await (const chunk of createReadStream(path))
|
|
8
|
+
import { fail } from '../model.js';
|
|
9
|
+
export async function fileSha256(path, signal) { const hash = createHash('sha256'); for await (const chunk of createReadStream(path, { signal }))
|
|
10
10
|
hash.update(chunk); return hash.digest('hex'); }
|
|
11
11
|
export function archiveName(name) {
|
|
12
12
|
if (!name || name.includes('\\') || name.includes('\0') || name.startsWith('/') || /^[a-zA-Z]:/.test(name) || name.split('/').includes('..'))
|
|
13
13
|
fail('invalid', 'Runtime archive contains an unsafe path.');
|
|
14
14
|
return name.replace(/^(\.\/)+/, '');
|
|
15
15
|
}
|
|
16
|
-
export async function extractArchive(file, destination, format) {
|
|
16
|
+
export async function extractArchive(file, destination, format, signal) {
|
|
17
|
+
signal?.throwIfAborted();
|
|
17
18
|
await mkdir(destination, { recursive: true, mode: 0o700 });
|
|
18
19
|
let count = 0, bytes = 0;
|
|
19
20
|
const bound = (name, size) => { archiveName(name); if (++count > 100000 || !Number.isSafeInteger(size) || size < 0 || (bytes += size) > 8 * 1024 ** 3)
|
|
20
21
|
fail('limit', 'Runtime archive exceeds extraction bounds.'); };
|
|
21
22
|
if (format === 'tgz') {
|
|
22
23
|
let unsafe;
|
|
23
|
-
await tar.t({
|
|
24
|
+
await readTar(file, tar.t({ strict: true, filter: (path, entry) => {
|
|
24
25
|
try {
|
|
25
26
|
if (!('type' in entry))
|
|
26
27
|
fail('invalid', 'Unsupported runtime archive metadata.');
|
|
@@ -42,10 +43,10 @@ export async function extractArchive(file, destination, format) {
|
|
|
42
43
|
unsafe ??= error;
|
|
43
44
|
return false;
|
|
44
45
|
}
|
|
45
|
-
} });
|
|
46
|
+
} }), 'end', signal);
|
|
46
47
|
if (unsafe)
|
|
47
48
|
throw unsafe;
|
|
48
|
-
await tar.x({
|
|
49
|
+
await readTar(file, tar.x({ cwd: destination, strict: true, preserveOwner: false, noChmod: false }), 'close', signal);
|
|
49
50
|
return;
|
|
50
51
|
}
|
|
51
52
|
const archive = await new Promise((ok, bad) => zip.open(file, { lazyEntries: true, strictFileNames: true }, (e, z) => e ? bad(e) : ok(z)));
|
|
@@ -55,6 +56,7 @@ export async function extractArchive(file, destination, format) {
|
|
|
55
56
|
archive.on('end', ok);
|
|
56
57
|
archive.on('entry', (entry) => {
|
|
57
58
|
void (async () => {
|
|
59
|
+
signal?.throwIfAborted();
|
|
58
60
|
bound(entry.fileName, entry.uncompressedSize);
|
|
59
61
|
const mode = entry.externalFileAttributes >>> 16, type = mode & 0o170000;
|
|
60
62
|
if (type && type !== 0o100000 && type !== 0o040000)
|
|
@@ -65,7 +67,7 @@ export async function extractArchive(file, destination, format) {
|
|
|
65
67
|
else {
|
|
66
68
|
await mkdir(dirname(path), { recursive: true, mode: 0o700 });
|
|
67
69
|
const stream = await new Promise((ok, bad) => archive.openReadStream(entry, (e, s) => e ? bad(e) : ok(s)));
|
|
68
|
-
await pipeline(stream, createWriteStream(path, { flags: 'wx', mode: mode & 0o111 ? 0o755 : 0o644 }));
|
|
70
|
+
await pipeline(stream, createWriteStream(path, { flags: 'wx', mode: mode & 0o111 ? 0o755 : 0o644 }), { signal });
|
|
69
71
|
}
|
|
70
72
|
archive.readEntry();
|
|
71
73
|
})().catch(failed);
|
|
@@ -73,11 +75,13 @@ export async function extractArchive(file, destination, format) {
|
|
|
73
75
|
archive.readEntry();
|
|
74
76
|
});
|
|
75
77
|
}
|
|
76
|
-
export async function cacheArtifact(artifact, cache, fetcher, signal, offline = false) {
|
|
78
|
+
export async function cacheArtifact(artifact, cache, fetcher, signal, offline = false, vendorDirect = false) {
|
|
79
|
+
signal.throwIfAborted();
|
|
77
80
|
await mkdir(cache, { recursive: true, mode: 0o700 });
|
|
78
81
|
const path = join(cache, artifact.sha256 + '.' + artifact.format);
|
|
79
82
|
try {
|
|
80
|
-
|
|
83
|
+
const cached = await lstat(path);
|
|
84
|
+
if (cached.isFile() && (artifact.size === undefined || cached.size === artifact.size) && await fileSha256(path, signal) === artifact.sha256)
|
|
81
85
|
return path;
|
|
82
86
|
fail('binding', 'Cached runtime archive failed its SHA256 check; remove the corrupt cache entry before retrying.');
|
|
83
87
|
}
|
|
@@ -86,27 +90,20 @@ export async function cacheArtifact(artifact, cache, fetcher, signal, offline =
|
|
|
86
90
|
throw error;
|
|
87
91
|
}
|
|
88
92
|
if (offline)
|
|
89
|
-
fail('configuration', 'Required runtime archive is not cached; run
|
|
93
|
+
fail('configuration', 'Required runtime archive is not cached; run the tool download command before using --offline.', { artifact: artifact.name, sha256: artifact.sha256 });
|
|
94
|
+
if (artifact.delivery?.kind === 'vendor-direct' && !vendorDirect)
|
|
95
|
+
fail('configuration', 'This non-redistributable runtime requires explicit vendor download; use --vendor-direct or supply a local archive.', { artifact: artifact.name, publisher: artifact.delivery.publisher, termsUrl: artifact.delivery.termsUrl });
|
|
90
96
|
const temporary = path + '.partial-' + randomUUID();
|
|
91
97
|
try {
|
|
92
|
-
|
|
93
|
-
if (artifact.url.startsWith('https://ghcr.io/v2/homebrew/core/ghidra/')) {
|
|
94
|
-
const response = await fetcher('https://ghcr.io/token?service=ghcr.io&scope=repository:homebrew/core/ghidra:pull', { signal, redirect: 'error' });
|
|
95
|
-
if (!response.ok)
|
|
96
|
-
fail('download', 'Anonymous runtime registry authorization failed.');
|
|
97
|
-
const value = await response.json();
|
|
98
|
-
if (!value.token || value.token.length > 8192)
|
|
99
|
-
fail('download', 'Invalid anonymous runtime registry token.');
|
|
100
|
-
headers = { Authorization: 'Bearer ' + value.token };
|
|
101
|
-
}
|
|
102
|
-
const response = await fetcher(artifact.url, { signal, headers });
|
|
98
|
+
const response = await fetcher(artifact.url, { signal, cache: 'no-store' });
|
|
103
99
|
if (!response.ok || !response.body)
|
|
104
100
|
fail('download', 'Pinned runtime download failed.', { artifact: artifact.name, status: response.status });
|
|
105
101
|
let size = 0;
|
|
106
102
|
const hash = createHash('sha256'), handle = await open(temporary, 'wx', 0o600);
|
|
107
103
|
try {
|
|
108
104
|
for await (const chunk of response.body) {
|
|
109
|
-
|
|
105
|
+
signal.throwIfAborted();
|
|
106
|
+
if ((size += chunk.byteLength) > (artifact.size ?? 2 * 1024 ** 3))
|
|
110
107
|
fail('limit', 'Runtime download exceeds two GiB.');
|
|
111
108
|
hash.update(chunk);
|
|
112
109
|
await handle.writeFile(chunk);
|
|
@@ -116,6 +113,8 @@ export async function cacheArtifact(artifact, cache, fetcher, signal, offline =
|
|
|
116
113
|
finally {
|
|
117
114
|
await handle.close();
|
|
118
115
|
}
|
|
116
|
+
if (artifact.size !== undefined && size !== artifact.size)
|
|
117
|
+
fail('binding', 'Downloaded runtime archive has an unexpected size.');
|
|
119
118
|
if (hash.digest('hex') !== artifact.sha256)
|
|
120
119
|
fail('binding', 'Downloaded runtime archive failed its pinned SHA256 check.');
|
|
121
120
|
await rename(temporary, path);
|
|
@@ -125,3 +124,71 @@ export async function cacheArtifact(artifact, cache, fetcher, signal, offline =
|
|
|
125
124
|
await rm(temporary, { force: true });
|
|
126
125
|
}
|
|
127
126
|
}
|
|
127
|
+
/** tar streams expose their own abort instead of Node's AbortSignal option. */
|
|
128
|
+
async function readTar(file, parser, event, signal) {
|
|
129
|
+
signal?.throwIfAborted();
|
|
130
|
+
const input = createReadStream(file, { signal });
|
|
131
|
+
await new Promise((ok, bad) => {
|
|
132
|
+
let settled = false;
|
|
133
|
+
const failed = (error) => { if (settled)
|
|
134
|
+
return; settled = true; input.unpipe(); input.destroy(); parser.abort(error); bad(error); };
|
|
135
|
+
parser.on('error', failed);
|
|
136
|
+
input.on('error', failed);
|
|
137
|
+
parser.once(event, () => { if (!settled) {
|
|
138
|
+
settled = true;
|
|
139
|
+
ok();
|
|
140
|
+
} });
|
|
141
|
+
input.pipe(parser);
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
/** Consume local input once; extraction never races later edits to the caller's archive. */
|
|
145
|
+
export async function consumeArchive(path, cache, artifact, checksum, signal) {
|
|
146
|
+
const { realpath, stat } = await import('node:fs/promises');
|
|
147
|
+
const source = await realpath(path), input = await open(source, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0)), temporary = join(cache, 'local.partial-' + randomUUID());
|
|
148
|
+
try {
|
|
149
|
+
const metadata = await input.stat();
|
|
150
|
+
if (!metadata.isFile() || metadata.size > 2 * 1024 ** 3)
|
|
151
|
+
fail('invalid', 'Local runtime archive must be a regular file below two GiB.');
|
|
152
|
+
await mkdir(cache, { recursive: true, mode: 0o700 });
|
|
153
|
+
let size = 0;
|
|
154
|
+
const file = await open(temporary, 'wx', 0o600), hash = createHash('sha256');
|
|
155
|
+
try {
|
|
156
|
+
for await (const b of input.createReadStream({ signal, autoClose: false })) {
|
|
157
|
+
size += b.length;
|
|
158
|
+
if (size > 2 * 1024 ** 3)
|
|
159
|
+
fail('limit', 'Local archive grew beyond two GiB.');
|
|
160
|
+
hash.update(b);
|
|
161
|
+
await file.writeFile(b);
|
|
162
|
+
}
|
|
163
|
+
await file.sync();
|
|
164
|
+
}
|
|
165
|
+
finally {
|
|
166
|
+
await file.close();
|
|
167
|
+
}
|
|
168
|
+
const sha256 = hash.digest('hex');
|
|
169
|
+
if (checksum !== undefined && checksum.toLowerCase() !== sha256)
|
|
170
|
+
fail('binding', 'Local runtime archive differs from its expected SHA256.');
|
|
171
|
+
const handle = await open(temporary, 'r'), magic = Buffer.alloc(2);
|
|
172
|
+
try {
|
|
173
|
+
await handle.read(magic, 0, 2, 0);
|
|
174
|
+
}
|
|
175
|
+
finally {
|
|
176
|
+
await handle.close();
|
|
177
|
+
}
|
|
178
|
+
const format = magic.toString('hex') === '504b' ? 'zip' : 'tgz', owned = join(cache, sha256 + '.' + format);
|
|
179
|
+
try {
|
|
180
|
+
if (await fileSha256(owned) !== sha256)
|
|
181
|
+
fail('binding', 'Existing local-archive cache is corrupt.');
|
|
182
|
+
}
|
|
183
|
+
catch (e) {
|
|
184
|
+
if (e.code !== 'ENOENT')
|
|
185
|
+
throw e;
|
|
186
|
+
await rename(temporary, owned);
|
|
187
|
+
}
|
|
188
|
+
return { path: owned, artifact: { ...artifact, sha256, size, format } };
|
|
189
|
+
}
|
|
190
|
+
finally {
|
|
191
|
+
await input.close();
|
|
192
|
+
await rm(temporary, { force: true });
|
|
193
|
+
}
|
|
194
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { fail } from '../model.js';
|
|
3
|
+
const catalog = JSON.parse(readFileSync(new URL('../../../runtime/tool-catalog.json', import.meta.url), 'utf8'));
|
|
4
|
+
/** Expected bytes come from the installed package, never a replaceable remote manifest. */
|
|
5
|
+
export function catalogArtifact(sha256) {
|
|
6
|
+
const a = catalog[sha256];
|
|
7
|
+
const dnspy = a?.url === 'https://github.com/dnSpyEx/dnSpy/releases/download/v6.6.0/dnSpy-net-win64.zip' && a.sha256 === '8ed48f165dc355e869f3a0037ad4f9216147f995a5ae0258b296eeef1f73aab0' && a.delivery?.publisher === 'dnSpyEx' && a.delivery.termsUrl === 'https://visualstudio.microsoft.com/license-terms/mlt552233/';
|
|
8
|
+
const microsoft = a?.delivery?.publisher === 'Microsoft' && new URL(a.delivery.termsUrl).hostname === 'learn.microsoft.com' && new URL(a.delivery.termsUrl).protocol === 'https:' && new URL(a.url).protocol === 'https:' && ['download.sysinternals.com', 'windbg.download.prss.microsoft.com'].includes(new URL(a.url).hostname);
|
|
9
|
+
const vendor = a?.delivery?.kind === 'vendor-direct' && Boolean(a.delivery.reason) && (dnspy || microsoft);
|
|
10
|
+
if (!a || a.sha256 !== sha256 || !(a.url.startsWith('https://github.com/iXab3r/insight-cli/releases/download/tool-') || vendor) || !Number.isSafeInteger(a.size) || a.size < 1)
|
|
11
|
+
fail('binding', 'Pinned tool distribution is absent or invalid in the retained catalog.');
|
|
12
|
+
return { ...a };
|
|
13
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type CommandContext, type CommandDefinition } from '@eyeauras/cli-factory';
|
|
2
|
+
import { type ProcessRecord } from './supervisor.js';
|
|
3
|
+
export interface ToolProcessHooks {
|
|
4
|
+
discover?: (c: CommandContext) => Promise<void>;
|
|
5
|
+
verify?: (record: ProcessRecord, c: CommandContext) => Promise<boolean | undefined>;
|
|
6
|
+
stop?: (record: ProcessRecord, c: CommandContext) => Promise<void>;
|
|
7
|
+
beforeKill?: (record: ProcessRecord, c: CommandContext) => Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
export declare function toolProcessCommands(hooks?: Record<string, ToolProcessHooks>, metadata?: readonly CommandDefinition[]): CommandDefinition[];
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { command, Permission, CliError } from '@eyeauras/cli-factory';
|
|
2
|
+
import { listProcesses, processStatus, terminateProcess } from './supervisor.js';
|
|
3
|
+
import { text } from '../model.js';
|
|
4
|
+
const number = (value, max, min = 0) => { const n = Number(value); if (!Number.isSafeInteger(n) || n < min || n > max)
|
|
5
|
+
throw new CliError('Invalid process page bound.', { code: 'tool.input' }); return n; };
|
|
6
|
+
export function toolProcessCommands(hooks = {}, metadata = []) {
|
|
7
|
+
const verifier = (c) => (record) => hooks[record.tool]?.verify?.(record, c) ?? Promise.resolve(undefined);
|
|
8
|
+
const discover = async (c) => { for (const h of Object.values(hooks))
|
|
9
|
+
await h.discover?.(c); };
|
|
10
|
+
const processes = {
|
|
11
|
+
name: 'processes', description: 'List owned tool processes; inspect or stop one recorded execution', permission: Permission.ReadOnly,
|
|
12
|
+
options: [{ flags: '--tool <name>', description: 'Filter by tool' }, { flags: '--session <id>', description: 'Filter by research session' }, { flags: '--target <id>', description: 'Filter by input target' },
|
|
13
|
+
{ flags: '--all', description: 'Include completed and failed executions' }, { flags: '--limit <count>', description: 'Maximum records in this page', defaultValue: 50, parse: v => number(v, 1000, 1) },
|
|
14
|
+
{ flags: '--offset <count>', description: 'Skip records before this page', defaultValue: 0, parse: v => number(v, 2147483647) }],
|
|
15
|
+
async run({ options: o }, c) {
|
|
16
|
+
await discover(c);
|
|
17
|
+
let items = await listProcesses(c.appArguments.AppDataDirectory, { tool: o.tool === undefined ? undefined : text(o.tool, 64), session: o.session === undefined ? undefined : text(o.session, 128), target: o.target === undefined ? undefined : text(o.target, 128) }, verifier(c));
|
|
18
|
+
if (!o.all)
|
|
19
|
+
items = items.filter(r => !['exited', 'failed'].includes(r.state));
|
|
20
|
+
const limit = number(o.limit, 1000, 1), offset = number(o.offset, 2147483647);
|
|
21
|
+
return { items: items.slice(offset, offset + limit), total: items.length, limit, offset, truncated: items.length > offset + limit };
|
|
22
|
+
},
|
|
23
|
+
children: [
|
|
24
|
+
command('show <process>', 'Inspect a recorded execution and its diagnostic paths', async ({ args }, c) => { await discover(c); return processStatus(c.appArguments.AppDataDirectory, text(args.process, 64), verifier(c)); }, { permission: Permission.ReadOnly }),
|
|
25
|
+
command('stop <process>', 'Request tool-aware graceful shutdown of an owned process', async ({ args }, c) => {
|
|
26
|
+
await discover(c);
|
|
27
|
+
return terminateProcess(c.appArguments.AppDataDirectory, text(args.process, 64), false, verifier(c), r => hooks[r.tool]?.stop?.(r, c) ?? Promise.resolve());
|
|
28
|
+
}, { permission: Permission.Update }),
|
|
29
|
+
command('kill <process>', 'Force termination of a verified owned process; preserve uncertain work', async ({ args }, c) => {
|
|
30
|
+
await discover(c);
|
|
31
|
+
const id = text(args.process, 64), r = await processStatus(c.appArguments.AppDataDirectory, id, verifier(c));
|
|
32
|
+
if (r.state === 'running')
|
|
33
|
+
await hooks[r.tool]?.beforeKill?.(r, c);
|
|
34
|
+
return terminateProcess(c.appArguments.AppDataDirectory, id, true, verifier(c));
|
|
35
|
+
}, { permission: 'Destructive' }),
|
|
36
|
+
],
|
|
37
|
+
};
|
|
38
|
+
return [command('tools', 'Inspect research tools and executions', [...metadata, processes])];
|
|
39
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** For reviewed native helper execs started inside an adapter worker, never an external target. */
|
|
2
|
+
export declare function inheritedDeadlineEnvironment(deadlineUnixSeconds: number, receipts: string): Promise<{
|
|
3
|
+
DYLD_INSERT_LIBRARIES: string;
|
|
4
|
+
INSIGHT_NATIVE_DEADLINE_UNIX_SECONDS: string;
|
|
5
|
+
INSIGHT_NATIVE_DEADLINE_RECEIPTS: string;
|
|
6
|
+
}>;
|
|
7
|
+
/** Internal, first-party exec helper. No service or timer in the owner is needed after exec. */
|
|
8
|
+
export declare function deadlineLaunch(executable: string, args: string[], timeoutMs: number): Promise<{
|
|
9
|
+
executable: string;
|
|
10
|
+
arguments: string[];
|
|
11
|
+
}>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { fileURLToPath } from 'node:url';
|
|
2
|
+
import { CliError } from '@eyeauras/cli-factory';
|
|
3
|
+
import { fileSha256 } from './archives.js';
|
|
4
|
+
import { isAbsolute } from 'node:path';
|
|
5
|
+
/** For reviewed native helper execs started inside an adapter worker, never an external target. */
|
|
6
|
+
export async function inheritedDeadlineEnvironment(deadlineUnixSeconds, receipts) {
|
|
7
|
+
if (process.platform !== 'darwin' || process.arch !== 'arm64' || !Number.isInteger(deadlineUnixSeconds) || deadlineUnixSeconds <= Date.now() / 1000 || deadlineUnixSeconds > Date.now() / 1000 + 600 || !isAbsolute(receipts))
|
|
8
|
+
throw new CliError('Invalid inherited native deadline.', { code: 'tool.configuration' });
|
|
9
|
+
const library = fileURLToPath(new URL('../../../runtime/native/deadline-alarm-darwin-universal.dylib', import.meta.url));
|
|
10
|
+
if (library.includes(':') || await fileSha256(library) !== 'cd5ebd65aa419b79cb327f2ae872f98f3fd222b93049c909e409776eab65b8ef')
|
|
11
|
+
throw new CliError('Inherited deadline library differs from its reviewed build or has an unsupported loader path.', { code: 'tool.binding' });
|
|
12
|
+
return { DYLD_INSERT_LIBRARIES: library, INSIGHT_NATIVE_DEADLINE_UNIX_SECONDS: String(deadlineUnixSeconds), INSIGHT_NATIVE_DEADLINE_RECEIPTS: receipts };
|
|
13
|
+
}
|
|
14
|
+
/** Internal, first-party exec helper. No service or timer in the owner is needed after exec. */
|
|
15
|
+
export async function deadlineLaunch(executable, args, timeoutMs) {
|
|
16
|
+
if (process.platform === 'linux' && process.arch === 'x64') {
|
|
17
|
+
if (!Number.isInteger(timeoutMs) || timeoutMs < 1000 || timeoutMs > 600000)
|
|
18
|
+
throw new CliError('Native deadline must be 1–600 seconds.', { code: 'tool.configuration' });
|
|
19
|
+
const helper = fileURLToPath(new URL('../../../runtime/native/child-deadline-linux-x64', import.meta.url));
|
|
20
|
+
if (await fileSha256(helper) !== 'e070e2de9a21aea78f224062877cdc0264be11229af314d3b88ff3b6bd77e26f')
|
|
21
|
+
throw new CliError('Packaged Linux launcher differs from its reviewed build.', { code: 'tool.binding' });
|
|
22
|
+
return { executable: helper, arguments: [String(Math.ceil(timeoutMs / 1000)), String(process.pid), executable, ...args] };
|
|
23
|
+
}
|
|
24
|
+
if (process.platform !== 'darwin' || process.arch !== 'arm64')
|
|
25
|
+
throw new CliError('A packaged native deadline is unavailable on this host.', { code: 'tool.unsupported' });
|
|
26
|
+
if (!Number.isInteger(timeoutMs) || timeoutMs < 1000 || timeoutMs > 600000)
|
|
27
|
+
throw new CliError('Native deadline must be between one and 600 seconds.', { code: 'tool.configuration' });
|
|
28
|
+
const helper = fileURLToPath(new URL('../../../runtime/native/deadline-exec-darwin-arm64', import.meta.url));
|
|
29
|
+
if (await fileSha256(helper) !== '32c146075d1c83422b068eeedd4a244d5e30cb768b279b185756c5d3b8008d88')
|
|
30
|
+
throw new CliError('Packaged native deadline differs from its reviewed build.', { code: 'tool.binding' });
|
|
31
|
+
return { executable: helper, arguments: [String(Math.ceil(timeoutMs / 1000)), '--', executable, ...args] };
|
|
32
|
+
}
|