@eyeauras/insight-cli 0.2.0 → 0.2.2

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.
Files changed (387) hide show
  1. package/.cli-package-build.json +1 -1
  2. package/README.md +25 -0
  3. package/SKILL.md +38 -54
  4. package/dist/src/binary.d.ts +3 -0
  5. package/dist/src/binary.js +74 -0
  6. package/dist/src/capture.d.ts +3 -0
  7. package/dist/src/capture.js +220 -0
  8. package/dist/src/cli.js +57 -12
  9. package/dist/src/contexts.d.ts +5 -0
  10. package/dist/src/contexts.js +42 -16
  11. package/dist/src/debugger-caller.d.ts +17 -0
  12. package/dist/src/debugger-caller.js +129 -0
  13. package/dist/src/debugger-launch.d.ts +2 -0
  14. package/dist/src/debugger-launch.js +17 -0
  15. package/dist/src/debugger-results.d.ts +1 -0
  16. package/dist/src/debugger-results.js +8 -0
  17. package/dist/src/debugger-supervisor.js +56 -13
  18. package/dist/src/debugger.js +16 -7
  19. package/dist/src/die.d.ts +12 -0
  20. package/dist/src/die.js +127 -0
  21. package/dist/src/dnspy-runtime.d.ts +8 -0
  22. package/dist/src/dnspy-runtime.js +46 -0
  23. package/dist/src/dnspy.d.ts +22 -0
  24. package/dist/src/dnspy.js +160 -0
  25. package/dist/src/dotnet-diagnostics.d.ts +13 -0
  26. package/dist/src/dotnet-diagnostics.js +101 -0
  27. package/dist/src/frida-worker.d.ts +1 -0
  28. package/dist/src/frida-worker.js +125 -0
  29. package/dist/src/frida.d.ts +16 -0
  30. package/dist/src/frida.js +125 -0
  31. package/dist/src/ghidra-debugger-runtime.d.ts +7 -0
  32. package/dist/src/ghidra-debugger-runtime.js +31 -0
  33. package/dist/src/ghidra-processes.d.ts +6 -0
  34. package/dist/src/ghidra-processes.js +121 -0
  35. package/dist/src/ghidra.js +6 -6
  36. package/dist/src/ilspy.d.ts +7 -0
  37. package/dist/src/ilspy.js +122 -0
  38. package/dist/src/lldb.d.ts +10 -0
  39. package/dist/src/lldb.js +99 -0
  40. package/dist/src/llvm.d.ts +6 -0
  41. package/dist/src/llvm.js +133 -0
  42. package/dist/src/managed-heap.d.ts +4 -0
  43. package/dist/src/managed-heap.js +73 -0
  44. package/dist/src/managed-metadata.d.ts +11 -0
  45. package/dist/src/managed-metadata.js +66 -0
  46. package/dist/src/mitmproxy.d.ts +55 -0
  47. package/dist/src/mitmproxy.js +172 -0
  48. package/dist/src/native-inputs.d.ts +3 -2
  49. package/dist/src/native-inputs.js +9 -4
  50. package/dist/src/package-version.d.ts +1 -0
  51. package/dist/src/package-version.js +3 -0
  52. package/dist/src/procmon-config.d.ts +2 -0
  53. package/dist/src/procmon-config.js +15 -0
  54. package/dist/src/procmon-events.d.ts +13 -0
  55. package/dist/src/procmon-events.js +82 -0
  56. package/dist/src/procmon.d.ts +4 -0
  57. package/dist/src/procmon.js +107 -0
  58. package/dist/src/research.d.ts +11 -2
  59. package/dist/src/research.js +5 -3
  60. package/dist/src/runtime-catalog.d.ts +5 -10
  61. package/dist/src/runtime-catalog.js +4 -5
  62. package/dist/src/runtime-manager.d.ts +27 -3
  63. package/dist/src/runtime-manager.js +100 -159
  64. package/dist/src/runtime-selection.js +21 -4
  65. package/dist/src/server.d.ts +13 -0
  66. package/dist/src/server.js +21 -45
  67. package/dist/src/sevenzip.d.ts +15 -0
  68. package/dist/src/sevenzip.js +119 -0
  69. package/dist/src/strace.d.ts +10 -0
  70. package/dist/src/strace.js +71 -0
  71. package/dist/src/text-window.d.ts +11 -0
  72. package/dist/src/text-window.js +6 -0
  73. package/dist/src/tool-runtime/archives.d.ts +10 -0
  74. package/dist/src/{runtime-archives.js → tool-runtime/archives.js} +91 -24
  75. package/dist/src/tool-runtime/catalog.d.ts +3 -0
  76. package/dist/src/tool-runtime/catalog.js +13 -0
  77. package/dist/src/tool-runtime/commands.d.ts +9 -0
  78. package/dist/src/tool-runtime/commands.js +39 -0
  79. package/dist/src/tool-runtime/deadline.d.ts +11 -0
  80. package/dist/src/tool-runtime/deadline.js +32 -0
  81. package/dist/src/tool-runtime/definition.d.ts +73 -0
  82. package/dist/src/tool-runtime/definition.js +49 -0
  83. package/dist/src/tool-runtime/dotnet.d.ts +4 -0
  84. package/dist/src/tool-runtime/dotnet.js +22 -0
  85. package/dist/src/tool-runtime/identity.d.ts +6 -0
  86. package/dist/src/tool-runtime/identity.js +50 -0
  87. package/dist/src/tool-runtime/installer.d.ts +101 -0
  88. package/dist/src/tool-runtime/installer.js +180 -0
  89. package/dist/src/tool-runtime/java-arguments.d.ts +6 -0
  90. package/dist/src/tool-runtime/java-arguments.js +44 -0
  91. package/dist/src/tool-runtime/launch-worker.d.ts +1 -0
  92. package/dist/src/tool-runtime/launch-worker.js +58 -0
  93. package/dist/src/tool-runtime/run.d.ts +51 -0
  94. package/dist/src/tool-runtime/run.js +159 -0
  95. package/dist/src/tool-runtime/store.d.ts +15 -0
  96. package/dist/src/tool-runtime/store.js +219 -0
  97. package/dist/src/tool-runtime/supervisor.d.ts +57 -0
  98. package/dist/src/tool-runtime/supervisor.js +269 -0
  99. package/dist/src/tool-runtime/windows-job.d.ts +22 -0
  100. package/dist/src/tool-runtime/windows-job.js +43 -0
  101. package/dist/src/toolbox.d.ts +84 -0
  102. package/dist/src/toolbox.js +35 -0
  103. package/dist/src/tshark.d.ts +23 -0
  104. package/dist/src/tshark.js +174 -0
  105. package/dist/src/windbg.d.ts +14 -0
  106. package/dist/src/windbg.js +119 -0
  107. package/dist/src/workspace.d.ts +1 -0
  108. package/dist/src/workspace.js +6 -0
  109. package/package.json +5 -4
  110. package/references/agent-execution.md +36 -0
  111. package/references/agent-setup.md +61 -0
  112. package/references/artifacts.md +5 -0
  113. package/references/debugger.md +22 -0
  114. package/references/ilspy.md +33 -0
  115. package/references/managed-runtime.md +53 -7
  116. package/references/native/InsightPythonWheels.java +283 -2
  117. package/references/native/InsightTraceState.java +28 -13
  118. package/references/native-workflows.md +10 -0
  119. package/references/setup.md +2 -1
  120. package/runtime/managed/insight-heap/Azure.Core.dll +0 -0
  121. package/runtime/managed/insight-heap/Azure.Identity.dll +0 -0
  122. package/runtime/managed/insight-heap/Insight.Heap.csproj +1 -0
  123. package/runtime/managed/insight-heap/Insight.Heap.deps.json +391 -0
  124. package/runtime/managed/insight-heap/Insight.Heap.dll +0 -0
  125. package/runtime/managed/insight-heap/Insight.Heap.runtimeconfig.json +13 -0
  126. package/runtime/managed/insight-heap/Microsoft.Bcl.AsyncInterfaces.dll +0 -0
  127. package/runtime/managed/insight-heap/Microsoft.Diagnostics.NETCore.Client.dll +0 -0
  128. package/runtime/managed/insight-heap/Microsoft.Diagnostics.Runtime.dll +0 -0
  129. package/runtime/managed/insight-heap/Microsoft.Extensions.Configuration.Abstractions.dll +0 -0
  130. package/runtime/managed/insight-heap/Microsoft.Extensions.DependencyInjection.Abstractions.dll +0 -0
  131. package/runtime/managed/insight-heap/Microsoft.Extensions.Diagnostics.Abstractions.dll +0 -0
  132. package/runtime/managed/insight-heap/Microsoft.Extensions.FileProviders.Abstractions.dll +0 -0
  133. package/runtime/managed/insight-heap/Microsoft.Extensions.Hosting.Abstractions.dll +0 -0
  134. package/runtime/managed/insight-heap/Microsoft.Extensions.Logging.Abstractions.dll +0 -0
  135. package/runtime/managed/insight-heap/Microsoft.Extensions.Options.dll +0 -0
  136. package/runtime/managed/insight-heap/Microsoft.Extensions.Primitives.dll +0 -0
  137. package/runtime/managed/insight-heap/Microsoft.Identity.Client.Extensions.Msal.dll +0 -0
  138. package/runtime/managed/insight-heap/Microsoft.Identity.Client.dll +0 -0
  139. package/runtime/managed/insight-heap/Microsoft.IdentityModel.Abstractions.dll +0 -0
  140. package/runtime/managed/insight-heap/Microsoft.Security.AntiSSRF.dll +0 -0
  141. package/runtime/managed/insight-heap/NuGet.Config +1 -0
  142. package/runtime/managed/insight-heap/Program.cs +20 -0
  143. package/runtime/managed/insight-heap/README.md +16 -0
  144. package/runtime/managed/insight-heap/System.ClientModel.dll +0 -0
  145. package/runtime/managed/insight-heap/System.Memory.Data.dll +0 -0
  146. package/runtime/managed/insight-heap/System.Security.Cryptography.ProtectedData.dll +0 -0
  147. package/runtime/managed/insight-heap/dependencies.json +436 -0
  148. package/runtime/managed/insight-heap/notices/Azure.Core-LICENSE.txt +21 -0
  149. package/runtime/managed/insight-heap/notices/Azure.Identity-LICENSE.txt +21 -0
  150. package/runtime/managed/insight-heap/notices/Microsoft.Bcl.AsyncInterfaces-LICENSE.txt +23 -0
  151. package/runtime/managed/insight-heap/notices/Microsoft.Bcl.AsyncInterfaces-THIRD-PARTY-NOTICES.TXT +1418 -0
  152. package/runtime/managed/insight-heap/notices/Microsoft.Diagnostics.NETCore.Client-LICENSE.txt +23 -0
  153. package/runtime/managed/insight-heap/notices/Microsoft.Diagnostics.Runtime-LICENSE.txt +23 -0
  154. package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Configuration.Abstractions-LICENSE.txt +23 -0
  155. package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Configuration.Abstractions-THIRD-PARTY-NOTICES.TXT +1418 -0
  156. package/runtime/managed/insight-heap/notices/Microsoft.Extensions.DependencyInjection.Abstractions-LICENSE.txt +23 -0
  157. package/runtime/managed/insight-heap/notices/Microsoft.Extensions.DependencyInjection.Abstractions-THIRD-PARTY-NOTICES.TXT +1418 -0
  158. package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Diagnostics.Abstractions-LICENSE.txt +23 -0
  159. package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Diagnostics.Abstractions-THIRD-PARTY-NOTICES.TXT +1418 -0
  160. package/runtime/managed/insight-heap/notices/Microsoft.Extensions.FileProviders.Abstractions-LICENSE.txt +23 -0
  161. package/runtime/managed/insight-heap/notices/Microsoft.Extensions.FileProviders.Abstractions-THIRD-PARTY-NOTICES.TXT +1418 -0
  162. package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Hosting.Abstractions-LICENSE.txt +23 -0
  163. package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Hosting.Abstractions-THIRD-PARTY-NOTICES.TXT +1418 -0
  164. package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Logging.Abstractions-LICENSE.txt +23 -0
  165. package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Logging.Abstractions-THIRD-PARTY-NOTICES.TXT +1418 -0
  166. package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Options-LICENSE.txt +23 -0
  167. package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Options-THIRD-PARTY-NOTICES.TXT +1418 -0
  168. package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Primitives-LICENSE.txt +23 -0
  169. package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Primitives-THIRD-PARTY-NOTICES.TXT +1418 -0
  170. package/runtime/managed/insight-heap/notices/Microsoft.Identity.Client-LICENSE.txt +21 -0
  171. package/runtime/managed/insight-heap/notices/Microsoft.Identity.Client.Extensions.Msal-LICENSE.txt +21 -0
  172. package/runtime/managed/insight-heap/notices/Microsoft.IdentityModel.Abstractions-LICENSE.txt +21 -0
  173. package/runtime/managed/insight-heap/notices/Microsoft.Security.AntiSSRF-LICENSE.txt +21 -0
  174. package/runtime/managed/insight-heap/notices/System.ClientModel-LICENSE.txt +21 -0
  175. package/runtime/managed/insight-heap/notices/System.Memory.Data-LICENSE.txt +23 -0
  176. package/runtime/managed/insight-heap/notices/System.Memory.Data-THIRD-PARTY-NOTICES.TXT +1418 -0
  177. package/runtime/managed/insight-heap/notices/System.Security.Cryptography.ProtectedData-LICENSE.TXT +23 -0
  178. package/runtime/managed/insight-heap/notices/System.Security.Cryptography.ProtectedData-THIRD-PARTY-NOTICES.TXT +309 -0
  179. package/runtime/managed/insight-heap/packages.lock.json +165 -0
  180. package/runtime/managed/insight-heap/provenance.json +146 -0
  181. package/runtime/managed/insight-heap/runtimes/win/lib/netstandard2.0/System.Security.Cryptography.ProtectedData.dll +0 -0
  182. package/runtime/managed/insight-managed/Insight.Managed.csproj +4 -0
  183. package/runtime/managed/insight-managed/Insight.Managed.deps.json +41 -0
  184. package/runtime/managed/insight-managed/Insight.Managed.dll +0 -0
  185. package/runtime/managed/insight-managed/Insight.Managed.runtimeconfig.json +13 -0
  186. package/runtime/managed/insight-managed/LICENSE.dnlib.txt +20 -0
  187. package/runtime/managed/insight-managed/NuGet.Config +1 -0
  188. package/runtime/managed/insight-managed/Program.cs +31 -0
  189. package/runtime/managed/insight-managed/README.md +16 -0
  190. package/runtime/managed/insight-managed/dnlib.dll +0 -0
  191. package/runtime/managed/insight-managed/packages.lock.json +13 -0
  192. package/runtime/managed/insight-managed/provenance.json +40 -0
  193. package/runtime/native/binary/README.md +22 -0
  194. package/runtime/native/binary/dependencies.json +166 -0
  195. package/runtime/native/binary/helper.cpp +44 -0
  196. package/runtime/native/binary/insight-binary-darwin-arm64 +0 -0
  197. package/runtime/native/binary/notices/Catch2-3.12.0--Catch2-3.12.0__LICENSE.txt +23 -0
  198. package/runtime/native/binary/notices/LIEF-LICENSE.txt +202 -0
  199. package/runtime/native/binary/notices/LIEF-attribution.txt +37 -0
  200. package/runtime/native/binary/notices/Melkor_ELF_Fuzzer-ac2495b--elf_fuzzer-master__LICENSE.txt +674 -0
  201. package/runtime/native/binary/notices/expected-1.3.1--expected-1.3.1__COPYING +121 -0
  202. package/runtime/native/binary/notices/frozen-61dce5a--frozen-61dce5ae18ca59931e27675c468e64118aba8744__AUTHORS +3 -0
  203. package/runtime/native/binary/notices/frozen-61dce5a--frozen-61dce5ae18ca59931e27675c468e64118aba8744__LICENSE +202 -0
  204. package/runtime/native/binary/notices/json-LICENSE.MIT +21 -0
  205. package/runtime/native/binary/notices/mbedtls-4.0.0.r0.gec4044008d--LICENSE +553 -0
  206. package/runtime/native/binary/notices/mbedtls-4.0.0.r0.gec4044008d--framework__LICENSE +553 -0
  207. package/runtime/native/binary/notices/mbedtls-4.0.0.r0.gec4044008d--tf-psa-crypto__LICENSE +552 -0
  208. package/runtime/native/binary/notices/mbedtls-4.0.0.r0.gec4044008d--tf-psa-crypto__framework__LICENSE +553 -0
  209. package/runtime/native/binary/notices/nanobind-2.13.0.r18.g4db9ed3f--LICENSE +26 -0
  210. package/runtime/native/binary/notices/nanobind-2.13.0.r18.g4db9ed3f--ext__robin_map__LICENSE +21 -0
  211. package/runtime/native/binary/notices/span-LICENSE_1_0.txt +23 -0
  212. package/runtime/native/binary/notices/span-attribution.txt +11 -0
  213. package/runtime/native/binary/notices/spdlog-1.17.0--spdlog-1.17.0__LICENSE +25 -0
  214. package/runtime/native/binary/notices/utfcpp-4.0.9--utfcpp-4.0.9__LICENSE +23 -0
  215. package/runtime/native/binary/provenance.json +48 -0
  216. package/runtime/native/child-deadline-linux-x64 +0 -0
  217. package/runtime/native/child-deadline-linux.c +24 -0
  218. package/runtime/native/child-deadline-linux.provenance.json +17 -0
  219. package/runtime/native/deadline-alarm-darwin-universal.dylib +0 -0
  220. package/runtime/native/deadline-alarm.c +33 -0
  221. package/runtime/native/deadline-alarm.provenance.json +22 -0
  222. package/runtime/native/deadline-exec-darwin-arm64 +0 -0
  223. package/runtime/native/deadline-exec.c +24 -0
  224. package/runtime/native/deadline-exec.provenance.json +17 -0
  225. package/runtime/native/dnspy-extension/Bridge.cs +58 -0
  226. package/runtime/native/dnspy-extension/Insight.DnSpy.csproj +13 -0
  227. package/runtime/native/dnspy-extension/Insight.DnSpy.x.dll +0 -0
  228. package/runtime/native/dnspy-extension/NuGet.Config +1 -0
  229. package/runtime/native/dnspy-extension/UNICODE-LOADER.md +26 -0
  230. package/runtime/native/dnspy-extension/packages.lock.json +6 -0
  231. package/runtime/native/dnspy-extension/provenance.json +27 -0
  232. package/runtime/native/dnspy-extension/upstream-public-build.snk +0 -0
  233. package/runtime/native/dnspy-extension/vendor-files.json +4341 -0
  234. package/runtime/native/file-version.ps1 +7 -0
  235. package/runtime/native/insight-registry-win-x64.dll +0 -0
  236. package/runtime/native/mitmproxy/bridge.py +180 -0
  237. package/runtime/native/mitmproxy/notices.json +476 -0
  238. package/runtime/native/sources/detours-LICENSE.md +23 -0
  239. package/runtime/native/sources/detours-e4bfd6b.tar.gz +0 -0
  240. package/runtime/native/sources/detours-provenance.json +10 -0
  241. package/runtime/native/tshark-layout.json +2247 -0
  242. package/runtime/native/windows-job/DirectoryAlias.cs +24 -0
  243. package/runtime/native/windows-job/Insight.WindowsJob.csproj +1 -0
  244. package/runtime/native/windows-job/Insight.WindowsJob.dll +0 -0
  245. package/runtime/native/windows-job/NuGet.Config +1 -0
  246. package/runtime/native/windows-job/OwnedJob.cs +79 -0
  247. package/runtime/native/windows-job/RegistryRedirect.cs +45 -0
  248. package/runtime/native/windows-job/packages.lock.json +21 -0
  249. package/runtime/native/windows-job/provenance.json +16 -0
  250. package/runtime/native/windows-job/windows-job.ps1 +8 -0
  251. package/runtime/native/windows-registry.c +21 -0
  252. package/runtime/native/windows-registry.def +3 -0
  253. package/runtime/native/windows-registry.provenance.json +14 -0
  254. package/runtime/notices/diagnostics-10.0.750501.txt +23 -0
  255. package/runtime/tool-catalog.json +290 -0
  256. package/runtime/toolbox.json +1401 -0
  257. package/skill-bundle/insight-artifacts/SKILL.md +30 -0
  258. package/skill-bundle/insight-artifacts/references/agent-execution.md +36 -0
  259. package/skill-bundle/insight-artifacts/references/artifacts.md +52 -0
  260. package/skill-bundle/insight-binary/SKILL.md +46 -0
  261. package/skill-bundle/insight-binary/references/agent-execution.md +36 -0
  262. package/skill-bundle/insight-capture/SKILL.md +56 -0
  263. package/skill-bundle/insight-capture/references/agent-execution.md +36 -0
  264. package/skill-bundle/insight-cli/SKILL.md +42 -0
  265. package/skill-bundle/insight-cli/references/agent-execution.md +36 -0
  266. package/skill-bundle/insight-cli/references/agent-setup.md +61 -0
  267. package/skill-bundle/insight-die/SKILL.md +49 -0
  268. package/skill-bundle/insight-die/references/agent-execution.md +36 -0
  269. package/skill-bundle/insight-dnspy/SKILL.md +65 -0
  270. package/skill-bundle/insight-dnspy/references/agent-execution.md +36 -0
  271. package/skill-bundle/insight-dotnet-dump/SKILL.md +46 -0
  272. package/skill-bundle/insight-dotnet-dump/references/agent-execution.md +36 -0
  273. package/skill-bundle/insight-dotnet-stack/SKILL.md +39 -0
  274. package/skill-bundle/insight-dotnet-stack/references/agent-execution.md +36 -0
  275. package/skill-bundle/insight-dotnet-trace/SKILL.md +45 -0
  276. package/skill-bundle/insight-dotnet-trace/references/agent-execution.md +36 -0
  277. package/skill-bundle/insight-frida/SKILL.md +67 -0
  278. package/skill-bundle/insight-frida/references/agent-execution.md +36 -0
  279. package/skill-bundle/insight-ghidra/SKILL.md +91 -0
  280. package/skill-bundle/insight-ghidra/references/administration.md +34 -0
  281. package/skill-bundle/insight-ghidra/references/agent-execution.md +36 -0
  282. package/skill-bundle/insight-ghidra/references/archive.md +32 -0
  283. package/skill-bundle/insight-ghidra/references/artifacts.md +52 -0
  284. package/skill-bundle/insight-ghidra/references/debugger.md +62 -0
  285. package/skill-bundle/insight-ghidra/references/extensions-and-sync.md +124 -0
  286. package/skill-bundle/insight-ghidra/references/managed-runtime.md +162 -0
  287. package/skill-bundle/insight-ghidra/references/native-workflows.md +122 -0
  288. package/skill-bundle/insight-ghidra/references/query-semantics.md +96 -0
  289. package/skill-bundle/insight-ghidra/references/recovery.md +53 -0
  290. package/skill-bundle/insight-ghidra/references/research.md +101 -0
  291. package/skill-bundle/insight-ghidra/references/setup.md +50 -0
  292. package/skill-bundle/insight-ilspy/SKILL.md +45 -0
  293. package/skill-bundle/insight-ilspy/references/agent-execution.md +36 -0
  294. package/skill-bundle/insight-ilspy/references/ilspy.md +33 -0
  295. package/skill-bundle/insight-interop/SKILL.md +54 -0
  296. package/skill-bundle/insight-interop/references/agent-execution.md +36 -0
  297. package/skill-bundle/insight-lldb/SKILL.md +54 -0
  298. package/skill-bundle/insight-lldb/references/agent-execution.md +36 -0
  299. package/skill-bundle/insight-llvm/SKILL.md +56 -0
  300. package/skill-bundle/insight-llvm/references/agent-execution.md +36 -0
  301. package/skill-bundle/insight-managed-heap/SKILL.md +43 -0
  302. package/skill-bundle/insight-managed-heap/references/agent-execution.md +36 -0
  303. package/skill-bundle/insight-managed-metadata/SKILL.md +52 -0
  304. package/skill-bundle/insight-managed-metadata/references/agent-execution.md +36 -0
  305. package/skill-bundle/insight-mitmproxy/SKILL.md +62 -0
  306. package/skill-bundle/insight-mitmproxy/references/agent-execution.md +36 -0
  307. package/skill-bundle/insight-overview/SKILL.md +79 -0
  308. package/skill-bundle/insight-overview/references/agent-execution.md +36 -0
  309. package/skill-bundle/insight-procmon/SKILL.md +49 -0
  310. package/skill-bundle/insight-procmon/references/agent-execution.md +36 -0
  311. package/skill-bundle/insight-re/SKILL.md +121 -0
  312. package/skill-bundle/insight-re/references/agent-execution.md +36 -0
  313. package/skill-bundle/insight-re/references/artifacts.md +52 -0
  314. package/skill-bundle/insight-re/references/recovery.md +53 -0
  315. package/skill-bundle/insight-sevenzip/SKILL.md +42 -0
  316. package/skill-bundle/insight-sevenzip/references/agent-execution.md +36 -0
  317. package/skill-bundle/insight-strace/SKILL.md +46 -0
  318. package/skill-bundle/insight-strace/references/agent-execution.md +36 -0
  319. package/skill-bundle/insight-tshark/SKILL.md +49 -0
  320. package/skill-bundle/insight-tshark/references/agent-execution.md +36 -0
  321. package/skill-bundle/insight-windbg/SKILL.md +46 -0
  322. package/skill-bundle/insight-windbg/references/agent-execution.md +36 -0
  323. package/skill-bundle/manifest.json +32 -0
  324. package/skills/insight-artifacts/SKILL.md +30 -0
  325. package/skills/insight-artifacts/references/agent-execution.md +36 -0
  326. package/skills/insight-artifacts/references/artifacts.md +52 -0
  327. package/skills/insight-binary/SKILL.md +46 -0
  328. package/skills/insight-binary/references/agent-execution.md +36 -0
  329. package/skills/insight-capture/SKILL.md +56 -0
  330. package/skills/insight-capture/references/agent-execution.md +36 -0
  331. package/skills/insight-die/SKILL.md +49 -0
  332. package/skills/insight-die/references/agent-execution.md +36 -0
  333. package/skills/insight-dnspy/SKILL.md +65 -0
  334. package/skills/insight-dnspy/references/agent-execution.md +36 -0
  335. package/skills/insight-dotnet-dump/SKILL.md +46 -0
  336. package/skills/insight-dotnet-dump/references/agent-execution.md +36 -0
  337. package/skills/insight-dotnet-stack/SKILL.md +39 -0
  338. package/skills/insight-dotnet-stack/references/agent-execution.md +36 -0
  339. package/skills/insight-dotnet-trace/SKILL.md +45 -0
  340. package/skills/insight-dotnet-trace/references/agent-execution.md +36 -0
  341. package/skills/insight-frida/SKILL.md +67 -0
  342. package/skills/insight-frida/references/agent-execution.md +36 -0
  343. package/skills/insight-ghidra/SKILL.md +91 -0
  344. package/skills/insight-ghidra/references/administration.md +34 -0
  345. package/skills/insight-ghidra/references/agent-execution.md +36 -0
  346. package/skills/insight-ghidra/references/archive.md +32 -0
  347. package/skills/insight-ghidra/references/artifacts.md +52 -0
  348. package/skills/insight-ghidra/references/debugger.md +62 -0
  349. package/skills/insight-ghidra/references/extensions-and-sync.md +124 -0
  350. package/skills/insight-ghidra/references/managed-runtime.md +162 -0
  351. package/skills/insight-ghidra/references/native-workflows.md +122 -0
  352. package/skills/insight-ghidra/references/query-semantics.md +96 -0
  353. package/skills/insight-ghidra/references/recovery.md +53 -0
  354. package/skills/insight-ghidra/references/research.md +101 -0
  355. package/skills/insight-ghidra/references/setup.md +50 -0
  356. package/skills/insight-ilspy/SKILL.md +45 -0
  357. package/skills/insight-ilspy/references/agent-execution.md +36 -0
  358. package/skills/insight-ilspy/references/ilspy.md +33 -0
  359. package/skills/insight-interop/SKILL.md +54 -0
  360. package/skills/insight-interop/references/agent-execution.md +36 -0
  361. package/skills/insight-lldb/SKILL.md +54 -0
  362. package/skills/insight-lldb/references/agent-execution.md +36 -0
  363. package/skills/insight-llvm/SKILL.md +56 -0
  364. package/skills/insight-llvm/references/agent-execution.md +36 -0
  365. package/skills/insight-managed-heap/SKILL.md +43 -0
  366. package/skills/insight-managed-heap/references/agent-execution.md +36 -0
  367. package/skills/insight-managed-metadata/SKILL.md +52 -0
  368. package/skills/insight-managed-metadata/references/agent-execution.md +36 -0
  369. package/skills/insight-mitmproxy/SKILL.md +62 -0
  370. package/skills/insight-mitmproxy/references/agent-execution.md +36 -0
  371. package/skills/insight-overview/SKILL.md +79 -0
  372. package/skills/insight-overview/references/agent-execution.md +36 -0
  373. package/skills/insight-procmon/SKILL.md +49 -0
  374. package/skills/insight-procmon/references/agent-execution.md +36 -0
  375. package/skills/insight-re/SKILL.md +22 -9
  376. package/skills/insight-re/references/agent-execution.md +36 -0
  377. package/skills/insight-re/references/artifacts.md +52 -0
  378. package/skills/insight-re/references/recovery.md +53 -0
  379. package/skills/insight-sevenzip/SKILL.md +42 -0
  380. package/skills/insight-sevenzip/references/agent-execution.md +36 -0
  381. package/skills/insight-strace/SKILL.md +46 -0
  382. package/skills/insight-strace/references/agent-execution.md +36 -0
  383. package/skills/insight-tshark/SKILL.md +49 -0
  384. package/skills/insight-tshark/references/agent-execution.md +36 -0
  385. package/skills/insight-windbg/SKILL.md +46 -0
  386. package/skills/insight-windbg/references/agent-execution.md +36 -0
  387. 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
- export declare function runtimeWrite(path: string, value: unknown): Promise<void>;
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
- checks: string[];
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 { command, Permission, CliError } from '@eyeauras/cli-factory';
2
- import { readFile, mkdir, rename, rm, open, realpath, readdir, stat, cp } from 'node:fs/promises';
3
- import { existsSync, constants } from 'node:fs';
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, fileSha256 } from './runtime-archives.js';
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
- const exec = promisify(execFile), suffix = process.platform === 'win32' ? '.exe' : '';
15
- export async function runtimeWrite(path, value) {
16
- await mkdir(dirname(path), { recursive: true, mode: 0o700 });
17
- const temporary = path + '.new-' + randomUUID(), handle = await open(temporary, 'wx', 0o600);
18
- try {
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
- const path = await realpath(resolve(this.c.cwd, text(provided, 4096))), cache = join(this.root, 'cache');
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
- await this.cleanupProbes();
268
- if (o.executable && o.archive)
269
- fail('invalid', 'Choose --executable or --archive.');
270
- if (o.archiveSha256 && !o.archive || o.javaArchiveSha256 && !o.javaArchive)
271
- fail('invalid', 'Archive checksum requires its archive path.');
272
- const catalog = runtimeCatalog(), offline = Boolean(o.offline), external = o.executable ? await externalGhidra(resolve(this.c.cwd, text(o.executable, 4096))) : undefined;
273
- const ghidra = external ? undefined : await this.archive(catalog.ghidra, o.archive, o.archiveSha256, offline);
274
- const java = o.java ? await realpath(resolve(this.c.cwd, text(o.java, 4096))) : undefined;
275
- if (java && o.javaArchive)
276
- fail('invalid', 'Choose --java or --java-archive.');
277
- const jdk = java ? undefined : await this.archive(catalog.java, o.javaArchive, o.javaArchiveSha256, offline);
278
- const identity = digest({ schema: 1, platform: process.platform, architecture: process.arch, external, java, ghidra: ghidra?.artifact.sha256, jdk: jdk?.artifact.sha256, bridge: pinnedMcpJar });
279
- const installation = join(this.root, 'installations', identity), temporary = join(this.root, 'stages', randomUUID());
280
- await mkdir(temporary, { recursive: true, mode: 0o700 });
281
- let selected, complete = false;
282
- try {
283
- let inputs;
284
- if (existsSync(join(installation, 'ready.json'))) {
285
- const receipt = object(JSON.parse(await readFile(join(installation, 'ready.json'), 'utf8')));
286
- inputs = await nativeInputs({ ...this.c.profile.values, java: java ?? receipt.java, ghidraHome: external ?? join(installation, 'ghidra') });
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
- await extractArchive(bottle, nativeRoot, 'tgz');
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
- await runtimeWrite(join(temporary, 'ready.json'), receipt);
328
- await mkdir(dirname(installation), { recursive: true, mode: 0o700 });
329
- if (existsSync(installation))
330
- fail('binding', 'Incomplete installation directory is retained; inspect it before removing it.');
331
- await rename(temporary, installation);
332
- if (process.platform !== 'win32') {
333
- const parent = await open(dirname(installation), 'r');
334
- try {
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
- complete = true;
345
- return { state: 'installed', ...selected, checks: ['jdk', 'native-decompiler', 'local-server-reader-publisher-authority'] };
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
- await this.cleanupProbes();
360
- const selected = runtimeSelection(this.directory);
361
- if (!selected)
362
- fail('configuration', 'No managed selection exists; externally configured profile paths are never removed.');
363
- if (selected.id) {
364
- if (!/^[a-f0-9]{64}$/.test(selected.id))
365
- fail('binding', 'Invalid installation identity.');
366
- await rm(join(this.root, 'installations', selected.id), { recursive: true, force: true });
367
- }
368
- if (purgeCache)
369
- await rm(join(this.root, 'cache'), { recursive: true, force: true });
370
- await runtimeWrite(join(this.root, 'selection.json'), { ...selected, uninstalledAt: new Date().toISOString() });
371
- // Retain the selection: an explicit external profile must never become an implicit fallback.
372
- return { state: 'uninstalled', mode: selected.mode, externalInstallationPreserved: selected.mode === 'external', researchPreserved: true, materialsPreserved: true, cachePreserved: !purgeCache };
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 exec(inputs.java, ['-Djava.awt.headless=true', '-Dghidra.home=' + inputs.ghidraHome, ...nativeJvmDirectories(root), '-cp', classes + delimiter + inputs.classpath, 'InsightRuntimeDoctor'], { cwd: root, env: { PATH: dirname(inputs.java), HOME: root, TMPDIR: root }, timeout: 90000, maxBuffer: 1024 * 1024, signal: this.c.signal });
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 (process.platform === 'darwin')
345
+ if (managedGhidraDebugger())
409
346
  try {
410
- const checked = await exec('/usr/bin/lldb', ['--no-lldbinit', '--batch', '-o', 'script import lldb,sys; print("INSIGHT_LLDB_PYTHON_OK")'], { env: { PATH: '/usr/bin:/bin', HOME: root, TMPDIR: root }, timeout: 30000, maxBuffer: 65536 });
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 [command('download', 'Cache the pinned complete Ghidra/JDK distribution without activation', ({ options: o }, c) => exclusive(c, () => new RuntimeManager(c).download(Boolean(o.offline)), false), { permission: Permission.Update, options: [source.at(-1)] }),
441
- command('install', 'Prepare, verify and select a complete runtime, including Ghidra Server', ({ options: o }, c) => exclusive(c, () => new RuntimeManager(c).install(o)), { permission: Permission.Update, options: source }),
442
- command('uninstall', 'Remove selected owned runtime files while preserving research and external installations', ({ options: o }, c) => exclusive(c, () => new RuntimeManager(c).uninstall(Boolean(o.purgeCache))), { permission: 'Destructive', options: [{ flags: '--purge-cache', description: 'Also remove owned downloaded archives' }] }),
443
- command('doctor', 'Launch a disposable native decompiler and local server probe', (_input, c) => exclusive(c, () => new RuntimeManager(c).doctor(), false), { permission: Permission.Update })];
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' && (!/^[a-f0-9]{64}$/.test(String(value.id)) || value.ghidraHome !== join(runtimeRoot(directory), 'installations', String(value.id), 'ghidra')))
13
- fail('binding', 'Managed runtime moved outside its owned installation.');
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) {
@@ -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 {};
@@ -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 log = await open(join(root, 'diagnostic.log'), 'a', 0o600);
78
- const child = spawn(this.inputs.java, ['-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, windowsHide: true, env: { PATH: this.c.environment.PATH ?? process.env.PATH, HOME: root, TMPDIR: root, ...environment }, stdio: ['pipe', 'pipe', log.fd] });
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
- child.stdin.on('error', () => { });
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
- finally {
114
- clearTimeout(timer);
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 = spawn(this.inputs.java, ['-Djava.awt.headless=true', '-Dghidra.home=' + this.inputs.ghidraHome,
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
- process.kill(local.pid, 'SIGTERM');
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))