@gajae-code/coding-agent 0.13.2 → 0.14.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 (610) hide show
  1. package/CHANGELOG.md +215 -8
  2. package/README.md +2 -0
  3. package/bin/gajaessi.js +4 -0
  4. package/dist/types/async/job-manager.d.ts +55 -2
  5. package/dist/types/async/support.d.ts +14 -0
  6. package/dist/types/capability/mcp.d.ts +6 -0
  7. package/dist/types/capability/types.d.ts +6 -0
  8. package/dist/types/cli/accounts-cli.d.ts +19 -0
  9. package/dist/types/cli/args.d.ts +3 -0
  10. package/dist/types/cli/config-cli.d.ts +6 -0
  11. package/dist/types/cli/crash-cli.d.ts +10 -0
  12. package/dist/types/cli/customize-doctor.d.ts +145 -0
  13. package/dist/types/cli/daemon-cli.d.ts +3 -1
  14. package/dist/types/cli/mcp-cli.d.ts +11 -0
  15. package/dist/types/cli/notify-cli.d.ts +1 -1
  16. package/dist/types/cli/root-flags.d.ts +12 -0
  17. package/dist/types/cli/setup-cli.d.ts +3 -1
  18. package/dist/types/cli/skills-cli.d.ts +2 -1
  19. package/dist/types/cli/update-cli.d.ts +19 -1
  20. package/dist/types/cli.d.ts +6 -0
  21. package/dist/types/commands/accounts.d.ts +40 -0
  22. package/dist/types/commands/crash.d.ts +24 -0
  23. package/dist/types/commands/customize.d.ts +22 -0
  24. package/dist/types/commands/daemon.d.ts +1 -1
  25. package/dist/types/commands/launch.d.ts +6 -0
  26. package/dist/types/commands/setup.d.ts +6 -0
  27. package/dist/types/commands/skills.d.ts +6 -1
  28. package/dist/types/commands/update.d.ts +7 -0
  29. package/dist/types/config/atomic-yaml-patch-worker.d.ts +25 -0
  30. package/dist/types/config/atomic-yaml-patch.d.ts +62 -2
  31. package/dist/types/config/config-schema-version.d.ts +10 -0
  32. package/dist/types/config/file-lock.d.ts +18 -0
  33. package/dist/types/config/model-profile-activation.d.ts +3 -1
  34. package/dist/types/config/model-registry.d.ts +10 -1
  35. package/dist/types/config/models-config-schema.d.ts +2 -0
  36. package/dist/types/config/settings-schema.d.ts +73 -9
  37. package/dist/types/config/settings.d.ts +63 -0
  38. package/dist/types/config/skill-settings-defaults.d.ts +26 -0
  39. package/dist/types/config/task-delegation.d.ts +39 -0
  40. package/dist/types/config/update-channel.d.ts +10 -0
  41. package/dist/types/coordinator-mcp/server.d.ts +5 -1
  42. package/dist/types/crash/index-store.d.ts +87 -0
  43. package/dist/types/crash/nudge.d.ts +50 -0
  44. package/dist/types/crash/record-loader.d.ts +17 -0
  45. package/dist/types/crash/report.d.ts +134 -0
  46. package/dist/types/crash/sanitize.d.ts +25 -0
  47. package/dist/types/cursor.d.ts +13 -2
  48. package/dist/types/customization/import.d.ts +37 -0
  49. package/dist/types/customization/index.d.ts +4 -0
  50. package/dist/types/customization/inventory.d.ts +25 -0
  51. package/dist/types/customization/mutations.d.ts +32 -0
  52. package/dist/types/customization/types.d.ts +115 -0
  53. package/dist/types/daemon/control-types.d.ts +8 -1
  54. package/dist/types/daemon/operator-contract.d.ts +4 -4
  55. package/dist/types/discovery/claude.d.ts +39 -1
  56. package/dist/types/discovery/codex.d.ts +39 -1
  57. package/dist/types/discovery/index.d.ts +2 -0
  58. package/dist/types/discovery/mcp-compat.d.ts +30 -0
  59. package/dist/types/edit/renderer.d.ts +23 -0
  60. package/dist/types/extensibility/extensions/runner.d.ts +3 -0
  61. package/dist/types/extensibility/extensions/types.d.ts +21 -4
  62. package/dist/types/extensibility/gjc-plugins/observability.d.ts +6 -1
  63. package/dist/types/extensibility/gjc-plugins/registry.d.ts +8 -1
  64. package/dist/types/extensibility/hooks/loader.d.ts +19 -5
  65. package/dist/types/extensibility/runtime-skill-discovery.d.ts +22 -1
  66. package/dist/types/extensibility/skill-management.d.ts +107 -0
  67. package/dist/types/gjc-runtime/deep-interview-runtime.d.ts +3 -1
  68. package/dist/types/gjc-runtime/launch-worktree.d.ts +8 -0
  69. package/dist/types/gjc-runtime/linux-proc.d.ts +3 -0
  70. package/dist/types/gjc-runtime/ralplan-runtime.d.ts +10 -6
  71. package/dist/types/gjc-runtime/session-state-lock.d.ts +104 -0
  72. package/dist/types/gjc-runtime/session-state-sidecar.d.ts +120 -2
  73. package/dist/types/gjc-runtime/state-writer.d.ts +10 -1
  74. package/dist/types/gjc-runtime/ultragoal-guard.d.ts +4 -2
  75. package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +8 -6
  76. package/dist/types/gjc-runtime/workflow-settings.d.ts +109 -0
  77. package/dist/types/hooks/events.d.ts +60 -0
  78. package/dist/types/hooks/normalize.d.ts +83 -0
  79. package/dist/types/hooks/skill-state.d.ts +9 -2
  80. package/dist/types/main.d.ts +2 -1
  81. package/dist/types/modes/acp/abort-scope.d.ts +13 -0
  82. package/dist/types/modes/acp/acp-agent.d.ts +7 -4
  83. package/dist/types/modes/components/customization/customization-dashboard.d.ts +44 -0
  84. package/dist/types/modes/components/customization/import-wizard.d.ts +21 -0
  85. package/dist/types/modes/components/customization/index.d.ts +1 -0
  86. package/dist/types/modes/components/dynamic-theme-text.d.ts +9 -0
  87. package/dist/types/modes/components/gajae-pet-widget.d.ts +6 -28
  88. package/dist/types/modes/components/irc-sidebar.d.ts +1 -0
  89. package/dist/types/modes/components/iterm-pet-transport.d.ts +122 -0
  90. package/dist/types/modes/components/oauth-selector.d.ts +10 -4
  91. package/dist/types/modes/components/pet-capability.d.ts +7 -21
  92. package/dist/types/modes/components/settings-selector.d.ts +5 -0
  93. package/dist/types/modes/components/status-line/gh.d.ts +6 -2
  94. package/dist/types/modes/controllers/extension-ui-controller.d.ts +1 -1
  95. package/dist/types/modes/controllers/selector-controller.d.ts +7 -8
  96. package/dist/types/modes/controllers/stt-controller.d.ts +1 -1
  97. package/dist/types/modes/interactive-mode.d.ts +1 -0
  98. package/dist/types/modes/theme/defaults/index.d.ts +118 -0
  99. package/dist/types/modes/types.d.ts +1 -0
  100. package/dist/types/modes/utils/injected-user-submission.d.ts +10 -0
  101. package/dist/types/runtime-mcp/config.d.ts +9 -0
  102. package/dist/types/runtime-mcp/manager.d.ts +26 -1
  103. package/dist/types/runtime-mcp/oauth-discovery.d.ts +4 -0
  104. package/dist/types/runtime-mcp/oauth-flow.d.ts +24 -1
  105. package/dist/types/runtime-mcp/pool-key.d.ts +2 -0
  106. package/dist/types/runtime-mcp/protocol.d.ts +278 -0
  107. package/dist/types/runtime-mcp/scope-config.d.ts +29 -0
  108. package/dist/types/runtime-mcp/tool-bridge.d.ts +15 -13
  109. package/dist/types/runtime-mcp/transports/http.d.ts +9 -0
  110. package/dist/types/runtime-mcp/types.d.ts +102 -10
  111. package/dist/types/sdk/acp/adapter.d.ts +26 -5
  112. package/dist/types/sdk/broker/broker.d.ts +3 -55
  113. package/dist/types/sdk/broker/lifecycle.d.ts +18 -12
  114. package/dist/types/sdk/broker/session-index.d.ts +14 -5
  115. package/dist/types/sdk/broker/startup-failure.d.ts +16 -1
  116. package/dist/types/sdk/bus/chat-daemon-control.d.ts +51 -1
  117. package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +4 -41
  118. package/dist/types/sdk/bus/config.d.ts +11 -0
  119. package/dist/types/sdk/bus/conversation-store.d.ts +0 -1
  120. package/dist/types/sdk/bus/daemon-paths.d.ts +6 -0
  121. package/dist/types/sdk/bus/discord-conversation.d.ts +2 -0
  122. package/dist/types/sdk/bus/discord-daemon.d.ts +17 -12
  123. package/dist/types/sdk/bus/existing-thread-readiness.d.ts +4 -34
  124. package/dist/types/sdk/bus/inbound-reaction-ordering.d.ts +61 -0
  125. package/dist/types/sdk/bus/index.d.ts +85 -99
  126. package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +29 -7
  127. package/dist/types/sdk/bus/managed-daemon.d.ts +2 -32
  128. package/dist/types/sdk/bus/notification-service.d.ts +52 -0
  129. package/dist/types/sdk/bus/operator-runtime.d.ts +1 -1
  130. package/dist/types/sdk/bus/prompt-reconciliation.d.ts +16 -5
  131. package/dist/types/sdk/bus/reconciliation-store.d.ts +113 -5
  132. package/dist/types/sdk/bus/session-control.d.ts +25 -1
  133. package/dist/types/sdk/bus/slack-conversation.d.ts +4 -0
  134. package/dist/types/sdk/bus/slack-daemon.d.ts +9 -17
  135. package/dist/types/sdk/bus/slack-live-provider.d.ts +3 -1
  136. package/dist/types/sdk/bus/slack-provider.d.ts +4 -0
  137. package/dist/types/sdk/bus/slack-thread-binding.d.ts +6 -40
  138. package/dist/types/sdk/bus/telegram-adoption-intent.d.ts +30 -104
  139. package/dist/types/sdk/bus/telegram-daemon-cli.d.ts +10 -0
  140. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +262 -19
  141. package/dist/types/sdk/bus/telegram-daemon-orphan-reap.d.ts +125 -0
  142. package/dist/types/sdk/bus/telegram-daemon-owner-registry.d.ts +22 -0
  143. package/dist/types/sdk/bus/telegram-daemon.d.ts +119 -310
  144. package/dist/types/sdk/bus/telegram-reference.d.ts +1 -47
  145. package/dist/types/sdk/bus/threaded-render.d.ts +1 -0
  146. package/dist/types/sdk/bus/topic-registry.d.ts +33 -17
  147. package/dist/types/sdk/cli/rows.d.ts +2 -11
  148. package/dist/types/sdk/cli/session-cli.d.ts +15 -25
  149. package/dist/types/sdk/client/client.d.ts +97 -1
  150. package/dist/types/sdk/host/control/dispatch.d.ts +0 -7
  151. package/dist/types/sdk/host/control/index.d.ts +1 -1
  152. package/dist/types/sdk/host/control/operations.d.ts +18 -5
  153. package/dist/types/sdk/host/control/runtime-gate.d.ts +19 -0
  154. package/dist/types/sdk/host/host.d.ts +15 -1
  155. package/dist/types/sdk/host/query/handlers.d.ts +5 -0
  156. package/dist/types/sdk/host/reverse-leases.d.ts +1 -1
  157. package/dist/types/sdk/host/session-runtime.d.ts +127 -7
  158. package/dist/types/sdk/host/types.d.ts +1 -1
  159. package/dist/types/sdk/host/websocket-transport.d.ts +1 -1
  160. package/dist/types/sdk/index.d.ts +2 -1
  161. package/dist/types/sdk/lifecycle/broker-client.d.ts +8 -0
  162. package/dist/types/sdk/lifecycle/client.d.ts +59 -0
  163. package/dist/types/sdk/lifecycle/index.d.ts +3 -0
  164. package/dist/types/sdk/lifecycle/service.d.ts +232 -0
  165. package/dist/types/sdk/mcp/server.d.ts +9 -6
  166. package/dist/types/sdk/prompt-deadline-lease.d.ts +43 -0
  167. package/dist/types/sdk/prompt-deadline-manager.d.ts +28 -0
  168. package/dist/types/sdk/prompt-status.d.ts +10 -3
  169. package/dist/types/sdk/protocol/operation-registry.d.ts +5 -0
  170. package/dist/types/sdk/receipt-state.d.ts +17 -0
  171. package/dist/types/sdk/reconciliation-extensions.d.ts +2 -0
  172. package/dist/types/sdk/router/index.d.ts +1 -0
  173. package/dist/types/sdk/router/session-router.d.ts +152 -0
  174. package/dist/types/sdk/session-list.d.ts +22 -0
  175. package/dist/types/sdk/session-reconnect.d.ts +43 -1
  176. package/dist/types/sdk/session.d.ts +34 -1
  177. package/dist/types/sdk/transport/serve-cli.d.ts +1 -4
  178. package/dist/types/session/account-inventory.d.ts +86 -0
  179. package/dist/types/session/agent-session.d.ts +145 -6
  180. package/dist/types/session/agent-storage.d.ts +10 -0
  181. package/dist/types/session/coordinator-tool-label.d.ts +28 -0
  182. package/dist/types/session/internal/managed-session-storage.d.ts +23 -4
  183. package/dist/types/session/messages.d.ts +1 -1
  184. package/dist/types/session/secure-token-file.d.ts +3 -0
  185. package/dist/types/session/session-manager.d.ts +47 -1
  186. package/dist/types/session/startup-auth-config.d.ts +44 -0
  187. package/dist/types/session/terminal-abort.d.ts +378 -0
  188. package/dist/types/session/yield-queue.d.ts +7 -0
  189. package/dist/types/session-import/claude.d.ts +26 -0
  190. package/dist/types/session-import/codex.d.ts +88 -0
  191. package/dist/types/session-import/command.d.ts +35 -0
  192. package/dist/types/session-import/detect.d.ts +22 -0
  193. package/dist/types/session-import/index.d.ts +7 -0
  194. package/dist/types/session-import/provider-codex.d.ts +22 -0
  195. package/dist/types/session-import/provider-service.d.ts +38 -0
  196. package/dist/types/session-import/redact.d.ts +23 -0
  197. package/dist/types/session-import/service.d.ts +47 -0
  198. package/dist/types/session-import/types.d.ts +120 -0
  199. package/dist/types/setup/paseo/check.d.ts +16 -0
  200. package/dist/types/setup/paseo/install-saga.d.ts +115 -0
  201. package/dist/types/setup/paseo/json-publisher.d.ts +76 -0
  202. package/dist/types/setup/paseo/orchestration-preferences.d.ts +24 -0
  203. package/dist/types/setup/paseo/paseo-ownership.d.ts +87 -0
  204. package/dist/types/setup/paseo/paseo-setup.d.ts +29 -0
  205. package/dist/types/setup/paseo/provider-config.d.ts +35 -0
  206. package/dist/types/setup/paseo/remove.d.ts +14 -0
  207. package/dist/types/setup/paseo/result-types.d.ts +59 -0
  208. package/dist/types/setup/paseo/setup-deps.d.ts +73 -0
  209. package/dist/types/setup/paseo/skills-bridge.d.ts +44 -0
  210. package/dist/types/skill-state/active-state.d.ts +5 -1
  211. package/dist/types/slash-commands/acp-builtins.d.ts +5 -1
  212. package/dist/types/slash-commands/builtin-registry.d.ts +2 -0
  213. package/dist/types/slash-commands/helpers/credential-switch.d.ts +12 -0
  214. package/dist/types/slash-commands/helpers/usage-report.d.ts +5 -6
  215. package/dist/types/slash-commands/types.d.ts +7 -1
  216. package/dist/types/task/executor.d.ts +10 -0
  217. package/dist/types/task/index.d.ts +3 -1
  218. package/dist/types/tools/ask-answer-registry.d.ts +6 -3
  219. package/dist/types/tools/bash-sleep-advisory.d.ts +14 -0
  220. package/dist/types/tools/bash.d.ts +2 -6
  221. package/dist/types/tools/browser/attach.d.ts +11 -0
  222. package/dist/types/tools/browser/launch.d.ts +20 -0
  223. package/dist/types/tools/browser/profile-discovery.d.ts +6 -0
  224. package/dist/types/tools/browser/render.d.ts +1 -0
  225. package/dist/types/tools/browser.d.ts +3 -1
  226. package/dist/types/tools/image-gen.d.ts +10 -2
  227. package/dist/types/tools/index.d.ts +8 -0
  228. package/dist/types/tools/monitor.d.ts +1 -1
  229. package/dist/types/tools/skill-discovery.d.ts +8 -1
  230. package/dist/types/tools/subagent.d.ts +2 -0
  231. package/dist/types/tools/ultragoal-ask-guard.d.ts +2 -2
  232. package/dist/types/utils/herdr-pane.d.ts +76 -0
  233. package/package.json +19 -9
  234. package/scripts/build-binary.ts +2 -1
  235. package/scripts/build-sdk-package-smoke.ts +2 -13
  236. package/scripts/capture-sticky-viewport-showcase.ts +0 -1
  237. package/scripts/compile-args.ts +2 -0
  238. package/scripts/generate-sdk-adapter-parity-manifest.ts +31 -16
  239. package/scripts/generate-sdk-operation-inventory.ts +28 -0
  240. package/scripts/generate-telegram-baseline-manifest.ts +1 -0
  241. package/scripts/generate-tool-catalog.ts +6 -4
  242. package/scripts/verify-gjc-sdk-canonicalization.ts +5 -39
  243. package/src/async/job-manager.ts +352 -17
  244. package/src/async/support.ts +25 -0
  245. package/src/autoresearch/dashboard.ts +28 -13
  246. package/src/capability/index.ts +3 -1
  247. package/src/capability/mcp.ts +6 -0
  248. package/src/capability/types.ts +6 -0
  249. package/src/cli/accounts-cli.ts +395 -0
  250. package/src/cli/args.ts +23 -0
  251. package/src/cli/auth-broker-cli.ts +136 -66
  252. package/src/cli/auth-gateway-cli.ts +94 -70
  253. package/src/cli/config-cli.ts +27 -2
  254. package/src/cli/crash-cli.ts +78 -0
  255. package/src/cli/customize-doctor.ts +1605 -0
  256. package/src/cli/daemon-cli.ts +12 -3
  257. package/src/cli/fast-help.ts +1 -0
  258. package/src/cli/mcp-cli.ts +128 -60
  259. package/src/cli/notify-cli.ts +8 -14
  260. package/src/cli/root-flags.ts +8 -0
  261. package/src/cli/setup-cli.ts +145 -0
  262. package/src/cli/skills-cli.ts +38 -2
  263. package/src/cli/update-cli.ts +167 -12
  264. package/src/cli.ts +4 -0
  265. package/src/commands/accounts.ts +71 -0
  266. package/src/commands/crash.ts +35 -0
  267. package/src/commands/customize.ts +84 -0
  268. package/src/commands/daemon.ts +2 -2
  269. package/src/commands/deep-interview.ts +2 -0
  270. package/src/commands/launch.ts +1 -0
  271. package/src/commands/mcp.ts +12 -7
  272. package/src/commands/ralplan.ts +2 -0
  273. package/src/commands/sdk.ts +65 -32
  274. package/src/commands/setup.ts +5 -0
  275. package/src/commands/skills.ts +14 -4
  276. package/src/commands/ultragoal.ts +10 -1
  277. package/src/commands/update.ts +26 -15
  278. package/src/config/atomic-yaml-patch-worker.ts +57 -0
  279. package/src/config/atomic-yaml-patch.ts +769 -29
  280. package/src/config/config-schema-version.ts +10 -0
  281. package/src/config/file-lock.ts +70 -1
  282. package/src/config/mcp-schema.json +52 -14
  283. package/src/config/model-profile-activation.ts +23 -2
  284. package/src/config/model-profiles.ts +88 -21
  285. package/src/config/model-registry.ts +147 -21
  286. package/src/config/models-config-schema.ts +1 -1
  287. package/src/config/settings-schema.ts +77 -7
  288. package/src/config/settings.ts +4038 -199
  289. package/src/config/skill-settings-defaults.ts +41 -3
  290. package/src/config/task-delegation.ts +87 -0
  291. package/src/config/update-channel.ts +23 -0
  292. package/src/coordinator-mcp/server.ts +377 -308
  293. package/src/crash/index-store.ts +723 -0
  294. package/src/crash/nudge.ts +89 -0
  295. package/src/crash/record-loader.ts +149 -0
  296. package/src/crash/report.ts +551 -0
  297. package/src/crash/sanitize.ts +129 -0
  298. package/src/cursor.ts +36 -10
  299. package/src/customization/import.ts +946 -0
  300. package/src/customization/index.ts +4 -0
  301. package/src/customization/inventory.ts +335 -0
  302. package/src/customization/mutations.ts +141 -0
  303. package/src/customization/types.ts +223 -0
  304. package/src/daemon/control-types.ts +8 -1
  305. package/src/daemon/operator-contract.ts +6 -6
  306. package/src/defaults/gjc/extensions/grok-cli-vendor/src/models/catalog.ts +31 -6
  307. package/src/defaults/gjc/skills/deep-interview/SKILL.md +11 -22
  308. package/src/defaults/gjc/skills/ralplan/SKILL.md +36 -23
  309. package/src/defaults/gjc/skills/ultragoal/SKILL.md +16 -0
  310. package/src/discovery/claude-hooks.ts +38 -0
  311. package/src/discovery/claude.ts +142 -209
  312. package/src/discovery/codex-hooks.ts +38 -0
  313. package/src/discovery/codex.ts +132 -198
  314. package/src/discovery/helpers.ts +8 -1
  315. package/src/discovery/index.ts +2 -0
  316. package/src/discovery/mcp-compat.ts +234 -0
  317. package/src/discovery/mcp-json.ts +6 -0
  318. package/src/edit/renderer.ts +40 -0
  319. package/src/edit/streaming.ts +4 -2
  320. package/src/exec/bash-executor.ts +24 -20
  321. package/src/export/html/index.ts +51 -2
  322. package/src/extensibility/extensions/loader.ts +9 -1
  323. package/src/extensibility/extensions/runner.ts +17 -4
  324. package/src/extensibility/extensions/types.ts +31 -6
  325. package/src/extensibility/gjc-plugins/constrained-hooks.ts +33 -0
  326. package/src/extensibility/gjc-plugins/installer.ts +9 -5
  327. package/src/extensibility/gjc-plugins/observability.ts +8 -2
  328. package/src/extensibility/gjc-plugins/registry.ts +13 -2
  329. package/src/extensibility/gjc-plugins/runtime-adapters.ts +3 -1
  330. package/src/extensibility/gjc-plugins/schema.ts +222 -39
  331. package/src/extensibility/hooks/loader.ts +154 -10
  332. package/src/extensibility/runtime-skill-discovery.ts +257 -60
  333. package/src/extensibility/skill-management.ts +368 -0
  334. package/src/extensibility/skills.ts +52 -16
  335. package/src/gjc-runtime/deep-interview-runtime.ts +45 -61
  336. package/src/gjc-runtime/launch-worktree.ts +56 -2
  337. package/src/gjc-runtime/linux-proc.ts +7 -1
  338. package/src/gjc-runtime/ralplan-runtime.ts +100 -164
  339. package/src/gjc-runtime/session-state-lock.ts +992 -0
  340. package/src/gjc-runtime/session-state-sidecar.ts +644 -142
  341. package/src/gjc-runtime/state-writer.ts +39 -14
  342. package/src/gjc-runtime/tmux-owner-isolation.ts +5 -4
  343. package/src/gjc-runtime/ultragoal-guard.ts +11 -4
  344. package/src/gjc-runtime/ultragoal-runtime.ts +44 -41
  345. package/src/gjc-runtime/workflow-settings.ts +596 -0
  346. package/src/goals/tools/goal-tool.ts +6 -1
  347. package/src/hooks/events.ts +291 -0
  348. package/src/hooks/native-skill-hook.ts +4 -0
  349. package/src/hooks/normalize.ts +369 -0
  350. package/src/hooks/skill-state.ts +165 -46
  351. package/src/internal-urls/docs-index.generated.ts +41 -32
  352. package/src/main.ts +36 -5
  353. package/src/migrate/mcp-mapper.ts +25 -2
  354. package/src/modes/acp/abort-scope.ts +29 -0
  355. package/src/modes/acp/acp-agent.ts +423 -98
  356. package/src/modes/components/assistant-message.ts +6 -1
  357. package/src/modes/components/chrome.ts +4 -3
  358. package/src/modes/components/customization/customization-dashboard.ts +443 -0
  359. package/src/modes/components/customization/import-wizard.ts +372 -0
  360. package/src/modes/components/customization/index.ts +1 -0
  361. package/src/modes/components/dynamic-theme-text.ts +22 -0
  362. package/src/modes/components/gajae-pet-widget.ts +607 -193
  363. package/src/modes/components/irc-sidebar.ts +11 -0
  364. package/src/modes/components/iterm-pet-transport.ts +585 -0
  365. package/src/modes/components/model-selector.ts +1 -6
  366. package/src/modes/components/oauth-selector.ts +277 -86
  367. package/src/modes/components/pet-capability.ts +35 -31
  368. package/src/modes/components/settings-selector.ts +29 -5
  369. package/src/modes/components/status-line/gh.ts +45 -1
  370. package/src/modes/components/status-line/segments.ts +19 -4
  371. package/src/modes/components/tool-status-header.ts +13 -3
  372. package/src/modes/controllers/command-controller.ts +20 -8
  373. package/src/modes/controllers/extension-ui-controller.ts +56 -257
  374. package/src/modes/controllers/input-controller.ts +10 -0
  375. package/src/modes/controllers/runtime-mcp-command-controller.ts +16 -3
  376. package/src/modes/controllers/selector-controller.ts +238 -77
  377. package/src/modes/controllers/stt-controller.ts +3 -3
  378. package/src/modes/interactive-mode.ts +88 -16
  379. package/src/modes/print-mode.ts +35 -6
  380. package/src/modes/runtime-init.ts +21 -68
  381. package/src/modes/theme/defaults/index.ts +2 -0
  382. package/src/modes/theme/defaults/ouroboros.json +118 -0
  383. package/src/modes/types.ts +1 -0
  384. package/src/modes/utils/injected-user-submission.ts +25 -0
  385. package/src/modes/utils/terminal-bell.ts +15 -1
  386. package/src/prompts/agent-fragments/ralplan-persistence.md +1 -1
  387. package/src/prompts/agent-fragments/restricted-bash.md +1 -1
  388. package/src/prompts/agents/critic.md +1 -1
  389. package/src/prompts/system/rlm-research.md +1 -1
  390. package/src/prompts/system/system-prompt.md +0 -2
  391. package/src/prompts/tools/bash.md +7 -1
  392. package/src/prompts/tools/browser.md +1 -1
  393. package/src/prompts/tools/cron.md +6 -6
  394. package/src/prompts/tools/read.md +0 -2
  395. package/src/prompts/tools/skill-discovery.md +4 -2
  396. package/src/runtime-mcp/client.ts +427 -23
  397. package/src/runtime-mcp/config.ts +37 -5
  398. package/src/runtime-mcp/manager-pool.test.ts +56 -0
  399. package/src/runtime-mcp/manager.ts +52 -2
  400. package/src/runtime-mcp/oauth-discovery.ts +13 -0
  401. package/src/runtime-mcp/oauth-flow.ts +46 -1
  402. package/src/runtime-mcp/pool-key.ts +5 -1
  403. package/src/runtime-mcp/pool.test.ts +9 -0
  404. package/src/runtime-mcp/protocol.test.ts +353 -0
  405. package/src/runtime-mcp/protocol.ts +624 -0
  406. package/src/runtime-mcp/scope-config.ts +78 -0
  407. package/src/runtime-mcp/tool-bridge.ts +44 -10
  408. package/src/runtime-mcp/transports/http.ts +84 -13
  409. package/src/runtime-mcp/types.ts +123 -12
  410. package/src/sdk/acp/adapter.ts +328 -97
  411. package/src/sdk/broker/broker.ts +160 -741
  412. package/src/sdk/broker/ensure.ts +9 -1
  413. package/src/sdk/broker/lifecycle.ts +510 -116
  414. package/src/sdk/broker/operation-receipt-ledger.ts +11 -2
  415. package/src/sdk/broker/process-incarnation.ts +19 -0
  416. package/src/sdk/broker/session-index.ts +516 -117
  417. package/src/sdk/broker/startup-failure.ts +28 -5
  418. package/src/sdk/broker/transport.ts +1 -13
  419. package/src/sdk/bus/chat-daemon-cli.ts +4 -2
  420. package/src/sdk/bus/chat-daemon-control.ts +67 -6
  421. package/src/sdk/bus/chat-daemon-runtime.ts +183 -859
  422. package/src/sdk/bus/config.ts +13 -0
  423. package/src/sdk/bus/conversation-store.ts +59 -171
  424. package/src/sdk/bus/daemon-paths.ts +20 -0
  425. package/src/sdk/bus/discord-conversation.ts +2 -0
  426. package/src/sdk/bus/discord-daemon.ts +524 -126
  427. package/src/sdk/bus/discord-live-provider.ts +206 -79
  428. package/src/sdk/bus/existing-thread-readiness.ts +4 -97
  429. package/src/sdk/bus/inbound-reaction-ordering.ts +122 -0
  430. package/src/sdk/bus/index.ts +2480 -456
  431. package/src/sdk/bus/kind-aware-reconciliation.ts +204 -34
  432. package/src/sdk/bus/lifecycle-commands.ts +2 -2
  433. package/src/sdk/bus/managed-daemon.ts +2 -145
  434. package/src/sdk/bus/notification-service.ts +196 -0
  435. package/src/sdk/bus/operator-runtime.ts +1 -1
  436. package/src/sdk/bus/prompt-reconciliation.ts +24 -15
  437. package/src/sdk/bus/reconciliation-store.ts +553 -24
  438. package/src/sdk/bus/session-control.ts +49 -3
  439. package/src/sdk/bus/slack-conversation.ts +4 -0
  440. package/src/sdk/bus/slack-daemon.ts +733 -134
  441. package/src/sdk/bus/slack-live-provider.ts +65 -15
  442. package/src/sdk/bus/slack-provider.ts +4 -0
  443. package/src/sdk/bus/slack-thread-binding.ts +9 -104
  444. package/src/sdk/bus/telegram-adoption-intent.ts +299 -209
  445. package/src/sdk/bus/telegram-daemon-cli.ts +194 -7
  446. package/src/sdk/bus/telegram-daemon-contract.ts +265 -19
  447. package/src/sdk/bus/telegram-daemon-control.ts +3 -13
  448. package/src/sdk/bus/telegram-daemon-orphan-reap.ts +498 -0
  449. package/src/sdk/bus/telegram-daemon-owner-registry.ts +176 -0
  450. package/src/sdk/bus/telegram-daemon.ts +2552 -2280
  451. package/src/sdk/bus/telegram-reference.ts +1 -226
  452. package/src/sdk/bus/telegram-setup.ts +2 -2
  453. package/src/sdk/bus/threaded-render.ts +1 -0
  454. package/src/sdk/bus/topic-registry.ts +279 -146
  455. package/src/sdk/cli/rows.ts +2 -35
  456. package/src/sdk/cli/session-cli.ts +776 -700
  457. package/src/sdk/client/client.ts +892 -1
  458. package/src/sdk/host/control/dispatch.ts +93 -58
  459. package/src/sdk/host/control/index.ts +1 -1
  460. package/src/sdk/host/control/operations.ts +18 -10
  461. package/src/sdk/host/control/runtime-gate.ts +40 -0
  462. package/src/sdk/host/host.ts +63 -12
  463. package/src/sdk/host/query/handlers.ts +66 -7
  464. package/src/sdk/host/reverse-leases.ts +2 -2
  465. package/src/sdk/host/sdk-surface-parity.test.ts +1 -1
  466. package/src/sdk/host/session-runtime.test.ts +2787 -34
  467. package/src/sdk/host/session-runtime.ts +1489 -101
  468. package/src/sdk/host/surface-policy.ts +12 -8
  469. package/src/sdk/host/types.ts +1 -1
  470. package/src/sdk/host/websocket-transport.lifecycle.test.ts +31 -59
  471. package/src/sdk/host/websocket-transport.ts +85 -50
  472. package/src/sdk/index.ts +2 -1
  473. package/src/sdk/lifecycle/broker-client.ts +53 -0
  474. package/src/sdk/lifecycle/client.ts +234 -0
  475. package/src/sdk/lifecycle/index.ts +3 -0
  476. package/src/sdk/{bus/recent-activity.ts → lifecycle/recent-sessions.ts} +5 -2
  477. package/src/sdk/lifecycle/service.ts +720 -0
  478. package/src/sdk/mcp/server.ts +226 -188
  479. package/src/sdk/prompt-deadline-lease.ts +55 -0
  480. package/src/sdk/prompt-deadline-manager.ts +148 -0
  481. package/src/sdk/prompt-status.ts +11 -3
  482. package/src/sdk/protocol/operation-inventory.generated.json +272 -129
  483. package/src/sdk/protocol/operation-registry.ts +71 -8
  484. package/src/sdk/receipt-state.ts +43 -0
  485. package/src/sdk/reconciliation-extensions.ts +14 -0
  486. package/src/sdk/router/index.ts +1 -0
  487. package/src/sdk/router/session-router.ts +1658 -0
  488. package/src/sdk/session-list.ts +93 -0
  489. package/src/sdk/session-reconnect.ts +45 -1
  490. package/src/sdk/session.ts +716 -120
  491. package/src/sdk/transport/serve-cli.ts +18 -34
  492. package/src/session/account-inventory.ts +603 -0
  493. package/src/session/agent-session.ts +2873 -559
  494. package/src/session/agent-storage.ts +35 -0
  495. package/src/session/blob-store.ts +32 -1
  496. package/src/session/coordinator-tool-label.ts +40 -0
  497. package/src/session/internal/managed-session-scope.ts +4 -0
  498. package/src/session/internal/managed-session-storage.ts +199 -31
  499. package/src/session/messages.ts +1 -1
  500. package/src/session/secure-token-file.ts +80 -0
  501. package/src/session/session-manager.ts +757 -57
  502. package/src/session/session-storage.ts +25 -16
  503. package/src/session/startup-auth-config.ts +297 -0
  504. package/src/session/terminal-abort.ts +1253 -0
  505. package/src/session/yield-queue.ts +57 -15
  506. package/src/session-import/claude.ts +334 -0
  507. package/src/session-import/codex.ts +1033 -0
  508. package/src/session-import/command.ts +77 -0
  509. package/src/session-import/detect.ts +133 -0
  510. package/src/session-import/index.ts +7 -0
  511. package/src/session-import/provider-codex.ts +327 -0
  512. package/src/session-import/provider-service.ts +457 -0
  513. package/src/session-import/redact.ts +128 -0
  514. package/src/session-import/service.ts +1264 -0
  515. package/src/session-import/types.ts +148 -0
  516. package/src/setup/paseo/check.ts +213 -0
  517. package/src/setup/paseo/install-saga.ts +293 -0
  518. package/src/setup/paseo/json-publisher.ts +263 -0
  519. package/src/setup/paseo/orchestration-preferences.ts +86 -0
  520. package/src/setup/paseo/paseo-ownership.ts +224 -0
  521. package/src/setup/paseo/paseo-setup.ts +253 -0
  522. package/src/setup/paseo/provider-config.ts +139 -0
  523. package/src/setup/paseo/remove.ts +183 -0
  524. package/src/setup/paseo/result-types.ts +79 -0
  525. package/src/setup/paseo/setup-deps.ts +175 -0
  526. package/src/setup/paseo/skills-bridge.ts +260 -0
  527. package/src/skill-state/active-state.ts +21 -11
  528. package/src/slash-commands/acp-builtins.ts +9 -1
  529. package/src/slash-commands/builtin-registry.ts +117 -19
  530. package/src/slash-commands/helpers/credential-switch.ts +143 -0
  531. package/src/slash-commands/helpers/mcp.ts +9 -3
  532. package/src/slash-commands/helpers/usage-report.ts +61 -56
  533. package/src/slash-commands/types.ts +7 -2
  534. package/src/task/executor.ts +30 -11
  535. package/src/task/index.ts +66 -7
  536. package/src/task/render.ts +23 -9
  537. package/src/tools/ask-answer-registry.ts +23 -7
  538. package/src/tools/ask.ts +8 -4
  539. package/src/tools/bash-sleep-advisory.ts +115 -0
  540. package/src/tools/bash.ts +98 -18
  541. package/src/tools/browser/attach.ts +71 -3
  542. package/src/tools/browser/launch.ts +86 -13
  543. package/src/tools/browser/profile-discovery.ts +57 -7
  544. package/src/tools/browser/render.ts +8 -1
  545. package/src/tools/browser.ts +130 -21
  546. package/src/tools/computer.enforcement.test.ts +1 -1
  547. package/src/tools/computer.ts +3 -2
  548. package/src/tools/cron.ts +12 -1
  549. package/src/tools/image-gen.ts +349 -142
  550. package/src/tools/index.ts +8 -0
  551. package/src/tools/job.ts +33 -6
  552. package/src/tools/monitor.ts +41 -2
  553. package/src/tools/skill-discovery.ts +21 -29
  554. package/src/tools/subagent.ts +142 -24
  555. package/src/tools/todo-contract.ts +55 -3
  556. package/src/tools/todo-write.ts +4 -3
  557. package/src/tools/tool-catalog.generated.ts +6 -6
  558. package/src/tools/ultragoal-ask-guard.ts +10 -3
  559. package/src/utils/herdr-pane.ts +345 -0
  560. package/src/utils/title-generator.ts +2 -0
  561. package/src/web/scrapers/index.ts +6 -4
  562. package/dist/types/cli/malloc-env-guard.test.d.ts +0 -1
  563. package/dist/types/defaults/gjc-defaults.test.d.ts +0 -1
  564. package/dist/types/memory-backend/lazy-loading.test.d.ts +0 -1
  565. package/dist/types/runtime/boot-ordering.test.d.ts +0 -1
  566. package/dist/types/runtime/lazy-service.test.d.ts +0 -1
  567. package/dist/types/runtime/network-prewarm-service.test.d.ts +0 -1
  568. package/dist/types/runtime/workspace-tree-service.test.d.ts +0 -1
  569. package/dist/types/runtime-mcp/config.test.d.ts +0 -1
  570. package/dist/types/runtime-mcp/http.test.d.ts +0 -1
  571. package/dist/types/runtime-mcp/manager-pool.test.d.ts +0 -1
  572. package/dist/types/runtime-mcp/pool-key.test.d.ts +0 -1
  573. package/dist/types/runtime-mcp/pool.test.d.ts +0 -1
  574. package/dist/types/sdk/bus/lifecycle-control-runtime.d.ts +0 -117
  575. package/dist/types/sdk/bus/lifecycle-orchestrator.d.ts +0 -141
  576. package/dist/types/sdk/bus/telegram-cli.d.ts +0 -31
  577. package/dist/types/sdk/elevation/allowlist.d.ts +0 -20
  578. package/dist/types/sdk/elevation/audit.d.ts +0 -93
  579. package/dist/types/sdk/elevation/capability.d.ts +0 -3
  580. package/dist/types/sdk/elevation/digest.d.ts +0 -72
  581. package/dist/types/sdk/elevation/dispatch-receipt.d.ts +0 -85
  582. package/dist/types/sdk/elevation/grant-ledger.d.ts +0 -163
  583. package/dist/types/sdk/elevation/owner.d.ts +0 -48
  584. package/dist/types/sdk/host/import-graph.test.d.ts +0 -1
  585. package/dist/types/sdk/host/sdk-surface-parity.test.d.ts +0 -1
  586. package/dist/types/sdk/host/session-runtime.test.d.ts +0 -1
  587. package/dist/types/sdk/host/websocket-transport.lifecycle.test.d.ts +0 -1
  588. package/dist/types/session/auth-broker-config.d.ts +0 -13
  589. package/dist/types/session/heap-eviction-artifacts.test.d.ts +0 -1
  590. package/dist/types/skills/skills.test.d.ts +0 -1
  591. package/dist/types/slash-commands/notify-command.test.d.ts +0 -1
  592. package/dist/types/task/token-log.test.d.ts +0 -1
  593. package/dist/types/tools/computer.enforcement.test.d.ts +0 -1
  594. package/dist/types/tools/descriptors.test.d.ts +0 -1
  595. package/scripts/g005-daemon-smoke.ts +0 -180
  596. package/scripts/g011-daemon-path-smoke.ts +0 -153
  597. package/src/sdk/bus/lifecycle-control-runtime.ts +0 -1733
  598. package/src/sdk/bus/lifecycle-orchestrator.ts +0 -489
  599. package/src/sdk/bus/telegram-cli.ts +0 -212
  600. package/src/sdk/elevation/allowlist.ts +0 -54
  601. package/src/sdk/elevation/audit.ts +0 -208
  602. package/src/sdk/elevation/capability.ts +0 -41
  603. package/src/sdk/elevation/digest.ts +0 -129
  604. package/src/sdk/elevation/dispatch-receipt.ts +0 -184
  605. package/src/sdk/elevation/grant-ledger.ts +0 -1142
  606. package/src/sdk/elevation/owner.ts +0 -109
  607. package/src/session/auth-broker-config.ts +0 -109
  608. /package/dist/types/{ai-core-import-gate.test.d.ts → discovery/claude-hooks.d.ts} +0 -0
  609. /package/dist/types/{cli/fixture-report.test.d.ts → discovery/codex-hooks.d.ts} +0 -0
  610. /package/dist/types/sdk/{bus/recent-activity.d.ts → lifecycle/recent-sessions.d.ts} +0 -0
@@ -13,6 +13,19 @@ import { ConfigFile, type LoadResult } from "../../config/config-file";
13
13
  * site marks it, never by inheriting a marked ancestor's environment.
14
14
  */
15
15
  export const SPAWN_PROVENANCE_ENV = "GJC_SPAWNED_BY_SESSION";
16
+ /**
17
+ * Telegram session eligibility: whether a session may own a forum topic and be
18
+ * admitted by the notification daemon.
19
+ *
20
+ * This follows the user's configuration, never how the session was launched.
21
+ * Gating it on coordinator/lifecycle provenance made every ordinary
22
+ * interactive session declare itself ineligible, and the daemon refuses an
23
+ * identity header that does so — so no notification was ever delivered even
24
+ * though the daemon looked healthy and attached.
25
+ */
26
+ export function isTelegramSessionEligible(cfg: NotificationConfig): boolean {
27
+ return isProviderEffectivelyEnabled(cfg, "telegram") && isTelegramComplete(cfg);
28
+ }
16
29
 
17
30
  export type TelegramActivationState = "inactive" | "blocked";
18
31
  export type TelegramActivationReason = "saved_inactive" | "identity_mismatch";
@@ -28,7 +28,6 @@ export interface ConversationStoreFs {
28
28
  readFile(file: string, encoding: "utf8"): Promise<string>;
29
29
  writeFile(file: string, data: string, options: { mode: number }): Promise<void>;
30
30
  rename(from: string, to: string): Promise<void>;
31
- link(from: string, to: string): Promise<void>;
32
31
  unlink(file: string): Promise<void>;
33
32
  open(file: string, flags: string): Promise<ConversationStoreFileHandle>;
34
33
  stat?(file: string): Promise<{ mtimeMs: number }>;
@@ -47,22 +46,11 @@ export class ConversationLockTimeoutError extends Error {
47
46
  interface ConversationStoreLock {
48
47
  pid: number;
49
48
  incarnation: string;
50
- isolateId?: string;
51
49
  timestamp: number;
52
- /** Uniquely identifies one acquire; lets a release prove it owns the lock file. */
53
- nonce?: string;
54
50
  }
55
51
 
56
52
  const nodeFs: ConversationStoreFs = fs;
57
- /** Unique to this module evaluation, including one Bun worker isolate. */
58
- const processIsolateId = randomUUID();
59
-
60
- /**
61
- * Lock files this process currently holds or is acquiring, across every store.
62
- * The token lets a releasing predecessor preserve a successor's marker when
63
- * the same path has already been reacquired.
64
- */
65
- const heldLockFiles = new Map<string, Set<string>>();
53
+ const UNPUBLISHED_LOCK_STALE_MS = 30_000;
66
54
 
67
55
  export function conversationStorePath(agentDir: string, kind: string, fileName = "conversations.json"): string {
68
56
  return path.join(agentDir, "sdk", "daemons", kind, fileName);
@@ -226,220 +214,108 @@ export class ConversationStore<T extends ConversationRecord> {
226
214
  const tail = previous.then(() => gate.promise);
227
215
  this.#locks.set(this.#file, tail);
228
216
  await previous;
229
- const lockFile = `${this.#file}.lock`;
230
217
  let fileLock: ConversationStoreFileHandle | undefined;
231
- let lockToken: ConversationStoreLock | undefined;
232
218
  try {
233
- const acquired = await this.#acquireFileLock();
234
- fileLock = acquired.handle;
235
- lockToken = acquired.lock;
219
+ fileLock = await this.#acquireFileLock();
236
220
  return await operation();
237
221
  } finally {
238
222
  try {
239
- // A failed close must never skip the unlink: that would leak a
240
- // well-formed lock whose pid is still alive and block every later
241
- // waiter for the full timeout. The unlink is ownership-checked so
242
- // it can only ever remove the lock this holder wrote.
243
- if (fileLock) await fileLock.close().catch(() => undefined);
244
- if (fileLock && lockToken) await this.#unlinkOwnedLock(lockFile, lockToken);
223
+ await closeConversationStoreFileLock(fileLock);
224
+ if (fileLock)
225
+ await this.#fs.unlink(`${this.#file}.lock`).catch(error => {
226
+ if (!isMissing(error)) throw error;
227
+ });
245
228
  } finally {
246
- if (lockToken) this.#releaseHeldLock(lockFile, lockToken);
247
229
  gate.resolve();
248
230
  if (this.#locks.get(this.#file) === tail) this.#locks.delete(this.#file);
249
231
  }
250
232
  }
251
233
  }
252
234
 
253
- #releaseHeldLock(lockFile: string, lock: ConversationStoreLock): void {
254
- const tokens = heldLockFiles.get(lockFile);
255
- if (!tokens) return;
256
- tokens.delete(lock.nonce!);
257
- if (tokens.size === 0) heldLockFiles.delete(lockFile);
258
- }
259
-
260
- async #unlinkOwnedLock(lockFile: string, expected: ConversationStoreLock): Promise<boolean> {
261
- let parsed: unknown;
262
- try {
263
- parsed = JSON.parse(await this.#fs.readFile(lockFile, "utf8"));
264
- } catch (error) {
265
- if (isMissing(error)) return false;
266
- return false; // unreadable: never remove a lock we cannot identify
267
- }
268
- if (
269
- !isConversationStoreLock(parsed) ||
270
- parsed.pid !== expected.pid ||
271
- parsed.incarnation !== expected.incarnation ||
272
- parsed.isolateId !== expected.isolateId ||
273
- parsed.timestamp !== expected.timestamp ||
274
- parsed.nonce !== expected.nonce
275
- )
276
- return false; // a successor holds the path now; leave it
277
- try {
278
- await this.#fs.unlink(lockFile);
279
- return true;
280
- } catch (error) {
281
- if (isMissing(error)) return false;
282
- throw error;
283
- }
284
- }
285
-
286
- async #acquireFileLock(): Promise<{ handle: ConversationStoreFileHandle; lock: ConversationStoreLock }> {
235
+ async #acquireFileLock(): Promise<ConversationStoreFileHandle> {
287
236
  const lockFile = `${this.#file}.lock`;
288
237
  const deadline = Date.now() + this.#lockTimeoutMs;
289
238
  await this.#fs.mkdir(this.#directory, { recursive: true, mode: 0o700 });
290
239
  for (;;) {
291
240
  try {
292
- return await this.#createLockFile(lockFile);
241
+ const handle = await this.#fs.open(lockFile, "wx");
242
+ try {
243
+ const lock: ConversationStoreLock = {
244
+ pid: this.#pid,
245
+ incarnation: this.#pidIncarnation(this.#pid) ?? "unavailable",
246
+ timestamp: this.#clock(),
247
+ };
248
+ await handle.writeFile(`${JSON.stringify(lock)}\n`, "utf8");
249
+ await handle.sync();
250
+ return handle;
251
+ } catch (error) {
252
+ await handle.close().catch(() => undefined);
253
+ await this.#fs.unlink(lockFile).catch(() => undefined);
254
+ throw error;
255
+ }
293
256
  } catch (error) {
294
257
  if (!isAlreadyExists(error)) throw error;
295
258
  if (await this.#reclaimStaleLock(lockFile)) continue;
296
- if (await this.#reclaimSameProcessLeak(lockFile)) continue;
297
259
  if (Date.now() >= deadline) throw new ConversationLockTimeoutError(lockFile, this.#lockTimeoutMs);
298
260
  await this.#sleep(Math.min(10, Math.max(1, deadline - Date.now())));
299
261
  }
300
262
  }
301
263
  }
302
264
 
303
- /**
304
- * Removes a well-formed lock this process wrote but no longer holds. Healing
305
- * is serialized by its own ownership-tracked reclaim lock, so concurrent
306
- * waiters cannot delete a successor after the original leak is removed.
307
- */
308
- async #reclaimSameProcessLeak(lockFile: string): Promise<boolean> {
309
- const expected = await this.#readLock(lockFile);
310
- if (
311
- !expected ||
312
- expected.pid !== this.#pid ||
313
- expected.isolateId !== processIsolateId ||
314
- heldLockFiles.has(lockFile)
315
- )
316
- return false;
317
-
318
- const reclaimFile = `${lockFile}.reclaim`;
319
- const reclaimLock = await this.#acquireReclaimLock(reclaimFile);
320
- if (!reclaimLock) return false;
321
- try {
322
- if (expected.pid !== this.#pid || expected.isolateId !== processIsolateId || heldLockFiles.has(lockFile))
323
- return false;
324
- return await this.#unlinkOwnedLock(lockFile, expected);
325
- } catch {
326
- return false;
327
- } finally {
328
- await reclaimLock.handle.close().catch(() => undefined);
329
- try {
330
- await this.#unlinkOwnedLock(reclaimFile, reclaimLock.lock).catch(() => undefined);
331
- } finally {
332
- this.#releaseHeldLock(reclaimFile, reclaimLock.lock);
333
- }
334
- }
335
- }
336
-
337
265
  async #reclaimStaleLock(lockFile: string): Promise<boolean> {
338
266
  if (!(await this.#isStaleLock(lockFile))) return false;
339
267
  const reclaimFile = `${lockFile}.reclaim`;
340
268
  const reclaimLock = await this.#acquireReclaimLock(reclaimFile);
341
269
  if (!reclaimLock) return false;
342
270
  try {
343
- const staleLock = await this.#readLock(lockFile);
344
- if (!staleLock || !(await this.#isStaleLock(lockFile))) return false;
345
- return await this.#unlinkOwnedLock(lockFile, staleLock);
346
- } catch {
347
- return false;
271
+ if (!(await this.#isStaleLock(lockFile))) return false;
272
+ await this.#fs.unlink(lockFile).catch(() => undefined);
273
+ return true;
348
274
  } finally {
349
- await reclaimLock.handle.close().catch(() => undefined);
350
- try {
351
- await this.#unlinkOwnedLock(reclaimFile, reclaimLock.lock).catch(() => undefined);
352
- } finally {
353
- this.#releaseHeldLock(reclaimFile, reclaimLock.lock);
354
- }
275
+ await reclaimLock.close().catch(() => undefined);
276
+ await this.#fs.unlink(reclaimFile).catch(() => undefined);
355
277
  }
356
278
  }
357
-
358
- async #acquireReclaimLock(
359
- reclaimFile: string,
360
- ): Promise<{ handle: ConversationStoreFileHandle; lock: ConversationStoreLock } | undefined> {
279
+ async #acquireReclaimLock(reclaimFile: string): Promise<ConversationStoreFileHandle | undefined> {
361
280
  try {
362
281
  return await this.#createLockFile(reclaimFile);
363
282
  } catch (error) {
364
- if (!isAlreadyExists(error)) return undefined;
365
- if (await this.#reclaimStaleLock(reclaimFile)) {
366
- try {
367
- return await this.#createLockFile(reclaimFile);
368
- } catch (retryError) {
369
- if (isAlreadyExists(retryError)) return undefined;
370
- throw retryError;
371
- }
372
- }
373
- if (await this.#reclaimSameProcessLeak(reclaimFile)) {
374
- try {
375
- return await this.#createLockFile(reclaimFile);
376
- } catch (retryError) {
377
- if (isAlreadyExists(retryError)) return undefined;
378
- throw retryError;
379
- }
283
+ if (!isAlreadyExists(error) || !(await this.#isStaleLock(reclaimFile))) return undefined;
284
+ await this.#fs.unlink(reclaimFile).catch(() => undefined);
285
+ try {
286
+ return await this.#createLockFile(reclaimFile);
287
+ } catch (retryError) {
288
+ if (isAlreadyExists(retryError)) return undefined;
289
+ throw retryError;
380
290
  }
381
- return undefined;
382
291
  }
383
292
  }
384
-
385
- async #createLockFile(
386
- lockFile: string,
387
- ): Promise<{ handle: ConversationStoreFileHandle; lock: ConversationStoreLock }> {
388
- const pendingFile = `${lockFile}.${this.#pid}.${randomUUID()}.pending`;
389
- const handle = await this.#fs.open(pendingFile, "wx");
390
- let lock: ConversationStoreLock | undefined;
391
- let published = false;
293
+ async #createLockFile(lockFile: string): Promise<ConversationStoreFileHandle> {
294
+ const handle = await this.#fs.open(lockFile, "wx");
392
295
  try {
393
- lock = {
296
+ const lock: ConversationStoreLock = {
394
297
  pid: this.#pid,
395
298
  incarnation: this.#pidIncarnation(this.#pid) ?? "unavailable",
396
- isolateId: processIsolateId,
397
299
  timestamp: this.#clock(),
398
- nonce: randomUUID(),
399
300
  };
400
- const heldTokens = heldLockFiles.get(lockFile) ?? new Set<string>();
401
- heldTokens.add(lock.nonce!);
402
- heldLockFiles.set(lockFile, heldTokens);
403
301
  await handle.writeFile(`${JSON.stringify(lock)}\n`, "utf8");
404
302
  await handle.sync();
405
- await this.#fs.link(pendingFile, lockFile);
406
- published = true;
407
- await this.#fs.unlink(pendingFile);
408
- return { handle, lock };
303
+ return handle;
409
304
  } catch (error) {
410
- try {
411
- await handle.close().catch(() => undefined);
412
- try {
413
- if (published && lock) await this.#unlinkOwnedLock(lockFile, lock);
414
- } finally {
415
- await this.#fs.unlink(pendingFile).catch(() => undefined);
416
- }
417
- } finally {
418
- if (lock) this.#releaseHeldLock(lockFile, lock);
419
- }
305
+ await handle.close().catch(() => undefined);
306
+ await this.#fs.unlink(lockFile).catch(() => undefined);
420
307
  throw error;
421
308
  }
422
309
  }
423
-
424
- async #readLock(lockFile: string): Promise<ConversationStoreLock | undefined> {
425
- try {
426
- const parsed: unknown = JSON.parse(await this.#fs.readFile(lockFile, "utf8"));
427
- return isConversationStoreLock(parsed) ? parsed : undefined;
428
- } catch {
429
- return undefined;
430
- }
431
- }
432
-
433
310
  async #isStaleLock(lockFile: string): Promise<boolean> {
434
311
  let parsed: unknown;
435
312
  try {
436
313
  parsed = JSON.parse(await this.#fs.readFile(lockFile, "utf8"));
437
- } catch {
438
- // An unreadable legacy marker may still have an open creator. It is
439
- // never safe to reclaim it based on age alone.
440
- return false;
314
+ } catch (error) {
315
+ if (isMissing(error)) return true;
316
+ return await this.#isExpiredUnpublishedLock(lockFile);
441
317
  }
442
- if (!isConversationStoreLock(parsed)) return false;
318
+ if (!isConversationStoreLock(parsed)) return await this.#isExpiredUnpublishedLock(lockFile);
443
319
  const currentIncarnation = this.#pidIncarnation(parsed.pid);
444
320
  return (
445
321
  !this.#pidAlive(parsed.pid) ||
@@ -448,6 +324,10 @@ export class ConversationStore<T extends ConversationRecord> {
448
324
  (currentIncarnation !== undefined && currentIncarnation !== parsed.incarnation)))
449
325
  );
450
326
  }
327
+ async #isExpiredUnpublishedLock(lockFile: string): Promise<boolean> {
328
+ const stat = this.#fs.stat ? await this.#fs.stat(lockFile).catch(() => undefined) : undefined;
329
+ return Boolean(stat && this.#clock() - stat.mtimeMs >= UNPUBLISHED_LOCK_STALE_MS);
330
+ }
451
331
 
452
332
  async #readDocument(): Promise<ConversationStoreDocument<T>> {
453
333
  try {
@@ -488,6 +368,15 @@ function isMissing(error: unknown): error is NodeJS.ErrnoException {
488
368
  return isRecord(error) && error.code === "ENOENT";
489
369
  }
490
370
 
371
+ async function closeConversationStoreFileLock(handle: ConversationStoreFileHandle | undefined): Promise<void> {
372
+ if (!handle) return;
373
+ // A failed close must never skip the unlink: that would leak a well-formed
374
+ // lock whose pid is still alive and block every later waiter. The unlink is
375
+ // ownership-checked by the pending-file model so it can only ever remove the
376
+ // lock this holder wrote, making a best-effort close safe.
377
+ await handle.close().catch(() => undefined);
378
+ }
379
+
491
380
  async function syncParentDirectory(
492
381
  fs: ConversationStoreFs,
493
382
  directory: string,
@@ -544,7 +433,6 @@ function isConversationStoreLock(value: unknown): value is ConversationStoreLock
544
433
  Number.isSafeInteger(value.pid) &&
545
434
  value.pid > 0 &&
546
435
  typeof value.incarnation === "string" &&
547
- (value.isolateId === undefined || typeof value.isolateId === "string") &&
548
436
  typeof value.timestamp === "number"
549
437
  );
550
438
  }
@@ -1,3 +1,4 @@
1
+ import * as crypto from "node:crypto";
1
2
  import * as path from "node:path";
2
3
 
3
4
  /**
@@ -19,8 +20,25 @@ export interface DaemonPaths {
19
20
  diagnostic: string;
20
21
  aliases: string;
21
22
  seenUpdates: string;
23
+ ownerRegistry: string;
24
+ recoveryReceipt: string;
22
25
  }
23
26
 
27
+ export function agentDirDigest(agentDir: string): string {
28
+ return crypto.createHash("sha256").update(path.resolve(agentDir)).digest("hex");
29
+ }
30
+
31
+ export function telegramDaemonOwnerMarkerPath(agentDir: string, acquisitionId: string): string {
32
+ const safe =
33
+ /^[A-Za-z0-9_.-]+$/.test(acquisitionId) && acquisitionId.length > 0 && acquisitionId.length <= 128
34
+ ? acquisitionId
35
+ : crypto.createHash("sha256").update(acquisitionId).digest("hex");
36
+ return path.join(daemonPaths(agentDir).ownerRegistry, `${safe}.json`);
37
+ }
38
+
39
+ export const daemonOwnerMarkerPath = telegramDaemonOwnerMarkerPath;
40
+ export const telegramDaemonProcessMarkerPath = telegramDaemonOwnerMarkerPath;
41
+
24
42
  export function daemonPaths(agentDir: string): DaemonPaths {
25
43
  const dir = path.join(agentDir, "notifications");
26
44
  return {
@@ -34,5 +52,7 @@ export function daemonPaths(agentDir: string): DaemonPaths {
34
52
  aliases: path.join(dir, "telegram-callback-aliases.json"),
35
53
  diagnostic: path.join(dir, "telegram-daemon.diagnostics.json"),
36
54
  seenUpdates: path.join(dir, "telegram-seen-updates.json"),
55
+ ownerRegistry: path.join(dir, "telegram-daemon-owners"),
56
+ recoveryReceipt: path.join(dir, "telegram-daemon.recovery.json"),
37
57
  };
38
58
  }
@@ -9,6 +9,7 @@ export interface DiscordInboundDispatchReceipt {
9
9
  actionId?: string;
10
10
  actionNonce?: string;
11
11
  endpointGeneration: number;
12
+ attachmentAuthorityId?: string;
12
13
  effectId: string;
13
14
  idempotencyKey: string;
14
15
  }
@@ -28,6 +29,7 @@ export interface DiscordConversation extends ConversationRecord {
28
29
  createOwner?: string;
29
30
  createLeaseExpiresAt?: number;
30
31
  endpointGeneration?: number;
32
+ attachmentAuthorityId?: string;
31
33
  /** Immutable lineage for archive and resume provider effects. */
32
34
  effectIncarnationId?: string;
33
35
  /** Current archive operation authority. */