@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
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { type CommandContext, type CommandDefinition } from '@eyeauras/cli-factory';
|
|
2
|
-
|
|
2
|
+
import { atomicWrite } from './tool-runtime/store.js';
|
|
3
|
+
export declare const runtimeWrite: typeof atomicWrite;
|
|
3
4
|
/** Passive, conservative inventory: a reused PID blocks deletion; it never grants kill authority. */
|
|
4
5
|
export declare function runtimeProcesses(directory: string): Promise<Record<string, unknown>[]>;
|
|
5
6
|
export declare function externalGhidra(path: string): Promise<string>;
|
|
6
7
|
export declare class RuntimeManager {
|
|
7
8
|
private readonly c;
|
|
8
9
|
readonly directory: string;
|
|
9
|
-
readonly root: string;
|
|
10
10
|
constructor(c: CommandContext);
|
|
11
|
+
get root(): string;
|
|
11
12
|
status(): Promise<{
|
|
12
13
|
missing: string[];
|
|
13
14
|
capabilities: {
|
|
@@ -16,11 +17,29 @@ export declare class RuntimeManager {
|
|
|
16
17
|
gui: boolean;
|
|
17
18
|
debugger: {
|
|
18
19
|
backend: string;
|
|
20
|
+
runtime: {
|
|
21
|
+
retainedStages: string[];
|
|
22
|
+
processes: import("./tool-runtime/supervisor.js").ProcessRecord[];
|
|
23
|
+
tool: string;
|
|
24
|
+
state: string;
|
|
25
|
+
mode: string;
|
|
26
|
+
installation: string | undefined;
|
|
27
|
+
executable: string | undefined;
|
|
28
|
+
components: Record<string, string>;
|
|
29
|
+
lastProbe: Record<string, unknown> | undefined;
|
|
30
|
+
recommended: string;
|
|
31
|
+
};
|
|
19
32
|
requires: string;
|
|
20
33
|
checkedBy: string;
|
|
34
|
+
} | {
|
|
35
|
+
backend: string;
|
|
36
|
+
requires: string;
|
|
37
|
+
checkedBy: string;
|
|
38
|
+
runtime?: undefined;
|
|
21
39
|
} | {
|
|
22
40
|
backend: string;
|
|
23
41
|
checkedBy: string;
|
|
42
|
+
runtime?: undefined;
|
|
24
43
|
requires?: undefined;
|
|
25
44
|
};
|
|
26
45
|
};
|
|
@@ -66,7 +85,12 @@ export declare class RuntimeManager {
|
|
|
66
85
|
private archive;
|
|
67
86
|
private cleanupProbes;
|
|
68
87
|
install(o: Record<string, unknown>): Promise<{
|
|
69
|
-
|
|
88
|
+
debugger?: {
|
|
89
|
+
backend: string;
|
|
90
|
+
installation: string;
|
|
91
|
+
fingerprint: string;
|
|
92
|
+
} | undefined;
|
|
93
|
+
checks: unknown;
|
|
70
94
|
schema: 1;
|
|
71
95
|
mode: "managed" | "external";
|
|
72
96
|
id?: string;
|
|
@@ -1,38 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { readFile, mkdir, rename, rm,
|
|
3
|
-
import { existsSync,
|
|
1
|
+
import { runTool } from './tool-runtime/run.js';
|
|
2
|
+
import { readFile, mkdir, rename, rm, realpath, readdir, stat, cp } from 'node:fs/promises';
|
|
3
|
+
import { existsSync, realpathSync } from 'node:fs';
|
|
4
4
|
import { join, dirname, resolve, delimiter, basename } from 'node:path';
|
|
5
5
|
import { randomUUID } from 'node:crypto';
|
|
6
|
-
import { execFile } from 'node:child_process';
|
|
7
|
-
import { promisify } from 'node:util';
|
|
8
6
|
import { runtimeRoot, runtimeSelection, runtimeValues } from './runtime-selection.js';
|
|
9
7
|
import { runtimeCatalog } from './runtime-catalog.js';
|
|
10
|
-
import { cacheArtifact, extractArchive,
|
|
8
|
+
import { cacheArtifact, extractArchive, consumeArchive } from './tool-runtime/archives.js';
|
|
11
9
|
import { nativeInputs, nativeHelpers, nativeJvmDirectories, pinnedMcpJar } from './native-inputs.js';
|
|
12
10
|
import { GhidraServer, stopLocalServer } from './server.js';
|
|
13
11
|
import { fail, text, digest, object } from './model.js';
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
await handle.writeFile(JSON.stringify(value, null, 2) + '\n');
|
|
20
|
-
await handle.sync();
|
|
21
|
-
}
|
|
22
|
-
finally {
|
|
23
|
-
await handle.close();
|
|
24
|
-
}
|
|
25
|
-
await rename(temporary, path);
|
|
26
|
-
if (process.platform !== 'win32') {
|
|
27
|
-
const parent = await open(dirname(path), 'r');
|
|
28
|
-
try {
|
|
29
|
-
await parent.sync();
|
|
30
|
-
}
|
|
31
|
-
finally {
|
|
32
|
-
await parent.close();
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
12
|
+
import { atomicWrite, installationStage, removeInstallation, withToolLock, assertUnused } from './tool-runtime/store.js';
|
|
13
|
+
import { lifecycleCommands as sharedLifecycle } from './tool-runtime/definition.js';
|
|
14
|
+
import { managedGhidraDebugger, ghidraDebuggerInstaller, prepareGhidraDebugger } from './ghidra-debugger-runtime.js';
|
|
15
|
+
const suffix = process.platform === 'win32' ? '.exe' : '';
|
|
16
|
+
export const runtimeWrite = atomicWrite;
|
|
36
17
|
const live = (pid) => { if (!Number.isSafeInteger(pid) || Number(pid) < 1)
|
|
37
18
|
return false; try {
|
|
38
19
|
process.kill(Number(pid), 0);
|
|
@@ -74,7 +55,7 @@ export async function runtimeProcesses(directory) {
|
|
|
74
55
|
throw error;
|
|
75
56
|
}
|
|
76
57
|
if (!stopped && live(p.pid))
|
|
77
|
-
items.push({ kind: p.kind, pid: p.pid, sessionContext: p.context, target: p.target, mode: p.mode });
|
|
58
|
+
items.push({ kind: p.kind, pid: p.pid, sessionContext: p.context, ...(typeof p.session === 'string' ? { session: p.session } : {}), target: p.target, mode: p.mode });
|
|
78
59
|
}
|
|
79
60
|
}
|
|
80
61
|
}
|
|
@@ -117,12 +98,13 @@ async function findRoot(root, marker, depth = 0) {
|
|
|
117
98
|
export class RuntimeManager {
|
|
118
99
|
c;
|
|
119
100
|
directory;
|
|
120
|
-
root;
|
|
121
101
|
constructor(c) {
|
|
122
102
|
this.c = c;
|
|
123
103
|
this.directory = c.appArguments.AppDataDirectory;
|
|
124
|
-
this.root = runtimeRoot(this.directory);
|
|
125
104
|
}
|
|
105
|
+
// Canonicalize storage once the profile exists, without creating it for passive status.
|
|
106
|
+
// Keep the Factory directory for shared process/lock identity and existing run receipts.
|
|
107
|
+
get root() { return runtimeRoot(existsSync(this.directory) ? realpathSync.native(this.directory) : this.directory); }
|
|
126
108
|
async status() {
|
|
127
109
|
const selected = runtimeSelection(this.directory), values = selected ? runtimeValuesForStatus(selected, this.c.profile.values) : this.c.profile.values;
|
|
128
110
|
const java = typeof values.java === 'string' ? values.java : undefined, home = typeof values.ghidraHome === 'string' ? values.ghidraHome : undefined;
|
|
@@ -185,7 +167,7 @@ export class RuntimeManager {
|
|
|
185
167
|
const processes = await runtimeProcesses(this.directory), server = processes.find(p => p.kind === 'server');
|
|
186
168
|
return { state: missing.length ? 'not_ready' : 'installed', mode: selected?.mode ?? (home || java ? 'external' : 'unconfigured'), recommended: 'managed', ghidraVersion: version, java, ghidraHome: home,
|
|
187
169
|
...(selected ? { installation: selected.id, fingerprint: selected.fingerprint } : {}), missing, capabilities: { headless: !missing.length, decompiler: !missing.length, gui: !missing.length,
|
|
188
|
-
debugger: process.platform === 'darwin' ? { backend: 'system-lldb', requires: 'Apple developer tools and OS debugger authorization', checkedBy: 'ghidra doctor' } : { backend: 'host-debugger', checkedBy: 'ghidra doctor' } },
|
|
170
|
+
debugger: managedGhidraDebugger() ? { backend: 'managed-lldb', runtime: await ghidraDebuggerInstaller(this.c).status(), requires: 'OS debugger authorization', checkedBy: 'ghidra doctor' } : process.platform === 'darwin' ? { backend: 'system-lldb', requires: 'Apple developer tools and OS debugger authorization', checkedBy: 'ghidra doctor' } : { backend: 'host-debugger', checkedBy: 'ghidra doctor' } },
|
|
189
171
|
server: { mode: this.c.profile.values.server ? 'external' : 'local', state: this.c.profile.values.server ? 'configured' : server ? 'running' : 'stopped', ...(server ? { pid: server.pid } : {}) }, processes, installations, retainedStages: stages, lastCheck: lastCheck ? { ...lastCheck, appliesToSelection: lastCheck.fingerprint === selected?.fingerprint && !selected?.uninstalledAt } : undefined,
|
|
190
172
|
storage: { runtime: this.root, research: join(this.directory, 'workspace'), materials: join(this.directory, 'materials') } };
|
|
191
173
|
}
|
|
@@ -195,48 +177,15 @@ export class RuntimeManager {
|
|
|
195
177
|
const path = await cacheArtifact(artifact, cache, this.c.fetch, this.c.signal, offline);
|
|
196
178
|
items.push({ name: artifact.name, path, sha256: artifact.sha256, license: artifact.license });
|
|
197
179
|
}
|
|
180
|
+
if (managedGhidraDebugger())
|
|
181
|
+
for (const item of (await ghidraDebuggerInstaller(this.c).download(offline)).items)
|
|
182
|
+
items.push({ name: 'LLDB/Python', path: item.path, sha256: item.sha256, license: item.license });
|
|
198
183
|
return { state: 'downloaded', ghidraVersion: catalog.ghidraVersion, javaVersion: catalog.javaVersion, items };
|
|
199
184
|
}
|
|
200
185
|
async archive(artifact, provided, checksum, offline) {
|
|
201
186
|
if (provided === undefined)
|
|
202
187
|
return { path: await cacheArtifact(artifact, join(this.root, 'cache'), this.c.fetch, this.c.signal, offline), artifact };
|
|
203
|
-
|
|
204
|
-
await mkdir(cache, { recursive: true, mode: 0o700 });
|
|
205
|
-
const temporary = join(cache, 'local.partial-' + randomUUID());
|
|
206
|
-
const source = await open(path, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0));
|
|
207
|
-
try {
|
|
208
|
-
const metadata = await source.stat();
|
|
209
|
-
if (!metadata.isFile() || metadata.size > 2 * 1024 ** 3)
|
|
210
|
-
fail('invalid', 'Local runtime archive must be a regular file no larger than two GiB.');
|
|
211
|
-
const target = await open(temporary, 'wx', 0o600);
|
|
212
|
-
let size = 0;
|
|
213
|
-
try {
|
|
214
|
-
for await (const chunk of source.createReadStream({ autoClose: false })) {
|
|
215
|
-
if ((size += chunk.length) > 2 * 1024 ** 3)
|
|
216
|
-
fail('limit', 'Local runtime archive grew beyond two GiB.');
|
|
217
|
-
await target.writeFile(chunk);
|
|
218
|
-
}
|
|
219
|
-
await target.sync();
|
|
220
|
-
}
|
|
221
|
-
finally {
|
|
222
|
-
await target.close();
|
|
223
|
-
}
|
|
224
|
-
const hash = await fileSha256(temporary);
|
|
225
|
-
if (checksum !== undefined && hash !== text(checksum, 64).toLowerCase())
|
|
226
|
-
fail('binding', 'Local runtime archive differs from its expected SHA256.');
|
|
227
|
-
const format = (await readMagic(temporary)) === '504b' ? 'zip' : 'tgz', owned = join(cache, hash + '.' + format);
|
|
228
|
-
if (existsSync(owned)) {
|
|
229
|
-
if (await fileSha256(owned) !== hash)
|
|
230
|
-
fail('binding', 'Existing local-archive cache entry is corrupt; remove it before retrying.');
|
|
231
|
-
}
|
|
232
|
-
else
|
|
233
|
-
await rename(temporary, owned);
|
|
234
|
-
return { path: owned, artifact: { ...artifact, sha256: hash, format } };
|
|
235
|
-
}
|
|
236
|
-
finally {
|
|
237
|
-
await source.close();
|
|
238
|
-
await rm(temporary, { force: true });
|
|
239
|
-
}
|
|
188
|
+
return consumeArchive(resolve(this.c.cwd, text(provided, 4096)), join(this.root, 'cache'), artifact, checksum === undefined ? undefined : text(checksum, 64), this.c.signal);
|
|
240
189
|
}
|
|
241
190
|
async cleanupProbes() {
|
|
242
191
|
// A killed owner may leave a disposable validation server alive. Its authenticated
|
|
@@ -264,34 +213,29 @@ export class RuntimeManager {
|
|
|
264
213
|
}
|
|
265
214
|
}
|
|
266
215
|
async install(o) {
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
if (inputs.fingerprint !== receipt.fingerprint)
|
|
288
|
-
fail('binding', 'Installed runtime differs from its verified installation receipt.');
|
|
289
|
-
}
|
|
290
|
-
else {
|
|
291
|
-
let ghidraHome = external;
|
|
216
|
+
return withToolLock(this.directory, 'ghidra', async () => {
|
|
217
|
+
await assertUnused(this.directory, 'ghidra');
|
|
218
|
+
await this.cleanupProbes();
|
|
219
|
+
if (o.executable && o.archive)
|
|
220
|
+
fail('invalid', 'Choose --executable or --archive.');
|
|
221
|
+
if (o.archiveSha256 && !o.archive || o.javaArchiveSha256 && !o.javaArchive)
|
|
222
|
+
fail('invalid', 'Archive checksum requires its archive path.');
|
|
223
|
+
if (o.debuggerArchiveSha256 && !o.debuggerArchive)
|
|
224
|
+
fail('invalid', 'Debugger archive checksum requires its archive path.');
|
|
225
|
+
if ((o.debuggerArchive || o.debuggerArchiveSha256) && !managedGhidraDebugger())
|
|
226
|
+
fail('unsupported', 'A managed debugger archive requires macOS 15+ ARM64.');
|
|
227
|
+
const catalog = runtimeCatalog(), offline = Boolean(o.offline), external = o.executable ? await externalGhidra(resolve(this.c.cwd, text(o.executable, 4096))) : undefined;
|
|
228
|
+
const ghidra = external ? undefined : await this.archive(catalog.ghidra, o.archive, o.archiveSha256, offline);
|
|
229
|
+
const java = o.java ? await realpath(resolve(this.c.cwd, text(o.java, 4096))) : undefined;
|
|
230
|
+
if (java && o.javaArchive)
|
|
231
|
+
fail('invalid', 'Choose --java or --java-archive.');
|
|
232
|
+
const jdk = java ? undefined : await this.archive(catalog.java, o.javaArchive, o.javaArchiveSha256, offline);
|
|
233
|
+
const identity = digest({ schema: 1, platform: process.platform, architecture: process.arch, external, java, ghidra: ghidra?.artifact.sha256, jdk: jdk?.artifact.sha256, bridge: pinnedMcpJar });
|
|
234
|
+
const receipt = await installationStage(this.root, identity, async (temporary, installation) => {
|
|
235
|
+
let ghidraHome = external, nativeOverlay;
|
|
292
236
|
if (ghidra) {
|
|
293
237
|
const extracted = join(temporary, 'ghidra-extract');
|
|
294
|
-
await extractArchive(ghidra.path, extracted, ghidra.artifact.format);
|
|
238
|
+
await extractArchive(ghidra.path, extracted, ghidra.artifact.format, this.c.signal);
|
|
295
239
|
const found = await findRoot(extracted, 'Ghidra/application.properties');
|
|
296
240
|
if (!found)
|
|
297
241
|
fail('configuration', 'Archive omitted a complete Ghidra installation.');
|
|
@@ -301,7 +245,8 @@ export class RuntimeManager {
|
|
|
301
245
|
const host = process.arch === 'arm64' ? 'mac_arm_64' : 'mac_x86_64';
|
|
302
246
|
if (process.platform === 'darwin' && !existsSync(join(ghidraHome, 'Ghidra/Features/Decompiler/os', host, 'decompile'))) {
|
|
303
247
|
const bottle = await cacheArtifact(catalog.ghidra, join(this.root, 'cache'), this.c.fetch, this.c.signal, offline), nativeRoot = join(temporary, 'native-extract');
|
|
304
|
-
|
|
248
|
+
nativeOverlay = catalog.ghidra;
|
|
249
|
+
await extractArchive(bottle, nativeRoot, 'tgz', this.c.signal);
|
|
305
250
|
const nativeHome = join(nativeRoot, catalog.ghidra.root);
|
|
306
251
|
for (const module of ['Decompiler', 'FileFormats'])
|
|
307
252
|
await cp(join(nativeHome, 'Ghidra/Features', module, 'os', host), join(ghidraHome, 'Ghidra/Features', module, 'os', host), { recursive: true, errorOnExist: true });
|
|
@@ -311,7 +256,7 @@ export class RuntimeManager {
|
|
|
311
256
|
let javaPath = java;
|
|
312
257
|
if (jdk) {
|
|
313
258
|
const extracted = join(temporary, 'jdk-extract');
|
|
314
|
-
await extractArchive(jdk.path, extracted, jdk.artifact.format);
|
|
259
|
+
await extractArchive(jdk.path, extracted, jdk.artifact.format, this.c.signal);
|
|
315
260
|
const home = await findRoot(extracted, 'bin/java' + suffix);
|
|
316
261
|
if (!home)
|
|
317
262
|
fail('configuration', 'Java archive omitted a JDK.');
|
|
@@ -319,64 +264,56 @@ export class RuntimeManager {
|
|
|
319
264
|
await rm(extracted, { recursive: true, force: true });
|
|
320
265
|
javaPath = join(temporary, 'jdk/bin/java' + suffix);
|
|
321
266
|
}
|
|
322
|
-
inputs = await nativeInputs({ ...this.c.profile.values, java: javaPath, ghidraHome });
|
|
267
|
+
const inputs = await nativeInputs({ ...this.c.profile.values, java: javaPath, ghidraHome }, undefined, this.c);
|
|
323
268
|
await this.probe(inputs, join(temporary, 'validation'));
|
|
324
269
|
await rm(join(temporary, 'validation'), { recursive: true, force: true });
|
|
325
270
|
const receipt = { schema: 1, id: identity, ghidraVersion: inputs.ghidraVersion, fingerprint: inputs.fingerprint, java: java ?? join(installation, 'jdk/bin/java' + suffix), ghidraHome: external ?? join(installation, 'ghidra'),
|
|
326
|
-
archives: [...(ghidra ? [{ sha256: ghidra.artifact.sha256, source: o.archive ? 'local' : catalog.ghidra.url }] : []), ...(jdk ? [{ sha256: jdk.artifact.sha256, source: o.javaArchive ? 'local' : catalog.java.url }] : [])], verifiedAt: new Date().toISOString(), checks: ['jdk', 'native-decompiler', 'local-server-reader-publisher-authority'] };
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
await parent.sync();
|
|
336
|
-
}
|
|
337
|
-
finally {
|
|
338
|
-
await parent.close();
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
selected = { schema: 1, mode: external ? 'external' : 'managed', id: identity, ghidraHome: external ?? join(installation, 'ghidra'), java: java ?? join(installation, 'jdk/bin/java' + suffix), fingerprint: inputs.fingerprint, selectedAt: new Date().toISOString() };
|
|
271
|
+
archives: [...(nativeOverlay ? [{ sha256: nativeOverlay.sha256, source: nativeOverlay.url }] : []), ...(ghidra ? [{ sha256: ghidra.artifact.sha256, source: o.archive ? 'local' : catalog.ghidra.url }] : []), ...(jdk ? [{ sha256: jdk.artifact.sha256, source: o.javaArchive ? 'local' : catalog.java.url }] : [])], verifiedAt: new Date().toISOString(), checks: ['jdk', 'native-decompiler', 'local-server-reader-publisher-authority'] };
|
|
272
|
+
return receipt;
|
|
273
|
+
}, async (receipt) => {
|
|
274
|
+
const inputs = await nativeInputs({ ...this.c.profile.values, java: receipt.java, ghidraHome: receipt.ghidraHome }, undefined, this.c);
|
|
275
|
+
if (inputs.fingerprint !== receipt.fingerprint)
|
|
276
|
+
fail('binding', 'Installed runtime differs from its verified installation receipt.');
|
|
277
|
+
}, this.c.signal);
|
|
278
|
+
const selected = { schema: 1, mode: external ? 'external' : 'managed', id: identity, ghidraHome: String(receipt.ghidraHome), java: String(receipt.java), fingerprint: String(receipt.fingerprint), selectedAt: new Date().toISOString() };
|
|
279
|
+
const debuggerRuntime = managedGhidraDebugger() ? await prepareGhidraDebugger(this.c, { archive: o.debuggerArchive, archiveSha256: o.debuggerArchiveSha256, offline: o.offline }) : undefined;
|
|
343
280
|
await runtimeWrite(join(this.root, 'selection.json'), selected);
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
}
|
|
347
|
-
catch (error) {
|
|
348
|
-
await runtimeWrite(join(temporary, 'failure.json'), { state: 'failed', code: error instanceof CliError ? error.code : 'installation', message: error instanceof Error ? error.message : 'Runtime installation failed' });
|
|
349
|
-
if (error instanceof CliError)
|
|
350
|
-
throw new CliError(error.message, { code: error.code, result: { ...(error.result && typeof error.result === 'object' ? error.result : {}), diagnostics: temporary } });
|
|
351
|
-
throw error;
|
|
352
|
-
}
|
|
353
|
-
finally {
|
|
354
|
-
if (complete)
|
|
355
|
-
await rm(temporary, { recursive: true, force: true });
|
|
356
|
-
}
|
|
281
|
+
return { state: 'installed', ...selected, checks: receipt.checks, ...(debuggerRuntime ? { debugger: { backend: 'managed-lldb', installation: debuggerRuntime.id, fingerprint: debuggerRuntime.fingerprint } } : {}) };
|
|
282
|
+
}, this.c.signal);
|
|
357
283
|
}
|
|
358
284
|
async uninstall(purgeCache = false) {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
285
|
+
return withToolLock(this.directory, 'ghidra', async () => {
|
|
286
|
+
await assertUnused(this.directory, 'ghidra');
|
|
287
|
+
await this.cleanupProbes();
|
|
288
|
+
const selected = runtimeSelection(this.directory);
|
|
289
|
+
if (!selected)
|
|
290
|
+
fail('configuration', 'No managed selection exists; externally configured profile paths are never removed.');
|
|
291
|
+
if (purgeCache && selected.id) {
|
|
292
|
+
const receipt = object(JSON.parse(await readFile(join(this.root, 'installations', selected.id, 'ready.json'), 'utf8')));
|
|
293
|
+
for (const a of Array.isArray(receipt.archives) ? receipt.archives : []) {
|
|
294
|
+
const sha = String(object(a).sha256);
|
|
295
|
+
if (!/^[a-f0-9]{64}$/.test(sha))
|
|
296
|
+
fail('binding', 'Invalid cached component identity.');
|
|
297
|
+
for (const ext of ['zip', 'tgz'])
|
|
298
|
+
await rm(join(this.root, 'cache', sha + '.' + ext), { force: true });
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
if (managedGhidraDebugger() && (await ghidraDebuggerInstaller(this.c).status()).state === 'installed')
|
|
302
|
+
await ghidraDebuggerInstaller(this.c).uninstall(purgeCache);
|
|
303
|
+
if (selected.id)
|
|
304
|
+
await removeInstallation(this.root, selected.id);
|
|
305
|
+
await runtimeWrite(join(this.root, 'selection.json'), { ...selected, uninstalledAt: new Date().toISOString() });
|
|
306
|
+
// Retain the selection: an explicit external profile must never become an implicit fallback.
|
|
307
|
+
return { state: 'uninstalled', mode: selected.mode, externalInstallationPreserved: selected.mode === 'external', researchPreserved: true, materialsPreserved: true, cachePreserved: !purgeCache };
|
|
308
|
+
}, this.c.signal);
|
|
373
309
|
}
|
|
374
310
|
async probe(inputs, root) {
|
|
375
311
|
await mkdir(root, { recursive: true, mode: 0o700 });
|
|
376
|
-
const classes = await nativeHelpers(root, inputs), log = join(root, 'doctor.log');
|
|
312
|
+
const classes = await nativeHelpers(root, inputs, this.c), log = join(root, 'doctor.log');
|
|
377
313
|
let output;
|
|
378
314
|
try {
|
|
379
|
-
output = await
|
|
315
|
+
output = await runTool(this.c, { tool: 'ghidra', role: 'doctor', installation: inputs.fingerprint, executable: inputs.java, arguments: ['-Djava.awt.headless=true', '-Dghidra.home=' + inputs.ghidraHome, ...nativeJvmDirectories(root), '-cp', classes + delimiter + inputs.classpath, 'InsightRuntimeDoctor'],
|
|
316
|
+
cwd: root, environment: { PATH: dirname(inputs.java), HOME: root, TMPDIR: root }, timeoutMs: 90000, maxOutputBytes: 1024 * 1024 });
|
|
380
317
|
}
|
|
381
318
|
catch (error) {
|
|
382
319
|
await runtimeWrite(log, { failure: String(error.stderr ?? error) });
|
|
@@ -403,11 +340,19 @@ export class RuntimeManager {
|
|
|
403
340
|
async doctor() {
|
|
404
341
|
await this.cleanupProbes();
|
|
405
342
|
const root = join(this.root, 'checks', randomUUID()), values = runtimeValues(this.directory, this.c.profile.values);
|
|
406
|
-
const inputs = await nativeInputs(values), native = await this.probe(inputs, root);
|
|
343
|
+
const inputs = await nativeInputs(values, undefined, this.c), native = await this.probe(inputs, root);
|
|
407
344
|
let debuggerCheck = { state: 'host_specific' };
|
|
408
|
-
if (
|
|
345
|
+
if (managedGhidraDebugger())
|
|
409
346
|
try {
|
|
410
|
-
const
|
|
347
|
+
const selected = await ghidraDebuggerInstaller(this.c).selected();
|
|
348
|
+
debuggerCheck = { ...(await ghidraDebuggerInstaller(this.c).doctor()), backend: 'managed-lldb', installation: selected.id };
|
|
349
|
+
}
|
|
350
|
+
catch {
|
|
351
|
+
debuggerCheck = { state: 'missing', backend: 'managed-lldb', reason: 'Run insight-cli ghidra install to prepare or repair its LLDB/Python runtime' };
|
|
352
|
+
}
|
|
353
|
+
else if (process.platform === 'darwin')
|
|
354
|
+
try {
|
|
355
|
+
const checked = await runTool(this.c, { tool: 'ghidra', role: 'debugger-doctor', executable: '/usr/bin/lldb', arguments: ['--no-lldbinit', '--batch', '-o', 'script import lldb,sys; print("INSIGHT_LLDB_PYTHON_OK")'], environment: { PATH: '/usr/bin:/bin', HOME: root, TMPDIR: root }, timeoutMs: 30000, maxOutputBytes: 65536 });
|
|
411
356
|
debuggerCheck = { state: checked.stdout.includes('INSIGHT_LLDB_PYTHON_OK') ? 'ready' : 'missing', backend: 'system-lldb' };
|
|
412
357
|
}
|
|
413
358
|
catch {
|
|
@@ -421,24 +366,20 @@ export class RuntimeManager {
|
|
|
421
366
|
}
|
|
422
367
|
}
|
|
423
368
|
function runtimeValuesForStatus(selection, values) { return { ...values, java: selection.java, ghidraHome: selection.ghidraHome }; }
|
|
424
|
-
async function readMagic(path) { const handle = await open(path, 'r'); try {
|
|
425
|
-
const b = Buffer.alloc(2);
|
|
426
|
-
await handle.read(b, 0, 2, 0);
|
|
427
|
-
return b.toString('hex');
|
|
428
|
-
}
|
|
429
|
-
finally {
|
|
430
|
-
await handle.close();
|
|
431
|
-
} }
|
|
432
369
|
export function runtimeCommands(exclusive) {
|
|
433
370
|
const source = [{ flags: '--archive <path>', description: 'Local Ghidra zip/tar.gz; missing dependencies are downloaded' },
|
|
371
|
+
{ flags: '--debugger-archive <path>', description: 'Local pinned LLDB/Python runtime archive (macOS 15+ ARM64)' },
|
|
372
|
+
{ flags: '--debugger-archive-sha256 <sha256>', description: 'Expected SHA256 for the supplied debugger runtime archive' },
|
|
434
373
|
{ flags: '--archive-sha256 <sha256>', description: 'Expected SHA256 for the supplied Ghidra archive' },
|
|
435
374
|
{ flags: '--java-archive <path>', description: 'Local Java 21 JDK zip/tar.gz' },
|
|
436
375
|
{ flags: '--java-archive-sha256 <sha256>', description: 'Expected SHA256 for the supplied JDK archive' },
|
|
437
376
|
{ flags: '--java <path>', description: 'Use an external Java 21 JDK executable' },
|
|
438
377
|
{ flags: '--executable <path>', description: 'Use an external Ghidra launcher or installation directory; never deleted' },
|
|
439
378
|
{ flags: '--offline', description: 'Use local archives/cache only; never access the network' }];
|
|
440
|
-
return
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
379
|
+
return sharedLifecycle({ id: 'ghidra', description: 'Complete Ghidra runtime', components: [], installOptions: source, lifecycle: {
|
|
380
|
+
download: (o, c) => exclusive(c, () => new RuntimeManager(c).download(Boolean(o.offline)), false),
|
|
381
|
+
install: (o, c) => exclusive(c, () => new RuntimeManager(c).install(o)),
|
|
382
|
+
uninstall: (o, c) => exclusive(c, () => new RuntimeManager(c).uninstall(Boolean(o.purgeCache))),
|
|
383
|
+
doctor: (_o, c) => exclusive(c, () => new RuntimeManager(c).doctor(), false),
|
|
384
|
+
} });
|
|
444
385
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { readFileSync, existsSync } from 'node:fs';
|
|
2
|
-
import { join, isAbsolute } from 'node:path';
|
|
1
|
+
import { readFileSync, existsSync, realpathSync } from 'node:fs';
|
|
2
|
+
import { join, isAbsolute, resolve } from 'node:path';
|
|
3
3
|
import { fail, object } from './model.js';
|
|
4
4
|
export const runtimeRoot = (directory) => join(directory, 'runtime');
|
|
5
5
|
export function runtimeSelection(directory) {
|
|
@@ -9,8 +9,25 @@ export function runtimeSelection(directory) {
|
|
|
9
9
|
const value = object(JSON.parse(readFileSync(path, 'utf8')));
|
|
10
10
|
if (value.schema !== 1 || !['managed', 'external'].includes(String(value.mode)) || typeof value.java !== 'string' || !isAbsolute(value.java) || typeof value.ghidraHome !== 'string' || !isAbsolute(value.ghidraHome) || !/^[a-f0-9]{64}$/.test(String(value.fingerprint)))
|
|
11
11
|
fail('binding', 'Runtime selection receipt is invalid.');
|
|
12
|
-
if (value.mode === 'managed'
|
|
13
|
-
|
|
12
|
+
if (value.mode === 'managed') {
|
|
13
|
+
const id = String(value.id), recordedProfile = resolve(value.ghidraHome, '../../../..');
|
|
14
|
+
if (!/^[a-f0-9]{64}$/.test(id) || value.ghidraHome !== join(runtimeRoot(recordedProfile), 'installations', id, 'ghidra'))
|
|
15
|
+
fail('binding', 'Managed runtime moved outside its owned installation.');
|
|
16
|
+
// Workspace resolves AppData physically; older install receipts can retain a profile
|
|
17
|
+
// alias such as /tmp -> /private/tmp. Accept that same profile, never an inner escape.
|
|
18
|
+
let profile, recorded, home;
|
|
19
|
+
try {
|
|
20
|
+
profile = realpathSync.native(directory);
|
|
21
|
+
recorded = realpathSync.native(recordedProfile);
|
|
22
|
+
if (existsSync(value.ghidraHome))
|
|
23
|
+
home = realpathSync.native(value.ghidraHome);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
fail('binding', 'Managed runtime profile ownership could not be verified.');
|
|
27
|
+
}
|
|
28
|
+
if (recorded !== profile || home !== undefined && home !== join(runtimeRoot(profile), 'installations', id, 'ghidra'))
|
|
29
|
+
fail('binding', 'Managed runtime moved outside its owned installation.');
|
|
30
|
+
}
|
|
14
31
|
return value;
|
|
15
32
|
}
|
|
16
33
|
export function runtimeValues(directory, values) {
|
package/dist/src/server.d.ts
CHANGED
|
@@ -10,6 +10,17 @@ export interface ServerBinding {
|
|
|
10
10
|
readerSecret: string;
|
|
11
11
|
publisherSecret: string;
|
|
12
12
|
}
|
|
13
|
+
interface LocalServer extends ServerBinding {
|
|
14
|
+
toolProcessId?: string;
|
|
15
|
+
mode: 'local';
|
|
16
|
+
instance: string;
|
|
17
|
+
port: number;
|
|
18
|
+
identityPort: number;
|
|
19
|
+
keySecret: string;
|
|
20
|
+
tokenSecret: string;
|
|
21
|
+
phase: 'seeded' | 'initialized' | 'running' | 'stopped';
|
|
22
|
+
pid?: number;
|
|
23
|
+
}
|
|
13
24
|
/** Own local startup; external profiles connect without taking ownership of their server. */
|
|
14
25
|
export declare class GhidraServer {
|
|
15
26
|
readonly directory: string;
|
|
@@ -42,5 +53,7 @@ export declare class GhidraServer {
|
|
|
42
53
|
private identity;
|
|
43
54
|
stop(): Promise<void>;
|
|
44
55
|
}
|
|
56
|
+
export declare function serverIdentity(local: LocalServer, c: CommandContext): Promise<Record<string, unknown>>;
|
|
45
57
|
/** Stop only the authenticated owned server recorded below this workspace/probe root. */
|
|
46
58
|
export declare function stopLocalServer(directory: string, c: CommandContext): Promise<void>;
|
|
59
|
+
export {};
|
package/dist/src/server.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { launchProcess, terminateProcess } from './tool-runtime/supervisor.js';
|
|
2
|
+
import { runTool } from './tool-runtime/run.js';
|
|
1
3
|
import { randomUUID, randomBytes, createHash } from 'node:crypto';
|
|
2
|
-
import { spawn } from 'node:child_process';
|
|
3
4
|
import { readFile, mkdir, open, rename, readdir, stat, chmod, realpath } from 'node:fs/promises';
|
|
4
5
|
import { delimiter, dirname, join, resolve } from 'node:path';
|
|
5
6
|
import { createServer } from 'node:net';
|
|
@@ -73,48 +74,19 @@ export class GhidraServer {
|
|
|
73
74
|
async run(label, main, args, environment = {}, input, acceptedCodes = [0], timeoutMilliseconds = 120000) {
|
|
74
75
|
const root = join(this.root(), 'calls', label + '-' + randomUUID());
|
|
75
76
|
await mkdir(root, { recursive: true, mode: 0o700 });
|
|
76
|
-
const classes = await nativeHelpers(this.directory, this.inputs);
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const exited = new Promise((resolve, reject) => { child.once('error', reject); child.once('exit', resolve); });
|
|
81
|
-
exited.catch(() => { });
|
|
82
|
-
await log.close();
|
|
83
|
-
let output = '', overflow = false;
|
|
84
|
-
child.stdout.on('data', chunk => { if (!overflow)
|
|
85
|
-
output += chunk.toString(); if (Buffer.byteLength(output) > 1024 * 1024) {
|
|
86
|
-
overflow = true;
|
|
87
|
-
child.kill('SIGTERM');
|
|
88
|
-
} });
|
|
89
|
-
const abort = () => child.kill('SIGTERM');
|
|
90
|
-
this.c.signal.addEventListener('abort', abort, { once: true });
|
|
91
|
-
const timer = setTimeout(abort, timeoutMilliseconds);
|
|
92
|
-
const force = setTimeout(() => { if (child.exitCode === null && child.signalCode === null)
|
|
93
|
-
child.kill('SIGKILL'); }, timeoutMilliseconds + 5000);
|
|
77
|
+
const classes = await nativeHelpers(this.directory, this.inputs, this.c);
|
|
78
|
+
const output = await runTool(this.c, { tool: 'ghidra', role: label, installation: this.inputs.fingerprint, executable: this.inputs.java, arguments: ['-Djava.awt.headless=true', '-Dghidra.home=' + this.inputs.ghidraHome,
|
|
79
|
+
...nativeJvmDirectories(root), ...nativeExtensionArguments(this.inputs), '-cp', classes + delimiter + this.inputs.classpath, main, ...args], cwd: root, environment, input, acceptedCodes, timeoutMs: timeoutMilliseconds, maxOutputBytes: 1024 * 1024 });
|
|
80
|
+
let result;
|
|
94
81
|
try {
|
|
95
|
-
|
|
96
|
-
child.stdin.end(input);
|
|
97
|
-
if (this.c.signal.aborted)
|
|
98
|
-
abort();
|
|
99
|
-
const code = await exited;
|
|
100
|
-
if (code === null || !acceptedCodes.includes(code) || overflow)
|
|
101
|
-
fail('authorization', 'Native server operation could not be verified; its owned diagnostic stage is retained.');
|
|
102
|
-
let result;
|
|
103
|
-
try {
|
|
104
|
-
result = object(parseDomainJson(output));
|
|
105
|
-
}
|
|
106
|
-
catch {
|
|
107
|
-
fail('malformed', 'Native server operation returned malformed content.');
|
|
108
|
-
}
|
|
109
|
-
if (result.error || result.state === 'failed')
|
|
110
|
-
fail('authorization', 'Native server operation did not establish its outcome.');
|
|
111
|
-
return result;
|
|
82
|
+
result = object(parseDomainJson(output.stdout));
|
|
112
83
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
clearTimeout(force);
|
|
116
|
-
this.c.signal.removeEventListener('abort', abort);
|
|
84
|
+
catch {
|
|
85
|
+
fail('malformed', 'Native server operation returned malformed content.');
|
|
117
86
|
}
|
|
87
|
+
if (result.error || result.state === 'failed')
|
|
88
|
+
fail('authorization', 'Native server operation did not establish its outcome.');
|
|
89
|
+
return result;
|
|
118
90
|
}
|
|
119
91
|
async credentials(binding, role) {
|
|
120
92
|
const url = new URL(binding.origin);
|
|
@@ -358,20 +330,21 @@ export class GhidraServer {
|
|
|
358
330
|
await this.run('certificate', 'InsightKeytool', [keystore], { INSIGHT_KEYSTORE_PASSWORD: await this.c.secrets.require(local.keySecret) });
|
|
359
331
|
await chmod(keystore, 0o600);
|
|
360
332
|
}
|
|
361
|
-
const classes = await nativeHelpers(this.directory, this.inputs);
|
|
333
|
+
const classes = await nativeHelpers(this.directory, this.inputs, this.c);
|
|
362
334
|
const processRoot = join(root, 'processes', randomUUID());
|
|
363
335
|
await mkdir(processRoot, { recursive: true, mode: 0o700 });
|
|
364
336
|
const log = await open(join(processRoot, 'runtime.log'), 'a', 0o600);
|
|
365
|
-
const child =
|
|
337
|
+
const child = await launchProcess(this.c.appArguments.AppDataDirectory, { tool: 'ghidra', role: 'server', installation: this.inputs.fingerprint, metadata: { serverDirectory: this.directory } }, this.inputs.java, ['-Djava.awt.headless=true', '-Dghidra.home=' + this.inputs.ghidraHome,
|
|
366
338
|
...nativeJvmDirectories(processRoot), '-cp', classes + delimiter + (this.inputs.serverClasspath ?? this.inputs.classpath),
|
|
367
339
|
'InsightServerMain', data, String(local.port), String(local.identityPort), local.instance, keystore], { cwd: processRoot, detached: true, windowsHide: true, env: { PATH: this.c.environment.PATH ?? process.env.PATH, HOME: processRoot, TMPDIR: processRoot,
|
|
368
|
-
INSIGHT_KEYSTORE_PASSWORD: await this.c.secrets.require(local.keySecret), INSIGHT_SERVER_TOKEN: await this.c.secrets.require(local.tokenSecret) }, stdio: ['ignore', log.fd, log.fd] });
|
|
340
|
+
INSIGHT_KEYSTORE_PASSWORD: await this.c.secrets.require(local.keySecret), INSIGHT_SERVER_TOKEN: await this.c.secrets.require(local.tokenSecret) }, stdio: ['ignore', log.fd, log.fd] }, { signal: this.c.signal });
|
|
369
341
|
child.on('error', () => { });
|
|
370
342
|
child.unref();
|
|
371
343
|
await log.close();
|
|
372
344
|
if (!child.pid)
|
|
373
345
|
fail('launch', 'Owned local Ghidra server could not be started.');
|
|
374
346
|
this.state.child = child;
|
|
347
|
+
local.toolProcessId = child.toolProcessId;
|
|
375
348
|
local.pid = child.pid;
|
|
376
349
|
local.phase = 'running';
|
|
377
350
|
await durable(saved, local);
|
|
@@ -401,7 +374,7 @@ export class GhidraServer {
|
|
|
401
374
|
identity(local) { return serverIdentity(local, this.c); }
|
|
402
375
|
async stop() { await stopLocalServer(this.directory, this.c); this.state.child = undefined; this.state.initializing = undefined; }
|
|
403
376
|
}
|
|
404
|
-
async function serverIdentity(local, c) {
|
|
377
|
+
export async function serverIdentity(local, c) {
|
|
405
378
|
const token = await c.secrets.require(local.tokenSecret);
|
|
406
379
|
const response = await c.fetch(`http://127.0.0.1:${local.identityPort}/identity`, { redirect: 'error',
|
|
407
380
|
signal: AbortSignal.timeout(1000), headers: { Authorization: 'Bearer ' + token } });
|
|
@@ -448,7 +421,10 @@ export async function stopLocalServer(directory, c) {
|
|
|
448
421
|
return;
|
|
449
422
|
if (live(local.pid)) {
|
|
450
423
|
await serverIdentity(local, c);
|
|
451
|
-
|
|
424
|
+
if (local.toolProcessId)
|
|
425
|
+
await terminateProcess(c.appArguments.AppDataDirectory, local.toolProcessId, false, async (r) => Number((await serverIdentity(local, c)).pid) === r.pid);
|
|
426
|
+
else
|
|
427
|
+
process.kill(local.pid, 'SIGTERM');
|
|
452
428
|
for (let i = 0; i < 100 && live(local.pid); i++)
|
|
453
429
|
await delay(50);
|
|
454
430
|
if (live(local.pid))
|