@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,9 +1,13 @@
1
1
  /** Internal LLDB child owner. It has no public command or independent product IPC host. */
2
- import { spawn } from 'node:child_process';
2
+ import { launchProcess, registerExistingProcess } from './tool-runtime/supervisor.js';
3
+ import { createServer } from 'node:http';
3
4
  import { readFile, writeFile, mkdir, open, rename, realpath } from 'node:fs/promises';
4
5
  import { join, resolve, delimiter } from 'node:path';
5
6
  import { randomUUID } from 'node:crypto';
6
7
  import { HttpBridge } from './transport.js';
8
+ import { callerMonitor } from './debugger-caller.js';
9
+ import { debuggerLaunchArguments } from './debugger-launch.js';
10
+ import { verifyManagedInstallation } from './tool-runtime/installer.js';
7
11
  async function main() {
8
12
  const root = await realpath(process.argv[2]), binding = JSON.parse(await readFile(join(root, 'process.json'), 'utf8'));
9
13
  if (root !== resolve(root) || binding.root !== root || binding.mode !== 'gui' || !Number.isSafeInteger(binding.pid))
@@ -38,6 +42,23 @@ async function main() {
38
42
  finally {
39
43
  await parent.close();
40
44
  } }
45
+ const appData = process.env.INSIGHT_TOOL_APPDATA, canonicalAppData = appData ? await realpath(appData) : undefined;
46
+ if (!appData || !canonicalAppData || !root.startsWith(join(canonicalAppData, 'workspace', 'ghidra-native') + '/'))
47
+ throw Error('Invalid tool profile');
48
+ if (binding.debuggerRuntime)
49
+ await verifyManagedInstallation(appData, 'ghidra-debugger', binding.debuggerRuntime);
50
+ const authority = createServer((req, res) => { if (req.url !== '/identity' || req.headers.authorization !== 'Bearer ' + token) {
51
+ res.writeHead(403).end();
52
+ return;
53
+ } res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify({ id, pid: process.pid, childPid: receipt.childPid, state: receipt.state })); });
54
+ await new Promise(ok => authority.listen(0, '127.0.0.1', ok));
55
+ authority.unref();
56
+ const address = authority.address();
57
+ if (!address || typeof address === 'string')
58
+ throw Error('No debugger identity port');
59
+ Object.assign(receipt, { identityPort: address.port });
60
+ const processSpec = { tool: 'ghidra', installation: binding.runtimeFingerprint, target: binding.target, session: binding.session, metadata: { debuggerReceipt: path, debuggerDiagnostics: join(directory, id + '.diagnostic.log'), contextRoot: root, ...(binding.debuggerRuntime ? { debuggerInstallation: binding.debuggerRuntime.id, debuggerFingerprint: binding.debuggerRuntime.fingerprint } : {}) } };
61
+ const helperProcess = await registerExistingProcess(appData, { ...processSpec, role: 'debugger-supervisor' }, process.execPath, process.pid, async () => true);
41
62
  await saved();
42
63
  const environment = { ...process.env };
43
64
  delete environment.GHIDRA_MCP_AUTH_TOKEN;
@@ -47,14 +68,22 @@ async function main() {
47
68
  const python = await realpath(environment.INSIGHT_DEBUGGER_PYTHON ?? '');
48
69
  if (!python.startsWith(root + '/debug-python-') || python !== environment.INSIGHT_DEBUGGER_PYTHON)
49
70
  throw Error('Owned debugger Python identity changed');
71
+ let debuggerExecutable = '/usr/bin/lldb';
72
+ if (binding.debuggerRuntime) {
73
+ debuggerExecutable = binding.debuggerRuntime.executable;
74
+ Object.assign(environment, binding.debuggerRuntime.environment);
75
+ Object.assign(receipt, { debuggerInstallation: binding.debuggerRuntime.id, debuggerFingerprint: binding.debuggerRuntime.fingerprint });
76
+ }
50
77
  environment.PYTHONPATH = python + delimiter + (environment.PYTHONPATH ?? '');
51
78
  delete environment.INSIGHT_DEBUGGER_PYTHON;
52
- let closing = false, finished = false;
79
+ let closing = false, finished = false, launchComplete = false;
53
80
  process.once('SIGHUP', close);
54
81
  process.once('SIGTERM', close);
55
82
  // A separate session keeps the GUI terminal's SIGHUP from bypassing our orderly kill.
56
- const child = spawn('/usr/bin/lldb', ['--no-lldbinit', '-o', 'settings set auto-confirm true', ...process.argv.slice(3)], { env: environment, detached: true, stdio: ['pipe', 'pipe', 'pipe'] });
57
- const exited = new Promise((ok, bad) => { child.once('error', bad); child.once('exit', () => { finished = true; ok(); }); });
83
+ const launchArguments = process.argv.slice(3), usesGhidra = launchArguments.includes('script import os, ghidralldb');
84
+ const child = await launchProcess(appData, { ...processSpec, role: 'debugger' }, debuggerExecutable, ['--no-lldbinit', '-o', 'settings set auto-confirm true', '-o', 'settings set target.detach-on-error false', ...debuggerLaunchArguments(launchArguments, launch.stopAtEntry === true, usesGhidra ? python : undefined)], { env: environment, detached: true, stdio: ['pipe', 'pipe', 'pipe'] });
85
+ launchComplete = true;
86
+ const exited = child.toolClosed.then(() => { finished = true; });
58
87
  void exited.catch(() => { });
59
88
  receipt.childPid = child.pid ?? 0;
60
89
  receipt.state = 'running';
@@ -87,6 +116,10 @@ async function main() {
87
116
  function close() {
88
117
  if (closing || finished)
89
118
  return;
119
+ if (!launchComplete) {
120
+ setTimeout(close, 10).unref();
121
+ return;
122
+ }
90
123
  closing = true;
91
124
  process.stdin.pause();
92
125
  child.stdout.unpipe(process.stdout);
@@ -104,13 +137,23 @@ async function main() {
104
137
  child.kill('SIGINT'); });
105
138
  process.stdin.once('end', close);
106
139
  process.stdin.once('error', close);
107
- const monitor = setInterval(() => { try {
108
- process.kill(binding.pid, 0);
109
- }
110
- catch (error) {
111
- if (error.code === 'ESRCH')
112
- close();
113
- } }, 250);
140
+ const observeCaller = callerMonitor(python, command => { if (!closing && !finished)
141
+ child.stdin.write(command); });
142
+ let callerDiagnostic = false;
143
+ const monitor = setInterval(() => {
144
+ try {
145
+ process.kill(binding.pid, 0);
146
+ }
147
+ catch (error) {
148
+ if (error.code === 'ESRCH')
149
+ close();
150
+ }
151
+ if (!closing && !finished)
152
+ void observeCaller().catch(() => { if (!callerDiagnostic) {
153
+ callerDiagnostic = true;
154
+ process.stderr.write('Native caller observation failed; its request is retained.\n');
155
+ } });
156
+ }, 250);
114
157
  try {
115
158
  await saved();
116
159
  await exited;
@@ -122,13 +165,13 @@ async function main() {
122
165
  receipt.inferiorTerminated = result?.id === id && result.inferiorTerminated === true;
123
166
  receipt.state = receipt.inferiorTerminated ? 'closed' : 'failed';
124
167
  Object.assign(receipt, { exitCode: child.exitCode, signalCode: child.signalCode });
125
- if (!receipt.inferiorTerminated)
126
- await writeFile(join(directory, id + '.diagnostic.log'), diagnostics, { mode: 0o600 });
168
+ await writeFile(join(directory, id + '.diagnostic.log'), diagnostics, { mode: 0o600 });
127
169
  await saved();
128
170
  }
129
171
  finally {
130
172
  clearInterval(monitor);
131
173
  process.stdin.pause();
174
+ authority.close();
132
175
  }
133
176
  // Keep a failed child outcome observable; never claim that killing LLDB proves inferior exit.
134
177
  process.exitCode = receipt.inferiorTerminated ? 0 : 1;
@@ -3,7 +3,7 @@ import { resolve } from 'node:path';
3
3
  import { scope, address, number } from './research.js';
4
4
  import { id, text, object, fail } from './model.js';
5
5
  import { selectedOptions } from './arguments.js';
6
- import { debuggerResult, debuggerProgramMetadata as metadata } from './debugger-results.js';
6
+ import { debuggerResult, debuggerExecutionSettled, debuggerProgramMetadata as metadata } from './debugger-results.js';
7
7
  import { setTimeout as delay } from 'node:timers/promises';
8
8
  import { randomUUID } from 'node:crypto';
9
9
  const lists = ['launch_offers', 'modules', 'list_breakpoints', 'stack_trace'];
@@ -89,7 +89,7 @@ export class Debugger {
89
89
  if (request.state === 'failed' && result.reason === 'disconnected')
90
90
  fail('disconnected', 'Selected trace has no live target.', result);
91
91
  if (request.state === 'failed' && result.reason === 'busy')
92
- fail('busy', 'This context already has a live debug target; use another session for another process.', result);
92
+ fail('busy', 'This context still has a connected debugger; close/reopen it or use another session before a new launch.', result);
93
93
  if (request.state === 'failed' && result.reason === 'native_precondition')
94
94
  fail('rejected', 'The native live precondition failed; the target write was not started.', result);
95
95
  fail('unknown', 'Debugger action is retained and is not repeated.', request.result);
@@ -98,7 +98,7 @@ export class Debugger {
98
98
  if (operation === 'launch' && (await backend.debuggerSaved(selected)).connected) {
99
99
  const result = { ...selected, state: 'not_started', reason: 'busy' };
100
100
  this.workspace.recordRequest(request.id, 'failed', result);
101
- fail('busy', 'This context already has a live debug target; use another session for another process.', result);
101
+ fail('busy', 'This context still has a connected debugger; close/reopen it or use another session before a new launch.', result);
102
102
  }
103
103
  const before = debuggerResult('status', {}, await backend.debuggerCall(selected, 'status'));
104
104
  if (operation !== 'launch' && object(before).target_connected !== true) {
@@ -125,11 +125,10 @@ export class Debugger {
125
125
  }
126
126
  const value = debuggerResult(operation, p, raw);
127
127
  if (['resume', 'interrupt', 'step'].includes(operation)) {
128
- const wanted = operation === 'resume' ? 'RUNNING' : 'STOPPED';
129
128
  let observed = false;
130
129
  for (let attempt = 0; attempt < 40; attempt++) {
131
130
  const status = object(debuggerResult('status', {}, await backend.debuggerCall(selected, 'status')));
132
- if (status.execution_state === wanted || operation === 'resume' && status.execution_state === 'STOPPED' && BigInt(String(status.snap ?? 0)) > BigInt(String(object(before).snap ?? 0))) {
131
+ if (debuggerExecutionSettled(operation, object(before), status)) {
133
132
  observed = true;
134
133
  break;
135
134
  }
@@ -151,11 +150,16 @@ export class Debugger {
151
150
  if (!observed)
152
151
  fail('partial', 'Breakpoint inventory did not verify the action.');
153
152
  }
153
+ if (operation === 'launch' && p.stop_at_entry === true) {
154
+ const stopped = object(debuggerResult('status', {}, await backend.debuggerCall(selected, 'status')));
155
+ if (stopped.target_connected !== true || stopped.execution_state !== 'STOPPED')
156
+ fail('partial', 'Entry-stop launch did not verify a stopped live target.');
157
+ }
154
158
  saved = await backend.debuggerSaved(selected);
155
159
  savedSnapshot = await backend.saved(selected);
156
160
  metadataChanged = beforeMetadata !== undefined && beforeMetadata !== await metadata(backend, savedSnapshot);
157
161
  const complexChanges = metadataChanged ? [...context.complexChanges, request.id] : context.complexChanges;
158
- const result = { ...selected, state: 'applied', ...(saved.active ? { trace: saved.active } : {}), pendingChanges: context.scalars.length + complexChanges.length, sharedState: context.scalars.length || complexChanges.length ? 'pending' : 'shared', value };
162
+ const result = { ...selected, state: 'applied', ...(operation === 'launch' && p.stop_at_entry === true ? { stoppedAtEntry: true } : {}), ...(saved.active ? { trace: saved.active } : {}), pendingChanges: context.scalars.length + complexChanges.length, sharedState: context.scalars.length || complexChanges.length ? 'pending' : 'shared', value };
159
163
  this.workspace.completeSavedRequest(selected, request.id, context.generation, { debugger: saved, workingSnapshot: savedSnapshot, complexChanges }, result);
160
164
  return result;
161
165
  }
@@ -195,7 +199,7 @@ export function debuggerCommands(service) {
195
199
  ...(operation === 'schedule' ? [{ flags: '--schedule <time>', description: 'Parse and validate a native time schedule without executing it', required: true }] : []),
196
200
  ...(paged ? [{ flags: '--limit <count>', description: 'Page size 1–100', defaultValue: 50 }, { flags: '--offset <count>', description: 'Page offset', defaultValue: 0 }] : []),
197
201
  ...(operation === 'step' ? [{ flags: '--kind <kind>', description: 'into, over or out', defaultValue: 'into' }] : []),
198
- ...(operation === 'launch' ? [{ flags: '--args <text>', description: 'Target command-line arguments', defaultValue: '' }, { flags: '--cwd <directory>', description: 'Target working directory (default owned run folder)' },
202
+ ...(operation === 'launch' ? [{ flags: '--stop-at-entry', description: 'macOS local LLDB: launch stopped at entry for inspection before running' }, { flags: '--args <text>', description: 'Target command-line arguments', defaultValue: '' }, { flags: '--cwd <directory>', description: 'Target working directory (default owned run folder)' },
199
203
  { flags: '--offer <name>', description: 'Launch offer title or configuration name', defaultValue: process.platform === 'win32' ? 'dbgeng' : process.platform === 'darwin' ? 'lldb' : 'gdb' }, { flags: '--timeout-seconds <count>', description: 'Launch wait 1–300 seconds', defaultValue: 60 }] : []), ...(changing ? [request] : [])];
200
204
  leaves.push(command(operation.replaceAll('_', '-'), 'Use the selected context debugger', ({ options: o }, c) => {
201
205
  const p = {};
@@ -248,6 +252,11 @@ export function debuggerCommands(service) {
248
252
  fail('invalid', 'Step kind must be into, over or out.');
249
253
  }
250
254
  if (operation === 'launch') {
255
+ if (o.stopAtEntry === true) {
256
+ if (process.platform !== 'darwin' || o.offer !== 'lldb')
257
+ fail('unsupported', '--stop-at-entry requires the local macOS lldb offer.');
258
+ p.stop_at_entry = true;
259
+ }
251
260
  if (typeof o.args !== 'string' || o.args.length > 8192 || o.args.includes('\0'))
252
261
  fail('invalid', 'Arguments must be bounded text.');
253
262
  p.args = o.args;
@@ -0,0 +1,12 @@
1
+ import { type CommandContext, type CommandDefinition } from '@eyeauras/cli-factory';
2
+ import { ToolInstaller } from './tool-runtime/installer.js';
3
+ import type { Workspace } from './workspace.js';
4
+ export declare function dieInstaller(c: CommandContext): ToolInstaller;
5
+ /** Upstream may append signature errors after its JSON while exiting zero. Never discard them. */
6
+ export declare function dieJson(stdout: string, stderr: string): {
7
+ data: Record<string, unknown>;
8
+ diagnostics: string[];
9
+ complete: boolean;
10
+ };
11
+ export declare function dieFindings(data: Record<string, unknown>): Record<string, string>[];
12
+ export declare function dieCommands(workspace: (c: CommandContext) => Workspace): CommandDefinition[];
@@ -0,0 +1,127 @@
1
+ import { command, Permission } from '@eyeauras/cli-factory';
2
+ import { dirname, join, resolve } from 'node:path';
3
+ import { release } from 'node:os';
4
+ import { mkdir, writeFile, stat } from 'node:fs/promises';
5
+ import { ToolInstaller } from './tool-runtime/installer.js';
6
+ import { treeFingerprint } from './tool-runtime/store.js';
7
+ import { defineTool, lifecycleCommands } from './tool-runtime/definition.js';
8
+ import { catalogArtifact } from './tool-runtime/catalog.js';
9
+ import { runTool } from './tool-runtime/run.js';
10
+ import { fileSha256 } from './tool-runtime/archives.js';
11
+ import { fail, text, id } from './model.js';
12
+ import { number } from './research.js';
13
+ const frameworks = ['QtConcurrent', 'QtCore', 'QtCore5Compat', 'QtNetwork', 'QtQml'];
14
+ const contents = (executable) => dirname(dirname(executable));
15
+ export function dieInstaller(c) {
16
+ return new ToolInstaller(c, { id: 'die', primary: 'die', components: () => {
17
+ if (process.platform !== 'darwin' || process.arch !== 'arm64' || Number(release().split('.')[0]) < 22)
18
+ fail('unsupported', 'Managed DiE requires macOS 13+ ARM64.');
19
+ return { die: catalogArtifact('5fc9f1d870b4c791ae688a07ccbae0dcdf677eedeeb6ae732bbc83eac61148af') };
20
+ }, launch: roots => ({ executable: join(roots.die, 'MacOS/diec'), arguments: [], environment: {} }), externalInputs: async (executable) => {
21
+ const root = contents(executable), inputs = {};
22
+ // The database is executable signature code: fingerprint it as part of the external tool.
23
+ for (const name of ['db', 'db_custom'])
24
+ inputs['Resources/' + name] = await treeFingerprint(join(root, 'Resources', name));
25
+ inputs['Resources/qt.conf'] = await fileSha256(join(root, 'Resources/qt.conf'));
26
+ for (const path of ['MacOS/qt.conf', 'Info.plist', 'PlugIns'])
27
+ try {
28
+ const at = join(root, path);
29
+ inputs[path] = (await stat(at)).isDirectory() ? await treeFingerprint(at) : await fileSha256(at);
30
+ }
31
+ catch (error) {
32
+ if (error.code !== 'ENOENT')
33
+ throw error;
34
+ }
35
+ if (process.platform === 'darwin')
36
+ for (const name of frameworks)
37
+ inputs[name] = await treeFingerprint(join(root, 'Frameworks', name + '.framework'));
38
+ return inputs;
39
+ }, probe: async (launch, context) => {
40
+ const root = contents(launch.executable);
41
+ await stat(join(root, 'Resources/db/_init'));
42
+ const r = await runTool(context, { tool: 'die', role: 'version', executable: launch.executable, arguments: ['--version'], maxOutputBytes: 65536, timeoutMs: 30000 });
43
+ if (!/\b3\.21\b/.test(r.stdout))
44
+ fail('configuration', 'The selected Detect It Easy console must provide version 3.21 with its adjacent Resources/db database.');
45
+ return { version: '3.21', database: 'adjacent Resources/db', managedMinimumMacOS: '13.0', signaturesAreHeuristic: true };
46
+ } });
47
+ }
48
+ /** Upstream may append signature errors after its JSON while exiting zero. Never discard them. */
49
+ export function dieJson(stdout, stderr) {
50
+ const start = stdout.search(/\S/);
51
+ if (start < 0 || stdout[start] !== '{')
52
+ fail('binding', 'DiE did not return a JSON object; inspect the retained native process diagnostics.');
53
+ let depth = 0, string = false, escaped = false, end = -1;
54
+ for (let i = start; i < stdout.length; i++) {
55
+ const ch = stdout[i];
56
+ if (string) {
57
+ if (escaped)
58
+ escaped = false;
59
+ else if (ch === '\\')
60
+ escaped = true;
61
+ else if (ch === '"')
62
+ string = false;
63
+ }
64
+ else if (ch === '"')
65
+ string = true;
66
+ else if (ch === '{')
67
+ depth++;
68
+ else if (ch === '}' && --depth === 0) {
69
+ end = i + 1;
70
+ break;
71
+ }
72
+ }
73
+ if (end < 0)
74
+ fail('binding', 'DiE returned incomplete JSON; inspect the retained native process diagnostics.');
75
+ let data;
76
+ try {
77
+ data = JSON.parse(stdout.slice(start, end));
78
+ }
79
+ catch {
80
+ fail('binding', 'DiE returned malformed JSON; inspect the retained native process diagnostics.');
81
+ }
82
+ const diagnostics = [stdout.slice(end).trim(), stderr.trim()].filter(Boolean);
83
+ return { data, diagnostics, complete: diagnostics.length === 0 };
84
+ }
85
+ export function dieFindings(data) {
86
+ if (!Array.isArray(data.detects))
87
+ fail('binding', 'DiE omitted its detection array; retained output is not a complete classification.');
88
+ const rows = [];
89
+ for (const group of data.detects) {
90
+ if (!group || typeof group !== 'object' || typeof group.filetype !== 'string' || !Array.isArray(group.values))
91
+ fail('binding', 'DiE returned an unsupported detection schema.');
92
+ for (const value of group.values) {
93
+ if (!value || typeof value !== 'object' || ['name', 'type', 'version', 'info', 'string'].some(k => typeof value[k] !== 'string'))
94
+ fail('binding', 'DiE returned an unsupported signature record.');
95
+ rows.push({ fileType: group.filetype, offset: String(group.offset ?? ''), region: String(group.parentfilepart ?? ''), ...Object.fromEntries(['name', 'type', 'version', 'info', 'string'].map(k => [k, value[k]])) });
96
+ }
97
+ }
98
+ return rows;
99
+ }
100
+ export function dieCommands(workspace) {
101
+ const definition = defineTool({ id: 'die', description: 'Classify binaries and retain compiler, runtime or packer signature evidence', components: [{ id: 'die', version: '3.21', artifacts: [] }], lifecycle: { download: (o, c) => dieInstaller(c).download(Boolean(o.offline)), install: (o, c) => dieInstaller(c).install(o), uninstall: (o, c) => dieInstaller(c).uninstall(Boolean(o.purgeCache)), doctor: (_o, c) => dieInstaller(c).doctor(), status: (_o, c) => dieInstaller(c).status() } });
102
+ return [command('die', definition.description, [...lifecycleCommands(definition), command('classify [input]', 'Read input format/architecture and signature evidence without running the input', async ({ args, options: o }, c) => {
103
+ if (Boolean(args.input) === Boolean(o.target))
104
+ fail('invalid', 'Supply exactly one input path or --target.');
105
+ const limit = number(o.limit, 400, 1), offset = number(o.offset, 1000000, 0), timeoutMs = number(o.timeoutSeconds, 600, 1) * 1000;
106
+ 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);
107
+ return dieInstaller(c).use(async (selected) => {
108
+ const database = join(contents(selected.executable), 'Resources/db'), calls = [];
109
+ for (const mode of ['info', 'scan']) {
110
+ const result = await runTool(c, { tool: 'die', role: mode, installation: selected.id, executable: selected.executable, arguments: ['--json', '--database', database, ...(mode === 'info' ? ['--info'] : [...(o.deep ? ['--deepscan'] : []), ...(o.heuristic ? ['--heuristicscan'] : [])]), input], environment: selected.environment, target: target.id, timeoutMs });
111
+ calls.push({ mode, result, parsed: dieJson(result.stdout, result.stderr) });
112
+ }
113
+ const info = calls[0].parsed.data.data;
114
+ if (!info?.Info || typeof info.Info !== 'object' || Array.isArray(info.Info))
115
+ fail('binding', 'DiE omitted its file information view.');
116
+ const findings = dieFindings(calls[1].parsed.data), diagnostics = calls.flatMap(call => call.parsed.diagnostics.map(message => ({ view: call.mode, message }))), complete = diagnostics.length === 0;
117
+ const base = { state: complete ? 'completed' : 'partial', complete, target: target.id, inputSha256: target.binarySha256, information: info.Info, diagnostics, coverage: 'Heuristic signatures are evidence; Unknown or no match does not prove absence of packing, obfuscation or a runtime.', processes: calls.map(call => ({ view: call.mode, process: call.result.process, diagnostics: call.result.diagnostics, elapsedMs: call.result.elapsedMs })) };
118
+ if (o.output) {
119
+ const output = resolve(c.cwd, text(o.output, 4096)), content = JSON.stringify({ ...base, findings }, null, 2) + '\n';
120
+ await mkdir(dirname(output), { recursive: true, mode: 0o700 });
121
+ await writeFile(output, content, { flag: 'wx', mode: 0o600 });
122
+ return { ...base, output, bytes: Buffer.byteLength(content), totalFindings: findings.length };
123
+ }
124
+ return { ...base, findings: findings.slice(offset, offset + limit), totalFindings: findings.length, offset, limit, truncated: offset + limit < findings.length };
125
+ });
126
+ }, { permission: Permission.Update, options: [{ flags: '--target <id>', description: 'Reuse an immutable research target' }, { flags: '--deep', description: 'Enable deeper signature scanning' }, { flags: '--heuristic', description: 'Enable optional heuristic scanning' }, { flags: '--output <file>', description: 'Save the full bounded classification and all warnings to a new JSON file' }, { flags: '--limit <count>', description: 'Maximum signature findings (1–400)', defaultValue: 100 }, { flags: '--offset <count>', description: 'Skip signature findings', defaultValue: 0 }, { flags: '--timeout-seconds <seconds>', description: 'Deadline per native view (1–600)', defaultValue: 120 }] })])];
127
+ }
@@ -0,0 +1,8 @@
1
+ import type { CommandContext } from '@eyeauras/cli-factory';
2
+ export declare const dnspyNative: string;
3
+ export declare function prepareDnspy(root: string, c: CommandContext): Promise<void>;
4
+ export declare function prepareExternalDnspy(executable: string, stage: string, c: CommandContext): Promise<{
5
+ executable: string;
6
+ arguments: never[];
7
+ environment: {};
8
+ }>;
@@ -0,0 +1,46 @@
1
+ import { join, dirname } from 'node:path';
2
+ import { fileURLToPath } from 'node:url';
3
+ import { mkdir, copyFile, rename, lstat } from 'node:fs/promises';
4
+ import { constants } from 'node:fs';
5
+ import { randomUUID } from 'node:crypto';
6
+ import { atomicWrite, readJson } from './tool-runtime/store.js';
7
+ import { fileSha256, archiveName } from './tool-runtime/archives.js';
8
+ import { runTool } from './tool-runtime/run.js';
9
+ import { fail } from './model.js';
10
+ export const dnspyNative = fileURLToPath(new URL('../../runtime/native/dnspy-extension/', import.meta.url));
11
+ const engine = 'dnSpy.Debugger.DotNet.CorDebug.x.dll', original = '13e0c4ea5396d071cdc7e31f0e5e9036c51da734a00b27d9d3dfeda9fa5b722f';
12
+ export async function prepareDnspy(root, c) {
13
+ const input = join(root, 'bin', engine);
14
+ if (await fileSha256(input) !== original)
15
+ fail('binding', 'The pinned dnSpy Core engine differs before local Unicode preparation.');
16
+ const directory = join(c.appArguments.AppDataDirectory, 'runtime/dnspy/preparation', randomUUID()), extension = join(directory, 'extension');
17
+ await mkdir(extension, { recursive: true, mode: 0o700 });
18
+ await copyFile(join(dnspyNative, 'Insight.DnSpy.x.dll'), join(extension, 'Insight.DnSpy.x.dll'), constants.COPYFILE_EXCL);
19
+ const nonce = randomUUID(), plan = join(directory, 'plan.json'), result = join(directory, 'result.json'), output = join(directory, engine);
20
+ await atomicWrite(plan, { Schema: 1, Nonce: nonce, Mode: 'patch-engine', Input: input, Output: output, BuildKey: join(dnspyNative, 'upstream-public-build.snk'), Result: result });
21
+ await runTool(c, { tool: 'dnspy', role: 'prepare-unicode-loader', executable: join(root, 'dnSpy.exe'), arguments: ['--multiple', '--no-activate', '--settings-file', join(directory, 'settings.xml'), '--extension-directory', extension, '--insight-plan:' + plan], nativeDeadline: true, timeoutMs: 60000, maxOutputBytes: 65536 });
22
+ const receipt = await readJson(result);
23
+ if (receipt?.schema !== 1 || receipt.nonce !== nonce || receipt.data?.state !== 'completed' || receipt.data.mode !== 'patch-engine' || receipt.data.beforeSha256 !== original || !receipt.data.unicodeLoader || !receipt.data.strongNameIdentityPreserved || await fileSha256(output) !== receipt.data.afterSha256)
24
+ fail('binding', 'Owned dnSpy Unicode-loader preparation was not verified.', { diagnostics: directory });
25
+ // The one-shot process has exited and the native Job has closed before replacing any mapped engine.
26
+ await rename(output, input);
27
+ await atomicWrite(join(root, 'insight-unicode-loader.json'), receipt.data);
28
+ }
29
+ export async function prepareExternalDnspy(executable, stage, c) {
30
+ const manifest = await readJson(join(dnspyNative, 'vendor-files.json'));
31
+ if (manifest?.schema !== 1 || manifest.files.length !== 867)
32
+ fail('binding', 'Pinned dnSpy file inventory is missing.');
33
+ const originalRoot = dirname(executable), owned = join(stage, 'execution');
34
+ for (const entry of manifest.files) {
35
+ archiveName(entry.path);
36
+ const source = join(originalRoot, entry.path), destination = join(owned, entry.path), info = await lstat(source);
37
+ if (!info.isFile() || info.size !== entry.size || await fileSha256(source) !== entry.sha256)
38
+ fail('binding', 'External dnSpy component differs from the pinned vendor bundle.', { component: entry.path });
39
+ await mkdir(dirname(destination), { recursive: true, mode: 0o700 });
40
+ await copyFile(source, destination, constants.COPYFILE_EXCL);
41
+ if (await fileSha256(destination) !== entry.sha256)
42
+ fail('binding', 'Copied dnSpy component differs from the pinned vendor bundle.');
43
+ }
44
+ await prepareDnspy(owned, c);
45
+ return { executable: join(owned, 'dnSpy.exe'), arguments: [], environment: {} };
46
+ }
@@ -0,0 +1,22 @@
1
+ import { type CommandContext, type CommandDefinition } from '@eyeauras/cli-factory';
2
+ import { ToolInstaller } from './tool-runtime/installer.js';
3
+ import type { Workspace } from './workspace.js';
4
+ export declare function dnspyInstaller(c: CommandContext): ToolInstaller;
5
+ export declare function dnspyToken(value: unknown): number;
6
+ export declare function dnspyPlan(o: Record<string, unknown>, mode: 'debug' | 'edit-constant'): {
7
+ ExpectedConstant: number;
8
+ ReplacementConstant: number;
9
+ Schema: number;
10
+ Mode: "debug" | "edit-constant";
11
+ Token: number;
12
+ Offset: number;
13
+ } | {
14
+ Runtime: string;
15
+ Parameters: number[];
16
+ Arguments: string[];
17
+ Schema: number;
18
+ Mode: "debug" | "edit-constant";
19
+ Token: number;
20
+ Offset: number;
21
+ };
22
+ export declare function dnspyCommands(workspace: (c: CommandContext) => Workspace): CommandDefinition[];
@@ -0,0 +1,160 @@
1
+ import { command, Permission, CliError } from '@eyeauras/cli-factory';
2
+ import { basename, dirname, join, resolve } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { copyFile, mkdir, writeFile, stat } from 'node:fs/promises';
5
+ import { constants } from 'node:fs';
6
+ import { randomUUID } from 'node:crypto';
7
+ import { ToolInstaller } from './tool-runtime/installer.js';
8
+ import { defineTool, lifecycleCommands } from './tool-runtime/definition.js';
9
+ import { catalogArtifact } from './tool-runtime/catalog.js';
10
+ import { dotnetArtifact } from './tool-runtime/dotnet.js';
11
+ import { runTool } from './tool-runtime/run.js';
12
+ import { fileSha256 } from './tool-runtime/archives.js';
13
+ import { treeFingerprint, atomicWrite, readJson } from './tool-runtime/store.js';
14
+ import { fail, text, id } from './model.js';
15
+ import { number } from './research.js';
16
+ import { dnspyNative as native, prepareDnspy, prepareExternalDnspy } from './dnspy-runtime.js';
17
+ function supported() { if (process.platform !== 'win32' || process.arch !== 'x64')
18
+ fail('unsupported', 'dnSpyEx requires Windows x64 with an interactive desktop; managed targets execute only in an owned debugger context.'); }
19
+ async function bridgeIdentity() { const identity = await readJson(join(native, 'provenance.json')); if (!identity || await fileSha256(join(native, 'Insight.DnSpy.x.dll')) !== identity.sha256)
20
+ fail('binding', 'Packaged dnSpy extension differs from its reviewed build.'); return identity; }
21
+ export function dnspyInstaller(c) {
22
+ return new ToolInstaller(c, { id: 'dnspy', primary: 'dnspy', preparationId: 'unicode-core-loader-v1', prepare: (roots, c) => prepareDnspy(roots.dnspy, c), prepareExternal: prepareExternalDnspy, components: () => { supported(); return { dnspy: catalogArtifact('8ed48f165dc355e869f3a0037ad4f9216147f995a5ae0258b296eeef1f73aab0'), dotnet: dotnetArtifact() }; }, launch: roots => ({ executable: join(roots.dnspy, 'dnSpy.exe'), arguments: [], environment: { DOTNET_ROOT: roots.dotnet, DOTNET_MULTILEVEL_LOOKUP: '0', DOTNET_CLI_TELEMETRY_OPTOUT: '1' } }), externalInputs: async (executable) => { supported(); if (basename(executable).toLowerCase() !== 'dnspy.exe')
23
+ fail('configuration', 'Select the dnSpyEx 6.6.0 root dnSpy.exe and its complete adjacent bin directory.'); return { runtimeFamily: await treeFingerprint(dirname(executable)) }; }, probe: async (launch, context) => {
24
+ supported();
25
+ const root = dirname(launch.executable), identity = await bridgeIdentity();
26
+ for (const [name, expected] of Object.entries(identity.contracts))
27
+ if (await fileSha256(join(root, 'bin', name)) !== expected)
28
+ fail('binding', 'dnSpyEx runtime contracts differ from the pinned 6.6.0 build.', { component: name });
29
+ const system = process.env.SystemRoot ?? process.env.WINDIR;
30
+ if (!system)
31
+ fail('configuration', 'Windows system directory is unavailable.');
32
+ const result = await runTool(context, { tool: 'dnspy', role: 'version', executable: join(system, 'System32/WindowsPowerShell/v1.0/powershell.exe'), arguments: ['-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass', '-File', fileURLToPath(new URL('../../runtime/native/file-version.ps1', import.meta.url)), '-Executable', launch.executable], nativeDeadline: true, timeoutMs: 15000, maxOutputBytes: 65536 });
33
+ if (!/^6\.6\.0(?:\.0)?$/.test(result.stdout.trim()))
34
+ fail('configuration', 'Select dnSpyEx 6.6.0.');
35
+ return { version: '6.6.0', selfContainedDebuggerRuntime: '10.0.9', privateTargetRuntime: launch.environment.DOTNET_ROOT ? '10.0.13' : 'External Core targets require --dotnet-host or a self-contained input', pinnedContractsVerified: true, ownedDebugger: true, interactiveDesktopRequired: true };
36
+ } });
37
+ }
38
+ function nativeFilename(name) { return name.length > 0 && name.length <= 255 && !/[<>:\x22/\\|?*\x00-\x1f]/.test(name) && !/[ .]$/.test(name) && name !== '.' && name !== '..'; }
39
+ export function dnspyToken(value) { const token = text(value, 16); if (!/^0x06[0-9a-fA-F]{6}$/.test(token) || Number(token) === 0x06000000)
40
+ fail('invalid', 'Use a MethodDef metadata token such as 0x06000002, from the selected managed module.'); return Number(token); }
41
+ export function dnspyPlan(o, mode) {
42
+ const Token = dnspyToken(o.method), Offset = number(o.ilOffset ?? 0, 0x1000000), base = { Schema: 1, Mode: mode, Token, Offset };
43
+ if (mode === 'edit-constant') {
44
+ const integer = (value) => { if (value === undefined || !/^[-+]?\d+$/.test(String(value)))
45
+ fail('invalid', 'Explicit signed Int32 expected/replacement constants are required.'); const n = Number(value); if (!Number.isSafeInteger(n) || n < -2147483648 || n > 2147483647)
46
+ fail('invalid', 'Constant is outside Int32.'); return n; };
47
+ return { ...base, ExpectedConstant: integer(o.expectInt32), ReplacementConstant: integer(o.setInt32) };
48
+ }
49
+ const Runtime = text(o.runtime ?? 'framework', 16);
50
+ if (!['framework', 'core'].includes(Runtime))
51
+ fail('invalid', 'Select framework or core runtime.');
52
+ if (Runtime === 'core' && !o.module)
53
+ fail('invalid', 'Core apphost debugging requires its paired --module managed DLL.');
54
+ if (Runtime !== 'core' && (o.module || o.dotnetHost))
55
+ fail('invalid', '--module and --dotnet-host apply to a Core apphost input.');
56
+ const Parameters = o.parameters === undefined ? [] : text(o.parameters, 256).split(',').map(v => { if (!/^\d+$/.test(v.trim()))
57
+ fail('invalid', 'Parameter indices must be decimal integers.'); return number(v.trim(), 65535); });
58
+ if (Parameters.length > 32 || new Set(Parameters).size !== Parameters.length)
59
+ fail('invalid', 'Select up to 32 distinct zero-based parameter indices.');
60
+ const Arguments = (Array.isArray(o.arg) ? o.arg : o.arg === undefined ? [] : [o.arg]).map(v => { if (typeof v !== 'string' || Buffer.byteLength(v) > 4096)
61
+ fail('invalid', 'Program argument must be a bounded literal string.'); return v; });
62
+ if (Arguments.length > 64 || Arguments.some(v => /[\0\r\n]/.test(v)))
63
+ fail('invalid', 'Program arguments exceed their literal bounds.');
64
+ return { ...base, Runtime, Parameters, Arguments };
65
+ }
66
+ export function dnspyCommands(workspace) {
67
+ const installer = (c) => dnspyInstaller(c), definition = defineTool({ id: 'dnspy', description: 'Observe managed breakpoint parameters and edit an explicit IL constant in a new assembly copy', vendorDirect: true, components: [{ id: 'dnspy', version: '6.6.0', artifacts: [], dependencies: ['dotnet'] }, { id: 'dotnet', version: '10.0.13', artifacts: [] }], installOptions: [{ flags: '--vendor-direct', description: 'Explicitly acquire the pinned unmodified upstream bundle' }, { flags: '--archive <path>', description: 'Matching local dnSpyEx archive' }, { flags: '--archive-sha256 <sha256>', description: 'Expected local tool archive SHA256' }, { flags: '--executable <file>', description: 'External root dnSpy.exe; complete adjacent runtime is fingerprinted' }, { flags: '--offline', description: 'Use only local archives and verified cache' }, { flags: '--dotnet-archive <path>', description: 'Matching private .NET 10.0.13 Windows x64 runtime archive for offline setup' }], lifecycle: { download: (o, c) => installer(c).download(Boolean(o.offline), Boolean(o.vendorDirect)), install: (o, c) => installer(c).install(o), uninstall: (o, c) => installer(c).uninstall(Boolean(o.purgeCache)), doctor: (_o, c) => installer(c).doctor(), status: (_o, c) => installer(c).status() } });
68
+ const common = [{ flags: '--target <id>', description: 'Reuse an immutable captured managed input' }, { flags: '--method <token>', description: 'Required MethodDef token (0x060000NN), scoped to the selected module' }, { flags: '--il-offset <bytes>', description: 'Exact decimal IL instruction offset', defaultValue: 0 }], execute = (mode) => command((mode === 'debug' ? 'inspect' : 'edit-constant') + ' [input]', mode === 'debug' ? 'Launch an owned managed debugger and read selected primitive parameters at an IL breakpoint' : 'Replace one expected Int32 IL constant and save a new ordinary assembly', async ({ args, options: o }, c) => {
69
+ supported();
70
+ if (Boolean(args.input) === Boolean(o.target))
71
+ fail('invalid', 'Supply exactly one input path or --target.');
72
+ if (mode === 'edit-constant' && !o.output)
73
+ fail('invalid', 'A new --output assembly path is required.');
74
+ const limit = number(o.limit ?? 32, 64, 1), offset = number(o.offset ?? 0, 64), plan = dnspyPlan(o, mode), w = workspace(c), target = args.input ? await w.importTarget(resolve(c.cwd, text(args.input, 4096))) : w.target(id(o.target)), source = await w.artifacts.verify(target.input), name = basename(args.input ? text(args.input, 4096) : target.name ?? 'input.exe');
75
+ if ((!nativeFilename(name) || !/\.(?:exe|dll)$/i.test(name)))
76
+ fail('invalid', 'Input must have an ordinary .exe or .dll filename.');
77
+ const directory = join(c.appArguments.AppDataDirectory, 'runtime/dnspy/queries', randomUUID()), inputDirectory = join(directory, 'input'), extension = join(directory, 'extension');
78
+ await mkdir(inputDirectory, { recursive: true, mode: 0o700 });
79
+ await mkdir(extension, { mode: 0o700 });
80
+ const input = join(inputDirectory, name);
81
+ await copyFile(source, input, constants.COPYFILE_EXCL);
82
+ const companions = {};
83
+ let companionBytes = 0;
84
+ const paths = [...(o.module ? [o.module] : []), ...(Array.isArray(o.companion) ? o.companion : o.companion === undefined ? [] : [o.companion])];
85
+ if (paths.length > 32)
86
+ fail('limit', 'At most 32 explicitly selected input companions are supported.');
87
+ for (const value of paths) {
88
+ const path = resolve(c.cwd, text(value, 4096)), name = basename(path);
89
+ if (!nativeFilename(name) || Object.keys(companions).some(x => x.toLowerCase() === name.toLowerCase()) || basename(input).toLowerCase() === name.toLowerCase())
90
+ fail('invalid', 'Companion filenames must be ordinary and unique.');
91
+ const artifact = await w.artifacts.capture(path, 'input');
92
+ if ((companionBytes += artifact.size) > 64 * 1024 ** 2)
93
+ fail('limit', 'Captured companions exceed 64 MiB.');
94
+ await copyFile(await w.artifacts.verify(artifact), join(inputDirectory, name), constants.COPYFILE_EXCL);
95
+ companions[name] = artifact.sha256;
96
+ }
97
+ if (mode === 'debug' && !/\.exe$/i.test(input))
98
+ fail('invalid', 'Debugging launches an EXE. For Core, supply the apphost EXE and its --module DLL plus declared sidecars.');
99
+ const nonce = randomUUID(), receipt = join(directory, 'result.json'), patched = join(directory, 'patched' + (name.toLowerCase().endsWith('.dll') ? '.dll' : '.exe')), identity = await bridgeIdentity();
100
+ await copyFile(join(native, 'Insight.DnSpy.x.dll'), join(extension, 'Insight.DnSpy.x.dll'), constants.COPYFILE_EXCL);
101
+ const planFile = join(directory, 'plan.json');
102
+ await atomicWrite(planFile, { ...plan, Nonce: nonce, Input: input, Module: o.module ? join(inputDirectory, basename(text(o.module, 4096))) : input, Result: receipt, ...(mode === 'edit-constant' ? { Output: patched } : {}) });
103
+ return installer(c).use(async (selected) => {
104
+ const environment = { ...selected.environment };
105
+ if (o.dotnetHost) {
106
+ const host = resolve(c.cwd, text(o.dotnetHost, 4096));
107
+ if (basename(host).toLowerCase() !== 'dotnet.exe')
108
+ fail('invalid', 'Select an explicit compatible dotnet.exe for the external Core target runtime.');
109
+ await fileSha256(host);
110
+ environment.DOTNET_ROOT = dirname(host);
111
+ environment.DOTNET_MULTILEVEL_LOOKUP = '0';
112
+ }
113
+ if (mode === 'debug' && o.runtime === 'core' && !environment.DOTNET_ROOT)
114
+ fail('configuration', 'External Core apphost debugging requires --dotnet-host pointing to a compatible runtime. Managed setup provides a private runtime.');
115
+ let result;
116
+ try {
117
+ result = await runTool(c, { tool: 'dnspy', role: mode, installation: selected.id, executable: selected.executable, arguments: ['--multiple', '--no-activate', '--settings-file', join(directory, 'settings.xml'), '--extension-directory', extension, '--insight-plan:' + planFile], environment, nativeDeadline: true, timeoutMs: 60000, target: target.id, metadata: { inputSha256: target.binarySha256, companions, method: plan.Token, ilOffset: plan.Offset, extensionSha256: identity.sha256, mode } });
118
+ }
119
+ catch (error) {
120
+ let observation;
121
+ try {
122
+ if ((await stat(receipt)).size <= 1024 ** 2) {
123
+ const value = await readJson(receipt);
124
+ if (value?.schema === 1 && value.nonce === nonce && value.data?.state === 'failed')
125
+ observation = value.data;
126
+ }
127
+ }
128
+ catch { }
129
+ if (error instanceof CliError && observation)
130
+ throw new CliError(String(observation.error ?? error.message), { code: error.code, cause: error, result: { ...error.result, nativeDiagnostics: error.result?.diagnostics, diagnostics: directory, observation } });
131
+ throw error;
132
+ }
133
+ if ((await stat(receipt)).size > 1024 ** 2)
134
+ fail('limit', 'Typed debugger receipt exceeds 1 MiB.');
135
+ const value = await readJson(receipt);
136
+ if (!value || value.schema !== 1 || value.nonce !== nonce || value.data?.state !== 'completed' || value.data.mode !== mode || value.data.token !== plan.Token)
137
+ throw new CliError('Managed debugger/editor did not complete the selected typed operation.', { code: 'tool.partial', result: { process: result.process, diagnostics: directory, observation: value?.data } });
138
+ if (await fileSha256(input) !== target.binarySha256)
139
+ fail('binding', 'Captured input bytes changed during the operation.');
140
+ const base = { state: 'completed', complete: true, target: target.id, inputSha256: target.binarySha256, companions, process: result.process, elapsedMs: result.elapsedMs, diagnostics: directory, observation: value.data, coverage: mode === 'debug' ? 'One owned execution and selected IL breakpoint; primitive parameters only, no expression evaluation. Adjacent input dependencies must be selected explicitly.' : 'Static edit of one expected Int32 IL constant in a new copy. Output behavior, signatures and strong names need independent verification; original bytes are preserved.' };
141
+ if (mode === 'edit-constant') {
142
+ if (!o.output)
143
+ fail('invalid', 'A new --output assembly path is required.');
144
+ const output = resolve(c.cwd, text(o.output, 4096));
145
+ await mkdir(dirname(output), { recursive: true, mode: 0o700 });
146
+ await copyFile(patched, output, constants.COPYFILE_EXCL);
147
+ return { ...base, output, outputSha256: await fileSha256(output) };
148
+ }
149
+ const frames = Array.isArray(value.data.frames) ? value.data.frames : [];
150
+ if (o.output) {
151
+ const output = resolve(c.cwd, text(o.output, 4096)), content = JSON.stringify({ ...base, observation: { ...value.data, frames } }, null, 2) + '\n';
152
+ await mkdir(dirname(output), { recursive: true, mode: 0o700 });
153
+ await writeFile(output, content, { flag: 'wx', mode: 0o600 });
154
+ return { ...base, output, bytes: Buffer.byteLength(content) };
155
+ }
156
+ return { ...base, observation: { ...value.data, frames: frames.slice(offset, offset + limit) }, totalFrames: frames.length, stackBoundReached: frames.length === 64, limit, offset, truncated: offset + limit < frames.length };
157
+ });
158
+ }, { permission: Permission.Update, options: [...common, ...(mode === 'debug' ? [{ flags: '--runtime <kind>', description: 'framework or core apphost', defaultValue: 'framework' }, { flags: '--module <file>', description: 'Core apphost paired managed DLL containing the breakpoint token' }, { flags: '--companion <files...>', description: 'Explicit DLL/runtimeconfig/deps companions copied beside the owned input' }, { flags: '--dotnet-host <file>', description: 'Compatible external dotnet.exe for Core targets with an external debugger selection' }, { flags: '--parameters <indices>', description: 'Comma-separated zero-based primitive parameter indices (at most 32)' }, { flags: '--arg <literal...>', description: 'Literal input program arguments' }, { flags: '--limit <count>', description: 'Maximum stack frames to return (1–64)', defaultValue: 32 }, { flags: '--offset <count>', description: 'Skip stack frames', defaultValue: 0 }, { flags: '--output <file>', description: 'Save full bounded JSON to a new ordinary file' }] : [{ flags: '--expect-int32 <value>', description: 'Required current Int32 constant' }, { flags: '--set-int32 <value>', description: 'Required replacement Int32 constant' }, { flags: '--output <file>', description: 'Required new assembly path; never overwrites' }])] });
159
+ return [command('dnspy', definition.description, [...lifecycleCommands(definition), execute('debug'), execute('edit-constant')])];
160
+ }
@@ -0,0 +1,13 @@
1
+ import { type CommandContext, type CommandDefinition } from '@eyeauras/cli-factory';
2
+ import { ToolInstaller } from './tool-runtime/installer.js';
3
+ import type { Workspace } from './workspace.js';
4
+ declare const packages: {
5
+ readonly 'dotnet-dump': "ae70c9f37548e1e006467893e21ae41a005fefaf2270e29642b415df053324a7";
6
+ readonly 'dotnet-stack': "cd35f399fe023f1793b528590a4d723a1f2f1d9b25696386d926a697bd24c0ca";
7
+ readonly 'dotnet-trace': "ef17f25724a55f9685bfaf8506a778ea87c2b62783eca2ca73263226128b0d4e";
8
+ };
9
+ export type DiagnosticTool = keyof typeof packages;
10
+ export declare function diagnosticsInstaller(tool: DiagnosticTool, c: CommandContext): ToolInstaller;
11
+ export declare function sosReadCommand(value: unknown): string;
12
+ export declare function diagnosticsCommands(workspace: (c: CommandContext) => Workspace): CommandDefinition[];
13
+ export {};