@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,159 @@
|
|
|
1
|
+
import { mkdir, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { join, isAbsolute, resolve } from 'node:path';
|
|
3
|
+
import { randomUUID } from 'node:crypto';
|
|
4
|
+
import { performance } from 'node:perf_hooks';
|
|
5
|
+
import { CliError } from '@eyeauras/cli-factory';
|
|
6
|
+
import { atomicWrite, withToolUse, toolRoot, readJson } from './store.js';
|
|
7
|
+
import { launchProcess } from './supervisor.js';
|
|
8
|
+
import { digest } from '../model.js';
|
|
9
|
+
import { deadlineLaunch } from './deadline.js';
|
|
10
|
+
import { windowsJobLaunch, windowsJobResult } from './windows-job.js';
|
|
11
|
+
export async function runTool(c, spec) {
|
|
12
|
+
c.signal.throwIfAborted();
|
|
13
|
+
const directory = c.appArguments.AppDataDirectory;
|
|
14
|
+
toolRoot(directory, spec.tool);
|
|
15
|
+
if (!isAbsolute(spec.executable))
|
|
16
|
+
throw new CliError('Tool executable must be an absolute path.', { code: 'tool.configuration' });
|
|
17
|
+
if ((spec.observedSubject || spec.nativeMutex || spec.nativeRegistry) && (!spec.nativeDeadline || process.platform !== 'win32'))
|
|
18
|
+
throw new CliError('Native subject/mutex/registry binding requires an owned Windows job.', { code: 'tool.configuration' });
|
|
19
|
+
if (spec.nativeChildDeadlines && !spec.nativeDeadline)
|
|
20
|
+
throw new CliError('Native child deadlines require the native collector deadline.', { code: 'tool.configuration' });
|
|
21
|
+
let launch = { executable: spec.executable, arguments: spec.arguments ?? [] };
|
|
22
|
+
const id = randomUUID(), root = join(directory, 'runtime/runs', id), path = join(directory, 'runtime/processes', id + '.json');
|
|
23
|
+
const started = performance.now(), limit = spec.maxOutputBytes ?? 4 * 1024 ** 2;
|
|
24
|
+
let child, outcome, truncated = false, bytes = 0;
|
|
25
|
+
const stdout = [], stderr = [], record = { schema: 1, id, tool: spec.tool, role: spec.role, installation: spec.installation ?? 'probe', state: 'starting', executable: spec.executable, createdAt: new Date().toISOString(), root, ownerPid: process.pid, profileBinding: digest(resolve(directory)), gated: process.platform !== 'win32' && typeof process.execve === 'function', phase: 'reserved', ...(spec.session ? { session: spec.session } : {}), ...(spec.target ? { target: spec.target } : {}) };
|
|
26
|
+
const lease = await withToolUse(directory, spec.tool, async () => { await mkdir(root, { recursive: true, mode: 0o700 }); }, c.signal);
|
|
27
|
+
const environment = { PATH: c.environment.PATH ?? process.env.PATH, HOME: root, TMPDIR: root, ...(process.platform === 'win32' ? { SystemRoot: process.env.SystemRoot, WINDIR: process.env.WINDIR, ComSpec: process.env.ComSpec, TEMP: root, TMP: root, USERPROFILE: root, LOCALAPPDATA: root, APPDATA: root } : {}), ...spec.environment };
|
|
28
|
+
const secrets = Object.entries(environment).filter(([key, value]) => /TOKEN|PASSWORD|SECRET|KEY/i.test(key) && value && value.length >= 4).map(([, v]) => v);
|
|
29
|
+
const redact = (value) => secrets.reduce((text, secret) => text.split(secret).join('[redacted]'), value);
|
|
30
|
+
let timer, force, drain, hard, settled = false, abandon;
|
|
31
|
+
const signal = (name) => {
|
|
32
|
+
if (!child?.pid || settled)
|
|
33
|
+
return;
|
|
34
|
+
try {
|
|
35
|
+
if (process.platform !== 'win32')
|
|
36
|
+
process.kill(-child.pid, name);
|
|
37
|
+
else if (child.exitCode === null && child.signalCode === null)
|
|
38
|
+
child.kill(name);
|
|
39
|
+
}
|
|
40
|
+
catch (e) {
|
|
41
|
+
if (e.code === 'ESRCH')
|
|
42
|
+
return;
|
|
43
|
+
record.terminationError = e.code ?? 'signal_failed';
|
|
44
|
+
if (child.exitCode === null && child.signalCode === null)
|
|
45
|
+
try {
|
|
46
|
+
child.kill(name);
|
|
47
|
+
}
|
|
48
|
+
catch { }
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
const stop = (reason) => { if (settled)
|
|
52
|
+
return; outcome ??= reason; signal('SIGTERM'); force ??= setTimeout(() => { signal('SIGKILL'); hard = setTimeout(() => { if (settled)
|
|
53
|
+
return; outcome = 'termination_unverified'; record.state = 'unverified'; child?.stdin?.destroy(); child?.stdout?.destroy(); child?.stderr?.destroy(); child?.unref(); abandon?.(new Error('termination_unverified')); }, 1000); hard.unref(); }, 1000); force.unref(); };
|
|
54
|
+
const aborted = () => stop('cancelled');
|
|
55
|
+
try {
|
|
56
|
+
c.signal.throwIfAborted();
|
|
57
|
+
if (spec.nativeDeadline)
|
|
58
|
+
launch = process.platform === 'win32' ? await windowsJobLaunch(root, id, spec.executable, spec.arguments ?? [], spec.cwd ?? root, spec.timeoutMs ?? 120000, { observedSubject: spec.observedSubject, nativeMutex: spec.nativeMutex, nativeRegistry: spec.nativeRegistry }) : await deadlineLaunch(spec.executable, spec.arguments ?? [], spec.timeoutMs ?? 120000);
|
|
59
|
+
child = await launchProcess(directory, { tool: spec.tool, role: spec.role, installation: spec.installation ?? 'probe', session: spec.session, target: spec.target, ...(spec.metadata || spec.nativeDeadline ? { metadata: { ...spec.metadata, ...(spec.observedSubject ? { observedSubject: spec.observedSubject } : {}), ...(spec.nativeMutex ? { nativeMutex: spec.nativeMutex } : {}), ...(spec.nativeRegistry ? { nativeRegistry: spec.nativeRegistry } : {}), ...(spec.nativeDeadline ? { nativeDeadlineSeconds: Math.ceil((spec.timeoutMs ?? 120000) / 1000), nativeExecutable: spec.executable, ...(spec.nativeChildDeadlines ? { nativeChildDeadlines: true } : {}) } : {}) } } : {}) }, launch.executable, launch.arguments, { cwd: spec.cwd ?? root, env: environment, windowsHide: true, detached: process.platform !== 'win32', stdio: ['pipe', 'pipe', 'pipe'] }, { id, finalize: false, signal: c.signal, onSpawn: launched => {
|
|
60
|
+
child = launched;
|
|
61
|
+
child.once('close', () => { settled = true; });
|
|
62
|
+
child.once('exit', () => { drain = setTimeout(() => stop('background_output'), 300); drain.unref(); });
|
|
63
|
+
const capture = (chunks, b) => { const available = Math.max(0, limit - bytes); if (available)
|
|
64
|
+
chunks.push(Buffer.from(b.subarray(0, available))); bytes += b.length; if (bytes > limit) {
|
|
65
|
+
truncated = true;
|
|
66
|
+
stop('output_limit');
|
|
67
|
+
} };
|
|
68
|
+
child.stdout.on('data', b => capture(stdout, b));
|
|
69
|
+
child.stderr.on('data', b => capture(stderr, b));
|
|
70
|
+
child.stdin.on('error', () => { });
|
|
71
|
+
child.stdin.end(spec.input);
|
|
72
|
+
c.signal.addEventListener('abort', aborted, { once: true });
|
|
73
|
+
if (c.signal.aborted)
|
|
74
|
+
aborted();
|
|
75
|
+
timer = setTimeout(() => stop('timeout'), spec.timeoutMs ?? 120000);
|
|
76
|
+
timer.unref();
|
|
77
|
+
} });
|
|
78
|
+
await Promise.race([child.toolClosed, new Promise((_ok, bad) => { abandon = bad; })]);
|
|
79
|
+
settled = true;
|
|
80
|
+
Object.assign(record, await readJson(path));
|
|
81
|
+
if (record.launchError)
|
|
82
|
+
outcome = 'launch_failed';
|
|
83
|
+
let exitCode = child.exitCode;
|
|
84
|
+
if (spec.nativeDeadline && process.platform === 'win32' && !outcome) {
|
|
85
|
+
try {
|
|
86
|
+
const job = await windowsJobResult(root, id, child.pid, Boolean(spec.nativeRegistry));
|
|
87
|
+
exitCode = job.childExitCode;
|
|
88
|
+
Object.assign(record, { windowsJob: job });
|
|
89
|
+
if (job.phase !== 'completed')
|
|
90
|
+
outcome = job.phase;
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
outcome = 'job_result_unverified';
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (!outcome && spec.nativeDeadline && child.signalCode === 'SIGALRM')
|
|
97
|
+
outcome = 'timeout';
|
|
98
|
+
if (!outcome && (exitCode === null || !(spec.acceptedCodes ?? [0]).includes(exitCode)))
|
|
99
|
+
outcome = 'exit_code';
|
|
100
|
+
const result = { process: id, stdout: redact(Buffer.concat(stdout).toString('utf8')), stderr: redact(Buffer.concat(stderr).toString('utf8')), exitCode, signal: child.signalCode, elapsedMs: Math.round(performance.now() - started), truncated, diagnostics: root };
|
|
101
|
+
if (spec.retainRawOutput) {
|
|
102
|
+
result.rawStdout = join(root, 'stdout.bin');
|
|
103
|
+
result.rawStderr = join(root, 'stderr.bin');
|
|
104
|
+
await writeFile(result.rawStdout, Buffer.concat(stdout), { mode: 0o600 });
|
|
105
|
+
await writeFile(result.rawStderr, Buffer.concat(stderr), { mode: 0o600 });
|
|
106
|
+
}
|
|
107
|
+
await writeFile(join(root, 'stdout.log'), result.stdout, { mode: 0o600 });
|
|
108
|
+
await writeFile(join(root, 'stderr.log'), result.stderr, { mode: 0o600 });
|
|
109
|
+
Object.assign(record, { state: outcome ? 'failed' : 'exited', outcome: outcome ?? 'completed', exitCode: result.exitCode, signal: result.signal, elapsedMs: result.elapsedMs, endedAt: new Date().toISOString() });
|
|
110
|
+
await atomicWrite(path, record);
|
|
111
|
+
if (outcome)
|
|
112
|
+
throw new CliError('Tool execution did not complete successfully: ' + outcome + '.', { code: 'tool.' + outcome.replaceAll('_', '.'), result });
|
|
113
|
+
if (spec.outputFile)
|
|
114
|
+
try {
|
|
115
|
+
await writeFile(spec.outputFile, Buffer.concat(stdout), { flag: 'wx', mode: 0o600 });
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
throw new CliError('Tool completed, but its binary output could not be written to a new file.', { code: 'tool.output', cause: error, result: { process: id, diagnostics: root } });
|
|
119
|
+
}
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
const failure = error;
|
|
124
|
+
await atomicWrite(join(root, 'error.json'), { name: failure.name, code: failure.code, message: redact(failure.message ?? String(error)), ...(failure.cause ? { cause: { name: failure.cause.name, message: redact(failure.cause.message) } } : {}) });
|
|
125
|
+
if (child && !settled && record.state !== 'unverified') {
|
|
126
|
+
stop('failed');
|
|
127
|
+
await new Promise(ok => { if (settled) {
|
|
128
|
+
ok();
|
|
129
|
+
return;
|
|
130
|
+
} child.once('close', () => ok()); setTimeout(() => { signal('SIGKILL'); ok(); }, 1500).unref(); });
|
|
131
|
+
}
|
|
132
|
+
Object.assign(record, await readJson(path));
|
|
133
|
+
if (c.signal.aborted && !outcome)
|
|
134
|
+
outcome = 'cancelled';
|
|
135
|
+
if (record.state === 'starting' || record.state === 'running' || record.state === 'failed') {
|
|
136
|
+
Object.assign(record, { state: 'failed', outcome: outcome ?? 'launch_failed', endedAt: new Date().toISOString(), elapsedMs: Math.round(performance.now() - started) });
|
|
137
|
+
await atomicWrite(path, record);
|
|
138
|
+
}
|
|
139
|
+
if (record.state === 'unverified')
|
|
140
|
+
await atomicWrite(path, record);
|
|
141
|
+
if (error instanceof CliError)
|
|
142
|
+
throw error;
|
|
143
|
+
if (record.state === 'unverified')
|
|
144
|
+
throw new CliError('Tool termination could not be verified; its process record blocks removal.', { code: 'tool.termination.unverified', result: { process: id, diagnostics: root } });
|
|
145
|
+
throw new CliError('Tool execution failed; inspect its retained process record.', { code: outcome ? 'tool.' + outcome.replaceAll('_', '.') : 'tool.launch', cause: error, result: { process: id, diagnostics: root } });
|
|
146
|
+
}
|
|
147
|
+
finally {
|
|
148
|
+
if (timer)
|
|
149
|
+
clearTimeout(timer);
|
|
150
|
+
if (force)
|
|
151
|
+
clearTimeout(force);
|
|
152
|
+
if (drain)
|
|
153
|
+
clearTimeout(drain);
|
|
154
|
+
if (hard)
|
|
155
|
+
clearTimeout(hard);
|
|
156
|
+
c.signal.removeEventListener('abort', aborted);
|
|
157
|
+
lease.release();
|
|
158
|
+
}
|
|
159
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare function atomicWrite(path: string, value: unknown): Promise<void>;
|
|
2
|
+
export declare function readJson<T>(path: string): Promise<T | undefined>;
|
|
3
|
+
export declare function toolRoot(directory: string, tool: string): string;
|
|
4
|
+
/** CLI clients already share Factory's elected owner. Do not create another IPC/lease protocol. */
|
|
5
|
+
export declare function withToolLock<T>(directory: string, tool: string, action: () => Promise<T>, signal?: AbortSignal): Promise<T>;
|
|
6
|
+
export declare function toolProfileBusy(directory: string): boolean;
|
|
7
|
+
export declare function toolUseCount(directory: string, tool: string): number;
|
|
8
|
+
export declare function withToolUse<T>(directory: string, tool: string, acquire: () => Promise<T>, signal?: AbortSignal): Promise<{
|
|
9
|
+
value: T;
|
|
10
|
+
release: () => void;
|
|
11
|
+
}>;
|
|
12
|
+
export declare function assertUnused(directory: string, tool: string): Promise<void>;
|
|
13
|
+
export declare function installationStage<T>(root: string, id: string, prepare: (stage: string, installed: string) => Promise<T>, verify: (receipt: T) => Promise<void>, signal?: AbortSignal): Promise<T>;
|
|
14
|
+
export declare function removeInstallation(root: string, id: string): Promise<void>;
|
|
15
|
+
export declare function treeFingerprint(root: string): Promise<string>;
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { mkdir, open, rename, rm, readFile, readdir, lstat, realpath } from 'node:fs/promises';
|
|
2
|
+
import { createReadStream } from 'node:fs';
|
|
3
|
+
import { dirname, join, resolve, relative, sep } from 'node:path';
|
|
4
|
+
import { randomUUID, createHash } from 'node:crypto';
|
|
5
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
6
|
+
import { CliError } from '@eyeauras/cli-factory';
|
|
7
|
+
import { fail } from '../model.js';
|
|
8
|
+
export async function atomicWrite(path, value) {
|
|
9
|
+
await mkdir(dirname(path), { recursive: true, mode: 0o700 });
|
|
10
|
+
const temporary = path + '.new-' + randomUUID(), file = await open(temporary, 'wx', 0o600);
|
|
11
|
+
try {
|
|
12
|
+
await file.writeFile(JSON.stringify(value, null, 2) + '\n');
|
|
13
|
+
await file.sync();
|
|
14
|
+
}
|
|
15
|
+
finally {
|
|
16
|
+
await file.close();
|
|
17
|
+
}
|
|
18
|
+
await rename(temporary, path);
|
|
19
|
+
if (process.platform !== 'win32') {
|
|
20
|
+
const parent = await open(dirname(path), 'r');
|
|
21
|
+
try {
|
|
22
|
+
await parent.sync();
|
|
23
|
+
}
|
|
24
|
+
finally {
|
|
25
|
+
await parent.close();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export async function readJson(path) { try {
|
|
30
|
+
return JSON.parse(await readFile(path, 'utf8'));
|
|
31
|
+
}
|
|
32
|
+
catch (e) {
|
|
33
|
+
if (e.code === 'ENOENT')
|
|
34
|
+
return;
|
|
35
|
+
throw e;
|
|
36
|
+
} }
|
|
37
|
+
export function toolRoot(directory, tool) { if (!/^[a-z][a-z0-9-]*$/.test(tool))
|
|
38
|
+
fail('invalid', 'Invalid tool identity.'); return tool === 'ghidra' ? join(directory, 'runtime') : join(directory, 'runtime', 'tools', tool); }
|
|
39
|
+
const queues = new Map(), held = new AsyncLocalStorage(), uses = new Map();
|
|
40
|
+
const key = (directory, tool) => resolve(directory) + '\0' + tool;
|
|
41
|
+
/** CLI clients already share Factory's elected owner. Do not create another IPC/lease protocol. */
|
|
42
|
+
export async function withToolLock(directory, tool, action, signal) {
|
|
43
|
+
signal?.throwIfAborted();
|
|
44
|
+
const k = key(directory, tool);
|
|
45
|
+
if (held.getStore()?.has(k))
|
|
46
|
+
return action();
|
|
47
|
+
const previous = queues.get(k) ?? Promise.resolve();
|
|
48
|
+
let started = false;
|
|
49
|
+
const execution = previous.then(() => { signal?.throwIfAborted(); started = true; return held.run(new Set([...(held.getStore() ?? []), k]), action); });
|
|
50
|
+
const tail = execution.then(() => { }, () => { });
|
|
51
|
+
queues.set(k, tail);
|
|
52
|
+
void tail.then(() => { if (queues.get(k) === tail)
|
|
53
|
+
queues.delete(k); });
|
|
54
|
+
if (!signal)
|
|
55
|
+
return execution;
|
|
56
|
+
return new Promise((ok, bad) => {
|
|
57
|
+
const aborted = () => { if (!started)
|
|
58
|
+
bad(signal.reason); };
|
|
59
|
+
signal.addEventListener('abort', aborted, { once: true });
|
|
60
|
+
if (signal.aborted)
|
|
61
|
+
aborted();
|
|
62
|
+
execution.then(ok, bad).finally(() => signal.removeEventListener('abort', aborted));
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
export function toolProfileBusy(directory) { const prefix = resolve(directory) + '\0'; return [...queues.keys(), ...uses.keys()].some(k => k.startsWith(prefix)); }
|
|
66
|
+
export function toolUseCount(directory, tool) { return uses.get(key(directory, tool)) ?? 0; }
|
|
67
|
+
export async function withToolUse(directory, tool, acquire, signal) {
|
|
68
|
+
return withToolLock(directory, tool, async () => {
|
|
69
|
+
const value = await acquire();
|
|
70
|
+
signal?.throwIfAborted();
|
|
71
|
+
const k = key(directory, tool);
|
|
72
|
+
uses.set(k, (uses.get(k) ?? 0) + 1);
|
|
73
|
+
let released = false;
|
|
74
|
+
return { value, release() { if (released)
|
|
75
|
+
return; released = true; const n = (uses.get(k) ?? 1) - 1; if (n)
|
|
76
|
+
uses.set(k, n);
|
|
77
|
+
else
|
|
78
|
+
uses.delete(k); } };
|
|
79
|
+
}, signal);
|
|
80
|
+
}
|
|
81
|
+
export async function assertUnused(directory, tool) {
|
|
82
|
+
if (toolUseCount(directory, tool))
|
|
83
|
+
fail('busy', 'Tool installation is reserved by an active operation.');
|
|
84
|
+
let names;
|
|
85
|
+
const root = join(directory, 'runtime/processes');
|
|
86
|
+
try {
|
|
87
|
+
names = await readdir(root);
|
|
88
|
+
}
|
|
89
|
+
catch (e) {
|
|
90
|
+
if (e.code === 'ENOENT')
|
|
91
|
+
return;
|
|
92
|
+
throw e;
|
|
93
|
+
}
|
|
94
|
+
for (const name of names) {
|
|
95
|
+
if (!/^[a-f0-9-]{36}\.json$/.test(name))
|
|
96
|
+
continue;
|
|
97
|
+
const retained = await readJson(join(root, name));
|
|
98
|
+
if (!retained || retained.tool !== tool)
|
|
99
|
+
continue;
|
|
100
|
+
const { processStatus } = await import('./supervisor.js'), record = await processStatus(directory, name.slice(0, -5));
|
|
101
|
+
if (['exited', 'failed'].includes(record.state))
|
|
102
|
+
continue;
|
|
103
|
+
if (record.phase === 'native_children_pending' || record.phase === 'native_children_unverified')
|
|
104
|
+
fail('busy', 'Tool has an active or unverified native helper; inspect its retained records before changing installations.');
|
|
105
|
+
if (!record.pid) {
|
|
106
|
+
if (record.gated && record.ownerPid)
|
|
107
|
+
try {
|
|
108
|
+
process.kill(record.ownerPid, 0);
|
|
109
|
+
}
|
|
110
|
+
catch (e) {
|
|
111
|
+
if (e.code === 'ESRCH')
|
|
112
|
+
continue;
|
|
113
|
+
throw e;
|
|
114
|
+
}
|
|
115
|
+
fail('busy', 'Tool has an unresolved process launch; inspect its process record.');
|
|
116
|
+
}
|
|
117
|
+
try {
|
|
118
|
+
process.kill(record.pid, 0);
|
|
119
|
+
fail('busy', 'Tool has an active or unverified process; stop it before changing installations.');
|
|
120
|
+
}
|
|
121
|
+
catch (e) {
|
|
122
|
+
if (e.code !== 'ESRCH')
|
|
123
|
+
throw e;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
export async function installationStage(root, id, prepare, verify, signal) {
|
|
128
|
+
if (!/^[a-f0-9]{64}$/.test(id))
|
|
129
|
+
fail('invalid', 'Invalid installation identity.');
|
|
130
|
+
signal?.throwIfAborted();
|
|
131
|
+
const installed = join(root, 'installations', id), receipt = await readJson(join(installed, 'ready.json'));
|
|
132
|
+
if (receipt) {
|
|
133
|
+
await verify(receipt);
|
|
134
|
+
return receipt;
|
|
135
|
+
}
|
|
136
|
+
const stage = join(root, 'stages', randomUUID());
|
|
137
|
+
await mkdir(stage, { recursive: true, mode: 0o700 });
|
|
138
|
+
try {
|
|
139
|
+
const value = await prepare(stage, installed);
|
|
140
|
+
signal?.throwIfAborted();
|
|
141
|
+
await atomicWrite(join(stage, 'ready.json'), value);
|
|
142
|
+
await mkdir(dirname(installed), { recursive: true, mode: 0o700 });
|
|
143
|
+
try {
|
|
144
|
+
await lstat(installed);
|
|
145
|
+
fail('binding', 'Incomplete installation is retained; inspect it before removing it.');
|
|
146
|
+
}
|
|
147
|
+
catch (e) {
|
|
148
|
+
if (e.code !== 'ENOENT')
|
|
149
|
+
throw e;
|
|
150
|
+
}
|
|
151
|
+
await rename(stage, installed);
|
|
152
|
+
if (process.platform !== 'win32') {
|
|
153
|
+
const p = await open(dirname(installed), 'r');
|
|
154
|
+
try {
|
|
155
|
+
await p.sync();
|
|
156
|
+
}
|
|
157
|
+
finally {
|
|
158
|
+
await p.close();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return value;
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
const code = error instanceof CliError ? error.code : 'installation';
|
|
165
|
+
await atomicWrite(join(stage, 'failure.json'), { state: 'failed', code });
|
|
166
|
+
if (error instanceof CliError)
|
|
167
|
+
throw new CliError(error.message, { code: error.code, result: { ...(error.result && typeof error.result === 'object' ? error.result : {}), diagnostics: stage } });
|
|
168
|
+
throw new CliError('Tool installation failed; the prior selection and diagnostic stage are retained.', { code: 'tool.installation', cause: error, result: { diagnostics: stage } });
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
export async function removeInstallation(root, id) {
|
|
172
|
+
if (!/^[a-f0-9]{64}$/.test(id))
|
|
173
|
+
fail('binding', 'Invalid installation identity.');
|
|
174
|
+
const path = join(root, 'installations', id);
|
|
175
|
+
let actual;
|
|
176
|
+
try {
|
|
177
|
+
actual = await realpath(path);
|
|
178
|
+
}
|
|
179
|
+
catch (e) {
|
|
180
|
+
if (e.code === 'ENOENT')
|
|
181
|
+
return;
|
|
182
|
+
throw e;
|
|
183
|
+
}
|
|
184
|
+
if (actual !== join(await realpath(root), 'installations', id))
|
|
185
|
+
fail('binding', 'Owned installation path was replaced by an external link.');
|
|
186
|
+
await rm(path, { recursive: true, force: true });
|
|
187
|
+
}
|
|
188
|
+
export async function treeFingerprint(root) {
|
|
189
|
+
const hash = createHash('sha256'), canonicalRoot = await realpath(root);
|
|
190
|
+
let count = 0;
|
|
191
|
+
async function visit(path) {
|
|
192
|
+
for (const name of (await readdir(path)).sort()) {
|
|
193
|
+
if (path === root && name === 'ready.json')
|
|
194
|
+
continue;
|
|
195
|
+
const at = join(path, name), st = await lstat(at);
|
|
196
|
+
if (++count > 100000)
|
|
197
|
+
fail('limit', 'Tool installation exceeds its file bound.');
|
|
198
|
+
hash.update(relative(root, at).replaceAll('\\', '/') + '\0');
|
|
199
|
+
if (st.isDirectory())
|
|
200
|
+
await visit(at);
|
|
201
|
+
else if (st.isSymbolicLink()) {
|
|
202
|
+
const destination = await realpath(at);
|
|
203
|
+
if (!destination.startsWith(canonicalRoot + sep))
|
|
204
|
+
fail('binding', 'Installed component link escapes its owned directory.');
|
|
205
|
+
hash.update('link:' + relative(canonicalRoot, destination));
|
|
206
|
+
}
|
|
207
|
+
else if (st.isFile()) {
|
|
208
|
+
const leaf = createHash('sha256');
|
|
209
|
+
for await (const b of createReadStream(at))
|
|
210
|
+
leaf.update(b);
|
|
211
|
+
hash.update('file:' + st.size + ':' + leaf.digest('hex') + '\0');
|
|
212
|
+
}
|
|
213
|
+
else
|
|
214
|
+
fail('binding', 'Unsupported tool installation entry.');
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
await visit(root);
|
|
218
|
+
return hash.digest('hex');
|
|
219
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { type ChildProcess, type SpawnOptions } from 'node:child_process';
|
|
2
|
+
import type { ToolProcess } from './definition.js';
|
|
3
|
+
export interface ProcessRecord extends ToolProcess {
|
|
4
|
+
root: string;
|
|
5
|
+
ownerPid: number;
|
|
6
|
+
profileBinding: string;
|
|
7
|
+
phase?: string;
|
|
8
|
+
strongIdentity?: boolean;
|
|
9
|
+
processGroup?: number;
|
|
10
|
+
gated: boolean;
|
|
11
|
+
metadata?: Record<string, unknown>;
|
|
12
|
+
outcome?: string;
|
|
13
|
+
requestedStop?: 'stop' | 'kill';
|
|
14
|
+
launchError?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface ProcessSpec {
|
|
17
|
+
tool: string;
|
|
18
|
+
role: string;
|
|
19
|
+
installation: string;
|
|
20
|
+
session?: string;
|
|
21
|
+
target?: string;
|
|
22
|
+
metadata?: Record<string, unknown>;
|
|
23
|
+
}
|
|
24
|
+
export interface TrackedChild extends ChildProcess {
|
|
25
|
+
toolProcessId: string;
|
|
26
|
+
toolClosed: Promise<void>;
|
|
27
|
+
}
|
|
28
|
+
export type OwnershipVerifier = (record: ProcessRecord) => Promise<boolean | undefined>;
|
|
29
|
+
export declare function launchProcess(directory: string, spec: ProcessSpec, executable: string, args: string[], options?: SpawnOptions, control?: {
|
|
30
|
+
id?: string;
|
|
31
|
+
finalize?: boolean;
|
|
32
|
+
onSpawn?: (child: TrackedChild) => void | Promise<void>;
|
|
33
|
+
signal?: AbortSignal;
|
|
34
|
+
}): Promise<TrackedChild>;
|
|
35
|
+
export declare function processStatus(directory: string, id: string, verify?: OwnershipVerifier): Promise<ProcessRecord>;
|
|
36
|
+
export declare function listProcesses(directory: string, filter?: {
|
|
37
|
+
tool?: string;
|
|
38
|
+
session?: string;
|
|
39
|
+
target?: string;
|
|
40
|
+
}, verify?: OwnershipVerifier): Promise<ProcessRecord[]>;
|
|
41
|
+
export declare function terminateProcess(directory: string, id: string, force: boolean, verify?: OwnershipVerifier, graceful?: (record: ProcessRecord) => Promise<void>): Promise<{
|
|
42
|
+
process: string;
|
|
43
|
+
state: string;
|
|
44
|
+
interrupted?: undefined;
|
|
45
|
+
tool?: undefined;
|
|
46
|
+
session?: undefined;
|
|
47
|
+
target?: undefined;
|
|
48
|
+
} | {
|
|
49
|
+
process: string;
|
|
50
|
+
state: string;
|
|
51
|
+
interrupted: boolean;
|
|
52
|
+
tool: string;
|
|
53
|
+
session: string | undefined;
|
|
54
|
+
target: string | undefined;
|
|
55
|
+
}>;
|
|
56
|
+
/** Migration/reconnection only: an adapter must authenticate a known existing tool before registration. */
|
|
57
|
+
export declare function registerExistingProcess(directory: string, spec: ProcessSpec, executable: string, pid: number, verify: OwnershipVerifier): Promise<string>;
|