@gajae-code/coding-agent 0.10.2 → 0.11.0

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 (465) hide show
  1. package/CHANGELOG.md +50 -2
  2. package/dist/types/append-only-mode.d.ts +1 -1
  3. package/dist/types/cli/args.d.ts +4 -5
  4. package/dist/types/cli/daemon-cli.d.ts +12 -1
  5. package/dist/types/cli/notify-cli.d.ts +21 -1
  6. package/dist/types/cli.d.ts +3 -0
  7. package/dist/types/commands/daemon.d.ts +39 -0
  8. package/dist/types/commands/launch.d.ts +3 -0
  9. package/dist/types/commands/notify.d.ts +28 -1
  10. package/dist/types/commands/sdk.d.ts +33 -0
  11. package/dist/types/config/atomic-yaml-patch.d.ts +85 -0
  12. package/dist/types/config/model-profile-activation.d.ts +35 -15
  13. package/dist/types/config/model-profiles.d.ts +11 -5
  14. package/dist/types/config/model-registry.d.ts +3 -3
  15. package/dist/types/config/model-resolver.d.ts +39 -6
  16. package/dist/types/config/model-selector-value.d.ts +17 -0
  17. package/dist/types/config/models-config-schema.d.ts +10 -6
  18. package/dist/types/config/settings-schema.d.ts +133 -6
  19. package/dist/types/config/settings.d.ts +63 -35
  20. package/dist/types/coordinator-mcp/model-preset.d.ts +7 -6
  21. package/dist/types/coordinator-mcp/server.d.ts +6 -49
  22. package/dist/types/daemon/builtin.d.ts +6 -5
  23. package/dist/types/daemon/control-types.d.ts +1 -1
  24. package/dist/types/discovery/mcp-json.d.ts +12 -1
  25. package/dist/types/extensibility/custom-tools/types.d.ts +1 -1
  26. package/dist/types/extensibility/extensions/compact-handler.d.ts +4 -2
  27. package/dist/types/extensibility/extensions/get-commands-handler.d.ts +2 -2
  28. package/dist/types/extensibility/extensions/loader.d.ts +10 -1
  29. package/dist/types/extensibility/extensions/runner.d.ts +3 -3
  30. package/dist/types/extensibility/extensions/types.d.ts +141 -16
  31. package/dist/types/extensibility/hooks/types.d.ts +1 -1
  32. package/dist/types/gjc-runtime/launch-tmux.d.ts +3 -2
  33. package/dist/types/gjc-runtime/psmux-detect.d.ts +3 -0
  34. package/dist/types/gjc-runtime/session-state-sidecar.d.ts +3 -0
  35. package/dist/types/gjc-runtime/team-runtime.d.ts +3 -4
  36. package/dist/types/gjc-runtime/tmux-owner-isolation-cli.d.ts +13 -0
  37. package/dist/types/gjc-runtime/tmux-sessions.d.ts +4 -1
  38. package/dist/types/gjc-runtime/windows-powershell-command.d.ts +9 -0
  39. package/dist/types/harness-control-plane/operate.d.ts +5 -5
  40. package/dist/types/harness-control-plane/owner.d.ts +18 -4
  41. package/dist/types/harness-control-plane/receipts.d.ts +0 -1
  42. package/dist/types/harness-control-plane/sdk-transport.d.ts +43 -0
  43. package/dist/types/harness-control-plane/session-transport.d.ts +48 -0
  44. package/dist/types/harness-control-plane/types.d.ts +3 -4
  45. package/dist/types/lsp/index.d.ts +1 -1
  46. package/dist/types/main.d.ts +32 -38
  47. package/dist/types/modes/acp/acp-agent.d.ts +224 -53
  48. package/dist/types/modes/acp/acp-client-bridge.d.ts +1 -0
  49. package/dist/types/modes/acp/acp-mode.d.ts +6 -15
  50. package/dist/types/modes/acp/permission-mode.d.ts +4 -0
  51. package/dist/types/modes/acp/startup-options.d.ts +6 -0
  52. package/dist/types/modes/components/agent-dashboard.d.ts +3 -0
  53. package/dist/types/modes/components/model-selector.d.ts +1 -0
  54. package/dist/types/modes/components/notifications-settings-editor.d.ts +135 -0
  55. package/dist/types/modes/components/settings-selector.d.ts +6 -4
  56. package/dist/types/modes/components/welcome.d.ts +1 -1
  57. package/dist/types/modes/controllers/selector-controller.d.ts +35 -1
  58. package/dist/types/modes/index.d.ts +0 -4
  59. package/dist/types/modes/interactive-mode.d.ts +3 -0
  60. package/dist/types/modes/runtime-init.d.ts +2 -2
  61. package/dist/types/modes/shared/agent-wire/approval-gate.d.ts +6 -9
  62. package/dist/types/modes/shared/agent-wire/deep-interview-gate.d.ts +4 -6
  63. package/dist/types/modes/shared/agent-wire/event-contract.d.ts +6 -6
  64. package/dist/types/modes/shared/agent-wire/event-envelope.d.ts +4 -9
  65. package/dist/types/modes/shared/agent-wire/event-observation.d.ts +1 -1
  66. package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +169 -30
  67. package/dist/types/modes/shared/agent-wire/workflow-gate-schema.d.ts +7 -7
  68. package/dist/types/modes/shared/agent-wire/workflow-gate-types.d.ts +105 -0
  69. package/dist/types/modes/types.d.ts +5 -0
  70. package/dist/types/runtime-mcp/client.d.ts +2 -0
  71. package/dist/types/runtime-mcp/config.d.ts +5 -1
  72. package/dist/types/runtime-mcp/manager.d.ts +8 -1
  73. package/dist/types/runtime-mcp/types.d.ts +4 -0
  74. package/dist/types/sdk/acp/adapter.d.ts +67 -0
  75. package/dist/types/sdk/acp/index.d.ts +2 -0
  76. package/dist/types/sdk/broker/broker.d.ts +53 -0
  77. package/dist/types/sdk/broker/discovery.d.ts +30 -0
  78. package/dist/types/sdk/broker/ensure.d.ts +33 -0
  79. package/dist/types/sdk/broker/identity.d.ts +3 -0
  80. package/dist/types/sdk/broker/index.d.ts +8 -0
  81. package/dist/types/sdk/broker/lifecycle-ledger.d.ts +95 -0
  82. package/dist/types/sdk/broker/lifecycle.d.ts +85 -0
  83. package/dist/types/sdk/broker/process-incarnation.d.ts +14 -0
  84. package/dist/types/sdk/broker/runtime.d.ts +33 -0
  85. package/dist/types/sdk/broker/session-index.d.ts +57 -0
  86. package/dist/types/sdk/broker/state-version.d.ts +8 -0
  87. package/dist/types/sdk/broker/transport.d.ts +9 -0
  88. package/dist/types/sdk/bus/chat-command-policy.d.ts +49 -0
  89. package/dist/types/sdk/bus/chat-daemon-cli.d.ts +21 -0
  90. package/dist/types/sdk/bus/chat-daemon-control.d.ts +111 -0
  91. package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +77 -0
  92. package/dist/types/sdk/bus/chat-effect-journal.d.ts +84 -0
  93. package/dist/types/{notifications → sdk/bus}/config-commands.d.ts +7 -2
  94. package/dist/types/sdk/bus/config.d.ts +274 -0
  95. package/dist/types/sdk/bus/conversation-store.d.ts +72 -0
  96. package/dist/types/sdk/bus/discord-conversation.d.ts +58 -0
  97. package/dist/types/sdk/bus/discord-daemon.d.ts +45 -0
  98. package/dist/types/sdk/bus/discord-live-provider.d.ts +70 -0
  99. package/dist/types/sdk/bus/discord-provider.d.ts +85 -0
  100. package/dist/types/{notifications → sdk/bus}/html-format.d.ts +2 -2
  101. package/dist/types/{notifications → sdk/bus}/index.d.ts +113 -13
  102. package/dist/types/{notifications → sdk/bus}/lifecycle-control-runtime.d.ts +4 -2
  103. package/dist/types/{notifications → sdk/bus}/lifecycle-orchestrator.d.ts +18 -21
  104. package/dist/types/{notifications → sdk/bus}/managed-daemon.d.ts +1 -1
  105. package/dist/types/sdk/bus/native-runtime-compatibility.d.ts +13 -0
  106. package/dist/types/sdk/bus/notification-orchestration.d.ts +170 -0
  107. package/dist/types/{notifications → sdk/bus}/notification-service.d.ts +7 -1
  108. package/dist/types/sdk/bus/session-control.d.ts +83 -0
  109. package/dist/types/sdk/bus/slack-conversation.d.ts +56 -0
  110. package/dist/types/sdk/bus/slack-daemon.d.ts +60 -0
  111. package/dist/types/sdk/bus/slack-live-provider.d.ts +59 -0
  112. package/dist/types/sdk/bus/slack-provider.d.ts +55 -0
  113. package/dist/types/{notifications → sdk/bus}/telegram-cli.d.ts +4 -4
  114. package/dist/types/{notifications → sdk/bus}/telegram-daemon-cli.d.ts +14 -5
  115. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +12 -0
  116. package/dist/types/{notifications → sdk/bus}/telegram-daemon-control.d.ts +2 -2
  117. package/dist/types/{notifications → sdk/bus}/telegram-daemon.d.ts +55 -17
  118. package/dist/types/{notifications → sdk/bus}/telegram-reference.d.ts +2 -2
  119. package/dist/types/sdk/bus/telegram-setup.d.ts +128 -0
  120. package/dist/types/{notifications → sdk/bus}/topic-registry.d.ts +11 -0
  121. package/dist/types/sdk/cli/index.d.ts +1 -0
  122. package/dist/types/sdk/cli/session-cli.d.ts +19 -0
  123. package/dist/types/sdk/client/client.d.ts +1 -0
  124. package/dist/types/sdk/client/discovery.d.ts +27 -0
  125. package/dist/types/sdk/client/index.d.ts +2 -0
  126. package/dist/types/sdk/host/control/dispatch.d.ts +34 -0
  127. package/dist/types/sdk/host/control/index.d.ts +2 -0
  128. package/dist/types/sdk/host/control/operations.d.ts +65 -0
  129. package/dist/types/sdk/host/events.d.ts +35 -0
  130. package/dist/types/sdk/host/host.d.ts +35 -0
  131. package/dist/types/sdk/host/index.d.ts +4 -0
  132. package/dist/types/sdk/host/query/cursor.d.ts +62 -0
  133. package/dist/types/sdk/host/query/handlers.d.ts +70 -0
  134. package/dist/types/sdk/host/query/index.d.ts +3 -0
  135. package/dist/types/sdk/host/query/revision-store.d.ts +60 -0
  136. package/dist/types/sdk/host/reverse-leases.d.ts +45 -0
  137. package/dist/types/sdk/host/types.d.ts +32 -0
  138. package/dist/types/sdk/index.d.ts +6 -0
  139. package/dist/types/sdk/lifecycle-session.d.ts +14 -0
  140. package/dist/types/sdk/mcp/index.d.ts +1 -0
  141. package/dist/types/sdk/mcp/server.d.ts +37 -0
  142. package/dist/types/sdk/models.d.ts +44 -0
  143. package/dist/types/sdk/protocol/adapter-validation.d.ts +14 -0
  144. package/dist/types/sdk/protocol/operation-registry.d.ts +24 -0
  145. package/dist/types/{sdk.d.ts → sdk/session.d.ts} +44 -38
  146. package/dist/types/sdk/startup-capability.d.ts +50 -0
  147. package/dist/types/session/agent-session.d.ts +114 -21
  148. package/dist/types/session/default-model-selection.d.ts +25 -0
  149. package/dist/types/session/fallback-chain-controller.d.ts +52 -0
  150. package/dist/types/session/session-manager.d.ts +58 -1
  151. package/dist/types/setup/credential-auto-import.d.ts +36 -6
  152. package/dist/types/tools/ask-answer-registry.d.ts +1 -1
  153. package/dist/types/tools/browser/benchmark/detector-report.d.ts +63 -0
  154. package/dist/types/tools/browser/benchmark/run-suite.d.ts +18 -0
  155. package/dist/types/tools/browser/launch.d.ts +22 -0
  156. package/dist/types/tools/browser/profile-discovery.d.ts +31 -0
  157. package/dist/types/tools/browser/profile-posture.d.ts +37 -0
  158. package/dist/types/tools/browser/profile-reuse.d.ts +39 -0
  159. package/dist/types/tools/browser/profile-warmup.d.ts +39 -0
  160. package/dist/types/tools/browser/registry.d.ts +19 -0
  161. package/dist/types/tools/browser/tab-protocol.d.ts +4 -0
  162. package/dist/types/tools/index.d.ts +8 -8
  163. package/package.json +34 -13
  164. package/scripts/build-sdk-package-smoke.ts +94 -0
  165. package/scripts/capture-notifications-settings-showcase.ts +435 -0
  166. package/scripts/compile-args.ts +4 -2
  167. package/scripts/g005-daemon-smoke.ts +4 -5
  168. package/scripts/g011-daemon-path-smoke.ts +5 -5
  169. package/scripts/generate-sdk-adapter-parity-manifest.ts +163 -0
  170. package/scripts/generate-sdk-operation-inventory.ts +867 -0
  171. package/scripts/generate-telegram-baseline-manifest.ts +128 -0
  172. package/scripts/manifest-schema.ts +124 -0
  173. package/scripts/run-test-manifest.ts +153 -0
  174. package/scripts/run-threat-model-check.ts +157 -0
  175. package/scripts/verify-gjc-sdk-canonicalization.ts +3467 -0
  176. package/scripts/verify-gjc-sdk-rename.ts +90 -0
  177. package/src/append-only-mode.ts +1 -1
  178. package/src/cli/args.ts +43 -12
  179. package/src/cli/auth-gateway-cli.ts +2 -2
  180. package/src/cli/config-cli.ts +2 -1
  181. package/src/cli/daemon-cli.ts +63 -14
  182. package/src/cli/list-models.ts +1 -1
  183. package/src/cli/notify-cli.ts +288 -286
  184. package/src/cli.ts +21 -2
  185. package/src/commands/daemon.ts +50 -6
  186. package/src/commands/harness.ts +93 -36
  187. package/src/commands/launch.ts +5 -2
  188. package/src/commands/mcp-serve.ts +19 -12
  189. package/src/commands/notify.ts +36 -3
  190. package/src/commands/sdk.ts +426 -0
  191. package/src/commit/agentic/agent.ts +1 -0
  192. package/src/config/atomic-yaml-patch.ts +423 -0
  193. package/src/config/model-profile-activation.ts +240 -89
  194. package/src/config/model-profiles.ts +18 -15
  195. package/src/config/model-registry.ts +51 -26
  196. package/src/config/model-resolver.ts +138 -51
  197. package/src/config/model-selector-value.ts +50 -0
  198. package/src/config/models-config-schema.ts +14 -21
  199. package/src/config/settings-schema.ts +128 -10
  200. package/src/config/settings.ts +1120 -158
  201. package/src/coordinator-mcp/model-preset.ts +74 -20
  202. package/src/coordinator-mcp/server.ts +1597 -3052
  203. package/src/daemon/builtin.ts +8 -5
  204. package/src/daemon/control-types.ts +1 -1
  205. package/src/defaults/gjc/skills/team/SKILL.md +4 -4
  206. package/src/discovery/mcp-json.ts +327 -20
  207. package/src/extensibility/custom-tools/types.ts +1 -1
  208. package/src/extensibility/extensions/compact-handler.ts +3 -3
  209. package/src/extensibility/extensions/get-commands-handler.ts +2 -2
  210. package/src/extensibility/extensions/loader.ts +69 -5
  211. package/src/extensibility/extensions/runner.ts +112 -4
  212. package/src/extensibility/extensions/types.ts +176 -17
  213. package/src/extensibility/hooks/types.ts +1 -1
  214. package/src/gjc-runtime/launch-tmux.ts +170 -86
  215. package/src/gjc-runtime/psmux-detect.ts +82 -4
  216. package/src/gjc-runtime/session-state-sidecar.ts +41 -31
  217. package/src/gjc-runtime/team-runtime.ts +54 -35
  218. package/src/gjc-runtime/tmux-owner-isolation-cli.ts +53 -17
  219. package/src/gjc-runtime/tmux-owner-isolation.ts +1 -1
  220. package/src/gjc-runtime/tmux-sessions.ts +19 -13
  221. package/src/gjc-runtime/ultragoal-guard.ts +53 -6
  222. package/src/gjc-runtime/ultragoal-runtime.ts +155 -3
  223. package/src/gjc-runtime/windows-powershell-command.ts +58 -0
  224. package/src/harness-control-plane/operate.ts +9 -9
  225. package/src/harness-control-plane/owner.ts +283 -39
  226. package/src/harness-control-plane/receipts.ts +0 -1
  227. package/src/harness-control-plane/sdk-transport.ts +395 -0
  228. package/src/harness-control-plane/session-transport.ts +94 -0
  229. package/src/harness-control-plane/types.ts +1 -1
  230. package/src/internal-urls/docs-index.generated.ts +34 -35
  231. package/src/lsp/client.ts +42 -6
  232. package/src/lsp/index.ts +2 -2
  233. package/src/main.ts +299 -204
  234. package/src/modes/DESIGN.md +258 -0
  235. package/src/modes/acp/acp-agent.ts +1228 -2612
  236. package/src/modes/acp/acp-client-bridge.ts +2 -20
  237. package/src/modes/acp/acp-event-mapper.ts +18 -2
  238. package/src/modes/acp/acp-mode.ts +8 -36
  239. package/src/modes/acp/permission-mode.ts +25 -0
  240. package/src/modes/acp/startup-options.ts +6 -0
  241. package/src/modes/components/agent-dashboard.ts +37 -17
  242. package/src/modes/components/model-selector.ts +93 -35
  243. package/src/modes/components/notifications-settings-editor.ts +1379 -0
  244. package/src/modes/components/settings-selector.ts +60 -11
  245. package/src/modes/components/welcome.ts +4 -4
  246. package/src/modes/controllers/command-controller.ts +1 -2
  247. package/src/modes/controllers/event-controller.ts +11 -16
  248. package/src/modes/controllers/extension-ui-controller.ts +348 -4
  249. package/src/modes/controllers/selector-controller.ts +674 -36
  250. package/src/modes/index.ts +0 -22
  251. package/src/modes/interactive-mode.ts +59 -20
  252. package/src/modes/runtime-init.ts +298 -6
  253. package/src/modes/shared/agent-wire/approval-gate.ts +9 -11
  254. package/src/modes/shared/agent-wire/deep-interview-gate.ts +10 -11
  255. package/src/modes/shared/agent-wire/event-contract.ts +7 -8
  256. package/src/modes/shared/agent-wire/event-envelope.ts +9 -17
  257. package/src/modes/shared/agent-wire/event-observation.ts +16 -7
  258. package/src/modes/shared/agent-wire/workflow-gate-broker.ts +1254 -87
  259. package/src/modes/shared/agent-wire/workflow-gate-schema.ts +15 -15
  260. package/src/modes/shared/agent-wire/workflow-gate-types.ts +113 -0
  261. package/src/modes/types.ts +5 -0
  262. package/src/runtime-mcp/client.ts +94 -19
  263. package/src/runtime-mcp/config.ts +27 -15
  264. package/src/runtime-mcp/manager.ts +343 -105
  265. package/src/runtime-mcp/oauth-flow.ts +42 -12
  266. package/src/runtime-mcp/transports/http.ts +49 -19
  267. package/src/runtime-mcp/transports/stdio.ts +47 -28
  268. package/src/runtime-mcp/types.ts +10 -0
  269. package/src/sdk/acp/adapter.ts +418 -0
  270. package/src/sdk/acp/index.ts +2 -0
  271. package/src/sdk/broker/broker.ts +642 -0
  272. package/src/sdk/broker/discovery.ts +94 -0
  273. package/src/sdk/broker/ensure.ts +249 -0
  274. package/src/sdk/broker/identity.ts +42 -0
  275. package/src/sdk/broker/index.ts +8 -0
  276. package/src/sdk/broker/internal-source-marker-2178.txt +1 -0
  277. package/src/sdk/broker/internal-source.bunfig.toml +1 -0
  278. package/src/sdk/broker/lifecycle-ledger.ts +286 -0
  279. package/src/sdk/broker/lifecycle.ts +2157 -0
  280. package/src/sdk/broker/process-incarnation.ts +159 -0
  281. package/src/sdk/broker/runtime.ts +164 -0
  282. package/src/sdk/broker/session-index.ts +318 -0
  283. package/src/sdk/broker/state-version.ts +23 -0
  284. package/src/sdk/broker/transport.ts +125 -0
  285. package/src/sdk/bus/chat-command-policy.ts +107 -0
  286. package/src/sdk/bus/chat-daemon-cli.ts +214 -0
  287. package/src/sdk/bus/chat-daemon-control.ts +713 -0
  288. package/src/sdk/bus/chat-daemon-runtime.ts +526 -0
  289. package/src/sdk/bus/chat-effect-journal.ts +353 -0
  290. package/src/{notifications → sdk/bus}/config-commands.ts +39 -10
  291. package/src/sdk/bus/config.ts +433 -0
  292. package/src/sdk/bus/conversation-store.ts +391 -0
  293. package/src/sdk/bus/discord-conversation.ts +85 -0
  294. package/src/sdk/bus/discord-daemon.ts +2275 -0
  295. package/src/sdk/bus/discord-live-provider.ts +521 -0
  296. package/src/sdk/bus/discord-provider.ts +56 -0
  297. package/src/{notifications → sdk/bus}/html-format.ts +2 -2
  298. package/src/sdk/bus/index.ts +3943 -0
  299. package/src/{notifications → sdk/bus}/lifecycle-commands.ts +2 -0
  300. package/src/{notifications → sdk/bus}/lifecycle-control-runtime.ts +225 -196
  301. package/src/{notifications → sdk/bus}/lifecycle-orchestrator.ts +161 -74
  302. package/src/{notifications → sdk/bus}/managed-daemon.ts +2 -2
  303. package/src/sdk/bus/native-runtime-compatibility.ts +42 -0
  304. package/src/sdk/bus/natives-augment.d.ts +38 -0
  305. package/src/sdk/bus/notification-orchestration.ts +535 -0
  306. package/src/{notifications → sdk/bus}/notification-service.ts +106 -12
  307. package/src/sdk/bus/session-control.ts +333 -0
  308. package/src/sdk/bus/slack-conversation.ts +74 -0
  309. package/src/sdk/bus/slack-daemon.ts +2144 -0
  310. package/src/sdk/bus/slack-live-provider.ts +380 -0
  311. package/src/sdk/bus/slack-provider.ts +76 -0
  312. package/src/{notifications → sdk/bus}/telegram-cli.ts +8 -8
  313. package/src/sdk/bus/telegram-daemon-cli.ts +330 -0
  314. package/src/sdk/bus/telegram-daemon-contract.ts +14 -0
  315. package/src/{notifications → sdk/bus}/telegram-daemon-control.ts +4 -4
  316. package/src/{notifications → sdk/bus}/telegram-daemon.ts +502 -54
  317. package/src/{notifications → sdk/bus}/telegram-reference.ts +2 -2
  318. package/src/sdk/bus/telegram-setup.ts +663 -0
  319. package/src/{notifications → sdk/bus}/topic-registry.ts +32 -0
  320. package/src/sdk/cli/index.ts +1 -0
  321. package/src/sdk/cli/session-cli.ts +275 -0
  322. package/src/sdk/client/client.ts +1 -0
  323. package/src/sdk/client/discovery.ts +108 -0
  324. package/src/sdk/client/index.ts +2 -0
  325. package/src/sdk/host/control/dispatch.ts +367 -0
  326. package/src/sdk/host/control/index.ts +10 -0
  327. package/src/sdk/host/control/operations.ts +63 -0
  328. package/src/sdk/host/events.ts +91 -0
  329. package/src/sdk/host/host.ts +296 -0
  330. package/src/sdk/host/index.ts +4 -0
  331. package/src/sdk/host/query/cursor.ts +189 -0
  332. package/src/sdk/host/query/handlers.ts +533 -0
  333. package/src/sdk/host/query/index.ts +3 -0
  334. package/src/sdk/host/query/revision-store.ts +1126 -0
  335. package/src/sdk/host/reverse-leases.ts +325 -0
  336. package/src/sdk/host/types.ts +29 -0
  337. package/src/sdk/index.ts +13 -0
  338. package/src/sdk/lifecycle-session.ts +39 -0
  339. package/src/sdk/mcp/index.ts +1 -0
  340. package/src/sdk/mcp/server.ts +332 -0
  341. package/src/sdk/models.ts +168 -0
  342. package/src/sdk/protocol/adapter-validation.ts +48 -0
  343. package/src/sdk/protocol/operation-inventory.generated.json +5654 -0
  344. package/src/sdk/protocol/operation-registry.ts +312 -0
  345. package/src/{sdk.ts → sdk/session.ts} +339 -212
  346. package/src/sdk/startup-capability.ts +189 -0
  347. package/src/session/agent-session.ts +2453 -894
  348. package/src/session/default-model-selection.ts +93 -0
  349. package/src/session/fallback-chain-controller.ts +136 -0
  350. package/src/session/session-manager.ts +438 -11
  351. package/src/session/session-storage.ts +8 -1
  352. package/src/setup/credential-auto-import.ts +290 -35
  353. package/src/setup/hermes/templates/operator-instructions.v1.md +3 -5
  354. package/src/slash-commands/builtin-registry.ts +2 -1
  355. package/src/task/executor.ts +62 -13
  356. package/src/tools/ask-answer-registry.ts +1 -1
  357. package/src/tools/ask.ts +13 -8
  358. package/src/tools/browser/STEALTH-THIRD-PARTY-NOTICES.md +26 -0
  359. package/src/tools/browser/benchmark/detector-report.ts +157 -0
  360. package/src/tools/browser/benchmark/run-suite.ts +39 -0
  361. package/src/tools/browser/launch.ts +124 -19
  362. package/src/tools/browser/profile-discovery.ts +63 -0
  363. package/src/tools/browser/profile-posture.ts +59 -0
  364. package/src/tools/browser/profile-reuse.ts +102 -0
  365. package/src/tools/browser/profile-warmup.ts +109 -0
  366. package/src/tools/browser/registry.ts +87 -11
  367. package/src/tools/browser/tab-protocol.ts +1 -0
  368. package/src/tools/browser/tab-supervisor.ts +1 -0
  369. package/src/tools/browser/tab-worker.ts +1 -1
  370. package/src/tools/browser.ts +6 -0
  371. package/src/tools/index.ts +8 -8
  372. package/src/tools/puppeteer/14_stealth_permissions.txt +57 -0
  373. package/src/tools/puppeteer/15_stealth_webrtc.txt +60 -0
  374. package/src/tools/telegram-send.ts +2 -2
  375. package/vendor/insane-search/MANIFEST.json +2 -1
  376. package/vendor/insane-search/engine/bias_check.py +4 -1
  377. package/vendor/insane-search/engine/phase0.py +26 -1
  378. package/dist/types/harness-control-plane/rpc-adapter.d.ts +0 -69
  379. package/dist/types/modes/bridge/auth.d.ts +0 -12
  380. package/dist/types/modes/bridge/bridge-client-bridge.d.ts +0 -9
  381. package/dist/types/modes/bridge/bridge-mode.d.ts +0 -47
  382. package/dist/types/modes/bridge/bridge-ui-context.d.ts +0 -88
  383. package/dist/types/modes/bridge/event-stream.d.ts +0 -8
  384. package/dist/types/modes/rpc/host-tools.d.ts +0 -1
  385. package/dist/types/modes/rpc/host-uris.d.ts +0 -1
  386. package/dist/types/modes/rpc/rpc-client.d.ts +0 -299
  387. package/dist/types/modes/rpc/rpc-mode.d.ts +0 -86
  388. package/dist/types/modes/rpc/rpc-socket-security.d.ts +0 -10
  389. package/dist/types/modes/rpc/rpc-types.d.ts +0 -810
  390. package/dist/types/modes/shared/agent-wire/command-contract.d.ts +0 -18
  391. package/dist/types/modes/shared/agent-wire/command-dispatch.d.ts +0 -37
  392. package/dist/types/modes/shared/agent-wire/command-validation.d.ts +0 -2
  393. package/dist/types/modes/shared/agent-wire/handshake.d.ts +0 -56
  394. package/dist/types/modes/shared/agent-wire/host-tool-bridge.d.ts +0 -16
  395. package/dist/types/modes/shared/agent-wire/host-uri-bridge.d.ts +0 -17
  396. package/dist/types/modes/shared/agent-wire/protocol.d.ts +0 -25
  397. package/dist/types/modes/shared/agent-wire/responses.d.ts +0 -4
  398. package/dist/types/modes/shared/agent-wire/scopes.d.ts +0 -18
  399. package/dist/types/modes/shared/agent-wire/session-registry.d.ts +0 -25
  400. package/dist/types/modes/shared/agent-wire/ui-request-broker.d.ts +0 -42
  401. package/dist/types/modes/shared/agent-wire/ui-result.d.ts +0 -27
  402. package/dist/types/modes/shared/agent-wire/unattended-action-policy.d.ts +0 -29
  403. package/dist/types/modes/shared/agent-wire/unattended-audit.d.ts +0 -68
  404. package/dist/types/modes/shared/agent-wire/unattended-run-controller.d.ts +0 -166
  405. package/dist/types/modes/shared/agent-wire/unattended-session.d.ts +0 -127
  406. package/dist/types/notifications/config.d.ts +0 -132
  407. package/src/harness-control-plane/rpc-adapter.ts +0 -290
  408. package/src/modes/bridge/auth.ts +0 -41
  409. package/src/modes/bridge/bridge-client-bridge.ts +0 -47
  410. package/src/modes/bridge/bridge-mode.ts +0 -675
  411. package/src/modes/bridge/bridge-ui-context.ts +0 -200
  412. package/src/modes/bridge/event-stream.ts +0 -70
  413. package/src/modes/rpc/host-tools.ts +0 -1
  414. package/src/modes/rpc/host-uris.ts +0 -1
  415. package/src/modes/rpc/rpc-client.ts +0 -1166
  416. package/src/modes/rpc/rpc-mode.ts +0 -1029
  417. package/src/modes/rpc/rpc-socket-security.ts +0 -115
  418. package/src/modes/rpc/rpc-types.ts +0 -637
  419. package/src/modes/shared/agent-wire/command-contract.ts +0 -18
  420. package/src/modes/shared/agent-wire/command-dispatch.ts +0 -498
  421. package/src/modes/shared/agent-wire/command-validation.ts +0 -181
  422. package/src/modes/shared/agent-wire/handshake.ts +0 -157
  423. package/src/modes/shared/agent-wire/host-tool-bridge.ts +0 -197
  424. package/src/modes/shared/agent-wire/host-uri-bridge.ts +0 -236
  425. package/src/modes/shared/agent-wire/protocol.ts +0 -46
  426. package/src/modes/shared/agent-wire/responses.ts +0 -17
  427. package/src/modes/shared/agent-wire/scopes.ts +0 -94
  428. package/src/modes/shared/agent-wire/session-registry.ts +0 -109
  429. package/src/modes/shared/agent-wire/ui-request-broker.ts +0 -150
  430. package/src/modes/shared/agent-wire/ui-result.ts +0 -48
  431. package/src/modes/shared/agent-wire/unattended-action-policy.ts +0 -365
  432. package/src/modes/shared/agent-wire/unattended-audit.ts +0 -176
  433. package/src/modes/shared/agent-wire/unattended-run-controller.ts +0 -426
  434. package/src/modes/shared/agent-wire/unattended-session.ts +0 -528
  435. package/src/notifications/config.ts +0 -219
  436. package/src/notifications/index.ts +0 -1835
  437. package/src/notifications/telegram-daemon-cli.ts +0 -243
  438. package/src/tools/puppeteer/09_stealth_locale.txt +0 -46
  439. /package/dist/types/{notifications → sdk/bus}/attachment-registry.d.ts +0 -0
  440. /package/dist/types/{notifications → sdk/bus}/chat-adapters.d.ts +0 -0
  441. /package/dist/types/{notifications → sdk/bus}/daemon-paths.d.ts +0 -0
  442. /package/dist/types/{notifications → sdk/bus}/engine.d.ts +0 -0
  443. /package/dist/types/{notifications → sdk/bus}/helpers.d.ts +0 -0
  444. /package/dist/types/{notifications → sdk/bus}/lifecycle-commands.d.ts +0 -0
  445. /package/dist/types/{notifications → sdk/bus}/operator-runtime.d.ts +0 -0
  446. /package/dist/types/{notifications → sdk/bus}/rate-limit-pool.d.ts +0 -0
  447. /package/dist/types/{notifications → sdk/bus}/recent-activity.d.ts +0 -0
  448. /package/dist/types/{notifications → sdk/bus}/reply-sent-store.d.ts +0 -0
  449. /package/dist/types/{notifications → sdk/bus}/rich-draft.d.ts +0 -0
  450. /package/dist/types/{notifications → sdk/bus}/rich-render.d.ts +0 -0
  451. /package/dist/types/{notifications → sdk/bus}/threaded-inbound.d.ts +0 -0
  452. /package/dist/types/{notifications → sdk/bus}/threaded-render.d.ts +0 -0
  453. /package/src/{notifications → sdk/bus}/attachment-registry.ts +0 -0
  454. /package/src/{notifications → sdk/bus}/chat-adapters.ts +0 -0
  455. /package/src/{notifications → sdk/bus}/daemon-paths.ts +0 -0
  456. /package/src/{notifications → sdk/bus}/engine.ts +0 -0
  457. /package/src/{notifications → sdk/bus}/helpers.ts +0 -0
  458. /package/src/{notifications → sdk/bus}/operator-runtime.ts +0 -0
  459. /package/src/{notifications → sdk/bus}/rate-limit-pool.ts +0 -0
  460. /package/src/{notifications → sdk/bus}/recent-activity.ts +0 -0
  461. /package/src/{notifications → sdk/bus}/reply-sent-store.ts +0 -0
  462. /package/src/{notifications → sdk/bus}/rich-draft.ts +0 -0
  463. /package/src/{notifications → sdk/bus}/rich-render.ts +0 -0
  464. /package/src/{notifications → sdk/bus}/threaded-inbound.ts +0 -0
  465. /package/src/{notifications → sdk/bus}/threaded-render.ts +0 -0
@@ -0,0 +1,391 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { randomUUID } from "node:crypto";
3
+ import { readFileSync } from "node:fs";
4
+ import * as fs from "node:fs/promises";
5
+ import * as path from "node:path";
6
+
7
+ export const CONVERSATION_STORE_VERSION = 1;
8
+ export const MAX_DEDUPE_IDS = 128;
9
+
10
+ export interface ConversationRecord {
11
+ generation: number;
12
+ }
13
+
14
+ export interface ConversationStoreDocument<T extends ConversationRecord> {
15
+ version: typeof CONVERSATION_STORE_VERSION;
16
+ conversations: Record<string, T>;
17
+ }
18
+
19
+ export interface ConversationStoreFileHandle {
20
+ sync(): Promise<void>;
21
+ close(): Promise<void>;
22
+ writeFile(data: string, encoding: "utf8"): Promise<void>;
23
+ }
24
+
25
+ /** Minimal persistence seam; callers can inject it to make durability failures deterministic. */
26
+ export interface ConversationStoreFs {
27
+ mkdir(directory: string, options: { recursive: true; mode: number }): Promise<unknown>;
28
+ chmod(target: string, mode: number): Promise<void>;
29
+ readFile(file: string, encoding: "utf8"): Promise<string>;
30
+ writeFile(file: string, data: string, options: { mode: number }): Promise<void>;
31
+ rename(from: string, to: string): Promise<void>;
32
+ unlink(file: string): Promise<void>;
33
+ open(file: string, flags: string): Promise<ConversationStoreFileHandle>;
34
+ stat?(file: string): Promise<{ mtimeMs: number }>;
35
+ }
36
+
37
+ export class ConversationLockTimeoutError extends Error {
38
+ constructor(
39
+ readonly lockFile: string,
40
+ readonly timeoutMs: number,
41
+ ) {
42
+ super(`Timed out waiting ${timeoutMs}ms for conversation store lock: ${lockFile}`);
43
+ this.name = "ConversationLockTimeoutError";
44
+ }
45
+ }
46
+
47
+ interface ConversationStoreLock {
48
+ pid: number;
49
+ incarnation: string;
50
+ timestamp: number;
51
+ }
52
+
53
+ const nodeFs: ConversationStoreFs = fs;
54
+ const UNPUBLISHED_LOCK_STALE_MS = 30_000;
55
+
56
+ export function conversationStorePath(agentDir: string, kind: string, fileName = "conversations.json"): string {
57
+ return path.join(agentDir, "sdk", "daemons", kind, fileName);
58
+ }
59
+
60
+ export function boundedDedupe(ids: readonly string[], limit = MAX_DEDUPE_IDS): string[] {
61
+ const unique: string[] = [];
62
+ const seen = new Set<string>();
63
+ for (const id of ids) {
64
+ if (!id || seen.has(id)) continue;
65
+ seen.add(id);
66
+ unique.push(id);
67
+ }
68
+ return unique.length <= limit ? unique : unique.slice(unique.length - limit);
69
+ }
70
+
71
+ function emptyDocument<T extends ConversationRecord>(): ConversationStoreDocument<T> {
72
+ return { version: CONVERSATION_STORE_VERSION, conversations: {} };
73
+ }
74
+
75
+ function isRecord(value: unknown): value is Record<string, unknown> {
76
+ return typeof value === "object" && value !== null && !Array.isArray(value);
77
+ }
78
+
79
+ /**
80
+ * Durable, per-transport mapping store. Every mutation takes an exclusive
81
+ * lock file shared across processes and reloads the on-disk document before
82
+ * applying its monotonic-generation compare-and-swap, preventing either stale
83
+ * writers or unrelated-key updates from replacing newer mappings.
84
+ */
85
+ export class ConversationStore<T extends ConversationRecord> {
86
+ readonly #directory: string;
87
+ readonly #file: string;
88
+ readonly #fs: ConversationStoreFs;
89
+ readonly #clock: () => number;
90
+ readonly #locks = new Map<string, Promise<void>>();
91
+ readonly #pid: number;
92
+ readonly #pidIncarnation: (pid: number) => string | undefined;
93
+ readonly #pidAlive: (pid: number) => boolean;
94
+ readonly #sleep: (ms: number) => Promise<void>;
95
+ readonly #lockTimeoutMs: number;
96
+
97
+ constructor(input: {
98
+ agentDir: string;
99
+ kind: string;
100
+ fileName?: string;
101
+ fs?: ConversationStoreFs;
102
+ now?: () => number;
103
+ pid?: number;
104
+ pidIncarnation?: (pid: number) => string | undefined;
105
+ pidAlive?: (pid: number) => boolean;
106
+ sleep?: (ms: number) => Promise<void>;
107
+ lockTimeoutMs?: number;
108
+ }) {
109
+ this.#file = conversationStorePath(input.agentDir, input.kind, input.fileName);
110
+ this.#directory = path.dirname(this.#file);
111
+ this.#fs = input.fs ?? nodeFs;
112
+ this.#clock = input.now ?? Date.now;
113
+ this.#pid = input.pid ?? process.pid;
114
+ this.#pidIncarnation = input.pidIncarnation ?? defaultPidIncarnation;
115
+ this.#pidAlive = input.pidAlive ?? defaultPidAlive;
116
+ this.#sleep = input.sleep ?? (async ms => await Bun.sleep(ms));
117
+ this.#lockTimeoutMs = input.lockTimeoutMs ?? 1_000;
118
+ }
119
+
120
+ get filePath(): string {
121
+ return this.#file;
122
+ }
123
+
124
+ async load(): Promise<ConversationStoreDocument<T>> {
125
+ return this.#readDocument();
126
+ }
127
+
128
+ async read(key: string): Promise<T | undefined> {
129
+ return (await this.#readDocument()).conversations[key];
130
+ }
131
+
132
+ /**
133
+ * Atomically write one mapping when its observed generation still matches.
134
+ * `undefined` only creates an absent mapping; successful writes must advance
135
+ * the generation by exactly one.
136
+ */
137
+ async write(key: string, expectedGeneration: number | undefined, record: T): Promise<boolean> {
138
+ return this.#withLock(async () => {
139
+ const document = await this.#readDocument();
140
+ const current = document.conversations[key];
141
+ if (current?.generation !== expectedGeneration) return false;
142
+ if (!current && expectedGeneration !== undefined) return false;
143
+ const nextGeneration = (expectedGeneration ?? 0) + 1;
144
+ if (record.generation !== nextGeneration) {
145
+ throw new Error(`Conversation generation must advance to ${nextGeneration}`);
146
+ }
147
+ document.conversations[key] = record;
148
+ await this.#persist(document);
149
+ return true;
150
+ });
151
+ }
152
+ async delete(key: string, expectedGeneration: number): Promise<boolean> {
153
+ return this.#withLock(async () => {
154
+ const document = await this.#readDocument();
155
+ const current = document.conversations[key];
156
+ if (!current || current.generation !== expectedGeneration) return false;
157
+ delete document.conversations[key];
158
+ await this.#persist(document);
159
+ return true;
160
+ });
161
+ }
162
+
163
+ /** Apply a synchronous update under the mapping lock, retrying no stale state. */
164
+ async transact(key: string, update: (current: T | undefined) => T | undefined): Promise<T | undefined> {
165
+ return this.#withLock(async () => {
166
+ const document = await this.#readDocument();
167
+ const current = document.conversations[key];
168
+ const next = update(current);
169
+ if (!next || next === current) return current;
170
+ const expectedGeneration = current?.generation;
171
+ const expectedNext = (expectedGeneration ?? 0) + 1;
172
+ if (next.generation !== expectedNext) {
173
+ throw new Error(`Conversation generation must advance to ${expectedNext}`);
174
+ }
175
+ document.conversations[key] = next;
176
+ await this.#persist(document);
177
+ return next;
178
+ });
179
+ }
180
+
181
+ async #withLock<R>(operation: () => Promise<R>): Promise<R> {
182
+ const previous = this.#locks.get(this.#file) ?? Promise.resolve();
183
+ const gate = Promise.withResolvers<void>();
184
+ const tail = previous.then(() => gate.promise);
185
+ this.#locks.set(this.#file, tail);
186
+ await previous;
187
+ let fileLock: ConversationStoreFileHandle | undefined;
188
+ try {
189
+ fileLock = await this.#acquireFileLock();
190
+ return await operation();
191
+ } finally {
192
+ try {
193
+ await fileLock?.close();
194
+ if (fileLock)
195
+ await this.#fs.unlink(`${this.#file}.lock`).catch(error => {
196
+ if (!isMissing(error)) throw error;
197
+ });
198
+ } finally {
199
+ gate.resolve();
200
+ if (this.#locks.get(this.#file) === tail) this.#locks.delete(this.#file);
201
+ }
202
+ }
203
+ }
204
+
205
+ async #acquireFileLock(): Promise<ConversationStoreFileHandle> {
206
+ const lockFile = `${this.#file}.lock`;
207
+ const deadline = Date.now() + this.#lockTimeoutMs;
208
+ await this.#fs.mkdir(this.#directory, { recursive: true, mode: 0o700 });
209
+ for (;;) {
210
+ try {
211
+ const handle = await this.#fs.open(lockFile, "wx");
212
+ try {
213
+ const lock: ConversationStoreLock = {
214
+ pid: this.#pid,
215
+ incarnation: this.#pidIncarnation(this.#pid) ?? "unavailable",
216
+ timestamp: this.#clock(),
217
+ };
218
+ await handle.writeFile(`${JSON.stringify(lock)}\n`, "utf8");
219
+ await handle.sync();
220
+ return handle;
221
+ } catch (error) {
222
+ await handle.close().catch(() => undefined);
223
+ await this.#fs.unlink(lockFile).catch(() => undefined);
224
+ throw error;
225
+ }
226
+ } catch (error) {
227
+ if (!isAlreadyExists(error)) throw error;
228
+ if (await this.#reclaimStaleLock(lockFile)) continue;
229
+ if (Date.now() >= deadline) throw new ConversationLockTimeoutError(lockFile, this.#lockTimeoutMs);
230
+ await this.#sleep(Math.min(10, Math.max(1, deadline - Date.now())));
231
+ }
232
+ }
233
+ }
234
+
235
+ async #reclaimStaleLock(lockFile: string): Promise<boolean> {
236
+ if (!(await this.#isStaleLock(lockFile))) return false;
237
+ const reclaimFile = `${lockFile}.reclaim`;
238
+ const reclaimLock = await this.#acquireReclaimLock(reclaimFile);
239
+ if (!reclaimLock) return false;
240
+ try {
241
+ if (!(await this.#isStaleLock(lockFile))) return false;
242
+ await this.#fs.unlink(lockFile).catch(() => undefined);
243
+ return true;
244
+ } finally {
245
+ await reclaimLock.close().catch(() => undefined);
246
+ await this.#fs.unlink(reclaimFile).catch(() => undefined);
247
+ }
248
+ }
249
+ async #acquireReclaimLock(reclaimFile: string): Promise<ConversationStoreFileHandle | undefined> {
250
+ try {
251
+ return await this.#createLockFile(reclaimFile);
252
+ } catch (error) {
253
+ if (!isAlreadyExists(error) || !(await this.#isStaleLock(reclaimFile))) return undefined;
254
+ await this.#fs.unlink(reclaimFile).catch(() => undefined);
255
+ try {
256
+ return await this.#createLockFile(reclaimFile);
257
+ } catch (retryError) {
258
+ if (isAlreadyExists(retryError)) return undefined;
259
+ throw retryError;
260
+ }
261
+ }
262
+ }
263
+ async #createLockFile(lockFile: string): Promise<ConversationStoreFileHandle> {
264
+ const handle = await this.#fs.open(lockFile, "wx");
265
+ try {
266
+ const lock: ConversationStoreLock = {
267
+ pid: this.#pid,
268
+ incarnation: this.#pidIncarnation(this.#pid) ?? "unavailable",
269
+ timestamp: this.#clock(),
270
+ };
271
+ await handle.writeFile(`${JSON.stringify(lock)}\n`, "utf8");
272
+ await handle.sync();
273
+ return handle;
274
+ } catch (error) {
275
+ await handle.close().catch(() => undefined);
276
+ await this.#fs.unlink(lockFile).catch(() => undefined);
277
+ throw error;
278
+ }
279
+ }
280
+ async #isStaleLock(lockFile: string): Promise<boolean> {
281
+ let parsed: unknown;
282
+ try {
283
+ parsed = JSON.parse(await this.#fs.readFile(lockFile, "utf8"));
284
+ } catch (error) {
285
+ if (isMissing(error)) return true;
286
+ return await this.#isExpiredUnpublishedLock(lockFile);
287
+ }
288
+ if (!isConversationStoreLock(parsed)) return await this.#isExpiredUnpublishedLock(lockFile);
289
+ const currentIncarnation = this.#pidIncarnation(parsed.pid);
290
+ return (
291
+ !this.#pidAlive(parsed.pid) ||
292
+ (currentIncarnation !== undefined &&
293
+ parsed.incarnation !== "unavailable" &&
294
+ currentIncarnation !== parsed.incarnation)
295
+ );
296
+ }
297
+ async #isExpiredUnpublishedLock(lockFile: string): Promise<boolean> {
298
+ const stat = this.#fs.stat ? await this.#fs.stat(lockFile).catch(() => undefined) : undefined;
299
+ return Boolean(stat && this.#clock() - stat.mtimeMs >= UNPUBLISHED_LOCK_STALE_MS);
300
+ }
301
+
302
+ async #readDocument(): Promise<ConversationStoreDocument<T>> {
303
+ try {
304
+ const parsed: unknown = JSON.parse(await this.#fs.readFile(this.#file, "utf8"));
305
+ if (!isRecord(parsed) || parsed.version !== CONVERSATION_STORE_VERSION || !isRecord(parsed.conversations)) {
306
+ throw new Error("Invalid conversation store document");
307
+ }
308
+ return { version: CONVERSATION_STORE_VERSION, conversations: parsed.conversations as Record<string, T> };
309
+ } catch (error) {
310
+ if (isMissing(error)) return emptyDocument<T>();
311
+ throw error;
312
+ }
313
+ }
314
+
315
+ async #persist(document: ConversationStoreDocument<T>): Promise<void> {
316
+ await this.#fs.mkdir(this.#directory, { recursive: true, mode: 0o700 });
317
+ await this.#fs.chmod(this.#directory, 0o700);
318
+ const temporary = `${this.#file}.${process.pid}.${randomUUID()}.tmp`;
319
+ try {
320
+ await this.#fs.writeFile(temporary, `${JSON.stringify(document)}\n`, { mode: 0o600 });
321
+ await this.#fs.chmod(temporary, 0o600);
322
+ const handle = await this.#fs.open(temporary, "r");
323
+ try {
324
+ await handle.sync();
325
+ } finally {
326
+ await handle.close();
327
+ }
328
+ await this.#fs.rename(temporary, this.#file);
329
+ const directory = await this.#fs.open(this.#directory, "r");
330
+ try {
331
+ await directory.sync();
332
+ } finally {
333
+ await directory.close();
334
+ }
335
+ } catch (error) {
336
+ await this.#fs.unlink(temporary).catch(() => undefined);
337
+ throw error;
338
+ }
339
+ }
340
+ }
341
+
342
+ function isMissing(error: unknown): error is NodeJS.ErrnoException {
343
+ return isRecord(error) && error.code === "ENOENT";
344
+ }
345
+
346
+ function isAlreadyExists(error: unknown): error is NodeJS.ErrnoException {
347
+ return isRecord(error) && error.code === "EEXIST";
348
+ }
349
+
350
+ function defaultPidAlive(pid: number): boolean {
351
+ try {
352
+ process.kill(pid, 0);
353
+ return true;
354
+ } catch {
355
+ return false;
356
+ }
357
+ }
358
+
359
+ function defaultPidIncarnation(pid: number): string | undefined {
360
+ if (!Number.isSafeInteger(pid) || pid <= 0) return undefined;
361
+ if (process.platform === "linux") {
362
+ try {
363
+ const stat = readFileSync(`/proc/${pid}/stat`, "utf8");
364
+ return `linux:${
365
+ stat
366
+ .slice(stat.lastIndexOf(")") + 2)
367
+ .trim()
368
+ .split(/\s+/)[19]
369
+ }`;
370
+ } catch {
371
+ return undefined;
372
+ }
373
+ }
374
+ if (process.platform === "darwin") {
375
+ const result = spawnSync("ps", ["-o", "lstart=", "-p", String(pid)], { encoding: "utf8" });
376
+ const startedAt = result.status === 0 ? result.stdout.trim() : "";
377
+ return startedAt ? `darwin:${startedAt}` : undefined;
378
+ }
379
+ return undefined;
380
+ }
381
+
382
+ function isConversationStoreLock(value: unknown): value is ConversationStoreLock {
383
+ return (
384
+ isRecord(value) &&
385
+ typeof value.pid === "number" &&
386
+ Number.isSafeInteger(value.pid) &&
387
+ value.pid > 0 &&
388
+ typeof value.incarnation === "string" &&
389
+ typeof value.timestamp === "number"
390
+ );
391
+ }
@@ -0,0 +1,85 @@
1
+ import { boundedDedupe, type ConversationRecord } from "./conversation-store";
2
+
3
+ /** Identifier-only reference to an inbound effect whose payload and lifecycle live in ChatEffectJournal. */
4
+ export interface DiscordInboundDispatchReceipt {
5
+ key: string;
6
+ eventId: string;
7
+ interactionId?: string;
8
+ kind: "action" | "command";
9
+ actionId?: string;
10
+ actionNonce?: string;
11
+ endpointGeneration: number;
12
+ effectId: string;
13
+ idempotencyKey: string;
14
+ }
15
+
16
+ export type DiscordConversationState = "absent" | "creating" | "active" | "archived" | "resuming" | "closed" | "error";
17
+
18
+ /** Durable Discord mapping. It deliberately contains identifiers only: never endpoint tokens or message bodies. */
19
+ export interface DiscordConversation extends ConversationRecord {
20
+ state: DiscordConversationState;
21
+ appId: string;
22
+ guildId: string;
23
+ parentChannelId: string;
24
+ threadId?: string;
25
+ sessionId?: string;
26
+ createNonce?: string;
27
+ /** A lease makes thread creation exclusive across daemon processes. */
28
+ createOwner?: string;
29
+ createLeaseExpiresAt?: number;
30
+ endpointGeneration?: number;
31
+ /** Immutable lineage for archive and resume provider effects. */
32
+ effectIncarnationId?: string;
33
+ /** Current archive operation authority. */
34
+ archiveOccurrenceId?: string;
35
+ archiveEffectId?: string;
36
+ /** Current resume operation authority. */
37
+ resumeOccurrenceId?: string;
38
+ resumeEffectId?: string;
39
+ /** Action authority only; action bodies and endpoint credentials are never persisted. */
40
+ pendingActionId?: string;
41
+ /** Immutable per-publication action authority, bound to component routes and inbound effects. */
42
+ pendingActionNonce?: string;
43
+ /** Durable journal identity for the immutable outbound action publication intent. */
44
+ pendingActionEffectId?: string;
45
+ /** Replayable durable receipts for acknowledged inbound effects. */
46
+ inboundDispatches?: DiscordInboundDispatchReceipt[];
47
+ updatedAt: number;
48
+ archivedAt?: number;
49
+ closedAt?: number;
50
+ supersededByThreadId?: string;
51
+ seenEventIds: string[];
52
+ seenInteractionIds: string[];
53
+ }
54
+
55
+ export function discordConversationKey(input: {
56
+ appId: string;
57
+ guildId: string;
58
+ parentChannelId: string;
59
+ threadId: string;
60
+ }): string {
61
+ return `${input.appId}:${input.guildId}:${input.parentChannelId}:${input.threadId}`;
62
+ }
63
+
64
+ export function normalizeDiscordConversation(record: DiscordConversation): DiscordConversation {
65
+ const dispatches = record.inboundDispatches ?? [];
66
+ return {
67
+ ...record,
68
+ seenEventIds: boundedDedupe(record.seenEventIds),
69
+ seenInteractionIds: boundedDedupe(record.seenInteractionIds),
70
+ ...(dispatches.length === 0 ? {} : { inboundDispatches: dispatches }),
71
+ };
72
+ }
73
+
74
+ export function acceptsDiscordInbound(
75
+ record: DiscordConversation,
76
+ threadId: string,
77
+ endpointGeneration: number,
78
+ ): boolean {
79
+ return (
80
+ record.state === "active" &&
81
+ record.threadId === threadId &&
82
+ record.supersededByThreadId === undefined &&
83
+ record.endpointGeneration === endpointGeneration
84
+ );
85
+ }