@eyeauras/insight-cli 0.1.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.
Files changed (391) hide show
  1. package/.cli-package-build.json +1 -1
  2. package/README.md +33 -2
  3. package/SKILL.md +38 -51
  4. package/dist/src/administration-results.js +1 -1
  5. package/dist/src/administration.d.ts +1 -1
  6. package/dist/src/administration.js +16 -2
  7. package/dist/src/binary.d.ts +3 -0
  8. package/dist/src/binary.js +74 -0
  9. package/dist/src/capture.d.ts +3 -0
  10. package/dist/src/capture.js +220 -0
  11. package/dist/src/cli.js +91 -14
  12. package/dist/src/contexts.d.ts +5 -0
  13. package/dist/src/contexts.js +54 -18
  14. package/dist/src/debugger-caller.d.ts +17 -0
  15. package/dist/src/debugger-caller.js +129 -0
  16. package/dist/src/debugger-launch.d.ts +2 -0
  17. package/dist/src/debugger-launch.js +17 -0
  18. package/dist/src/debugger-results.d.ts +1 -0
  19. package/dist/src/debugger-results.js +8 -0
  20. package/dist/src/debugger-supervisor.js +56 -13
  21. package/dist/src/debugger.js +16 -7
  22. package/dist/src/die.d.ts +12 -0
  23. package/dist/src/die.js +127 -0
  24. package/dist/src/dnspy-runtime.d.ts +8 -0
  25. package/dist/src/dnspy-runtime.js +46 -0
  26. package/dist/src/dnspy.d.ts +22 -0
  27. package/dist/src/dnspy.js +160 -0
  28. package/dist/src/dotnet-diagnostics.d.ts +13 -0
  29. package/dist/src/dotnet-diagnostics.js +101 -0
  30. package/dist/src/frida-worker.d.ts +1 -0
  31. package/dist/src/frida-worker.js +125 -0
  32. package/dist/src/frida.d.ts +16 -0
  33. package/dist/src/frida.js +125 -0
  34. package/dist/src/ghidra-debugger-runtime.d.ts +7 -0
  35. package/dist/src/ghidra-debugger-runtime.js +31 -0
  36. package/dist/src/ghidra-processes.d.ts +6 -0
  37. package/dist/src/ghidra-processes.js +121 -0
  38. package/dist/src/ghidra.js +6 -6
  39. package/dist/src/ilspy.d.ts +7 -0
  40. package/dist/src/ilspy.js +122 -0
  41. package/dist/src/lifecycle.d.ts +1 -1
  42. package/dist/src/lifecycle.js +8 -2
  43. package/dist/src/lldb.d.ts +10 -0
  44. package/dist/src/lldb.js +99 -0
  45. package/dist/src/llvm.d.ts +6 -0
  46. package/dist/src/llvm.js +133 -0
  47. package/dist/src/managed-heap.d.ts +4 -0
  48. package/dist/src/managed-heap.js +73 -0
  49. package/dist/src/managed-metadata.d.ts +11 -0
  50. package/dist/src/managed-metadata.js +66 -0
  51. package/dist/src/mitmproxy.d.ts +55 -0
  52. package/dist/src/mitmproxy.js +172 -0
  53. package/dist/src/native-inputs.d.ts +3 -2
  54. package/dist/src/native-inputs.js +21 -5
  55. package/dist/src/package-version.d.ts +1 -0
  56. package/dist/src/package-version.js +3 -0
  57. package/dist/src/procmon-config.d.ts +2 -0
  58. package/dist/src/procmon-config.js +15 -0
  59. package/dist/src/procmon-events.d.ts +13 -0
  60. package/dist/src/procmon-events.js +82 -0
  61. package/dist/src/procmon.d.ts +4 -0
  62. package/dist/src/procmon.js +107 -0
  63. package/dist/src/research.d.ts +11 -2
  64. package/dist/src/research.js +5 -3
  65. package/dist/src/runtime-catalog.d.ts +13 -0
  66. package/dist/src/runtime-catalog.js +26 -0
  67. package/dist/src/runtime-manager.d.ts +125 -0
  68. package/dist/src/runtime-manager.js +385 -0
  69. package/dist/src/runtime-selection.d.ts +13 -0
  70. package/dist/src/runtime-selection.js +42 -0
  71. package/dist/src/server.d.ts +15 -0
  72. package/dist/src/server.js +77 -96
  73. package/dist/src/sevenzip.d.ts +15 -0
  74. package/dist/src/sevenzip.js +119 -0
  75. package/dist/src/strace.d.ts +10 -0
  76. package/dist/src/strace.js +71 -0
  77. package/dist/src/text-window.d.ts +11 -0
  78. package/dist/src/text-window.js +6 -0
  79. package/dist/src/tool-runtime/archives.d.ts +10 -0
  80. package/dist/src/tool-runtime/archives.js +194 -0
  81. package/dist/src/tool-runtime/catalog.d.ts +3 -0
  82. package/dist/src/tool-runtime/catalog.js +13 -0
  83. package/dist/src/tool-runtime/commands.d.ts +9 -0
  84. package/dist/src/tool-runtime/commands.js +39 -0
  85. package/dist/src/tool-runtime/deadline.d.ts +11 -0
  86. package/dist/src/tool-runtime/deadline.js +32 -0
  87. package/dist/src/tool-runtime/definition.d.ts +73 -0
  88. package/dist/src/tool-runtime/definition.js +49 -0
  89. package/dist/src/tool-runtime/dotnet.d.ts +4 -0
  90. package/dist/src/tool-runtime/dotnet.js +22 -0
  91. package/dist/src/tool-runtime/identity.d.ts +6 -0
  92. package/dist/src/tool-runtime/identity.js +50 -0
  93. package/dist/src/tool-runtime/installer.d.ts +101 -0
  94. package/dist/src/tool-runtime/installer.js +180 -0
  95. package/dist/src/tool-runtime/launch-worker.d.ts +1 -0
  96. package/dist/src/tool-runtime/launch-worker.js +58 -0
  97. package/dist/src/tool-runtime/run.d.ts +51 -0
  98. package/dist/src/tool-runtime/run.js +159 -0
  99. package/dist/src/tool-runtime/store.d.ts +15 -0
  100. package/dist/src/tool-runtime/store.js +219 -0
  101. package/dist/src/tool-runtime/supervisor.d.ts +57 -0
  102. package/dist/src/tool-runtime/supervisor.js +266 -0
  103. package/dist/src/tool-runtime/windows-job.d.ts +22 -0
  104. package/dist/src/tool-runtime/windows-job.js +43 -0
  105. package/dist/src/toolbox.d.ts +84 -0
  106. package/dist/src/toolbox.js +35 -0
  107. package/dist/src/tshark.d.ts +23 -0
  108. package/dist/src/tshark.js +174 -0
  109. package/dist/src/windbg.d.ts +14 -0
  110. package/dist/src/windbg.js +119 -0
  111. package/dist/src/workspace.d.ts +1 -0
  112. package/dist/src/workspace.js +6 -0
  113. package/package.json +7 -4
  114. package/references/administration.md +2 -1
  115. package/references/agent-execution.md +36 -0
  116. package/references/agent-setup.md +61 -0
  117. package/references/artifacts.md +5 -0
  118. package/references/debugger.md +22 -0
  119. package/references/ilspy.md +33 -0
  120. package/references/managed-runtime.md +157 -0
  121. package/references/native/InsightPythonWheels.java +283 -2
  122. package/references/native/InsightRuntimeDoctor.java +33 -0
  123. package/references/native/InsightTraceState.java +28 -13
  124. package/references/setup.md +6 -3
  125. package/runtime/managed/insight-heap/Azure.Core.dll +0 -0
  126. package/runtime/managed/insight-heap/Azure.Identity.dll +0 -0
  127. package/runtime/managed/insight-heap/Insight.Heap.csproj +1 -0
  128. package/runtime/managed/insight-heap/Insight.Heap.deps.json +391 -0
  129. package/runtime/managed/insight-heap/Insight.Heap.dll +0 -0
  130. package/runtime/managed/insight-heap/Insight.Heap.runtimeconfig.json +13 -0
  131. package/runtime/managed/insight-heap/Microsoft.Bcl.AsyncInterfaces.dll +0 -0
  132. package/runtime/managed/insight-heap/Microsoft.Diagnostics.NETCore.Client.dll +0 -0
  133. package/runtime/managed/insight-heap/Microsoft.Diagnostics.Runtime.dll +0 -0
  134. package/runtime/managed/insight-heap/Microsoft.Extensions.Configuration.Abstractions.dll +0 -0
  135. package/runtime/managed/insight-heap/Microsoft.Extensions.DependencyInjection.Abstractions.dll +0 -0
  136. package/runtime/managed/insight-heap/Microsoft.Extensions.Diagnostics.Abstractions.dll +0 -0
  137. package/runtime/managed/insight-heap/Microsoft.Extensions.FileProviders.Abstractions.dll +0 -0
  138. package/runtime/managed/insight-heap/Microsoft.Extensions.Hosting.Abstractions.dll +0 -0
  139. package/runtime/managed/insight-heap/Microsoft.Extensions.Logging.Abstractions.dll +0 -0
  140. package/runtime/managed/insight-heap/Microsoft.Extensions.Options.dll +0 -0
  141. package/runtime/managed/insight-heap/Microsoft.Extensions.Primitives.dll +0 -0
  142. package/runtime/managed/insight-heap/Microsoft.Identity.Client.Extensions.Msal.dll +0 -0
  143. package/runtime/managed/insight-heap/Microsoft.Identity.Client.dll +0 -0
  144. package/runtime/managed/insight-heap/Microsoft.IdentityModel.Abstractions.dll +0 -0
  145. package/runtime/managed/insight-heap/Microsoft.Security.AntiSSRF.dll +0 -0
  146. package/runtime/managed/insight-heap/NuGet.Config +1 -0
  147. package/runtime/managed/insight-heap/Program.cs +20 -0
  148. package/runtime/managed/insight-heap/README.md +16 -0
  149. package/runtime/managed/insight-heap/System.ClientModel.dll +0 -0
  150. package/runtime/managed/insight-heap/System.Memory.Data.dll +0 -0
  151. package/runtime/managed/insight-heap/System.Security.Cryptography.ProtectedData.dll +0 -0
  152. package/runtime/managed/insight-heap/dependencies.json +436 -0
  153. package/runtime/managed/insight-heap/notices/Azure.Core-LICENSE.txt +21 -0
  154. package/runtime/managed/insight-heap/notices/Azure.Identity-LICENSE.txt +21 -0
  155. package/runtime/managed/insight-heap/notices/Microsoft.Bcl.AsyncInterfaces-LICENSE.txt +23 -0
  156. package/runtime/managed/insight-heap/notices/Microsoft.Bcl.AsyncInterfaces-THIRD-PARTY-NOTICES.TXT +1418 -0
  157. package/runtime/managed/insight-heap/notices/Microsoft.Diagnostics.NETCore.Client-LICENSE.txt +23 -0
  158. package/runtime/managed/insight-heap/notices/Microsoft.Diagnostics.Runtime-LICENSE.txt +23 -0
  159. package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Configuration.Abstractions-LICENSE.txt +23 -0
  160. package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Configuration.Abstractions-THIRD-PARTY-NOTICES.TXT +1418 -0
  161. package/runtime/managed/insight-heap/notices/Microsoft.Extensions.DependencyInjection.Abstractions-LICENSE.txt +23 -0
  162. package/runtime/managed/insight-heap/notices/Microsoft.Extensions.DependencyInjection.Abstractions-THIRD-PARTY-NOTICES.TXT +1418 -0
  163. package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Diagnostics.Abstractions-LICENSE.txt +23 -0
  164. package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Diagnostics.Abstractions-THIRD-PARTY-NOTICES.TXT +1418 -0
  165. package/runtime/managed/insight-heap/notices/Microsoft.Extensions.FileProviders.Abstractions-LICENSE.txt +23 -0
  166. package/runtime/managed/insight-heap/notices/Microsoft.Extensions.FileProviders.Abstractions-THIRD-PARTY-NOTICES.TXT +1418 -0
  167. package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Hosting.Abstractions-LICENSE.txt +23 -0
  168. package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Hosting.Abstractions-THIRD-PARTY-NOTICES.TXT +1418 -0
  169. package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Logging.Abstractions-LICENSE.txt +23 -0
  170. package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Logging.Abstractions-THIRD-PARTY-NOTICES.TXT +1418 -0
  171. package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Options-LICENSE.txt +23 -0
  172. package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Options-THIRD-PARTY-NOTICES.TXT +1418 -0
  173. package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Primitives-LICENSE.txt +23 -0
  174. package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Primitives-THIRD-PARTY-NOTICES.TXT +1418 -0
  175. package/runtime/managed/insight-heap/notices/Microsoft.Identity.Client-LICENSE.txt +21 -0
  176. package/runtime/managed/insight-heap/notices/Microsoft.Identity.Client.Extensions.Msal-LICENSE.txt +21 -0
  177. package/runtime/managed/insight-heap/notices/Microsoft.IdentityModel.Abstractions-LICENSE.txt +21 -0
  178. package/runtime/managed/insight-heap/notices/Microsoft.Security.AntiSSRF-LICENSE.txt +21 -0
  179. package/runtime/managed/insight-heap/notices/System.ClientModel-LICENSE.txt +21 -0
  180. package/runtime/managed/insight-heap/notices/System.Memory.Data-LICENSE.txt +23 -0
  181. package/runtime/managed/insight-heap/notices/System.Memory.Data-THIRD-PARTY-NOTICES.TXT +1418 -0
  182. package/runtime/managed/insight-heap/notices/System.Security.Cryptography.ProtectedData-LICENSE.TXT +23 -0
  183. package/runtime/managed/insight-heap/notices/System.Security.Cryptography.ProtectedData-THIRD-PARTY-NOTICES.TXT +309 -0
  184. package/runtime/managed/insight-heap/packages.lock.json +165 -0
  185. package/runtime/managed/insight-heap/provenance.json +146 -0
  186. package/runtime/managed/insight-heap/runtimes/win/lib/netstandard2.0/System.Security.Cryptography.ProtectedData.dll +0 -0
  187. package/runtime/managed/insight-managed/Insight.Managed.csproj +4 -0
  188. package/runtime/managed/insight-managed/Insight.Managed.deps.json +41 -0
  189. package/runtime/managed/insight-managed/Insight.Managed.dll +0 -0
  190. package/runtime/managed/insight-managed/Insight.Managed.runtimeconfig.json +13 -0
  191. package/runtime/managed/insight-managed/LICENSE.dnlib.txt +20 -0
  192. package/runtime/managed/insight-managed/NuGet.Config +1 -0
  193. package/runtime/managed/insight-managed/Program.cs +31 -0
  194. package/runtime/managed/insight-managed/README.md +16 -0
  195. package/runtime/managed/insight-managed/dnlib.dll +0 -0
  196. package/runtime/managed/insight-managed/packages.lock.json +13 -0
  197. package/runtime/managed/insight-managed/provenance.json +40 -0
  198. package/runtime/native/binary/README.md +22 -0
  199. package/runtime/native/binary/dependencies.json +166 -0
  200. package/runtime/native/binary/helper.cpp +44 -0
  201. package/runtime/native/binary/insight-binary-darwin-arm64 +0 -0
  202. package/runtime/native/binary/notices/Catch2-3.12.0--Catch2-3.12.0__LICENSE.txt +23 -0
  203. package/runtime/native/binary/notices/LIEF-LICENSE.txt +202 -0
  204. package/runtime/native/binary/notices/LIEF-attribution.txt +37 -0
  205. package/runtime/native/binary/notices/Melkor_ELF_Fuzzer-ac2495b--elf_fuzzer-master__LICENSE.txt +674 -0
  206. package/runtime/native/binary/notices/expected-1.3.1--expected-1.3.1__COPYING +121 -0
  207. package/runtime/native/binary/notices/frozen-61dce5a--frozen-61dce5ae18ca59931e27675c468e64118aba8744__AUTHORS +3 -0
  208. package/runtime/native/binary/notices/frozen-61dce5a--frozen-61dce5ae18ca59931e27675c468e64118aba8744__LICENSE +202 -0
  209. package/runtime/native/binary/notices/json-LICENSE.MIT +21 -0
  210. package/runtime/native/binary/notices/mbedtls-4.0.0.r0.gec4044008d--LICENSE +553 -0
  211. package/runtime/native/binary/notices/mbedtls-4.0.0.r0.gec4044008d--framework__LICENSE +553 -0
  212. package/runtime/native/binary/notices/mbedtls-4.0.0.r0.gec4044008d--tf-psa-crypto__LICENSE +552 -0
  213. package/runtime/native/binary/notices/mbedtls-4.0.0.r0.gec4044008d--tf-psa-crypto__framework__LICENSE +553 -0
  214. package/runtime/native/binary/notices/nanobind-2.13.0.r18.g4db9ed3f--LICENSE +26 -0
  215. package/runtime/native/binary/notices/nanobind-2.13.0.r18.g4db9ed3f--ext__robin_map__LICENSE +21 -0
  216. package/runtime/native/binary/notices/span-LICENSE_1_0.txt +23 -0
  217. package/runtime/native/binary/notices/span-attribution.txt +11 -0
  218. package/runtime/native/binary/notices/spdlog-1.17.0--spdlog-1.17.0__LICENSE +25 -0
  219. package/runtime/native/binary/notices/utfcpp-4.0.9--utfcpp-4.0.9__LICENSE +23 -0
  220. package/runtime/native/binary/provenance.json +48 -0
  221. package/runtime/native/child-deadline-linux-x64 +0 -0
  222. package/runtime/native/child-deadline-linux.c +24 -0
  223. package/runtime/native/child-deadline-linux.provenance.json +17 -0
  224. package/runtime/native/deadline-alarm-darwin-universal.dylib +0 -0
  225. package/runtime/native/deadline-alarm.c +33 -0
  226. package/runtime/native/deadline-alarm.provenance.json +22 -0
  227. package/runtime/native/deadline-exec-darwin-arm64 +0 -0
  228. package/runtime/native/deadline-exec.c +24 -0
  229. package/runtime/native/deadline-exec.provenance.json +17 -0
  230. package/runtime/native/dnspy-extension/Bridge.cs +58 -0
  231. package/runtime/native/dnspy-extension/Insight.DnSpy.csproj +13 -0
  232. package/runtime/native/dnspy-extension/Insight.DnSpy.x.dll +0 -0
  233. package/runtime/native/dnspy-extension/NuGet.Config +1 -0
  234. package/runtime/native/dnspy-extension/UNICODE-LOADER.md +26 -0
  235. package/runtime/native/dnspy-extension/packages.lock.json +6 -0
  236. package/runtime/native/dnspy-extension/provenance.json +27 -0
  237. package/runtime/native/dnspy-extension/upstream-public-build.snk +0 -0
  238. package/runtime/native/dnspy-extension/vendor-files.json +4341 -0
  239. package/runtime/native/file-version.ps1 +7 -0
  240. package/runtime/native/insight-registry-win-x64.dll +0 -0
  241. package/runtime/native/mitmproxy/bridge.py +180 -0
  242. package/runtime/native/mitmproxy/notices.json +476 -0
  243. package/runtime/native/sources/detours-LICENSE.md +23 -0
  244. package/runtime/native/sources/detours-e4bfd6b.tar.gz +0 -0
  245. package/runtime/native/sources/detours-provenance.json +10 -0
  246. package/runtime/native/tshark-layout.json +2247 -0
  247. package/runtime/native/windows-job/DirectoryAlias.cs +24 -0
  248. package/runtime/native/windows-job/Insight.WindowsJob.csproj +1 -0
  249. package/runtime/native/windows-job/Insight.WindowsJob.dll +0 -0
  250. package/runtime/native/windows-job/NuGet.Config +1 -0
  251. package/runtime/native/windows-job/OwnedJob.cs +79 -0
  252. package/runtime/native/windows-job/RegistryRedirect.cs +45 -0
  253. package/runtime/native/windows-job/packages.lock.json +21 -0
  254. package/runtime/native/windows-job/provenance.json +16 -0
  255. package/runtime/native/windows-job/windows-job.ps1 +8 -0
  256. package/runtime/native/windows-registry.c +21 -0
  257. package/runtime/native/windows-registry.def +3 -0
  258. package/runtime/native/windows-registry.provenance.json +14 -0
  259. package/runtime/notices/diagnostics-10.0.750501.txt +23 -0
  260. package/runtime/tool-catalog.json +290 -0
  261. package/runtime/toolbox.json +1401 -0
  262. package/skill-bundle/insight-artifacts/SKILL.md +30 -0
  263. package/skill-bundle/insight-artifacts/references/agent-execution.md +36 -0
  264. package/skill-bundle/insight-artifacts/references/artifacts.md +52 -0
  265. package/skill-bundle/insight-binary/SKILL.md +46 -0
  266. package/skill-bundle/insight-binary/references/agent-execution.md +36 -0
  267. package/skill-bundle/insight-capture/SKILL.md +56 -0
  268. package/skill-bundle/insight-capture/references/agent-execution.md +36 -0
  269. package/skill-bundle/insight-cli/SKILL.md +42 -0
  270. package/skill-bundle/insight-cli/references/agent-execution.md +36 -0
  271. package/skill-bundle/insight-cli/references/agent-setup.md +61 -0
  272. package/skill-bundle/insight-die/SKILL.md +49 -0
  273. package/skill-bundle/insight-die/references/agent-execution.md +36 -0
  274. package/skill-bundle/insight-dnspy/SKILL.md +65 -0
  275. package/skill-bundle/insight-dnspy/references/agent-execution.md +36 -0
  276. package/skill-bundle/insight-dotnet-dump/SKILL.md +46 -0
  277. package/skill-bundle/insight-dotnet-dump/references/agent-execution.md +36 -0
  278. package/skill-bundle/insight-dotnet-stack/SKILL.md +39 -0
  279. package/skill-bundle/insight-dotnet-stack/references/agent-execution.md +36 -0
  280. package/skill-bundle/insight-dotnet-trace/SKILL.md +45 -0
  281. package/skill-bundle/insight-dotnet-trace/references/agent-execution.md +36 -0
  282. package/skill-bundle/insight-frida/SKILL.md +67 -0
  283. package/skill-bundle/insight-frida/references/agent-execution.md +36 -0
  284. package/skill-bundle/insight-ghidra/SKILL.md +91 -0
  285. package/skill-bundle/insight-ghidra/references/administration.md +34 -0
  286. package/skill-bundle/insight-ghidra/references/agent-execution.md +36 -0
  287. package/skill-bundle/insight-ghidra/references/archive.md +32 -0
  288. package/skill-bundle/insight-ghidra/references/artifacts.md +52 -0
  289. package/skill-bundle/insight-ghidra/references/debugger.md +62 -0
  290. package/skill-bundle/insight-ghidra/references/extensions-and-sync.md +124 -0
  291. package/skill-bundle/insight-ghidra/references/managed-runtime.md +157 -0
  292. package/skill-bundle/insight-ghidra/references/native-workflows.md +112 -0
  293. package/skill-bundle/insight-ghidra/references/query-semantics.md +96 -0
  294. package/skill-bundle/insight-ghidra/references/recovery.md +53 -0
  295. package/skill-bundle/insight-ghidra/references/research.md +101 -0
  296. package/skill-bundle/insight-ghidra/references/setup.md +50 -0
  297. package/skill-bundle/insight-ilspy/SKILL.md +45 -0
  298. package/skill-bundle/insight-ilspy/references/agent-execution.md +36 -0
  299. package/skill-bundle/insight-ilspy/references/ilspy.md +33 -0
  300. package/skill-bundle/insight-interop/SKILL.md +54 -0
  301. package/skill-bundle/insight-interop/references/agent-execution.md +36 -0
  302. package/skill-bundle/insight-lldb/SKILL.md +54 -0
  303. package/skill-bundle/insight-lldb/references/agent-execution.md +36 -0
  304. package/skill-bundle/insight-llvm/SKILL.md +56 -0
  305. package/skill-bundle/insight-llvm/references/agent-execution.md +36 -0
  306. package/skill-bundle/insight-managed-heap/SKILL.md +43 -0
  307. package/skill-bundle/insight-managed-heap/references/agent-execution.md +36 -0
  308. package/skill-bundle/insight-managed-metadata/SKILL.md +52 -0
  309. package/skill-bundle/insight-managed-metadata/references/agent-execution.md +36 -0
  310. package/skill-bundle/insight-mitmproxy/SKILL.md +62 -0
  311. package/skill-bundle/insight-mitmproxy/references/agent-execution.md +36 -0
  312. package/skill-bundle/insight-overview/SKILL.md +79 -0
  313. package/skill-bundle/insight-overview/references/agent-execution.md +36 -0
  314. package/skill-bundle/insight-procmon/SKILL.md +49 -0
  315. package/skill-bundle/insight-procmon/references/agent-execution.md +36 -0
  316. package/skill-bundle/insight-re/SKILL.md +121 -0
  317. package/skill-bundle/insight-re/references/agent-execution.md +36 -0
  318. package/skill-bundle/insight-re/references/artifacts.md +52 -0
  319. package/skill-bundle/insight-re/references/recovery.md +53 -0
  320. package/skill-bundle/insight-sevenzip/SKILL.md +42 -0
  321. package/skill-bundle/insight-sevenzip/references/agent-execution.md +36 -0
  322. package/skill-bundle/insight-strace/SKILL.md +46 -0
  323. package/skill-bundle/insight-strace/references/agent-execution.md +36 -0
  324. package/skill-bundle/insight-tshark/SKILL.md +49 -0
  325. package/skill-bundle/insight-tshark/references/agent-execution.md +36 -0
  326. package/skill-bundle/insight-windbg/SKILL.md +46 -0
  327. package/skill-bundle/insight-windbg/references/agent-execution.md +36 -0
  328. package/skill-bundle/manifest.json +32 -0
  329. package/skills/insight-artifacts/SKILL.md +30 -0
  330. package/skills/insight-artifacts/references/agent-execution.md +36 -0
  331. package/skills/insight-artifacts/references/artifacts.md +52 -0
  332. package/skills/insight-binary/SKILL.md +46 -0
  333. package/skills/insight-binary/references/agent-execution.md +36 -0
  334. package/skills/insight-capture/SKILL.md +56 -0
  335. package/skills/insight-capture/references/agent-execution.md +36 -0
  336. package/skills/insight-die/SKILL.md +49 -0
  337. package/skills/insight-die/references/agent-execution.md +36 -0
  338. package/skills/insight-dnspy/SKILL.md +65 -0
  339. package/skills/insight-dnspy/references/agent-execution.md +36 -0
  340. package/skills/insight-dotnet-dump/SKILL.md +46 -0
  341. package/skills/insight-dotnet-dump/references/agent-execution.md +36 -0
  342. package/skills/insight-dotnet-stack/SKILL.md +39 -0
  343. package/skills/insight-dotnet-stack/references/agent-execution.md +36 -0
  344. package/skills/insight-dotnet-trace/SKILL.md +45 -0
  345. package/skills/insight-dotnet-trace/references/agent-execution.md +36 -0
  346. package/skills/insight-frida/SKILL.md +67 -0
  347. package/skills/insight-frida/references/agent-execution.md +36 -0
  348. package/skills/insight-ghidra/SKILL.md +91 -0
  349. package/skills/insight-ghidra/references/administration.md +34 -0
  350. package/skills/insight-ghidra/references/agent-execution.md +36 -0
  351. package/skills/insight-ghidra/references/archive.md +32 -0
  352. package/skills/insight-ghidra/references/artifacts.md +52 -0
  353. package/skills/insight-ghidra/references/debugger.md +62 -0
  354. package/skills/insight-ghidra/references/extensions-and-sync.md +124 -0
  355. package/skills/insight-ghidra/references/managed-runtime.md +157 -0
  356. package/skills/insight-ghidra/references/native-workflows.md +112 -0
  357. package/skills/insight-ghidra/references/query-semantics.md +96 -0
  358. package/skills/insight-ghidra/references/recovery.md +53 -0
  359. package/skills/insight-ghidra/references/research.md +101 -0
  360. package/skills/insight-ghidra/references/setup.md +50 -0
  361. package/skills/insight-ilspy/SKILL.md +45 -0
  362. package/skills/insight-ilspy/references/agent-execution.md +36 -0
  363. package/skills/insight-ilspy/references/ilspy.md +33 -0
  364. package/skills/insight-interop/SKILL.md +54 -0
  365. package/skills/insight-interop/references/agent-execution.md +36 -0
  366. package/skills/insight-lldb/SKILL.md +54 -0
  367. package/skills/insight-lldb/references/agent-execution.md +36 -0
  368. package/skills/insight-llvm/SKILL.md +56 -0
  369. package/skills/insight-llvm/references/agent-execution.md +36 -0
  370. package/skills/insight-managed-heap/SKILL.md +43 -0
  371. package/skills/insight-managed-heap/references/agent-execution.md +36 -0
  372. package/skills/insight-managed-metadata/SKILL.md +52 -0
  373. package/skills/insight-managed-metadata/references/agent-execution.md +36 -0
  374. package/skills/insight-mitmproxy/SKILL.md +62 -0
  375. package/skills/insight-mitmproxy/references/agent-execution.md +36 -0
  376. package/skills/insight-overview/SKILL.md +79 -0
  377. package/skills/insight-overview/references/agent-execution.md +36 -0
  378. package/skills/insight-procmon/SKILL.md +49 -0
  379. package/skills/insight-procmon/references/agent-execution.md +36 -0
  380. package/skills/insight-re/SKILL.md +22 -9
  381. package/skills/insight-re/references/agent-execution.md +36 -0
  382. package/skills/insight-re/references/artifacts.md +52 -0
  383. package/skills/insight-re/references/recovery.md +53 -0
  384. package/skills/insight-sevenzip/SKILL.md +42 -0
  385. package/skills/insight-sevenzip/references/agent-execution.md +36 -0
  386. package/skills/insight-strace/SKILL.md +46 -0
  387. package/skills/insight-strace/references/agent-execution.md +36 -0
  388. package/skills/insight-tshark/SKILL.md +49 -0
  389. package/skills/insight-tshark/references/agent-execution.md +36 -0
  390. package/skills/insight-windbg/SKILL.md +46 -0
  391. package/skills/insight-windbg/references/agent-execution.md +36 -0
@@ -1 +1 @@
1
- {"version":1,"artifact":"c3714e4dd4db303fdccc352327ce7c7f5dff074726238298a6953be70aca1db3"}
1
+ {"version":1,"artifact":"b65915991d87f45608bceba8cc7afa48b2e04f292149acf604aaf91ec2d2d6ba"}
package/README.md CHANGED
@@ -17,14 +17,40 @@ The executable is `insight-cli`. Its global npm executable directory must be on
17
17
  No source checkout, TypeScript build or separate Factory installation is required.
18
18
  The pinned Factory IPC runtime is a normal npm dependency fetched from an immutable
19
19
  GitHub tarball URL; installation therefore needs npm registry and GitHub access.
20
- Ghidra 12.1.2 and Java 21 are external dependencies for Ghidra commands.
20
+ Use `insight-cli ghidra install` to deliver the pinned Ghidra/JDK/native/server runtime.
21
+ External Ghidra launchers and Java paths are also supported.
22
+ `insight-cli ilspy install` delivers ILSpy and its private .NET runtime for managed-code
23
+ research. Tool downloads use pinned assets retained in our GitHub Releases.
24
+ Use `insight-cli tools processes` to inspect owned executions across tools.
21
25
  Help, skill discovery and saving ordinary files do not need Ghidra or Java.
22
26
 
27
+ Downloading a tool does not expose it in an agent's tool list. Connect the packaged skills
28
+ to your agent host, or explicitly give the agent the path returned by `insight-cli skill
29
+ insight-re --json`. See [agent setup](references/agent-setup.md) for tested project-local
30
+ Codex setup and a practical usability check. Installation leaves agent settings unchanged.
31
+
32
+ ## Discover the toolbox
33
+
34
+ ```sh
35
+ insight-cli tools list --json
36
+ insight-cli tools show die --json
37
+ insight-cli skill insight-die --json
38
+ ```
39
+
40
+ The catalog describes the adapters and their packaged skills before any runtime is downloaded.
41
+ Use each tool's `status` to check the selected profile, then follow its skill and generated help.
42
+ The toolbox includes Ghidra, ILSpy, 7-Zip, LLVM utilities, DiE, LLDB, Frida, WinDbg, strace and .NET dump/stack/trace; platform
43
+ and capability limits are explicit per tool. A partial classification or a failed native process
44
+ is not a complete finding. Preserve useful output in ordinary project files and checkpoint it
45
+ with `artifacts save` when useful. Existing project RE instructions retain precedence.
46
+
23
47
  ## Start
24
48
 
25
49
  ```sh
26
- insight-cli profile create local --java /path/to/java --ghidra-home /path/to/ghidra
50
+ insight-cli profile create local
27
51
  insight-cli --profile local permissions grant Update
52
+ insight-cli --profile local ghidra install
53
+ insight-cli --profile local ghidra status
28
54
  insight-cli --profile local ghidra open ./client.exe --session new --json
29
55
  ```
30
56
 
@@ -53,3 +79,8 @@ and `insight-cli skill insight-re` to locate packaged instructions and reference
53
79
 
54
80
  Full documentation and verification: [GitHub](https://github.com/iXab3r/insight-cli).
55
81
  License: MIT. The bundled GhidraMCP bridge has its own Apache-2.0 license and notice.
82
+
83
+ Runtime management, local archives and external paths: [managed runtime](references/managed-runtime.md).
84
+ The host debugger and OS permissions are checked separately by `ghidra doctor`.
85
+
86
+ Static .NET commands and ordinary output files: [ILSpy](references/ilspy.md).
package/SKILL.md CHANGED
@@ -1,55 +1,42 @@
1
1
  ---
2
2
  name: insight-cli
3
- description: Research several executable inputs through durable independent sessions and isolated Ghidra contexts using the matching insight-cli facade. Agents supply the investigation and interpret results.
3
+ description: Choose and prepare reverse-engineering capabilities from the insight-cli toolbox for binary, managed-code and runtime investigations. Use to discover the appropriate tool or its packaged skill before installing native runtimes.
4
4
  ---
5
5
 
6
- # insight-cli 0.1.0
7
-
8
- This skill and its executable helper are one npm package. Run `insight-cli skill` to locate
9
- these installed resources. Use generated `--help` for syntax; read the references as needed.
10
- Follow applicable project RE rules for tools, source of truth, evidence layout and format;
11
- this package's walkthroughs fill gaps rather than replacing those conventions.
12
-
13
- For coordinating a reverse-engineering investigation with ordinary files, external tools
14
- and multiple agents, read the packaged [Insight RE skill](skills/insight-re/SKILL.md),
15
- also located by `insight-cli skill insight-re`. When a retained checkpoint is useful, save
16
- a completed project file or folder with
17
- `insight-cli artifacts save <path>`; [save semantics](references/artifacts.md) describe the
18
- ordinary saved copy and its receipt. Neither operation requires a Ghidra installation.
19
-
20
- 1. Select the configured runtime profile. Ordinary work uses a managed local server; an external
21
- server is optional. See [setup](references/setup.md). Factory permissions authorize changes.
22
- 2. Open the input with `ghidra open <input> --session new`. Retain the returned session and target.
23
- Another agent chooses `new` independently; one session can open several inputs.
24
- 3. Pass both `--session` and `--target` on research calls. Follow strings to xrefs and their
25
- function addresses, then inspect/decompile. See [research](references/research.md).
26
- 4. Rename functions or set/clear comments through ordinary commands. An `applied` result means
27
- verified saved private work. Other sessions keep their own views; local edits remain unpublished in the default manual mode.
28
- 5. By default, publish explicitly with `ghidra merge`; receive safe shared changes with `ghidra refresh`.
29
- Resolve overlapping names/comments against an explicitly observed shared value. A conflict
30
- prevents the whole selected merge and retains local work.
31
- 6. Continue with `ghidra open --session <id> --target <id>`. For uncertain outcomes inspect
32
- `sessions status <id> --target <id>` and [recovery](references/recovery.md). Supplying a stable
33
- optional `--request-id` lets a repeated changing intent retrieve its outcome without rerunning.
34
-
35
- The facade exposes the pinned static research/editing catalog, merge/refresh, project/server/GUI
36
- controls, debugger, archive exchange and supported recovery. Preserve private work
37
- and journals while an outcome is unresolved. The CLI supplies the investigation tools; agents
38
- choose research goals and interpret findings.
39
- Installing this package does not register this skill in an agent's configuration.
40
-
41
- For project files, program export/import and configured-server administration, read
42
- [administration](references/administration.md). These operations preserve separate research views;
43
- their external effects do not participate in program merge.
44
-
45
- For owned GUI execution, CPU state, breakpoints and retained traces, read
46
- [debugger](references/debugger.md). Execution side effects remain separate from program publication.
47
-
48
- For explicit external documentation exchange and retained submission outcomes, read
49
- [archive](references/archive.md).
50
-
51
- For selected native SDK extensions (VT, DB differences, byte/assembly edits, formats, GDT,
52
- FID/BSim, namespaces and typed IR), read [native workflows](references/native-workflows.md).
53
-
54
- For managed SDK extension modules, actual language/analyzer/plugin discovery and opt-in
55
- automatic synchronization, read [extensions and sync](references/extensions-and-sync.md).
6
+ # insight-cli 0.2.1
7
+
8
+ If local help/status reports AppData or IPC access denied, retry that **read-only probe**
9
+ with the agent host's normal permission escalation, then use that route for later authorized
10
+ CLI calls too. An explicit **no command was sent** denial is known undispatched and can be
11
+ retried through that route. Keep HOME, profile and owner state; see
12
+ [host execution permissions](references/agent-execution.md). A lost mutation reply needs
13
+ request/status recovery, never blind retry.
14
+
15
+ Read the project's RE instructions and existing findings first. They own tool choices,
16
+ evidence layout, formats and source of truth. These skills fill the remaining gaps.
17
+
18
+ 1. Run `insight-cli tools list --json` to discover the capabilities shipped in this version.
19
+ The catalog works before profile configuration, downloads or IPC startup. A downloaded
20
+ runtime is not needed to discover what a tool does.
21
+ 2. Use `insight-cli tools show <tool> --json` for tasks, supported inputs/platforms,
22
+ dependencies and its skill path. Read that skill before preparing or using the tool.
23
+ 3. Select a profile for execution. Run the selected application's `status` and generated
24
+ `--help`. `install` prepares its private runtime; archives/offline and external paths
25
+ are tool-specific and described in its skill. Update permission is required for tool
26
+ preparation/execution and saved changes: `insight-cli permissions grant Update`.
27
+ 4. Answer the question with focused queries and ordinary project files. Follow results to
28
+ useful detail; a large raw dump is not an interpretation. External tools remain welcome.
29
+ 5. Preserve completed files with `insight-cli artifacts save <path> --json` when a retained
30
+ checkpoint helps. For several agents sharing Ghidra analysis, use separate sessions,
31
+ then explicit merge/refresh as described by its skill.
32
+
33
+ `insight-cli skill` locates this entry point. `skill insight-re` gives investigation and
34
+ multi-agent guidance; `skill insight-ghidra`, `skill insight-ilspy` and
35
+ `skill insight-artifacts` locate the relevant instructions. Skills ship with the CLI;
36
+ installing npm binaries does not register them in an agent host. See
37
+ [agent connection](references/agent-setup.md) for current setup and access requirements.
38
+
39
+ Use generated help as the syntax authority. Catalog metadata describes shipped capabilities;
40
+ profile runtime readiness comes from the selected tool's `status`. Unavailable profile/IPC
41
+ access means execution readiness is unknown. Preserve work and diagnose access before trying
42
+ again; stopping a shared owner does not grant a denied agent access to it.
@@ -12,7 +12,7 @@ export function administrationResult(operation, p, raw) {
12
12
  const value = object(raw);
13
13
  if (JSON.stringify(value).length > 1048576)
14
14
  fail('limit', 'Administration result exceeds one MiB.');
15
- if (['status', 'connect', 'disconnect'].includes(operation)) {
15
+ if (['status', 'connect', 'disconnect', 'stop'].includes(operation)) {
16
16
  if (typeof value.connected !== 'boolean' || !['local', 'external'].includes(String(value.mode)))
17
17
  fail('partial', 'Server status is incomplete.');
18
18
  if (value.connected && typeof value.repository !== 'string')
@@ -11,4 +11,4 @@ export declare class Administration {
11
11
  read(operation: string, parameters: Record<string, unknown>): Promise<Record<string, unknown>>;
12
12
  change(operation: string, parameters: Record<string, unknown>, callerId?: string): Promise<unknown>;
13
13
  }
14
- export declare function administrationCommands(service: (context: CommandContext) => Administration): CommandDefinition[];
14
+ export declare function administrationCommands(service: (context: CommandContext) => Administration, unconfiguredStatus?: (context: CommandContext) => Promise<Record<string, unknown> | undefined>): CommandDefinition[];
@@ -1,6 +1,7 @@
1
1
  import { command, Permission } from '@eyeauras/cli-factory';
2
2
  import { fail, id, text } from './model.js';
3
3
  import { option, parsed, key } from './arguments.js';
4
+ import { runtimeProcesses } from './runtime-manager.js';
4
5
  import { administrationResult } from './administration-results.js';
5
6
  const repository = (value) => { const name = text(value, 128); if (name !== name.trim() || /[\\/\0]/.test(name) || name.startsWith('.'))
6
7
  fail('invalid', 'Repository name must be a single bounded name.'); return name; };
@@ -67,6 +68,8 @@ export class Administration {
67
68
  const repo = { name: 'repository', type: 'string', required: true }, path = { name: 'path', type: 'string', required: false, default: '/' };
68
69
  const leaves = [
69
70
  { names: ['status'], operation: 'status', gate: Permission.ReadOnly, params: [] },
71
+ { names: ['start'], operation: 'connect', gate: Permission.Update, params: [] },
72
+ { names: ['stop'], operation: 'stop', gate: Permission.Update, params: [] },
70
73
  { names: ['connect'], operation: 'connect', gate: Permission.Update, params: [] },
71
74
  { names: ['disconnect'], operation: 'disconnect', gate: Permission.Update, params: [] },
72
75
  { names: ['repositories', 'list'], operation: 'repositories', gate: Permission.ReadOnly, params: [] },
@@ -81,11 +84,22 @@ const leaves = [
81
84
  { names: ['admin', 'terminate-checkout'], operation: 'terminate_checkout', gate: 'Destructive', params: [repo, { ...path, required: true, default: undefined }, { name: 'checkout_id', type: 'string', required: false }] },
82
85
  { names: ['admin', 'terminate-all-checkouts'], operation: 'terminate_all_checkouts', gate: 'Destructive', params: [repo, path] },
83
86
  ];
84
- export function administrationCommands(service) {
87
+ export function administrationCommands(service, unconfiguredStatus) {
85
88
  const children = [];
86
89
  for (const leaf of leaves) {
87
90
  const changing = leaf.gate !== Permission.ReadOnly;
88
- const definition = command(leaf.names.at(-1), 'Operate on the configured server and explicit repository', ({ options: o }, c) => {
91
+ const definition = command(leaf.names.at(-1), 'Operate on the configured server and explicit repository', async ({ options: o }, c) => {
92
+ if (leaf.operation === 'stop') {
93
+ if (c.profile.values.server)
94
+ fail('authorization', 'External server lifecycle is owned by its operator. Use server disconnect.');
95
+ if ((await runtimeProcesses(c.appArguments.AppDataDirectory)).some(p => p.kind !== 'server'))
96
+ fail('busy', 'Close active Ghidra contexts before stopping their server.');
97
+ }
98
+ if (leaf.operation === 'status' && unconfiguredStatus) {
99
+ const passive = await unconfiguredStatus(c);
100
+ if (passive)
101
+ return passive;
102
+ }
89
103
  const parameters = {};
90
104
  for (const p of leaf.params) {
91
105
  const value = o[key(p.name)];
@@ -0,0 +1,3 @@
1
+ import { type CommandContext, type CommandDefinition } from '@eyeauras/cli-factory';
2
+ import type { Workspace } from './workspace.js';
3
+ export declare function binaryCommands(workspace: (c: CommandContext) => Workspace): CommandDefinition[];
@@ -0,0 +1,74 @@
1
+ import { command, Permission, CliError } from '@eyeauras/cli-factory';
2
+ import { join, resolve, dirname } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { mkdir, writeFile, copyFile, readFile } from 'node:fs/promises';
5
+ import { constants } from 'node:fs';
6
+ import { release } from 'node:os';
7
+ import { randomUUID } from 'node:crypto';
8
+ import { runTool } from './tool-runtime/run.js';
9
+ import { atomicWrite } from './tool-runtime/store.js';
10
+ import { fileSha256 } from './tool-runtime/archives.js';
11
+ import { fail, text, id } from './model.js';
12
+ import { number } from './research.js';
13
+ const helper = fileURLToPath(new URL('../../runtime/native/binary/insight-binary-darwin-arm64', import.meta.url));
14
+ export function binaryCommands(workspace) {
15
+ const run = (mode) => command(mode + ' [input]', mode === 'query' ? 'Inspect bounded PE, ELF or thin Mach-O metadata without executing the input' : 'Change one expected PE subsystem field in a new copy and independently read it back', async ({ args, options: o }, c) => {
16
+ if (process.platform !== 'darwin' || process.arch !== 'arm64' || Number(release().split('.')[0]) < 23)
17
+ fail('unsupported', 'The packaged LIEF facade is currently verified on macOS14+ ARM64; input formats are PE, ELF and thin Mach-O.');
18
+ if (Boolean(args.input) === Boolean(o.target))
19
+ fail('invalid', 'Supply one binary input or --target.');
20
+ const view = mode === 'query' ? text(o.view ?? 'overview', 16) : undefined;
21
+ if (view && !['overview', 'sections', 'libraries', 'imports', 'exports'].includes(view))
22
+ fail('invalid', 'Use overview, sections, libraries, imports or exports.');
23
+ const limit = number(o.limit ?? 50, 500, 1), offset = number(o.offset ?? 0, 1000000), w = workspace(c), target = args.input ? await w.importTarget(resolve(c.cwd, text(args.input, 4096))) : w.target(id(o.target));
24
+ if (target.input.size > 64 * 1024 ** 2)
25
+ fail('limit', 'Structured binary input exceeds 64 MiB.');
26
+ const input = await w.artifacts.verify(target.input);
27
+ const directory = join(c.appArguments.AppDataDirectory, 'runtime/binary/queries', randomUUID()), plan = join(directory, 'plan.json'), edited = join(directory, 'edited.exe');
28
+ let edit;
29
+ if (mode === 'edit-subsystem') {
30
+ if (!o.output)
31
+ fail('invalid', 'Copy-only editing requires --output FILE.');
32
+ const values = { gui: 2, console: 3 }, expected = values[text(o.expectSubsystem, 16)], value = values[text(o.subsystem, 16)];
33
+ if (!expected || !value || expected === value)
34
+ fail('invalid', 'Choose a different gui/console subsystem and an explicit --expect-subsystem.');
35
+ edit = { expectedSubsystem: expected, subsystem: value, output: edited };
36
+ }
37
+ await atomicWrite(plan, { schema: 1, mode, input, view, filter: o.filter === undefined ? undefined : text(o.filter, 4096), limit, offset, ...edit });
38
+ const result = await runTool(c, { tool: 'binary', role: mode, executable: helper, arguments: [plan], timeoutMs: 60000, maxOutputBytes: 8 * 1024 ** 2, nativeDeadline: true, target: target.id, metadata: { view, helperSha256: await fileSha256(helper) } });
39
+ let observation;
40
+ try {
41
+ observation = JSON.parse(result.stdout);
42
+ }
43
+ catch {
44
+ throw new CliError('Binary parser did not return complete bounded JSON.', { code: 'tool.partial', result: { process: result.process, diagnostics: result.diagnostics } });
45
+ }
46
+ if (!['completed', 'partial'].includes(observation?.state) || typeof observation.complete !== 'boolean')
47
+ fail('partial', 'Binary query receipt was not verified.', { process: result.process, diagnostics: result.diagnostics });
48
+ if (await fileSha256(input) !== target.binarySha256)
49
+ fail('binding', 'Immutable binary changed during inspection.');
50
+ const warnings = result.stderr.trim(), value = { ...observation, ...(warnings ? { state: 'partial', complete: false, reason: 'native_parser_diagnostics', warnings: warnings.slice(0, 4096), warningsTruncated: warnings.length > 4096 } : {}), target: target.id, inputSha256: target.binarySha256, process: result.process, elapsedMs: result.elapsedMs, diagnostics: result.diagnostics };
51
+ if (mode === 'edit-subsystem') {
52
+ if (!value.complete)
53
+ fail('partial', 'Native parser diagnostics prevent accepting the copied edit.', value);
54
+ const before = await readFile(input), after = await readFile(edited), at = Number(BigInt(observation.fieldOffset));
55
+ if (after.length !== before.length || !Number.isSafeInteger(at) || at < 0 || at + 2 > before.length)
56
+ fail('binding', 'Copied PE edit did not retain its field bounds.');
57
+ for (let n = 0; n < before.length; n++)
58
+ if (n !== at && n !== at + 1 && before[n] !== after[n])
59
+ fail('binding', 'Copied PE edit changed bytes outside the declared field.');
60
+ const output = resolve(c.cwd, text(o.output, 4096));
61
+ await mkdir(dirname(output), { recursive: true, mode: 0o700 });
62
+ await copyFile(edited, output, constants.COPYFILE_EXCL);
63
+ return { ...value, output, outputSha256: await fileSha256(output), originalPreserved: true };
64
+ }
65
+ if (o.output) {
66
+ const output = resolve(c.cwd, text(o.output, 4096)), content = JSON.stringify(value, null, 2) + '\n';
67
+ await mkdir(dirname(output), { recursive: true, mode: 0o700 });
68
+ await writeFile(output, content, { flag: 'wx', mode: 0o600 });
69
+ return { state: value.state, complete: value.complete, reason: value.reason, target: target.id, output, bytes: Buffer.byteLength(content), process: result.process, diagnostics: result.diagnostics };
70
+ }
71
+ return value;
72
+ }, { permission: Permission.Update, options: [{ flags: '--target <id>', description: 'Reuse immutable input bytes' }, { flags: '--output <file>', description: mode === 'query' ? 'Save this bounded page to a new JSON file' : 'Required new executable copy; never overwrite an existing file' }, ...(mode === 'query' ? [{ flags: '--view <kind>', description: 'overview, sections, libraries, imports or exports', defaultValue: 'overview' }, { flags: '--filter <text>', description: 'Literal metadata name substring before pagination' }, { flags: '--limit <count>', description: 'Return 1–500 rows', defaultValue: 50 }, { flags: '--offset <count>', description: 'Skip matching rows', defaultValue: 0 }] : [{ flags: '--expect-subsystem <kind>', description: 'Required current PE subsystem: gui or console', required: true }, { flags: '--subsystem <kind>', description: 'Required different PE subsystem: gui or console', required: true }])] });
73
+ return [command('binary', 'Structured binary metadata and guarded copy-only edits', [run('query'), run('edit-subsystem')])];
74
+ }
@@ -0,0 +1,3 @@
1
+ import { type CommandContext, type CommandDefinition } from '@eyeauras/cli-factory';
2
+ import type { Workspace } from './workspace.js';
3
+ export declare function captureCommands(workspace: (c: CommandContext) => Workspace): CommandDefinition[];
@@ -0,0 +1,220 @@
1
+ import { command, Permission, CliError } from '@eyeauras/cli-factory';
2
+ import { join, resolve, dirname, basename, sep } from 'node:path';
3
+ import { mkdir, writeFile, copyFile, chmod, open, realpath, lstat } from 'node:fs/promises';
4
+ import { constants } from 'node:fs';
5
+ import { release } from 'node:os';
6
+ import { createHash } from 'node:crypto';
7
+ import { runTool } from './tool-runtime/run.js';
8
+ import { atomicWrite, readJson } from './tool-runtime/store.js';
9
+ import { listProcesses } from './tool-runtime/supervisor.js';
10
+ import { fileSha256 } from './tool-runtime/archives.js';
11
+ import { fail, text, id } from './model.js';
12
+ import { number } from './research.js';
13
+ const sha = (b) => createHash('sha256').update(b).digest('hex');
14
+ const list = (v) => v === undefined ? [] : (Array.isArray(v) ? v : [v]).map(s => text(s, 4096));
15
+ const root = (c, request) => { if (!/^a_[a-f0-9-]{36}$/.test(request))
16
+ fail('invalid', 'Select a capture request returned by capture run.'); return join(c.appArguments.AppDataDirectory, 'runtime/capture', request); };
17
+ function relativeFile(value) { const name = text(value, 1024); if (name.includes('\\') || name.startsWith('/') || name.split('/').some(p => !p || p === '.' || p === '..') || name.toLowerCase() === 'subject')
18
+ fail('invalid', 'Watch paths must be ordinary relative files inside the owned working directory.'); return name; }
19
+ async function boundedFile(path, max = 16 * 1024 ** 2) {
20
+ const handle = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW);
21
+ try {
22
+ const before = await handle.stat();
23
+ if (!before.isFile() || before.size > max)
24
+ fail('limit', 'Selected file must be regular and within its byte bound.');
25
+ const chunks = [];
26
+ let bytes = 0;
27
+ for await (const chunk of handle.createReadStream({ autoClose: false })) {
28
+ bytes += chunk.length;
29
+ if (bytes > max)
30
+ fail('limit', 'Selected file grew beyond its capture bound.');
31
+ chunks.push(chunk);
32
+ }
33
+ const after = await handle.stat();
34
+ if (before.size !== after.size || before.mtimeMs !== after.mtimeMs || before.ctimeMs !== after.ctimeMs || before.ino !== after.ino)
35
+ fail('binding', 'Selected file changed while being read.');
36
+ return Buffer.concat(chunks);
37
+ }
38
+ finally {
39
+ await handle.close();
40
+ }
41
+ }
42
+ async function snapshot(directory, name) {
43
+ const file = join(directory, name);
44
+ try {
45
+ const parent = await realpath(dirname(file)), base = await realpath(directory);
46
+ if (parent !== base && !parent.startsWith(base + sep))
47
+ return { path: name, state: 'unavailable', reason: 'parent_outside_owned_directory' };
48
+ const info = await lstat(file);
49
+ if (!info.isFile() || info.isSymbolicLink())
50
+ return { path: name, state: 'unavailable', reason: 'not_regular_file' };
51
+ const bytes = await boundedFile(file);
52
+ return { path: name, state: 'present', bytes: bytes.length, sha256: sha(bytes) };
53
+ }
54
+ catch (error) {
55
+ if (error.code === 'ENOENT')
56
+ return { path: name, state: 'absent' };
57
+ return { path: name, state: 'unavailable', reason: error.code ?? 'unreadable' };
58
+ }
59
+ }
60
+ function pageStream(value, offset, limit) { if (!value)
61
+ return { available: false }; const all = Buffer.from(value.base64, 'base64'), bytes = all.subarray(offset, offset + limit); return { available: true, totalBytes: value.bytes, sha256: value.sha256, offset, limit, base64: bytes.toString('base64'), text: bytes.toString('utf8'), textEncoding: 'UTF-8 preview with replacement; base64 preserves exact selected bytes', truncated: offset + limit < all.length }; }
62
+ function overview(receipt) { const { stdout, stderr, files, ...rest } = receipt; return { ...rest, stdout: pageStream(stdout, 0, 256), stderr: pageStream(stderr, 0, 256), declaredFiles: files.length, fileChanges: files.filter(f => f.change !== 'unchanged').map(f => ({ path: f.path, change: f.change })) }; }
63
+ async function exportReceipt(c, value, option) { const output = resolve(c.cwd, text(option, 4096)), content = JSON.stringify(value, null, 2) + '\n'; await mkdir(dirname(output), { recursive: true, mode: 0o700 }); await writeFile(output, content, { flag: 'wx', mode: 0o600 }); return output; }
64
+ async function receiptFor(c, w, request) { const stored = w.administration(request); if (stored.operation !== 'capture.run')
65
+ fail('invalid', 'Request is not an owned process capture.'); const file = join(root(c, request), 'capture.json'), receipt = await readJson(file); if (receipt && stored.state === 'applied') {
66
+ const result = stored.result;
67
+ if (result?.receiptSha256 !== await fileSha256(file))
68
+ fail('binding', 'Capture receipt differs from its durable outcome.');
69
+ validateReport(receipt);
70
+ if (receipt.request !== request)
71
+ fail('binding', 'Capture receipt has a different request identity.');
72
+ return receipt;
73
+ } return { state: stored.state === 'accepted' ? 'prepared' : 'unknown', complete: false, request, intent: stored.intent, processes: (await listProcesses(c.appArguments.AppDataDirectory, { tool: 'capture' })).filter(p => p.metadata?.request === request), directory: root(c, request), workingDirectory: join(root(c, request), 'working'), scope: 'No completed capture receipt. Inspect retained process/input/files explicitly; never rerun this request to manufacture a result.' }; }
74
+ function validateReport(value) {
75
+ const hash = (v) => typeof v === 'string' && /^[a-f0-9]{64}$/.test(v);
76
+ if (value?.schema !== 1 || value.kind !== 'insight-process-capture' || typeof value.complete !== 'boolean' || value.state !== (value.complete ? 'completed' : 'partial') || !hash(value.inputSha256) || !Array.isArray(value.files) || value.files.length > 32 || !value.execution || !Array.isArray(value.arguments) || value.arguments.length > 64 || value.arguments.some(a => typeof a !== 'string' || a.length > 4096) || !Array.isArray(value.inputs) || value.inputs.length > 32)
77
+ fail('invalid', 'Select a structured insight process capture report.');
78
+ if (value.execution.exitCode !== null && (!Number.isInteger(value.execution.exitCode) || value.execution.exitCode < 0 || value.execution.exitCode > 255))
79
+ fail('invalid', 'Invalid captured exit code.');
80
+ let bytes = 0;
81
+ for (const stream of [value.stdout, value.stderr])
82
+ if (stream) {
83
+ if (!hash(stream.sha256) || typeof stream.base64 !== 'string')
84
+ fail('invalid', 'Malformed capture byte stream.');
85
+ const raw = Buffer.from(stream.base64, 'base64');
86
+ if (raw.toString('base64') !== stream.base64 || raw.length !== stream.bytes || sha(raw) !== stream.sha256 || (bytes += raw.length) > 4 * 1024 ** 2)
87
+ fail('binding', 'Capture byte stream differs from its bounds/hash.');
88
+ }
89
+ if (value.complete && (!value.stdout || !value.stderr || value.execution.exitCode === null || value.execution.signal !== null))
90
+ fail('invalid', 'A complete capture requires known terminal output and exit.');
91
+ const seen = new Set();
92
+ for (const file of value.files) {
93
+ const name = relativeFile(file.path);
94
+ if (seen.has(name))
95
+ fail('invalid', 'Duplicate declared capture path.');
96
+ seen.add(name);
97
+ for (const observed of [file.before, file.after])
98
+ if (!observed || observed.path !== name || !['present', 'absent', 'unavailable'].includes(observed.state) || observed.state === 'present' && (!hash(observed.sha256) || !Number.isSafeInteger(observed.bytes) || observed.bytes < 0 || observed.bytes > 16 * 1024 ** 2))
99
+ fail('invalid', 'Malformed declared file observation.');
100
+ }
101
+ }
102
+ export function captureCommands(workspace) {
103
+ const run = command('run [input]', 'Capture one explicitly selected owned native execution and declared file snapshots', async ({ args, options: o }, c) => {
104
+ if (process.platform !== 'darwin' || process.arch !== 'arm64' || Number(release().split('.')[0]) < 23)
105
+ fail('unsupported', 'Process capture is verified on macOS14+ ARM64 thin native executables.');
106
+ if (Boolean(args.input) === Boolean(o.target))
107
+ fail('invalid', 'Supply one native program or --target.');
108
+ const w = workspace(c), target = args.input ? await w.importTarget(resolve(c.cwd, text(args.input, 4096))) : w.target(id(o.target)), input = await w.artifacts.verify(target.input);
109
+ if (target.input.size > 64 * 1024 ** 2)
110
+ fail('limit', 'Owned executable exceeds 64 MiB.');
111
+ const header = (await boundedFile(input, 64 * 1024 ** 2)).subarray(0, 32);
112
+ if (header.length < 32 || header.subarray(0, 4).toString('hex') !== 'cffaedfe' || header.readUInt32LE(4) !== 0x0100000c || header.readUInt32LE(12) !== 2)
113
+ fail('unsupported', 'Select a thin ARM64 Mach-O executable, not a PE/ELF, script, library or universal container.');
114
+ const argv = list(o.arg), selected = list(o.inputFile), watched = [...new Set(list(o.watch).map(relativeFile))];
115
+ if (argv.length > 64 || selected.length > 32 || watched.length > 32)
116
+ fail('limit', 'Capture permits 64 literal arguments, 32 selected input files and 32 watch paths.');
117
+ const timeoutMs = number(o.timeoutSeconds ?? 10, 600, 1) * 1000, files = [];
118
+ let total = 0;
119
+ for (const option of selected) {
120
+ const path = resolve(c.cwd, option), name = basename(path);
121
+ if (name.toLowerCase() === 'subject' || files.some(f => f.name.normalize('NFD').toLowerCase() === name.normalize('NFD').toLowerCase()) || !/^[^/\\\0]+$/.test(name))
122
+ fail('invalid', 'Selected input basenames must be ordinary and unique.');
123
+ const data = await boundedFile(path);
124
+ if ((total += data.length) > 64 * 1024 ** 2)
125
+ fail('limit', 'Selected input files exceed 64 MiB.');
126
+ files.push({ name, sha256: sha(data), bytes: data.length, data });
127
+ }
128
+ const stdin = o.stdinFile ? await boundedFile(resolve(c.cwd, text(o.stdinFile, 4096)), 1024 ** 2) : Buffer.alloc(0);
129
+ if (o.output && !(o.requestId && w.administrationByCaller(id(o.requestId))))
130
+ try {
131
+ await lstat(resolve(c.cwd, text(o.output, 4096)));
132
+ fail('invalid', 'Capture output already exists.');
133
+ }
134
+ catch (error) {
135
+ if (error.code !== 'ENOENT')
136
+ throw error;
137
+ }
138
+ const intent = { target: target.id, inputSha256: target.binarySha256, arguments: argv, inputs: files.map(({ data, ...f }) => f), stdin: { sha256: sha(stdin), bytes: stdin.length }, watch: watched, timeoutMs, output: o.output ? resolve(c.cwd, text(o.output, 4096)) : undefined };
139
+ const reservation = w.reserveAdministration('capture.run', intent, o.requestId === undefined ? undefined : id(o.requestId)), request = reservation.request.id;
140
+ if (reservation.replay) {
141
+ const previous = await receiptFor(c, w, request);
142
+ if (reservation.request.state === 'applied' && 'kind' in previous) {
143
+ if (!previous.complete)
144
+ throw new CliError('Prior capture remains partial; no execution was repeated.', { code: 'tool.capture.partial', result: overview(previous) });
145
+ return { ...overview(previous), replayed: true };
146
+ }
147
+ throw new CliError('Capture request already exists without a verified complete outcome; no execution was repeated.', { code: 'tool.capture.unknown', result: previous });
148
+ }
149
+ const directory = root(c, request), working = join(directory, 'working'), subject = join(working, 'subject');
150
+ await mkdir(working, { recursive: true, mode: 0o700 });
151
+ await copyFile(input, subject, constants.COPYFILE_EXCL);
152
+ await chmod(subject, 0o700);
153
+ if (await fileSha256(subject) !== target.binarySha256)
154
+ fail('binding', 'Owned executable differs from captured input.');
155
+ for (const f of files)
156
+ await writeFile(join(working, f.name), f.data, { flag: 'wx', mode: 0o600 });
157
+ const before = await Promise.all(watched.map(name => snapshot(working, name)));
158
+ await atomicWrite(join(directory, 'intent.json'), { request, ...intent });
159
+ w.administrationState(request, 'running', { directory });
160
+ let result, failure;
161
+ try {
162
+ result = await runTool(c, { tool: 'capture', role: 'run', executable: subject, arguments: argv, cwd: working, input: stdin, timeoutMs, maxOutputBytes: 4 * 1024 ** 2, retainRawOutput: true, nativeDeadline: true, acceptedCodes: Array.from({ length: 127 }, (_, n) => n), target: target.id, metadata: { request, working, scope: 'Owned program copy; selected input copies and declared file snapshots; no shell or OS sandbox' } });
163
+ }
164
+ catch (error) {
165
+ failure = error;
166
+ if (error instanceof CliError && error.result && typeof error.result === 'object' && 'stdout' in error.result)
167
+ result = error.result;
168
+ }
169
+ const after = await Promise.all(watched.map(name => snapshot(working, name))), unavailable = [...before, ...after].some(f => f.state === 'unavailable');
170
+ const stream = async (file) => { if (!file)
171
+ return; const b = await boundedFile(file, 4 * 1024 ** 2); return { bytes: b.length, sha256: sha(b), base64: b.toString('base64') }; };
172
+ const value = { schema: 1, kind: 'insight-process-capture', request, state: failure || unavailable ? 'partial' : 'completed', complete: !failure && !unavailable, ...(failure ? { reason: failure instanceof CliError ? failure.code : 'capture_failed' } : unavailable ? { reason: 'declared_file_unavailable' } : {}), target: target.id, inputSha256: target.binarySha256, timeoutMs, arguments: argv, inputs: intent.inputs, stdin: intent.stdin, stdout: await stream(result?.rawStdout), stderr: await stream(result?.rawStderr), execution: { process: result?.process, exitCode: result?.exitCode ?? null, signal: result?.signal ?? null, elapsedMs: result?.elapsedMs, diagnostics: result?.diagnostics }, files: watched.map((path, n) => { const a = before[n], b = after[n]; return { path, before: a, after: b, change: a.state === 'unavailable' || b.state === 'unavailable' ? 'unknown' : a.state === b.state && (a.state === 'absent' || a.sha256 === b.sha256) ? 'unchanged' : a.state === 'absent' ? 'created' : b.state === 'absent' ? 'deleted' : 'changed' }; }), scope: 'One owned program copy with literal argv, exact bounded stdout/stderr bytes and selected file snapshots. This is not an OS sandbox, a trace of all filesystem/network effects or proof of causality. Native deadline assumes the subject does not deliberately replace the inherited alarm. Known nonzero subject exits are captured outcomes; interrupted/overflow/unknown capture stays partial.' };
173
+ if (!value.stdout || !value.stderr) {
174
+ value.complete = false;
175
+ value.state = 'partial';
176
+ value.reason ??= 'raw_output_unavailable';
177
+ }
178
+ const path = join(directory, 'capture.json');
179
+ await atomicWrite(path, value);
180
+ w.administrationState(request, 'applied', { receipt: path, receiptSha256: await fileSha256(path), complete: value.complete });
181
+ const output = o.output ? await exportReceipt(c, value, o.output) : undefined;
182
+ if (!value.complete)
183
+ throw new CliError('Capture is partial; retained output/files are available and execution was not replayed.', { code: 'tool.capture.partial', result: { ...overview(value), directory, ...(output ? { output } : {}) } });
184
+ return { ...overview(value), directory, ...(output ? { output } : {}) };
185
+ }, { permission: Permission.Update, options: [{ flags: '--target <id>', description: 'Reuse immutable native program bytes' }, { flags: '--arg <text...>', description: 'Literal subject arguments; no shell string or expansion' }, { flags: '--input-file <file...>', description: 'Copy selected regular files by unique basename into owned cwd' }, { flags: '--stdin-file <file>', description: 'Optional bounded input byte stream (up to 1 MiB)' }, { flags: '--watch <path...>', description: 'Declared relative regular files to snapshot before and after execution' }, { flags: '--timeout-seconds <seconds>', description: 'Owned execution deadline (1–600)', defaultValue: 10 }, { flags: '--output <file>', description: 'Save a new portable bounded JSON capture, including exact output base64' }, { flags: '--request-id <id>', description: 'Retrieve this exact capture intent without executing it again' }] });
186
+ const show = command('show <request>', 'Inspect retained capture bytes or an unresolved intent without rerunning a program', async ({ args, options: o }, c) => { const request = text(args.request, 128), value = await receiptFor(c, workspace(c), request); if (!('kind' in value))
187
+ return value; if (o.output)
188
+ return { request, complete: value.complete, output: await exportReceipt(c, value, o.output) }; const view = text(o.view ?? 'overview', 16), limit = number(o.limit ?? 50, 1000, 1), offset = number(o.offset ?? 0, 8 * 1024 ** 2); if (view === 'overview')
189
+ return overview(value); if (view === 'stdout' || view === 'stderr')
190
+ return { request, state: value.state, complete: value.complete, view, ...pageStream(value[view], offset, limit) }; if (view === 'files')
191
+ return { request, state: value.state, complete: value.complete, items: value.files.slice(offset, offset + limit), total: value.files.length, offset, limit, truncated: offset + limit < value.files.length }; fail('invalid', 'Use overview, stdout, stderr or files.'); }, { permission: Permission.Update, options: [{ flags: '--view <kind>', description: 'overview, stdout, stderr or files', defaultValue: 'overview' }, { flags: '--limit <count>', description: '1–1000 output bytes or file rows', defaultValue: 50 }, { flags: '--offset <count>', description: 'Skip output bytes or file rows', defaultValue: 0 }, { flags: '--output <file>', description: 'Export portable retained capture to a new ordinary JSON file' }] });
192
+ const compare = command('compare <left> <right>', 'Compare two retained capture reports without re-executing their subjects', async ({ args, options: o }, c) => {
193
+ async function load(path) { const file = resolve(c.cwd, text(path, 4096)), bytes = await boundedFile(file, 8 * 1024 ** 2); let value; try {
194
+ value = JSON.parse(bytes.toString('utf8'));
195
+ }
196
+ catch {
197
+ fail('invalid', 'Capture report must be bounded JSON.');
198
+ } validateReport(value); return { value, sha256: sha(bytes) }; }
199
+ const left = await load(args.left), right = await load(args.right), a = left.value, b = right.value, changes = [], unknown = [];
200
+ for (const field of ['stdout', 'stderr']) {
201
+ if (!a[field] || !b[field])
202
+ unknown.push(field);
203
+ else if (a[field].sha256 !== b[field].sha256)
204
+ changes.push({ field, left: a[field].sha256, right: b[field].sha256 });
205
+ }
206
+ if (a.execution.exitCode !== b.execution.exitCode || a.execution.signal !== b.execution.signal)
207
+ changes.push({ field: 'exit', left: a.execution, right: b.execution });
208
+ const af = new Map(a.files.map(f => [f.path, f])), bf = new Map(b.files.map(f => [f.path, f]));
209
+ for (const name of [...new Set([...af.keys(), ...bf.keys()])].sort()) {
210
+ const l = af.get(name)?.after, r = bf.get(name)?.after;
211
+ if (!l || !r || l.state === 'unavailable' || r.state === 'unavailable')
212
+ unknown.push('file:' + name);
213
+ else if (l.state !== r.state || l.sha256 !== r.sha256)
214
+ changes.push({ field: 'file:' + name, left: l, right: r });
215
+ }
216
+ const limit = number(o.limit ?? 50, 500, 1), offset = number(o.offset ?? 0, 1000000), complete = a.complete && b.complete && !unknown.length;
217
+ return { state: complete ? 'completed' : 'partial', complete, left: { reportSha256: left.sha256, inputSha256: a.inputSha256 }, right: { reportSha256: right.sha256, inputSha256: b.inputSha256 }, sameDeclaredIntent: JSON.stringify({ target: a.inputSha256, argv: a.arguments, inputs: a.inputs, stdin: a.stdin, watch: a.files.map(f => f.path), timeoutMs: a.timeoutMs }) === JSON.stringify({ target: b.inputSha256, argv: b.arguments, inputs: b.inputs, stdin: b.stdin, watch: b.files.map(f => f.path), timeoutMs: b.timeoutMs }), items: changes.slice(offset, offset + limit), total: changes.length, unknown, offset, limit, truncated: offset + limit < changes.length, scope: 'Literal retained field/byte comparison; no subject rerun, causal equivalence or execution-time speedup claim. Partial reports cannot prove global equality.' };
218
+ }, { permission: Permission.ReadOnly, options: [{ flags: '--limit <count>', description: 'Return 1–500 changed fields', defaultValue: 50 }, { flags: '--offset <count>', description: 'Skip changed fields', defaultValue: 0 }] });
219
+ return [command('capture', 'Own bounded native executions and compare explicitly retained observations', [run, show, compare])];
220
+ }