@adhdev/daemon-core 0.9.82-rc.46 → 0.9.82-rc.461

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 (440) hide show
  1. package/dist/boot/daemon-lifecycle.d.ts +9 -0
  2. package/dist/boot/process-hardening.d.ts +50 -0
  3. package/dist/build-info.d.ts +37 -0
  4. package/dist/chat/source-machine.d.ts +166 -0
  5. package/dist/chat/source-resolver.d.ts +104 -0
  6. package/dist/chat/subscription-updates.d.ts +1 -0
  7. package/dist/cli-adapter-types.d.ts +68 -2
  8. package/dist/cli-adapters/cli-script-runner.d.ts +117 -0
  9. package/dist/cli-adapters/cli-state-engine.d.ts +200 -0
  10. package/dist/cli-adapters/provider-cli-adapter.d.ts +126 -64
  11. package/dist/cli-adapters/provider-cli-parse.d.ts +5 -0
  12. package/dist/cli-adapters/provider-cli-runtime.d.ts +34 -0
  13. package/dist/cli-adapters/provider-cli-shared.d.ts +74 -0
  14. package/dist/cli-adapters/pty-write-chunking.d.ts +34 -0
  15. package/dist/cli-adapters/raw-terminal-io.d.ts +37 -0
  16. package/dist/cli-adapters/resolve-executable.d.ts +69 -0
  17. package/dist/cli-adapters/terminal-backends/ghostty-vt-backend.d.ts +6 -3
  18. package/dist/cli-adapters/terminal-backends/types.d.ts +10 -2
  19. package/dist/cli-adapters/terminal-screen.d.ts +4 -11
  20. package/dist/commands/chat-commands-debug-bundle.d.ts +14 -0
  21. package/dist/commands/chat-commands-read.d.ts +7 -0
  22. package/dist/commands/chat-commands-scope.d.ts +39 -0
  23. package/dist/commands/chat-commands-shared.d.ts +33 -0
  24. package/dist/commands/chat-commands-write.d.ts +14 -0
  25. package/dist/commands/chat-commands.d.ts +10 -23
  26. package/dist/commands/cli-manager.d.ts +25 -1
  27. package/dist/commands/handler.d.ts +125 -0
  28. package/dist/commands/high-family/index.d.ts +3 -0
  29. package/dist/commands/high-family/mesh-coordinator-launch.d.ts +2 -0
  30. package/dist/commands/high-family/mesh-events.d.ts +2 -0
  31. package/dist/commands/high-family/mesh-status.d.ts +2 -0
  32. package/dist/commands/high-family/types.d.ts +64 -0
  33. package/dist/commands/low-family/coordinator-prompt.d.ts +9 -0
  34. package/dist/commands/low-family/daemon-lifecycle.d.ts +2 -0
  35. package/dist/commands/low-family/diagnostics.d.ts +2 -0
  36. package/dist/commands/low-family/index.d.ts +3 -0
  37. package/dist/commands/low-family/mesh-ledger.d.ts +10 -0
  38. package/dist/commands/low-family/mesh-node-logs.d.ts +2 -0
  39. package/dist/commands/low-family/notification.d.ts +2 -0
  40. package/dist/commands/low-family/refine-config.d.ts +2 -0
  41. package/dist/commands/low-family/session-host.d.ts +2 -0
  42. package/dist/commands/low-family/spec-providerdev.d.ts +11 -0
  43. package/dist/commands/low-family/status-meta.d.ts +2 -0
  44. package/dist/commands/low-family/types.d.ts +33 -0
  45. package/dist/commands/med-family/cli-agent.d.ts +2 -0
  46. package/dist/commands/med-family/fast-forward.d.ts +2 -0
  47. package/dist/commands/med-family/ide.d.ts +10 -0
  48. package/dist/commands/med-family/index.d.ts +3 -0
  49. package/dist/commands/med-family/mesh-crud.d.ts +48 -0
  50. package/dist/commands/med-family/mesh-host-pairing.d.ts +2 -0
  51. package/dist/commands/med-family/mesh-queue.d.ts +2 -0
  52. package/dist/commands/med-family/mesh-restart.d.ts +2 -0
  53. package/dist/commands/med-family/types.d.ts +152 -0
  54. package/dist/commands/mesh-coordinator.d.ts +85 -1
  55. package/dist/commands/router-refine.d.ts +137 -0
  56. package/dist/commands/router-worktree-cleanup.d.ts +133 -0
  57. package/dist/commands/router.d.ts +241 -12
  58. package/dist/commands/upgrade-helper.d.ts +41 -1
  59. package/dist/config/chat-history.d.ts +9 -0
  60. package/dist/config/config.d.ts +19 -0
  61. package/dist/config/mesh-config.d.ts +136 -1
  62. package/dist/config/mesh-json-config.d.ts +199 -0
  63. package/dist/config/registry-resolver.d.ts +54 -0
  64. package/dist/config/repo-settings.d.ts +77 -0
  65. package/dist/daemon/dev-server.d.ts +0 -2
  66. package/dist/detection/cli-detector.d.ts +17 -0
  67. package/dist/detection/ide-detector.d.ts +13 -0
  68. package/dist/detection/win32-ide-version.d.ts +37 -0
  69. package/dist/git/change-impact-config.d.ts +159 -0
  70. package/dist/git/git-commands.d.ts +26 -2
  71. package/dist/git/git-diff.d.ts +6 -0
  72. package/dist/git/git-executor.d.ts +11 -0
  73. package/dist/git/git-status.d.ts +57 -0
  74. package/dist/git/git-types.d.ts +2 -50
  75. package/dist/git/git-worktree.d.ts +71 -1
  76. package/dist/git/index.d.ts +3 -1
  77. package/dist/index.d.ts +67 -15
  78. package/dist/index.js +58583 -25541
  79. package/dist/index.js.map +1 -1
  80. package/dist/index.mjs +58207 -25332
  81. package/dist/index.mjs.map +1 -1
  82. package/dist/installer.d.ts +1 -4
  83. package/dist/ipc/local-ipc-server.d.ts +91 -0
  84. package/dist/launch.d.ts +1 -1
  85. package/dist/logging/async-batch-writer.d.ts +10 -0
  86. package/dist/logging/debug-config.d.ts +16 -0
  87. package/dist/logging/log-redactor.d.ts +24 -0
  88. package/dist/logging/log-tail-reader.d.ts +81 -0
  89. package/dist/logging/logger.d.ts +1 -1
  90. package/dist/mesh/contracts.d.ts +230 -0
  91. package/dist/mesh/coordinator-prompt.d.ts +76 -0
  92. package/dist/mesh/coordinator-registry.d.ts +59 -0
  93. package/dist/mesh/mesh-active-work.d.ts +174 -0
  94. package/dist/mesh/mesh-clone-grace.d.ts +8 -0
  95. package/dist/mesh/mesh-coordinator-config.d.ts +21 -0
  96. package/dist/mesh/mesh-delivery-policy.d.ts +131 -0
  97. package/dist/mesh/mesh-event-classify.d.ts +7 -0
  98. package/dist/mesh/mesh-event-forwarding.d.ts +41 -0
  99. package/dist/mesh/mesh-event-trace.d.ts +21 -0
  100. package/dist/mesh/mesh-events-coordinator.d.ts +4 -0
  101. package/dist/mesh/mesh-events-pending.d.ts +155 -0
  102. package/dist/mesh/mesh-events-stale.d.ts +61 -0
  103. package/dist/mesh/mesh-events-utils.d.ts +75 -0
  104. package/dist/mesh/mesh-events.d.ts +6 -49
  105. package/dist/mesh/mesh-fast-forward.d.ts +81 -0
  106. package/dist/mesh/mesh-host-ownership.d.ts +29 -0
  107. package/dist/mesh/mesh-init.d.ts +128 -0
  108. package/dist/mesh/mesh-ledger-reconciliation.d.ts +23 -4
  109. package/dist/mesh/mesh-ledger.d.ts +133 -1
  110. package/dist/mesh/mesh-magi-status.d.ts +63 -0
  111. package/dist/mesh/mesh-missions.d.ts +189 -0
  112. package/dist/mesh/mesh-node-identity.d.ts +310 -0
  113. package/dist/mesh/mesh-queue-assignment.d.ts +158 -0
  114. package/dist/mesh/mesh-reconcile-loop.d.ts +80 -0
  115. package/dist/mesh/mesh-refine-batch.d.ts +68 -0
  116. package/dist/mesh/mesh-refine-gates.d.ts +428 -0
  117. package/dist/mesh/mesh-refine-status.d.ts +62 -0
  118. package/dist/mesh/mesh-review-inbox.d.ts +90 -0
  119. package/dist/mesh/mesh-routing.d.ts +70 -0
  120. package/dist/mesh/mesh-runtime-store.d.ts +493 -0
  121. package/dist/mesh/mesh-scheduling-runtime.d.ts +78 -0
  122. package/dist/mesh/mesh-task-inflight.d.ts +46 -0
  123. package/dist/mesh/mesh-task-stats.d.ts +49 -0
  124. package/dist/mesh/mesh-unresolved-forward-outbox.d.ts +30 -0
  125. package/dist/mesh/mesh-warmup-deadline.d.ts +68 -0
  126. package/dist/mesh/mesh-work-queue.d.ts +318 -5
  127. package/dist/mesh/preview-freshness.d.ts +28 -0
  128. package/dist/mesh/refine-config.d.ts +216 -0
  129. package/dist/mesh/worktree-bootstrap-config.d.ts +219 -0
  130. package/dist/providers/acp-provider-instance.d.ts +5 -0
  131. package/dist/providers/approval-utils.d.ts +45 -0
  132. package/dist/providers/chat-message-normalization.d.ts +58 -1
  133. package/dist/providers/cli-provider-instance.d.ts +290 -3
  134. package/dist/providers/contracts.d.ts +149 -6
  135. package/dist/providers/external-sources.d.ts +71 -0
  136. package/dist/providers/manual-attendance.d.ts +79 -0
  137. package/dist/providers/native-history/antigravity-claim-registry.d.ts +28 -0
  138. package/dist/providers/native-history/antigravity-cli-transcript.d.ts +137 -0
  139. package/dist/providers/native-history/claude-cli-transcript.d.ts +70 -0
  140. package/dist/providers/native-history/codex-cli-transcript.d.ts +73 -0
  141. package/dist/providers/native-history/constants.d.ts +12 -0
  142. package/dist/providers/native-history/dispatcher.d.ts +31 -0
  143. package/dist/providers/native-history/hermes-cli-transcript.d.ts +30 -0
  144. package/dist/providers/native-history/index.d.ts +13 -0
  145. package/dist/providers/provider-instance-manager.d.ts +29 -0
  146. package/dist/providers/provider-instance.d.ts +30 -1
  147. package/dist/providers/provider-loader.d.ts +42 -5
  148. package/dist/providers/provider-trust.d.ts +31 -0
  149. package/dist/providers/read-chat-contract.d.ts +29 -0
  150. package/dist/providers/sdk/v1/builders/acp/detect-status.d.ts +68 -0
  151. package/dist/providers/sdk/v1/builders/cli/detect-status.d.ts +86 -0
  152. package/dist/providers/sdk/v1/builders/cli/parse-approval-squash.d.ts +59 -0
  153. package/dist/providers/sdk/v1/builders/cli/parse-approval.d.ts +65 -0
  154. package/dist/providers/sdk/v1/builders/cli/parse-session.d.ts +91 -0
  155. package/dist/providers/sdk/v1/builders/cli/visible-region.d.ts +42 -0
  156. package/dist/providers/sdk/v1/fixture-tooling/format.d.ts +126 -0
  157. package/dist/providers/sdk/v1/fixture-tooling/index.d.ts +8 -0
  158. package/dist/providers/sdk/v1/fixture-tooling/replay.d.ts +38 -0
  159. package/dist/providers/sdk/v1/index.d.ts +30 -0
  160. package/dist/providers/sdk/v1/sandbox/README-design.d.ts +193 -0
  161. package/dist/providers/sdk/v1/sandbox/require-whitelist.d.ts +74 -0
  162. package/dist/providers/sdk/v1/sandbox/script-runner.d.ts +98 -0
  163. package/dist/providers/sdk/v1/types/cli/index.d.ts +277 -0
  164. package/dist/providers/sdk/v1/types/common/index.d.ts +203 -0
  165. package/dist/providers/sdk/v1/validators/index.d.ts +5 -0
  166. package/dist/providers/sdk/v1/validators/manifest.d.ts +40 -0
  167. package/dist/providers/sdk/v1/validators/taint.d.ts +52 -0
  168. package/dist/providers/spec/adapter.d.ts +98 -0
  169. package/dist/providers/spec/cli-adapter.d.ts +223 -0
  170. package/dist/providers/spec/evaluator.d.ts +45 -0
  171. package/dist/providers/spec/fsm-driver.d.ts +449 -0
  172. package/dist/providers/spec/fsm-evaluator.d.ts +93 -0
  173. package/dist/providers/spec/fsm-loader.d.ts +14 -0
  174. package/dist/providers/spec/fsm-types.d.ts +202 -0
  175. package/dist/providers/spec/native-history-executor.d.ts +41 -0
  176. package/dist/providers/spec/pre-launch-trust.d.ts +16 -0
  177. package/dist/providers/spec/route.d.ts +4 -0
  178. package/dist/providers/spec/types.d.ts +222 -0
  179. package/dist/providers/status-monitor.d.ts +7 -7
  180. package/dist/providers/transcript-v2.d.ts +176 -0
  181. package/dist/providers/types/interactive-prompt.d.ts +84 -0
  182. package/dist/providers/working-dir.d.ts +17 -0
  183. package/dist/repo-mesh-types.d.ts +598 -12
  184. package/dist/runtime-defaults.d.ts +2 -0
  185. package/dist/session-host/managed-host.d.ts +64 -0
  186. package/dist/session-host/runtime-surface.d.ts +10 -16
  187. package/dist/sessions/registry.d.ts +6 -0
  188. package/dist/shared-types-extra.d.ts +2 -4
  189. package/dist/shared-types.d.ts +86 -55
  190. package/dist/status/normalize.d.ts +1 -1
  191. package/dist/status/normalize.js +1 -0
  192. package/dist/status/normalize.js.map +1 -1
  193. package/dist/status/normalize.mjs +1 -0
  194. package/dist/status/normalize.mjs.map +1 -1
  195. package/dist/status/reporter.d.ts +2 -0
  196. package/dist/status/snapshot.d.ts +26 -0
  197. package/dist/system/hash.d.ts +8 -0
  198. package/dist/system/load-better-sqlite3.d.ts +21 -0
  199. package/dist/types.d.ts +5 -0
  200. package/package.json +11 -4
  201. package/src/agent-stream/poller.ts +2 -3
  202. package/src/agent-stream/provider-adapter.ts +1 -1
  203. package/src/boot/daemon-lifecycle.ts +80 -14
  204. package/src/boot/process-hardening.ts +89 -0
  205. package/src/build-info.ts +73 -0
  206. package/src/chat/source-machine.ts +534 -0
  207. package/src/chat/source-resolver.ts +0 -0
  208. package/src/chat/subscription-updates.ts +20 -1
  209. package/src/cli-adapter-types.d.ts +3 -1
  210. package/src/cli-adapter-types.ts +68 -2
  211. package/src/cli-adapters/cli-script-runner.ts +421 -0
  212. package/src/cli-adapters/cli-state-engine.ts +1246 -0
  213. package/src/cli-adapters/provider-cli-adapter.d.ts +1 -1
  214. package/src/cli-adapters/provider-cli-adapter.ts +914 -1144
  215. package/src/cli-adapters/provider-cli-parse.d.ts +2 -0
  216. package/src/cli-adapters/provider-cli-parse.ts +19 -0
  217. package/src/cli-adapters/provider-cli-runtime.ts +56 -7
  218. package/src/cli-adapters/provider-cli-shared.d.ts +4 -0
  219. package/src/cli-adapters/provider-cli-shared.ts +121 -11
  220. package/src/cli-adapters/pty-transport.ts +2 -1
  221. package/src/cli-adapters/pty-write-chunking.ts +106 -0
  222. package/src/cli-adapters/raw-terminal-io.ts +252 -0
  223. package/src/cli-adapters/resolve-executable.ts +204 -0
  224. package/src/cli-adapters/session-host-transport.ts +2 -1
  225. package/src/cli-adapters/terminal-backends/ghostty-vt-backend.ts +63 -29
  226. package/src/cli-adapters/terminal-backends/types.ts +10 -3
  227. package/src/cli-adapters/terminal-screen.ts +16 -81
  228. package/src/commands/chat-commands-debug-bundle.ts +398 -0
  229. package/src/commands/chat-commands-read.ts +2488 -0
  230. package/src/commands/chat-commands-scope.ts +54 -0
  231. package/src/commands/chat-commands-shared.ts +114 -0
  232. package/src/commands/chat-commands-write.ts +891 -0
  233. package/src/commands/chat-commands.ts +19 -1841
  234. package/src/commands/cli-manager.ts +596 -27
  235. package/src/commands/handler.ts +845 -2
  236. package/src/commands/high-family/index.ts +28 -0
  237. package/src/commands/high-family/mesh-coordinator-launch.ts +680 -0
  238. package/src/commands/high-family/mesh-events.ts +89 -0
  239. package/src/commands/high-family/mesh-status.ts +832 -0
  240. package/src/commands/high-family/types.ts +80 -0
  241. package/src/commands/low-family/coordinator-prompt.ts +72 -0
  242. package/src/commands/low-family/daemon-lifecycle.ts +120 -0
  243. package/src/commands/low-family/diagnostics.ts +57 -0
  244. package/src/commands/low-family/index.ts +37 -0
  245. package/src/commands/low-family/mesh-ledger.ts +62 -0
  246. package/src/commands/low-family/mesh-node-logs.ts +87 -0
  247. package/src/commands/low-family/notification.ts +116 -0
  248. package/src/commands/low-family/refine-config.ts +106 -0
  249. package/src/commands/low-family/session-host.ts +274 -0
  250. package/src/commands/low-family/spec-providerdev.ts +217 -0
  251. package/src/commands/low-family/status-meta.ts +112 -0
  252. package/src/commands/low-family/types.ts +39 -0
  253. package/src/commands/med-family/cli-agent.ts +241 -0
  254. package/src/commands/med-family/fast-forward.ts +230 -0
  255. package/src/commands/med-family/ide.ts +163 -0
  256. package/src/commands/med-family/index.ts +37 -0
  257. package/src/commands/med-family/mesh-crud.ts +1287 -0
  258. package/src/commands/med-family/mesh-host-pairing.ts +234 -0
  259. package/src/commands/med-family/mesh-queue.ts +167 -0
  260. package/src/commands/med-family/mesh-restart.ts +92 -0
  261. package/src/commands/med-family/types.ts +153 -0
  262. package/src/commands/mesh-coordinator.ts +334 -124
  263. package/src/commands/router-refine.ts +1711 -0
  264. package/src/commands/router-worktree-cleanup.ts +870 -0
  265. package/src/commands/router.ts +1025 -4070
  266. package/src/commands/stream-commands.ts +8 -0
  267. package/src/commands/upgrade-helper.ts +310 -45
  268. package/src/config/chat-history.ts +493 -24
  269. package/src/config/config.ts +30 -0
  270. package/src/config/mesh-config.ts +632 -23
  271. package/src/config/mesh-json-config.ts +376 -0
  272. package/src/config/recent-activity.ts +8 -2
  273. package/src/config/registry-resolver.ts +100 -0
  274. package/src/config/repo-settings.ts +111 -0
  275. package/src/daemon/dev-auto-implement.ts +3 -2
  276. package/src/daemon/dev-cli-debug.ts +10 -1
  277. package/src/daemon/dev-server.ts +0 -541
  278. package/src/detection/cli-detector.ts +94 -9
  279. package/src/detection/ide-detector.ts +55 -16
  280. package/src/detection/win32-ide-version.ts +106 -0
  281. package/src/git/change-impact-config.ts +354 -0
  282. package/src/git/git-commands.ts +112 -16
  283. package/src/git/git-diff.ts +81 -11
  284. package/src/git/git-executor.ts +12 -0
  285. package/src/git/git-status.ts +767 -48
  286. package/src/git/git-types.ts +14 -62
  287. package/src/git/git-worktree.ts +261 -4
  288. package/src/git/index.ts +17 -0
  289. package/src/index.ts +200 -12
  290. package/src/installer.d.ts +1 -1
  291. package/src/installer.ts +8 -6
  292. package/src/ipc/local-ipc-server.ts +278 -0
  293. package/src/launch.d.ts +1 -1
  294. package/src/launch.ts +37 -28
  295. package/src/logging/async-batch-writer.ts +55 -0
  296. package/src/logging/command-log.ts +7 -5
  297. package/src/logging/debug-config.ts +25 -0
  298. package/src/logging/debug-trace.ts +7 -2
  299. package/src/logging/log-redactor.ts +100 -0
  300. package/src/logging/log-tail-reader.ts +341 -0
  301. package/src/logging/logger.ts +14 -7
  302. package/src/mesh/contracts.ts +469 -0
  303. package/src/mesh/coordinator-prompt.ts +554 -34
  304. package/src/mesh/coordinator-registry.ts +121 -0
  305. package/src/mesh/mesh-active-work.ts +656 -0
  306. package/src/mesh/mesh-clone-grace.ts +68 -0
  307. package/src/mesh/mesh-coordinator-config.ts +97 -0
  308. package/src/mesh/mesh-delivery-policy.ts +315 -0
  309. package/src/mesh/mesh-event-classify.ts +73 -0
  310. package/src/mesh/mesh-event-forwarding.ts +1950 -0
  311. package/src/mesh/mesh-event-trace.ts +67 -0
  312. package/src/mesh/mesh-events-coordinator.ts +32 -0
  313. package/src/mesh/mesh-events-pending.ts +1132 -0
  314. package/src/mesh/mesh-events-stale.ts +440 -0
  315. package/src/mesh/mesh-events-utils.ts +443 -0
  316. package/src/mesh/mesh-events.ts +35 -1035
  317. package/src/mesh/mesh-fast-forward.ts +856 -0
  318. package/src/mesh/mesh-host-ownership.ts +111 -0
  319. package/src/mesh/mesh-init.ts +350 -0
  320. package/src/mesh/mesh-ledger-reconciliation.ts +12 -7
  321. package/src/mesh/mesh-ledger.ts +873 -102
  322. package/src/mesh/mesh-magi-status.ts +223 -0
  323. package/src/mesh/mesh-missions.ts +449 -0
  324. package/src/mesh/mesh-node-identity.ts +2065 -0
  325. package/src/mesh/mesh-queue-assignment.ts +2233 -0
  326. package/src/mesh/mesh-reconcile-loop.ts +2397 -0
  327. package/src/mesh/mesh-refine-batch.ts +205 -0
  328. package/src/mesh/mesh-refine-gates.ts +1686 -0
  329. package/src/mesh/mesh-refine-status.ts +231 -0
  330. package/src/mesh/mesh-review-inbox.ts +308 -0
  331. package/src/mesh/mesh-routing.ts +291 -0
  332. package/src/mesh/mesh-runtime-store.ts +2056 -0
  333. package/src/mesh/mesh-scheduling-runtime.ts +198 -0
  334. package/src/mesh/mesh-task-inflight.ts +70 -0
  335. package/src/mesh/mesh-task-stats.ts +161 -0
  336. package/src/mesh/mesh-unresolved-forward-outbox.ts +185 -0
  337. package/src/mesh/mesh-warmup-deadline.ts +152 -0
  338. package/src/mesh/mesh-work-queue.ts +1281 -141
  339. package/src/mesh/preview-freshness.ts +163 -0
  340. package/src/mesh/refine-config.ts +423 -0
  341. package/src/mesh/worktree-bootstrap-config.ts +599 -0
  342. package/src/providers/acp-provider-instance.ts +43 -10
  343. package/src/providers/approval-utils.d.ts +5 -0
  344. package/src/providers/approval-utils.ts +99 -5
  345. package/src/providers/chat-message-normalization.ts +126 -4
  346. package/src/providers/cli-provider-instance.ts +2456 -107
  347. package/src/providers/contracts.d.ts +55 -0
  348. package/src/providers/contracts.ts +160 -6
  349. package/src/providers/extension-provider-instance.ts +12 -7
  350. package/src/providers/external-sources.ts +218 -0
  351. package/src/providers/ide-provider-instance.ts +35 -12
  352. package/src/providers/manual-attendance.ts +105 -0
  353. package/src/providers/native-history/antigravity-claim-registry.ts +131 -0
  354. package/src/providers/native-history/antigravity-cli-transcript.ts +1193 -0
  355. package/src/providers/native-history/claude-cli-transcript.ts +396 -0
  356. package/src/providers/native-history/codex-cli-transcript.ts +479 -0
  357. package/src/providers/native-history/constants.ts +19 -0
  358. package/src/providers/native-history/dispatcher.ts +503 -0
  359. package/src/providers/native-history/hermes-cli-transcript.ts +260 -0
  360. package/src/providers/native-history/index.ts +30 -0
  361. package/src/providers/provider-instance-manager.ts +71 -0
  362. package/src/providers/provider-instance.ts +24 -1
  363. package/src/providers/provider-loader.ts +700 -55
  364. package/src/providers/provider-schema.ts +87 -14
  365. package/src/providers/provider-trust.ts +114 -0
  366. package/src/providers/read-chat-contract.ts +76 -16
  367. package/src/providers/sdk/README.md +49 -0
  368. package/src/providers/sdk/v1/builders/acp/detect-status.ts +144 -0
  369. package/src/providers/sdk/v1/builders/cli/detect-status.ts +313 -0
  370. package/src/providers/sdk/v1/builders/cli/parse-approval-squash.ts +158 -0
  371. package/src/providers/sdk/v1/builders/cli/parse-approval.ts +261 -0
  372. package/src/providers/sdk/v1/builders/cli/parse-session.ts +276 -0
  373. package/src/providers/sdk/v1/builders/cli/visible-region.ts +143 -0
  374. package/src/providers/sdk/v1/fixture-tooling/format.ts +130 -0
  375. package/src/providers/sdk/v1/fixture-tooling/index.ts +22 -0
  376. package/src/providers/sdk/v1/fixture-tooling/replay.ts +352 -0
  377. package/src/providers/sdk/v1/index.ts +152 -0
  378. package/src/providers/sdk/v1/sandbox/README-design.ts +195 -0
  379. package/src/providers/sdk/v1/sandbox/require-whitelist.ts +472 -0
  380. package/src/providers/sdk/v1/sandbox/script-runner.ts +150 -0
  381. package/src/providers/sdk/v1/schemas/cli/provider.schema.json +509 -0
  382. package/src/providers/sdk/v1/schemas/primitives/acp-session-protocol-v1.json +131 -0
  383. package/src/providers/sdk/v1/schemas/primitives/native-history-codex-rollout-v1.json +66 -0
  384. package/src/providers/sdk/v1/schemas/primitives/tui-approval-squash-v1.json +91 -0
  385. package/src/providers/sdk/v1/schemas/primitives/tui-assistant-block-v1.json +91 -0
  386. package/src/providers/sdk/v1/schemas/primitives/tui-cue-ordering-v1.json +47 -0
  387. package/src/providers/sdk/v1/schemas/primitives/tui-dispatch-order-v1.json +32 -0
  388. package/src/providers/sdk/v1/schemas/primitives/tui-footer-chrome-v1.json +42 -0
  389. package/src/providers/sdk/v1/schemas/primitives/tui-index-finder-v1.json +27 -0
  390. package/src/providers/sdk/v1/schemas/primitives/tui-modal-v1.json +125 -0
  391. package/src/providers/sdk/v1/schemas/primitives/tui-prompt-marker-v1.json +45 -0
  392. package/src/providers/sdk/v1/schemas/primitives/tui-session-id-extraction-v1.json +46 -0
  393. package/src/providers/sdk/v1/schemas/primitives/tui-settled-prompt-v1.json +71 -0
  394. package/src/providers/sdk/v1/schemas/primitives/tui-spinner-v1.json +83 -0
  395. package/src/providers/sdk/v1/schemas/primitives/tui-transcript-pty-v1.json +83 -0
  396. package/src/providers/sdk/v1/schemas/primitives/tui-visible-region-v1.json +57 -0
  397. package/src/providers/sdk/v1/schemas/primitives/tui-welcome-screen-v1.json +35 -0
  398. package/src/providers/sdk/v1/types/cli/index.ts +365 -0
  399. package/src/providers/sdk/v1/types/common/index.ts +229 -0
  400. package/src/providers/sdk/v1/validators/index.ts +19 -0
  401. package/src/providers/sdk/v1/validators/manifest.ts +110 -0
  402. package/src/providers/sdk/v1/validators/taint.ts +309 -0
  403. package/src/providers/spec/adapter.ts +246 -0
  404. package/src/providers/spec/cli-adapter.ts +1064 -0
  405. package/src/providers/spec/evaluator.ts +407 -0
  406. package/src/providers/spec/fsm-driver.ts +1528 -0
  407. package/src/providers/spec/fsm-evaluator.ts +290 -0
  408. package/src/providers/spec/fsm-loader.ts +128 -0
  409. package/src/providers/spec/fsm-types.ts +301 -0
  410. package/src/providers/spec/native-history-executor.ts +1174 -0
  411. package/src/providers/spec/pre-launch-trust.ts +104 -0
  412. package/src/providers/spec/route.ts +51 -0
  413. package/src/providers/spec/types.ts +262 -0
  414. package/src/providers/status-monitor.d.ts +7 -7
  415. package/src/providers/status-monitor.ts +37 -22
  416. package/src/providers/transcript-v2.ts +567 -0
  417. package/src/providers/types/interactive-prompt.ts +536 -0
  418. package/src/providers/version-archive.ts +64 -24
  419. package/src/providers/working-dir.ts +23 -0
  420. package/src/repo-mesh-types.ts +836 -13
  421. package/src/runtime-defaults.ts +39 -0
  422. package/src/session-host/managed-host.ts +218 -0
  423. package/src/session-host/runtime-surface.ts +20 -80
  424. package/src/sessions/registry.ts +6 -0
  425. package/src/shared-types-extra.ts +2 -4
  426. package/src/shared-types.d.ts +8 -0
  427. package/src/shared-types.ts +124 -55
  428. package/src/status/builders.ts +26 -6
  429. package/src/status/normalize.ts +2 -0
  430. package/src/status/reporter.ts +19 -1
  431. package/src/status/snapshot.ts +95 -26
  432. package/src/system/hash.ts +23 -0
  433. package/src/system/host-memory.ts +29 -12
  434. package/src/system/load-better-sqlite3.ts +68 -0
  435. package/src/types.ts +5 -0
  436. package/dist/cli-adapters/terminal-backends/xterm-backend.d.ts +0 -17
  437. package/dist/mesh/mesh-sync.d.ts +0 -53
  438. package/src/cli-adapters/terminal-backends/ghostty-vt-backend.d.ts +0 -16
  439. package/src/cli-adapters/terminal-backends/xterm-backend.ts +0 -97
  440. package/src/mesh/mesh-sync.ts +0 -111
@@ -0,0 +1,195 @@
1
+ /**
2
+ * @file README-design.ts
3
+ * @description Phase 5 Sandbox Design Document
4
+ *
5
+ * This file is a design document written as TypeScript JSDoc/comments.
6
+ * It is NOT executable — it exists to communicate the sandboxing architecture
7
+ * to future implementors, reviewers, and delegated agents.
8
+ *
9
+ * =============================================================================
10
+ * CONTEXT: EXTENDED-LEGACY PROVIDER SCRIPT EXECUTION (PRE-PHASE-5)
11
+ * =============================================================================
12
+ *
13
+ * "Extended-legacy" providers (e.g. hermes-cli, and any provider using the
14
+ * `compatibility` script format) supply JavaScript override scripts that the
15
+ * daemon loads and calls directly via Node.js `require()`:
16
+ *
17
+ * provider-loader.ts → require(scriptsPath) // load
18
+ * cli-script-runner.ts → this.invoke(fn, input) // call at runtime
19
+ *
20
+ * The loaded module exports plain JS functions (detectStatus, parseApproval,
21
+ * parseSession, etc.). These functions run **in the daemon process with full
22
+ * Node.js access** — no memory cap, no CPU limit, full `require`, `fs`, `net`.
23
+ *
24
+ * The `extended-legacy` label refers to providers that still use the JS-function
25
+ * override layer rather than the pure-declarative `tui` manifest block. The
26
+ * claude-cli provider (scripts/v1/detect_status.js) is the canonical example of
27
+ * this pattern: it delegates to `sdk.declarativeDetectStatus` for the raw verdict
28
+ * but adds a stateful generating-hold on top that cannot be expressed declaratively.
29
+ *
30
+ * =============================================================================
31
+ * PHASE 5 GOAL: isolated-vm SANDBOXING
32
+ * =============================================================================
33
+ *
34
+ * Phase 5 wraps each script call in an isolated-vm context so that:
35
+ *
36
+ * 1. CPU time is capped per call (default 50 ms hard limit).
37
+ * 2. Memory is capped per Isolate (default 32 MB heap limit).
38
+ * 3. The script cannot reach back into the daemon process — no `require`,
39
+ * no `import`, no Node.js built-ins (fs, net, child_process, etc.).
40
+ * 4. Execution errors and timeouts are caught and surfaced cleanly instead
41
+ * of propagating exceptions that could crash the daemon parse loop.
42
+ *
43
+ * =============================================================================
44
+ * SANDBOX EXECUTION MODEL
45
+ * =============================================================================
46
+ *
47
+ * Each call to SandboxedScriptRunner.run() creates a **fresh evaluation context**
48
+ * inside the Isolate. Persistent state across calls (e.g. the `state` object in
49
+ * detectStatus) is cloned in/out of the sandbox via structured serialization.
50
+ *
51
+ * Flow per call:
52
+ *
53
+ * 1. Serialize `context` (input + state) into a plain JSON-safe value.
54
+ * 2. Create a new isolated-vm Context from the shared Isolate.
55
+ * 3. Inject allowed globals (see below) into the context.
56
+ * 4. Compile + run the script string with `cpuTimeLimitMs` enforced.
57
+ * 5. Deserialize and return the result.
58
+ * 6. Discard the Context (short-lived).
59
+ *
60
+ * The Isolate itself is reused across calls so that the V8 JIT and snapshot
61
+ * warm-up cost is paid once per runner instance, not per call.
62
+ *
63
+ * Memory limit (32 MB) applies to the Isolate heap. If a script allocates
64
+ * beyond the limit, isolated-vm throws RangeError: Array buffer allocation
65
+ * failed (or similar). The runner catches this and returns an error signal.
66
+ *
67
+ * CPU time limit (50 ms) is a wall-clock limit on the script execution tick
68
+ * measured by isolated-vm's internal timer. Async operations inside the script
69
+ * are not permitted (the context is synchronous-only).
70
+ *
71
+ * =============================================================================
72
+ * ALLOWED API SURFACE (what scripts CAN use)
73
+ * =============================================================================
74
+ *
75
+ * The following globals are explicitly injected into the sandbox context:
76
+ *
77
+ * - `input` — the calling frame's input object (CliStatusInput, etc.)
78
+ * - `sdk` — a controlled facade object; see sdk shape below
79
+ * - `console.log` — redirected to daemon LOG.debug; console.error/warn also
80
+ * allowed but routed to LOG.warn
81
+ * - `JSON` — standard JSON object (parse + stringify)
82
+ * - `Math` — standard Math object
83
+ * - `Date` — Date constructor (read-only; no timers)
84
+ * - `String`, `Number`, `Boolean`, `Array`, `Object`, `RegExp`
85
+ * — standard constructors
86
+ * - `undefined`, `null`, `NaN`, `Infinity`, `parseInt`, `parseFloat`,
87
+ * `isNaN`, `isFinite`, `encodeURIComponent`, `decodeURIComponent`
88
+ *
89
+ * sdk shape injected into the sandbox:
90
+ *
91
+ * sdk.declarativeDetectStatus(input) → string
92
+ * Calls the daemon-built declarative verdict function. The implementation
93
+ * serializes the call, executes the declarative function in daemon-land,
94
+ * and returns the result string into the sandbox.
95
+ *
96
+ * sdk.tailHasPrimitive(input, primitive) → boolean
97
+ * Returns true if the screen tail contains the named TUI primitive token.
98
+ *
99
+ * sdk.state (object | null)
100
+ * The per-session state object returned by createState(). Mutable inside
101
+ * the script; mutations are copied back after the call completes.
102
+ *
103
+ * =============================================================================
104
+ * FORBIDDEN API SURFACE (what scripts CANNOT use)
105
+ * =============================================================================
106
+ *
107
+ * The sandbox provides NO access to:
108
+ *
109
+ * - `require` / `import` / `module` / `exports` / `__dirname` / `__filename`
110
+ * - `process` (no env, no exit, no stdio)
111
+ * - `fs`, `path`, `os`, `net`, `http`, `https`, `child_process`, `worker_threads`
112
+ * - `setTimeout`, `setInterval`, `setImmediate`, `clearTimeout`, `clearInterval`
113
+ * (async scheduling is blocked; scripts must be synchronous)
114
+ * - `Promise`, `async/await` (not injected; async resolution is disallowed)
115
+ * - `WebAssembly` (not injected)
116
+ * - `Buffer`, `TextEncoder`, `TextDecoder` (not injected by default; can be
117
+ * added to allowedGlobals if a specific script family requires them)
118
+ * - Any daemon-internal module, class, or singleton
119
+ *
120
+ * =============================================================================
121
+ * MIGRATION PATH FOR HERMES-CLI (when Phase 5 lands)
122
+ * =============================================================================
123
+ *
124
+ * hermes-cli (adhdev-providers/cli/hermes-cli) uses the `compatibility` script
125
+ * format with `defaultScriptDir: "scripts/1.0"`. Its scripts are loaded via
126
+ * require() in provider-loader.ts → loadScriptsFromDir() and called via
127
+ * CliScriptRunner.invoke().
128
+ *
129
+ * Phase 5 migration steps:
130
+ *
131
+ * 1. The ProviderLoader detects at load time whether a provider's scriptDir
132
+ * uses the extended-legacy JS override layer (i.e. scripts.js exports
133
+ * function(s) rather than a pure-declarative object).
134
+ *
135
+ * 2. For extended-legacy providers, instead of storing the raw Function
136
+ * references in `normalizedProvider.scripts`, the loader stores the
137
+ * **script source strings** alongside a flag `sandboxed: true`.
138
+ *
139
+ * 3. CliScriptRunner is extended with an optional SandboxedScriptRunner
140
+ * member. When present, invoke() routes script calls through the sandbox
141
+ * instead of calling the function directly.
142
+ *
143
+ * 4. hermes-cli's scripts/1.0/scripts.js is updated (or a scripts/2.0/ dir
144
+ * created) with source strings compatible with the allowed API surface.
145
+ * In particular:
146
+ * - `require` calls must be removed.
147
+ * - Any direct Node.js module access must be replaced with sdk equivalents.
148
+ *
149
+ * 5. The daemon's dev server (port 19280) exposes a /sandbox/test endpoint
150
+ * that accepts a script source string + input and returns the sandboxed
151
+ * result — useful for provider authors to iterate without restarting.
152
+ *
153
+ * 6. Fallback: providers that have not been migrated to the sandbox API still
154
+ * run via DirectEvalRunner (see script-runner.ts) — unsafe but compatible,
155
+ * with a visible deprecation warning in the daemon log.
156
+ *
157
+ * =============================================================================
158
+ * SandboxedScriptRunner INTERFACE (to be satisfied by the Phase 5 implementation)
159
+ * =============================================================================
160
+ *
161
+ * The interface defined in script-runner.ts must be satisfied by two
162
+ * implementations:
163
+ *
164
+ * DirectEvalRunner — no-op stub; runs script via eval() in a try/catch.
165
+ * Used when isolated-vm is not installed or when
166
+ * sandboxing is explicitly disabled for development.
167
+ * Logs a warning on first use.
168
+ * Safe to use in tests (no native dependency).
169
+ *
170
+ * IsolatedVmRunner — full implementation using the `isolated-vm` npm package.
171
+ * Created by createScriptRunner() when isolated-vm is
172
+ * importable. Not committed to the OSS package — loaded
173
+ * dynamically at runtime.
174
+ *
175
+ * Factory function createScriptRunner(options?) returns:
176
+ * - IsolatedVmRunner if `require('isolated-vm')` succeeds
177
+ * - DirectEvalRunner otherwise, with a LOG.warn() deprecation notice
178
+ *
179
+ * =============================================================================
180
+ * FILE LAYOUT (Phase 5 deliverables under this directory)
181
+ * =============================================================================
182
+ *
183
+ * sandbox/
184
+ * README-design.ts ← this file (design document)
185
+ * script-runner.ts ← SandboxedScriptRunner interface + DirectEvalRunner stub
186
+ * isolated-vm-runner.ts ← IsolatedVmRunner (Phase 5 full impl, not yet committed)
187
+ *
188
+ * Related files that will be touched in Phase 5:
189
+ * cli-adapters/cli-script-runner.ts ← add optional SandboxedScriptRunner member
190
+ * providers/provider-loader.ts ← detect extended-legacy, store source strings
191
+ * providers/cli-provider-instance.ts ← TODO comment (already added in Phase 4 scaffold)
192
+ */
193
+
194
+ // This file contains no executable code.
195
+ export {};
@@ -0,0 +1,472 @@
1
+ /**
2
+ * Provider script require() whitelist.
3
+ *
4
+ * Provider scripts (detect_status.js, parse_session.js, the override layer
5
+ * the v1 contract exposes, plus their _shared helpers) execute in the
6
+ * daemon process with full Node access — see sandbox/README-design.ts for
7
+ * the long story. Full isolation via isolated-vm has a real perf cost and
8
+ * a real marshalling-complexity cost, so we instead constrain the most
9
+ * dangerous attack surface: what a provider script can `require()`.
10
+ *
11
+ * The hook wraps Node's CJS `Module._load` and, when the calling file is
12
+ * inside a directory that this loader has registered as a provider script
13
+ * root, blocks every module that isn't on the allowlist below. Relative
14
+ * paths are allowed but only when they resolve back inside the same
15
+ * provider root — providers can require their sibling helpers but they
16
+ * can't reach `../../../../etc/passwd` through a clever segment.
17
+ *
18
+ * The hook installs exactly once per process; subsequent `register()` /
19
+ * `unregister()` calls just adjust the set of roots that are gated.
20
+ *
21
+ * Performance: the hook adds one `path.normalize` + one Set lookup to
22
+ * every require call coming from a registered root. At the measured
23
+ * baseline (~6 script invocations / second / session, each making
24
+ * ≤1 require during initial module evaluation, zero during steady-state
25
+ * calls), this is unmeasurable.
26
+ */
27
+
28
+ import * as path from 'node:path';
29
+ import { createRequire } from 'node:module';
30
+ import * as nodeFs from 'node:fs';
31
+ import * as nodeChildProcess from 'node:child_process';
32
+ import { LOG } from '../../../../logging/logger.js';
33
+
34
+ /**
35
+ * Standard library modules a provider script may import unchanged.
36
+ * Each entry is bare ("crypto") and node-prefixed ("node:crypto") so
37
+ * both spellings work; production scripts use a mix of the two.
38
+ *
39
+ * Anything that touches the network, the process tree, or the V8 isolate
40
+ * is intentionally absent. fs and child_process are NOT here; they're
41
+ * exposed via the shims further down with a reduced surface.
42
+ */
43
+ const SAFE_STDLIB = new Set<string>([
44
+ 'path', 'os', 'util', 'url', 'querystring', 'buffer',
45
+ 'events', 'stream', 'string_decoder', 'assert',
46
+ 'crypto', 'timers', 'punycode', 'zlib',
47
+ ]);
48
+
49
+ /**
50
+ * Standard library modules that need a shim — we expose a deliberately
51
+ * narrowed surface and trap everything else.
52
+ */
53
+ const SHIMMED_STDLIB = new Set<string>(['fs', 'child_process', 'process']);
54
+
55
+ const ALL_GATED_STDLIB = new Set<string>([
56
+ ...SAFE_STDLIB,
57
+ ...SHIMMED_STDLIB,
58
+ ]);
59
+
60
+ /** Strip an optional `node:` prefix for bookkeeping. */
61
+ function normalizeModuleName(request: string): string {
62
+ return request.startsWith('node:') ? request.slice(5) : request;
63
+ }
64
+
65
+ // ─── fs shim — read-only surface ────────────────────────────────────────────
66
+
67
+ /**
68
+ * The set of `fs` members provider scripts are allowed to call. Each is
69
+ * a read-only operation on the local filesystem. Anything that writes,
70
+ * deletes, opens for write, or alters file metadata is omitted.
71
+ *
72
+ * We expose the *real* function reference so behavior is identical to
73
+ * `require('fs')` for the operations that do pass — including streaming
74
+ * iterators, error semantics, and {withFileTypes}-style overloads.
75
+ */
76
+ const FS_READ_ONLY_MEMBERS = [
77
+ 'existsSync', 'statSync', 'lstatSync', 'realpathSync',
78
+ 'readFileSync', 'readdirSync', 'readlinkSync',
79
+ 'accessSync', 'constants',
80
+ // Async equivalents — same read-only set.
81
+ 'exists', 'stat', 'lstat', 'realpath',
82
+ 'readFile', 'readdir', 'readlink', 'access',
83
+ // Allow `fs.promises.{readFile,...}` for the modern async style.
84
+ 'promises',
85
+ ] as const;
86
+
87
+ const FS_PROMISES_READ_ONLY_MEMBERS = [
88
+ 'stat', 'lstat', 'realpath', 'readFile', 'readdir', 'readlink', 'access',
89
+ ] as const;
90
+
91
+ function buildFsShim(): typeof nodeFs {
92
+ const shim: any = {};
93
+ for (const key of FS_READ_ONLY_MEMBERS) {
94
+ if (key === 'promises') continue; // handled below
95
+ const real = (nodeFs as any)[key];
96
+ if (real !== undefined) shim[key] = real;
97
+ }
98
+ // Re-build a minimal `promises` namespace so destructuring works.
99
+ const realPromises = (nodeFs as any).promises || {};
100
+ const promisesShim: any = {};
101
+ for (const key of FS_PROMISES_READ_ONLY_MEMBERS) {
102
+ const real = realPromises[key];
103
+ if (real !== undefined) promisesShim[key] = real;
104
+ }
105
+ shim.promises = promisesShim;
106
+ return shim as typeof nodeFs;
107
+ }
108
+
109
+ const FS_SHIM = Object.freeze(buildFsShim());
110
+
111
+ // ─── child_process shim — execFileSync only ─────────────────────────────────
112
+
113
+ interface NarrowedExecFileSyncOptions {
114
+ cwd?: string;
115
+ timeout?: number;
116
+ encoding?: BufferEncoding | 'buffer';
117
+ maxBuffer?: number;
118
+ input?: string | Buffer | NodeJS.ArrayBufferView;
119
+ }
120
+
121
+ /**
122
+ * `child_process.execFileSync(file, args, opts)` wrapper that strips
123
+ * every option a provider script has no business setting — most
124
+ * importantly `shell`, which would otherwise re-introduce arbitrary
125
+ * command injection. `args` must be a string array; `file` is a
126
+ * single binary name or absolute path; `opts` is narrowed to the
127
+ * fields below.
128
+ *
129
+ * `spawn`, `exec`, `execSync`, `fork` are intentionally absent from
130
+ * the shim. Providers that need them should ship a daemon-side
131
+ * capability instead of running raw subprocesses out of their script.
132
+ */
133
+ function shimmedExecFileSync(
134
+ file: unknown,
135
+ args?: unknown,
136
+ options?: unknown,
137
+ ): Buffer | string {
138
+ if (typeof file !== 'string' || file.length === 0) {
139
+ throw new TypeError('execFileSync: `file` must be a non-empty string');
140
+ }
141
+ let safeArgs: string[] = [];
142
+ if (args !== undefined && args !== null) {
143
+ if (!Array.isArray(args) || !args.every((a) => typeof a === 'string')) {
144
+ throw new TypeError('execFileSync: `args` must be a string[] (no shell expansion).');
145
+ }
146
+ safeArgs = args as string[];
147
+ }
148
+ const safeOpts: NarrowedExecFileSyncOptions = {};
149
+ if (options && typeof options === 'object') {
150
+ const o = options as Record<string, unknown>;
151
+ if (typeof o.cwd === 'string') safeOpts.cwd = o.cwd;
152
+ if (typeof o.timeout === 'number') safeOpts.timeout = o.timeout;
153
+ if (typeof o.encoding === 'string') safeOpts.encoding = o.encoding as BufferEncoding;
154
+ if (typeof o.maxBuffer === 'number') safeOpts.maxBuffer = o.maxBuffer;
155
+ if (typeof o.input === 'string' || o.input instanceof Buffer) {
156
+ safeOpts.input = o.input as any;
157
+ }
158
+ // shell / env / uid / gid / detached / windowsHide / killSignal — all dropped.
159
+ }
160
+ return nodeChildProcess.execFileSync(file, safeArgs, safeOpts as any);
161
+ }
162
+
163
+ const CHILD_PROCESS_SHIM = Object.freeze({
164
+ execFileSync: shimmedExecFileSync,
165
+ });
166
+
167
+ // ─── process shim — block lifecycle/abort/native bridges ────────────────────
168
+
169
+ /**
170
+ * The methods on `globalThis.process` that a provider script must NEVER be
171
+ * able to call. `exit`/`kill`/`abort` would terminate the daemon; `binding`
172
+ * and `dlopen` are escape hatches that re-introduce arbitrary native code
173
+ * (the whole reason the require() whitelist exists in the first place).
174
+ */
175
+ const DANGEROUS_PROCESS_METHODS = new Set<string>([
176
+ 'exit', 'kill', 'abort', 'binding', 'dlopen', '_kill', '_exit',
177
+ 'reallyExit', '_fatalException',
178
+ ]);
179
+
180
+ let _processGloballyHardened = false;
181
+ let _originalProcessMethods: Map<string, unknown> | null = null;
182
+
183
+ /**
184
+ * Decide whether the current call stack passes through a registered provider
185
+ * script root. We use `new Error().stack` (cheaper than `Error.captureStackTrace`
186
+ * for hot paths because we never need a frame object). The stack string format
187
+ * is `at <fn> (<filename>:line:col)` per frame; we scan for any registered
188
+ * provider root substring. This is best-effort: a determined attacker who
189
+ * controls a non-provider module loaded BY a provider could escape this, but
190
+ * the require() whitelist already prevents loading such modules.
191
+ */
192
+ function callStackTouchesProviderRoot(): boolean {
193
+ if (_gatedRoots.length === 0) return false;
194
+ const stack = new Error().stack || '';
195
+ for (const root of _gatedRoots) {
196
+ if (stack.includes(root.rootPath)) return true;
197
+ }
198
+ return false;
199
+ }
200
+
201
+ /**
202
+ * Wrap `globalThis.process` methods so calls from provider script stacks
203
+ * throw, while every other caller (daemon-core itself, npm deps, the test
204
+ * harness) goes through untouched.
205
+ *
206
+ * Trade-off: this is a stack-introspection check on every call to the
207
+ * affected methods. The methods in question (exit/kill/abort/binding/dlopen)
208
+ * are not hot paths — they're either never called or called once at
209
+ * shutdown. The cost is negligible.
210
+ *
211
+ * Alternative considered: wrap only the module-scope `process` binding via
212
+ * Module._extensions. Node's ESM/CJS semantics make this unreliable across
213
+ * dynamic-require paths. Stack introspection is uglier but correct.
214
+ *
215
+ * Caveat: a provider script that grabs `globalThis.process.exit` once and
216
+ * passes the reference to a non-provider callback can still escape — the
217
+ * stack at the actual call site no longer goes through provider code. We
218
+ * accept this gap; the threat model assumes scripts are not actively
219
+ * trying to launder calls through arbitrary daemon callbacks, just that
220
+ * a naive `process.exit(0)` should not silently terminate the daemon.
221
+ */
222
+ export function installProviderProcessShim(): void {
223
+ if (_processGloballyHardened) return;
224
+ _processGloballyHardened = true;
225
+ const proc = globalThis.process as unknown as Record<string, unknown>;
226
+ if (!proc) return;
227
+ _originalProcessMethods = new Map();
228
+ for (const name of DANGEROUS_PROCESS_METHODS) {
229
+ const original = proc[name];
230
+ if (typeof original !== 'function') continue;
231
+ _originalProcessMethods.set(name, original);
232
+ const wrapped = function gatedProcessMethod(this: unknown, ...args: unknown[]): unknown {
233
+ if (callStackTouchesProviderRoot()) {
234
+ const err: any = new Error(
235
+ `process.${name}() denied: provider scripts cannot terminate, signal, or extend the daemon process.`,
236
+ );
237
+ err.code = 'PROVIDER_PROCESS_DENIED';
238
+ err.method = name;
239
+ throw err;
240
+ }
241
+ return (original as (...a: unknown[]) => unknown).apply(this, args);
242
+ };
243
+ try {
244
+ // Preserve `.name` for stack traces / debugging tools.
245
+ Object.defineProperty(wrapped, 'name', { value: name, configurable: true });
246
+ proc[name] = wrapped;
247
+ } catch {
248
+ // Some Node builds mark certain process.* members non-writable.
249
+ // Skip silently; the require('process') gate still applies.
250
+ }
251
+ }
252
+ }
253
+
254
+ /** For tests — restore the original process.* methods. */
255
+ export function _uninstallProviderProcessShimForTest(): void {
256
+ if (!_originalProcessMethods) {
257
+ _processGloballyHardened = false;
258
+ return;
259
+ }
260
+ const proc = globalThis.process as unknown as Record<string, unknown>;
261
+ for (const [name, original] of _originalProcessMethods) {
262
+ try { proc[name] = original; } catch { /* noop */ }
263
+ }
264
+ _originalProcessMethods = null;
265
+ _processGloballyHardened = false;
266
+ }
267
+
268
+ /**
269
+ * Build the `process` shim returned to provider scripts that do
270
+ * `require('process')`. Same surface as `globalThis.process` minus the
271
+ * dangerous methods, which are replaced with throwers regardless of caller
272
+ * (because they got here via the whitelist — caller is definitively a
273
+ * provider script).
274
+ */
275
+ function buildProcessShim(): NodeJS.Process {
276
+ const real = globalThis.process;
277
+ const shim: Record<string, unknown> = Object.create(null);
278
+ for (const key of Object.keys(real) as Array<keyof NodeJS.Process>) {
279
+ if (DANGEROUS_PROCESS_METHODS.has(String(key))) continue;
280
+ try { shim[key as string] = (real as any)[key]; } catch { /* noop */ }
281
+ }
282
+ for (const name of DANGEROUS_PROCESS_METHODS) {
283
+ shim[name] = function blockedProcessMethod(): never {
284
+ const err: any = new Error(
285
+ `process.${name}() denied via require('process'): provider scripts cannot terminate, signal, or extend the daemon.`,
286
+ );
287
+ err.code = 'PROVIDER_PROCESS_DENIED';
288
+ err.method = name;
289
+ throw err;
290
+ };
291
+ }
292
+ return Object.freeze(shim) as unknown as NodeJS.Process;
293
+ }
294
+
295
+ const PROCESS_SHIM = buildProcessShim();
296
+
297
+ // ─── Hook installation ─────────────────────────────────────────────────────
298
+
299
+ interface GatedRoot {
300
+ /** Normalized, realpath-resolved absolute path. */
301
+ rootPath: string;
302
+ }
303
+
304
+ const _gatedRoots: GatedRoot[] = [];
305
+ let _installed = false;
306
+
307
+ /**
308
+ * Register a directory whose `.js` files should be subject to the
309
+ * whitelist when they call require(). Idempotent — repeated registration
310
+ * of the same root is a no-op. Pass the same string back to
311
+ * `unregisterProviderScriptRoot` to remove it.
312
+ */
313
+ export function registerProviderScriptRoot(absRoot: string): void {
314
+ const normalized = canonicalize(absRoot);
315
+ if (!normalized) return;
316
+ if (_gatedRoots.some((g) => g.rootPath === normalized)) return;
317
+ _gatedRoots.push({ rootPath: normalized });
318
+ ensureInstalled();
319
+ }
320
+
321
+ /** Inverse of registerProviderScriptRoot. */
322
+ export function unregisterProviderScriptRoot(absRoot: string): void {
323
+ const normalized = canonicalize(absRoot);
324
+ if (!normalized) return;
325
+ const idx = _gatedRoots.findIndex((g) => g.rootPath === normalized);
326
+ if (idx >= 0) _gatedRoots.splice(idx, 1);
327
+ }
328
+
329
+ /** For tests — drop every registration and reset internal state. */
330
+ export function _resetProviderScriptRoots(): void {
331
+ _gatedRoots.length = 0;
332
+ }
333
+
334
+ /** For tests — peek at the gated root list. */
335
+ export function _getRegisteredRoots(): readonly string[] {
336
+ return _gatedRoots.map((g) => g.rootPath);
337
+ }
338
+
339
+ function canonicalize(p: string): string | null {
340
+ try {
341
+ const resolved = path.resolve(p);
342
+ try {
343
+ return nodeFs.realpathSync.native
344
+ ? nodeFs.realpathSync.native(resolved)
345
+ : nodeFs.realpathSync(resolved);
346
+ } catch {
347
+ // Root may not exist yet (e.g. external dir created lazily);
348
+ // we still register the resolved path so future requires from
349
+ // inside are gated once the directory shows up.
350
+ return resolved;
351
+ }
352
+ } catch {
353
+ return null;
354
+ }
355
+ }
356
+
357
+ function isCallerInsideGatedRoot(callerFilename: string): GatedRoot | null {
358
+ if (!callerFilename) return null;
359
+ let normalized: string;
360
+ try { normalized = canonicalize(callerFilename) || callerFilename; } catch { normalized = callerFilename; }
361
+ for (const root of _gatedRoots) {
362
+ if (normalized === root.rootPath) return root;
363
+ if (normalized.startsWith(root.rootPath + path.sep)) return root;
364
+ }
365
+ return null;
366
+ }
367
+
368
+ /**
369
+ * Wrap Module._load exactly once. Subsequent calls to register/unregister
370
+ * just adjust the set of roots — the hook itself stays installed.
371
+ */
372
+ function ensureInstalled(): void {
373
+ if (_installed) return;
374
+ _installed = true;
375
+
376
+ // CJS-only hook. ESM provider scripts are not currently supported
377
+ // (everything in adhdev-providers/ is CJS), so we don't need a
378
+ // matching `module.register()` ESM loader. If/when we accept ESM
379
+ // provider scripts, this hook becomes a no-op for them and we'll
380
+ // need to extend it.
381
+ const Module = require('module') as any;
382
+ const originalLoad = Module._load as (
383
+ request: string,
384
+ parent: NodeJS.Module | null,
385
+ isMain: boolean,
386
+ ) => unknown;
387
+
388
+ Module._load = function gatedLoad(
389
+ this: unknown,
390
+ request: string,
391
+ parent: NodeJS.Module | null,
392
+ isMain: boolean,
393
+ ): unknown {
394
+ const callerFilename = parent?.filename || '';
395
+ const gated = isCallerInsideGatedRoot(callerFilename);
396
+ if (!gated) {
397
+ // Caller is not provider code — bypass the gate entirely so
398
+ // daemon-core, vendored npm modules, etc. work as before.
399
+ return originalLoad.call(this, request, parent, isMain);
400
+ }
401
+ return gatedRequire.call(this, request, parent, isMain, gated, originalLoad);
402
+ };
403
+ }
404
+
405
+ /**
406
+ * The actual gate. Runs only when the caller lives inside a registered
407
+ * provider script root. `this` is forwarded from Module._load so
408
+ * delegating to originalLoad mirrors Node's own semantics.
409
+ */
410
+ function gatedRequire(
411
+ this: unknown,
412
+ request: string,
413
+ parent: NodeJS.Module | null,
414
+ isMain: boolean,
415
+ gated: GatedRoot,
416
+ originalLoad: (this: unknown, request: string, parent: NodeJS.Module | null, isMain: boolean) => unknown,
417
+ ): unknown {
418
+ // 1. Relative imports — must stay inside the same provider root.
419
+ if (request.startsWith('./') || request.startsWith('../') || path.isAbsolute(request)) {
420
+ let resolved: string;
421
+ try {
422
+ // Reuse the caller's require to mirror Node's resolution rules.
423
+ const callerRequire = parent?.filename ? createRequire(parent.filename) : createRequire(path.join(gated.rootPath, '__entry__.js'));
424
+ resolved = callerRequire.resolve(request);
425
+ } catch {
426
+ // Fall through to the regular loader; it will throw the
427
+ // standard MODULE_NOT_FOUND with the same path Node would.
428
+ return originalLoad.call(this, request, parent, isMain);
429
+ }
430
+ const resolvedCanon = canonicalize(resolved) || resolved;
431
+ if (!(resolvedCanon === gated.rootPath || resolvedCanon.startsWith(gated.rootPath + path.sep))) {
432
+ denyRequire(request, parent, `relative path escapes provider root (resolved to ${resolvedCanon})`);
433
+ }
434
+ // Inside the root — let it through. The hook will gate any
435
+ // subsequent require() calls made by the loaded file too.
436
+ return originalLoad.call(this, request, parent, isMain);
437
+ }
438
+
439
+ // 2. Bare specifier — only the stdlib subset is allowed.
440
+ const normalized = normalizeModuleName(request);
441
+ if (!ALL_GATED_STDLIB.has(normalized)) {
442
+ denyRequire(request, parent, 'module not on the provider script whitelist');
443
+ }
444
+ if (normalized === 'fs') return FS_SHIM;
445
+ if (normalized === 'child_process') return CHILD_PROCESS_SHIM;
446
+ if (normalized === 'process') return PROCESS_SHIM;
447
+ // SAFE_STDLIB — pass through.
448
+ return originalLoad.call(this, request, parent, isMain);
449
+ }
450
+
451
+ function denyRequire(request: string, parent: NodeJS.Module | null, reason: string): never {
452
+ const caller = parent?.filename || '<unknown>';
453
+ const message = `Provider script require('${request}') denied: ${reason}. Caller: ${caller}`;
454
+ LOG.warn('ProviderScript', `[require-whitelist] ${message}`);
455
+ const err: any = new Error(message);
456
+ err.code = 'PROVIDER_REQUIRE_DENIED';
457
+ err.deniedModule = request;
458
+ err.callerFilename = caller;
459
+ throw err;
460
+ }
461
+
462
+ /**
463
+ * Public re-exports — registry consumers want to know what's on the
464
+ * allowlist without parsing this file.
465
+ */
466
+ export const PROVIDER_REQUIRE_POLICY = Object.freeze({
467
+ safeStdlib: Array.from(SAFE_STDLIB).sort(),
468
+ shimmedStdlib: Array.from(SHIMMED_STDLIB).sort(),
469
+ fsAllowedMembers: Array.from(FS_READ_ONLY_MEMBERS),
470
+ childProcessAllowedMembers: ['execFileSync'],
471
+ processDeniedMembers: Array.from(DANGEROUS_PROCESS_METHODS).sort(),
472
+ });