@gajae-code/coding-agent 0.11.11 → 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (344) hide show
  1. package/CHANGELOG.md +131 -4
  2. package/dist/types/async/job-manager.d.ts +17 -3
  3. package/dist/types/cli/read-cli.d.ts +1 -0
  4. package/dist/types/commands/deep-interview.d.ts +9 -0
  5. package/dist/types/commands/harness.d.ts +22 -0
  6. package/dist/types/commands/read.d.ts +6 -0
  7. package/dist/types/config/model-registry.d.ts +4 -0
  8. package/dist/types/config/provider-auth-health.d.ts +14 -0
  9. package/dist/types/config/provider-ranking.d.ts +59 -0
  10. package/dist/types/config/settings-schema.d.ts +83 -1
  11. package/dist/types/config/settings.d.ts +2 -0
  12. package/dist/types/exa/mcp-client.d.ts +10 -1
  13. package/dist/types/exec/bash-executor.d.ts +45 -12
  14. package/dist/types/extensibility/extensions/types.d.ts +38 -4
  15. package/dist/types/extensibility/gjc-plugins/index.d.ts +12 -2
  16. package/dist/types/extensibility/gjc-plugins/installer.d.ts +63 -7
  17. package/dist/types/extensibility/gjc-plugins/lifecycle-reconciliation.d.ts +55 -0
  18. package/dist/types/extensibility/gjc-plugins/lifecycle.d.ts +64 -0
  19. package/dist/types/extensibility/gjc-plugins/runtime-quarantine.d.ts +67 -0
  20. package/dist/types/extensibility/gjc-plugins/session-validation.d.ts +3 -1
  21. package/dist/types/extensibility/gjc-plugins/types.d.ts +124 -0
  22. package/dist/types/extensibility/shared-events.d.ts +6 -0
  23. package/dist/types/gjc-runtime/deep-interview-ambiguity.d.ts +5 -12
  24. package/dist/types/gjc-runtime/deep-interview-recorder.d.ts +17 -32
  25. package/dist/types/gjc-runtime/deep-interview-stage.d.ts +37 -0
  26. package/dist/types/gjc-runtime/deep-interview-state.d.ts +4 -135
  27. package/dist/types/gjc-runtime/gc-runtime.d.ts +1 -1
  28. package/dist/types/gjc-runtime/launch-tmux.d.ts +1 -0
  29. package/dist/types/gjc-runtime/memory-guard-owner-claims.d.ts +47 -0
  30. package/dist/types/gjc-runtime/ralplan-runtime.d.ts +70 -1
  31. package/dist/types/gjc-runtime/state-writer.d.ts +5 -46
  32. package/dist/types/gjc-runtime/team-launch.d.ts +1 -1
  33. package/dist/types/gjc-runtime/team-runtime.d.ts +27 -1
  34. package/dist/types/gjc-runtime/team-store.d.ts +12 -0
  35. package/dist/types/gjc-runtime/team-worker-heartbeat.d.ts +43 -0
  36. package/dist/types/gjc-runtime/team-worker-memory-guard.d.ts +92 -0
  37. package/dist/types/gjc-runtime/tmux-owner-isolation.d.ts +17 -0
  38. package/dist/types/gjc-runtime/ultragoal-receipt-freshness.d.ts +8 -0
  39. package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +31 -80
  40. package/dist/types/gjc-runtime/workflow-manifest.d.ts +3 -5
  41. package/dist/types/internal-urls/local-root-gc.d.ts +2 -0
  42. package/dist/types/main.d.ts +1 -1
  43. package/dist/types/memories/index.d.ts +2 -0
  44. package/dist/types/modes/acp/acp-agent.d.ts +10 -19
  45. package/dist/types/modes/components/assistant-message.d.ts +3 -1
  46. package/dist/types/modes/components/gjc-bundle-settings.d.ts +34 -0
  47. package/dist/types/modes/components/irc-sidebar.d.ts +41 -0
  48. package/dist/types/modes/components/notifications-settings-editor.d.ts +1 -0
  49. package/dist/types/modes/components/read-tool-group.d.ts +4 -4
  50. package/dist/types/modes/components/session-observer-overlay.d.ts +22 -0
  51. package/dist/types/modes/components/settings-selector.d.ts +11 -0
  52. package/dist/types/modes/components/status-line/gh.d.ts +5 -0
  53. package/dist/types/modes/components/tool-execution.d.ts +8 -0
  54. package/dist/types/modes/components/transcript-viewer-overlay.d.ts +18 -1
  55. package/dist/types/modes/controllers/event-controller.d.ts +3 -0
  56. package/dist/types/modes/interactive-mode.d.ts +2 -0
  57. package/dist/types/modes/irc-observation-ledger.d.ts +17 -1
  58. package/dist/types/modes/types.d.ts +2 -0
  59. package/dist/types/modes/utils/ui-helpers.d.ts +16 -0
  60. package/dist/types/reminders/star-reminder.d.ts +3 -13
  61. package/dist/types/runtime-mcp/manager.d.ts +1 -0
  62. package/dist/types/runtime-mcp/smithery-auth.d.ts +5 -0
  63. package/dist/types/sdk/acp/adapter.d.ts +3 -1
  64. package/dist/types/sdk/broker/lifecycle.d.ts +5 -0
  65. package/dist/types/sdk/broker/transport.d.ts +2 -0
  66. package/dist/types/sdk/bus/attachment-registry.d.ts +1 -0
  67. package/dist/types/sdk/bus/chat-daemon-control.d.ts +4 -1
  68. package/dist/types/sdk/bus/config.d.ts +6 -2
  69. package/dist/types/sdk/bus/control-drain-lease.d.ts +52 -0
  70. package/dist/types/sdk/bus/index.d.ts +44 -1
  71. package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +44 -0
  72. package/dist/types/sdk/bus/lifecycle-control-runtime.d.ts +4 -0
  73. package/dist/types/sdk/bus/prompt-reconciliation.d.ts +2 -1
  74. package/dist/types/sdk/bus/reconciliation-store.d.ts +69 -0
  75. package/dist/types/sdk/bus/rich-draft.d.ts +1 -0
  76. package/dist/types/sdk/bus/rich-render.d.ts +2 -0
  77. package/dist/types/sdk/bus/telegram-adoption-intent.d.ts +165 -0
  78. package/dist/types/sdk/bus/telegram-cli.d.ts +12 -0
  79. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +11 -4
  80. package/dist/types/sdk/bus/telegram-daemon.d.ts +25 -1
  81. package/dist/types/sdk/bus/telegram-reference.d.ts +11 -1
  82. package/dist/types/sdk/bus/threaded-render.d.ts +3 -2
  83. package/dist/types/sdk/bus/topic-registry.d.ts +11 -1
  84. package/dist/types/sdk/host/control/operations.d.ts +1 -1
  85. package/dist/types/sdk/host/host.d.ts +2 -0
  86. package/dist/types/sdk/host/query/handlers.d.ts +5 -0
  87. package/dist/types/sdk/host/query/revision-store.d.ts +2 -0
  88. package/dist/types/sdk/host/reverse-leases.d.ts +1 -1
  89. package/dist/types/sdk/prompt-status.d.ts +23 -3
  90. package/dist/types/sdk/session.d.ts +6 -0
  91. package/dist/types/session/agent-session.d.ts +82 -12
  92. package/dist/types/session/artifacts.d.ts +8 -0
  93. package/dist/types/session/blob-store.d.ts +57 -4
  94. package/dist/types/session/internal/managed-session-storage.d.ts +8 -1
  95. package/dist/types/session/memory-guard-checkpoint-participant.d.ts +69 -0
  96. package/dist/types/session/session-manager.d.ts +48 -19
  97. package/dist/types/session/session-storage.d.ts +4 -0
  98. package/dist/types/session/streaming-output.d.ts +96 -12
  99. package/dist/types/setup/credential-import.d.ts +12 -0
  100. package/dist/types/skill-state/active-state.d.ts +12 -4
  101. package/dist/types/skill-state/workflow-hud.d.ts +9 -0
  102. package/dist/types/task/executor.d.ts +3 -2
  103. package/dist/types/task/index.d.ts +3 -1
  104. package/dist/types/task/provider-retry-status.d.ts +8 -0
  105. package/dist/types/task/receipt.d.ts +7 -1
  106. package/dist/types/task/types.d.ts +23 -0
  107. package/dist/types/tools/ask-answer-registry.d.ts +2 -2
  108. package/dist/types/tools/bash-interactive.d.ts +4 -1
  109. package/dist/types/tools/bash.d.ts +3 -1
  110. package/dist/types/tools/browser/launch.d.ts +7 -0
  111. package/dist/types/tools/fetch.d.ts +17 -1
  112. package/dist/types/tools/image-gen.d.ts +4 -0
  113. package/dist/types/tools/index.d.ts +4 -0
  114. package/dist/types/tools/output-meta.d.ts +44 -3
  115. package/dist/types/tools/path-utils.d.ts +1 -0
  116. package/dist/types/tools/read-internals.d.ts +12 -0
  117. package/dist/types/tools/read.d.ts +45 -7
  118. package/dist/types/tools/resource-gc.d.ts +4 -0
  119. package/dist/types/tools/review.d.ts +5 -7
  120. package/dist/types/tools/subagent.d.ts +2 -0
  121. package/dist/types/tools/tool-result.d.ts +7 -1
  122. package/dist/types/utils/gh.d.ts +13 -0
  123. package/dist/types/utils/image-resize.d.ts +1 -0
  124. package/dist/types/web/search/providers/kimi.d.ts +2 -0
  125. package/dist/types/web/search/providers/searxng.d.ts +7 -0
  126. package/dist/types/web/search/providers/xai.d.ts +2 -0
  127. package/package.json +11 -13
  128. package/scripts/acp-conformance-agent.ts +218 -0
  129. package/scripts/benchmark-sticky-viewport-pr1.ts +239 -0
  130. package/scripts/capture-gjc-bundle-settings.ts +306 -0
  131. package/scripts/capture-sticky-viewport-showcase.ts +292 -0
  132. package/scripts/generate-sdk-operation-inventory.ts +5 -0
  133. package/scripts/resident-memory-bench.ts +1341 -0
  134. package/scripts/run-acp-conformance.ts +285 -0
  135. package/scripts/verify-gjc-sdk-canonicalization.ts +122 -18
  136. package/scripts/verify-sticky-viewport-showcase.ts +611 -0
  137. package/src/async/job-manager.ts +78 -20
  138. package/src/capability/index.ts +8 -0
  139. package/src/cli/fast-help.ts +1 -1
  140. package/src/cli/plugin-cli.ts +176 -18
  141. package/src/cli/read-cli.ts +2 -1
  142. package/src/cli.ts +1 -0
  143. package/src/commands/deep-interview.ts +29 -9
  144. package/src/commands/harness.ts +35 -12
  145. package/src/commands/read.ts +11 -2
  146. package/src/commands/team.ts +20 -2
  147. package/src/config/file-lock.ts +11 -2
  148. package/src/config/model-registry.ts +21 -2
  149. package/src/config/provider-auth-health.ts +42 -0
  150. package/src/config/provider-ranking.ts +119 -0
  151. package/src/config/settings-schema.ts +74 -1
  152. package/src/config/settings.ts +246 -108
  153. package/src/coordinator-mcp/question-gate-codec.ts +1 -1
  154. package/src/coordinator-mcp/server.ts +5 -12
  155. package/src/defaults/gjc/skills/deep-interview/SKILL.md +230 -82
  156. package/src/defaults/gjc/skills/ralplan/SKILL.md +77 -41
  157. package/src/defaults/gjc/skills/team/SKILL.md +3 -1
  158. package/src/defaults/gjc/skills/ultragoal/SKILL.md +62 -39
  159. package/src/defaults/gjc/skills/ultragoal/validation-batch-contracts.md +12 -0
  160. package/src/defaults/gjc-defaults.ts +4 -4
  161. package/src/eval/py/executor.ts +7 -2
  162. package/src/exa/mcp-client.ts +12 -3
  163. package/src/exec/bash-executor.ts +144 -27
  164. package/src/extensibility/extensions/runner.ts +15 -0
  165. package/src/extensibility/extensions/types.ts +46 -5
  166. package/src/extensibility/gjc-plugins/constrained-hooks.ts +8 -2
  167. package/src/extensibility/gjc-plugins/index.ts +19 -2
  168. package/src/extensibility/gjc-plugins/installer.ts +189 -50
  169. package/src/extensibility/gjc-plugins/lifecycle-reconciliation.ts +199 -0
  170. package/src/extensibility/gjc-plugins/lifecycle.ts +626 -0
  171. package/src/extensibility/gjc-plugins/observability.ts +3 -3
  172. package/src/extensibility/gjc-plugins/prompt-appendix.ts +5 -1
  173. package/src/extensibility/gjc-plugins/runtime-adapters.ts +12 -2
  174. package/src/extensibility/gjc-plugins/runtime-quarantine.ts +121 -0
  175. package/src/extensibility/gjc-plugins/schema.ts +84 -12
  176. package/src/extensibility/gjc-plugins/session-validation.ts +9 -3
  177. package/src/extensibility/gjc-plugins/types.ts +141 -0
  178. package/src/extensibility/gjc-plugins/validation.ts +9 -0
  179. package/src/extensibility/shared-events.ts +5 -0
  180. package/src/gjc-runtime/deep-interview-ambiguity.ts +47 -82
  181. package/src/gjc-runtime/deep-interview-recorder.ts +227 -310
  182. package/src/gjc-runtime/deep-interview-runtime.ts +109 -270
  183. package/src/gjc-runtime/deep-interview-stage.ts +1016 -0
  184. package/src/gjc-runtime/deep-interview-state.ts +12 -943
  185. package/src/gjc-runtime/gc-render.ts +1 -0
  186. package/src/gjc-runtime/gc-runtime.ts +11 -1
  187. package/src/gjc-runtime/launch-tmux.ts +25 -6
  188. package/src/gjc-runtime/managed-owner-admission.ts +1 -1
  189. package/src/gjc-runtime/memory-guard-owner-claims.ts +389 -0
  190. package/src/gjc-runtime/ralplan-runtime.ts +1149 -98
  191. package/src/gjc-runtime/state-runtime.ts +2 -1
  192. package/src/gjc-runtime/state-writer.ts +70 -222
  193. package/src/gjc-runtime/team-launch.ts +42 -5
  194. package/src/gjc-runtime/team-runtime.ts +1085 -40
  195. package/src/gjc-runtime/team-store.ts +32 -0
  196. package/src/gjc-runtime/team-worker-heartbeat.ts +149 -0
  197. package/src/gjc-runtime/team-worker-memory-guard.ts +363 -0
  198. package/src/gjc-runtime/team-workers.ts +1 -0
  199. package/src/gjc-runtime/tmux-owner-isolation.ts +28 -0
  200. package/src/gjc-runtime/tmux-sessions.ts +58 -13
  201. package/src/gjc-runtime/ultragoal-receipt-freshness.ts +20 -0
  202. package/src/gjc-runtime/ultragoal-runtime.ts +414 -618
  203. package/src/gjc-runtime/workflow-manifest.generated.json +105 -449
  204. package/src/gjc-runtime/workflow-manifest.ts +38 -247
  205. package/src/hooks/native-skill-hook.ts +17 -4
  206. package/src/hooks/skill-state.ts +1 -23
  207. package/src/internal-urls/docs-index.generated.ts +21 -22
  208. package/src/internal-urls/local-root-gc.ts +127 -0
  209. package/src/main.ts +9 -5
  210. package/src/memories/index.ts +10 -0
  211. package/src/modes/DESIGN.md +98 -0
  212. package/src/modes/acp/acp-agent.ts +339 -191
  213. package/src/modes/acp/acp-event-mapper.ts +14 -7
  214. package/src/modes/acp/acp-mode.ts +39 -3
  215. package/src/modes/components/assistant-message.ts +123 -22
  216. package/src/modes/components/gjc-bundle-settings.ts +508 -0
  217. package/src/modes/components/irc-sidebar.ts +176 -62
  218. package/src/modes/components/model-selector.ts +61 -4
  219. package/src/modes/components/notifications-settings-editor.ts +12 -1
  220. package/src/modes/components/oauth-selector.ts +96 -28
  221. package/src/modes/components/read-tool-group.ts +82 -14
  222. package/src/modes/components/session-observer-overlay.ts +457 -83
  223. package/src/modes/components/settings-selector.ts +116 -23
  224. package/src/modes/components/status-line/gh.ts +16 -0
  225. package/src/modes/components/tool-execution.ts +138 -27
  226. package/src/modes/components/tool-status-header.ts +3 -14
  227. package/src/modes/components/transcript-viewer-overlay.ts +99 -24
  228. package/src/modes/controllers/command-controller.ts +4 -0
  229. package/src/modes/controllers/event-controller.ts +109 -27
  230. package/src/modes/controllers/extension-ui-controller.ts +26 -2
  231. package/src/modes/controllers/input-controller.ts +18 -3
  232. package/src/modes/controllers/selector-controller.ts +127 -36
  233. package/src/modes/interactive-mode.ts +62 -3
  234. package/src/modes/irc-observation-ledger.ts +71 -15
  235. package/src/modes/runtime-init.ts +22 -2
  236. package/src/modes/types.ts +2 -0
  237. package/src/modes/utils/ui-helpers.ts +94 -1
  238. package/src/prompts/agent-fragments/ralplan-persistence.md +4 -3
  239. package/src/prompts/agents/architect.md +9 -1
  240. package/src/prompts/agents/critic.md +9 -0
  241. package/src/prompts/system/eager-todo.md +8 -4
  242. package/src/prompts/system/system-prompt.md +11 -5
  243. package/src/prompts/tools/bash.md +5 -5
  244. package/src/prompts/tools/read.md +4 -2
  245. package/src/prompts/tools/search-tool-bm25.md +5 -0
  246. package/src/prompts/tools/task.md +1 -1
  247. package/src/reminders/star-reminder.ts +4 -42
  248. package/src/runtime-mcp/manager.ts +19 -4
  249. package/src/runtime-mcp/smithery-auth.ts +17 -2
  250. package/src/runtime-mcp/smithery-connect.ts +11 -1
  251. package/src/sdk/acp/adapter.ts +22 -6
  252. package/src/sdk/broker/lifecycle.ts +25 -6
  253. package/src/sdk/broker/transport.ts +35 -3
  254. package/src/sdk/bus/attachment-registry.ts +5 -1
  255. package/src/sdk/bus/chat-daemon-cli.ts +4 -39
  256. package/src/sdk/bus/chat-daemon-control.ts +6 -3
  257. package/src/sdk/bus/config.ts +18 -2
  258. package/src/sdk/bus/control-drain-lease.ts +104 -0
  259. package/src/sdk/bus/index.ts +984 -146
  260. package/src/sdk/bus/kind-aware-reconciliation.ts +317 -0
  261. package/src/sdk/bus/lifecycle-commands.ts +4 -1
  262. package/src/sdk/bus/lifecycle-control-runtime.ts +403 -88
  263. package/src/sdk/bus/prompt-reconciliation.ts +2 -1
  264. package/src/sdk/bus/reconciliation-store.ts +303 -0
  265. package/src/sdk/bus/rich-draft.ts +1 -1
  266. package/src/sdk/bus/rich-render.ts +2 -2
  267. package/src/sdk/bus/telegram-adoption-intent.ts +574 -0
  268. package/src/sdk/bus/telegram-cli.ts +33 -8
  269. package/src/sdk/bus/telegram-daemon-cli.ts +1 -0
  270. package/src/sdk/bus/telegram-daemon-contract.ts +11 -4
  271. package/src/sdk/bus/telegram-daemon.ts +916 -23
  272. package/src/sdk/bus/telegram-reference.ts +40 -3
  273. package/src/sdk/bus/threaded-render.ts +48 -3
  274. package/src/sdk/bus/topic-registry.ts +20 -0
  275. package/src/sdk/host/control/dispatch.ts +5 -1
  276. package/src/sdk/host/control/operations.ts +1 -1
  277. package/src/sdk/host/host.ts +23 -1
  278. package/src/sdk/host/query/handlers.ts +55 -0
  279. package/src/sdk/host/query/revision-store.ts +36 -2
  280. package/src/sdk/host/reverse-leases.ts +44 -7
  281. package/src/sdk/mcp/server.ts +46 -18
  282. package/src/sdk/prompt-status.ts +16 -3
  283. package/src/sdk/protocol/operation-inventory.generated.json +51 -0
  284. package/src/sdk/protocol/operation-registry.ts +7 -2
  285. package/src/sdk/session.ts +101 -10
  286. package/src/session/agent-session.ts +1286 -220
  287. package/src/session/artifacts.ts +22 -0
  288. package/src/session/auth-broker-config.ts +10 -3
  289. package/src/session/blob-store.ts +915 -24
  290. package/src/session/internal/managed-session-scope.ts +44 -6
  291. package/src/session/internal/managed-session-storage.ts +48 -6
  292. package/src/session/memory-guard-checkpoint-participant.ts +131 -0
  293. package/src/session/session-manager.ts +2364 -438
  294. package/src/session/session-storage.ts +9 -1
  295. package/src/session/streaming-output.ts +500 -111
  296. package/src/setup/credential-import.ts +75 -13
  297. package/src/setup/provider-onboarding.ts +19 -4
  298. package/src/skill-state/active-state.ts +32 -10
  299. package/src/skill-state/workflow-hud.ts +42 -2
  300. package/src/skill-state/workflow-mutation-guard.ts +560 -8
  301. package/src/task/executor.ts +122 -39
  302. package/src/task/index.ts +23 -14
  303. package/src/task/provider-retry-status.ts +16 -0
  304. package/src/task/receipt.ts +23 -7
  305. package/src/task/render.ts +6 -2
  306. package/src/task/types.ts +108 -0
  307. package/src/tools/ask-answer-registry.ts +12 -6
  308. package/src/tools/ask.ts +169 -118
  309. package/src/tools/ast-edit.ts +1 -0
  310. package/src/tools/ast-grep.ts +1 -0
  311. package/src/tools/bash-interactive.ts +8 -3
  312. package/src/tools/bash.ts +503 -60
  313. package/src/tools/browser/launch.ts +41 -6
  314. package/src/tools/fetch.ts +114 -23
  315. package/src/tools/find.ts +1 -0
  316. package/src/tools/image-gen.ts +29 -5
  317. package/src/tools/index.ts +4 -0
  318. package/src/tools/output-meta.ts +281 -20
  319. package/src/tools/path-utils.ts +8 -3
  320. package/src/tools/read-internals.ts +44 -0
  321. package/src/tools/read.ts +1560 -310
  322. package/src/tools/resource-gc.ts +182 -18
  323. package/src/tools/review.ts +5 -7
  324. package/src/tools/search.ts +1 -0
  325. package/src/tools/subagent-render.ts +6 -2
  326. package/src/tools/subagent.ts +6 -0
  327. package/src/tools/telegram-send.ts +6 -3
  328. package/src/tools/tool-result.ts +14 -1
  329. package/src/utils/gh.ts +39 -0
  330. package/src/utils/image-resize.ts +3 -0
  331. package/src/web/search/providers/anthropic.ts +4 -4
  332. package/src/web/search/providers/codex.ts +1 -1
  333. package/src/web/search/providers/kimi.ts +15 -5
  334. package/src/web/search/providers/searxng.ts +47 -4
  335. package/src/web/search/providers/xai.ts +7 -2
  336. package/dist/types/gjc-runtime/deep-interview-draft.d.ts +0 -8
  337. package/dist/types/gjc-runtime/deep-interview-payload.d.ts +0 -41
  338. package/dist/types/gjc-runtime/deep-interview-repair.d.ts +0 -17
  339. package/dist/types/gjc-runtime/ultragoal-pipeline.d.ts +0 -23
  340. package/src/defaults/gjc/skills/ultragoal/pipeline-validation-contracts.md +0 -30
  341. package/src/gjc-runtime/deep-interview-draft.ts +0 -843
  342. package/src/gjc-runtime/deep-interview-payload.ts +0 -262
  343. package/src/gjc-runtime/deep-interview-repair.ts +0 -1674
  344. package/src/gjc-runtime/ultragoal-pipeline.ts +0 -306
@@ -14,6 +14,7 @@ const BROKER_OPERATIONS = new Set([
14
14
  "session.resume",
15
15
  "session.close",
16
16
  "session.delete",
17
+ "broker.shutdown",
17
18
  ]);
18
19
  type RequestInput = Record<string, unknown>;
19
20
  type BrokerRequest = {
@@ -32,8 +33,15 @@ function tokenMatches(expected: string, actual: string | null): boolean {
32
33
  function isInput(value: unknown): value is RequestInput {
33
34
  return typeof value === "object" && value !== null && !Array.isArray(value);
34
35
  }
35
- function send(socket: ServerWebSocket<unknown>, frame: Record<string, unknown>): void {
36
- socket.send(JSON.stringify(frame));
36
+ function send(socket: ServerWebSocket<unknown>, frame: Record<string, unknown>): number {
37
+ return socket.send(JSON.stringify(frame));
38
+ }
39
+
40
+ export type BrokerShutdownSendAction = "dropped" | "wait_for_drain" | "close";
41
+
42
+ export function brokerShutdownSendAction(status: number): BrokerShutdownSendAction {
43
+ if (status === 0) return "dropped";
44
+ return status < 0 ? "wait_for_drain" : "close";
37
45
  }
38
46
  function sendError(socket: ServerWebSocket<unknown>, id: string | undefined, code: string, message: string): void {
39
47
  send(socket, { type: "broker_response", ...(id === undefined ? {} : { id }), ok: false, error: { code, message } });
@@ -45,6 +53,8 @@ export class BrokerTransport {
45
53
  readonly #requestedPort: number;
46
54
  #server: Bun.Server<undefined> | null = null;
47
55
  #port = 0;
56
+ readonly #shutdownBackpressured = new WeakSet<ServerWebSocket<unknown>>();
57
+ #shutdownRequested = false;
48
58
  constructor(broker: Broker, token: string, port = 0) {
49
59
  this.#broker = broker;
50
60
  this.#token = token;
@@ -71,8 +81,13 @@ export class BrokerTransport {
71
81
  },
72
82
  websocket: {
73
83
  maxPayloadLength: MAX_BROKER_JSON_FRAME_BYTES * 2,
74
- open: socket => send(socket, { type: "broker_hello", protocolVersion: PROTOCOL_VERSION }),
84
+ open: socket => {
85
+ send(socket, { type: "broker_hello", protocolVersion: PROTOCOL_VERSION });
86
+ },
75
87
  message: (socket, message) => void this.#handleMessage(socket, message),
88
+ drain: socket => {
89
+ if (this.#shutdownBackpressured.delete(socket)) this.#scheduleStopAfterShutdownResponse();
90
+ },
76
91
  },
77
92
  });
78
93
  this.#port = this.#server.port ?? 0;
@@ -84,6 +99,10 @@ export class BrokerTransport {
84
99
  if (server) await server.stop(true);
85
100
  }
86
101
  async #handleMessage(socket: ServerWebSocket<unknown>, raw: string | Buffer): Promise<void> {
102
+ if (this.#shutdownRequested) {
103
+ sendError(socket, undefined, "unavailable", "broker is shutting down");
104
+ return;
105
+ }
87
106
  if (Buffer.byteLength(raw) > MAX_BROKER_JSON_FRAME_BYTES) {
88
107
  sendError(socket, undefined, "payload_too_large", "broker JSON frame exceeds 4 MiB limit");
89
108
  return;
@@ -115,6 +134,16 @@ export class BrokerTransport {
115
134
  sendError(socket, frame.id, "invalid_input", "idempotencyKey must be a string");
116
135
  return;
117
136
  }
137
+ if (frame.operation === "broker.shutdown") {
138
+ const action = brokerShutdownSendAction(
139
+ send(socket, { type: "broker_response", id: frame.id, ok: true, result: { accepted: true } }),
140
+ );
141
+ if (action === "dropped") return;
142
+ this.#shutdownRequested = true;
143
+ if (action === "wait_for_drain") this.#shutdownBackpressured.add(socket);
144
+ else this.#scheduleStopAfterShutdownResponse();
145
+ return;
146
+ }
118
147
  try {
119
148
  const result = await this.#broker.handleRequest(frame.operation, frame.input, frame.idempotencyKey);
120
149
  send(socket, { type: "broker_response", id: frame.id, ...result });
@@ -122,4 +151,7 @@ export class BrokerTransport {
122
151
  sendError(socket, frame.id, "unavailable", "broker request failed");
123
152
  }
124
153
  }
154
+ #scheduleStopAfterShutdownResponse(): void {
155
+ setTimeout(() => void this.#broker.stop(), 25);
156
+ }
125
157
  }
@@ -5,7 +5,11 @@
5
5
  */
6
6
 
7
7
  /** Delivers a local file to the session's Telegram chat. */
8
- export type TelegramFileSink = (file: { path: string; caption?: string }) => Promise<{ ok: boolean; error?: string }>;
8
+ export type TelegramFileSink = (file: {
9
+ path: string;
10
+ caption?: string;
11
+ mime?: string;
12
+ }) => Promise<{ ok: boolean; error?: string }>;
9
13
 
10
14
  const sinks = new Map<string, TelegramFileSink>();
11
15
 
@@ -60,27 +60,10 @@ async function loadConfig(agentDir: string, kind: ChatDaemonKind): Promise<ChatD
60
60
  const config = notificationConfigFromFile(loaded.value);
61
61
  if (!config.enabled) return undefined;
62
62
  if (kind === "discord") {
63
- if (
64
- !isDiscordConfigured({
65
- ...config,
66
- sessionScope: "all",
67
- idleTimeoutMs: 60_000,
68
- rich: { enabled: true },
69
- richDraft: { enabled: false },
70
- toolActivity: { enabled: false },
71
- topics: { nameTemplate: undefined },
72
- btw: { enabled: true },
73
- streaming: { enabled: true },
74
- })
75
- ) {
63
+ if (!isDiscordConfigured(config)) {
76
64
  throw new Error("Discord notifications are enabled but configuration is incomplete");
77
65
  }
78
- const discord = config.discord as {
79
- botToken: string;
80
- applicationId: string;
81
- guildId: string;
82
- parentChannelId: string;
83
- };
66
+ const discord = config.discord;
84
67
  const { botToken, applicationId, guildId, parentChannelId } = discord;
85
68
  const identity = crypto
86
69
  .createHash("sha256")
@@ -95,28 +78,10 @@ async function loadConfig(agentDir: string, kind: ChatDaemonKind): Promise<ChatD
95
78
  presentation: { redact: config.redact, verbosity: config.verbosity },
96
79
  };
97
80
  }
98
- if (
99
- !isSlackConfigured({
100
- ...config,
101
- sessionScope: "all",
102
- idleTimeoutMs: 60_000,
103
- rich: { enabled: true },
104
- richDraft: { enabled: false },
105
- toolActivity: { enabled: false },
106
- topics: { nameTemplate: undefined },
107
- btw: { enabled: true },
108
- streaming: { enabled: true },
109
- })
110
- ) {
81
+ if (!isSlackConfigured(config)) {
111
82
  throw new Error("Slack notifications are enabled but configuration is incomplete");
112
83
  }
113
- const slack = config.slack as {
114
- botToken: string;
115
- appToken: string;
116
- workspaceId: string;
117
- channelId: string;
118
- authorizedUserId?: string;
119
- };
84
+ const slack = config.slack;
120
85
  const { botToken, appToken, workspaceId, channelId, authorizedUserId } = slack;
121
86
  const identity = crypto
122
87
  .createHash("sha256")
@@ -35,11 +35,14 @@ export type ChatDaemonAction = "stop" | "reload";
35
35
  * when deleting an observed owner-lock lease. Generation 12 refreshes retained
36
36
  * native path and process authority semantics. Generation 13 rejects special
37
37
  * files before retained native authority opens. Generation 14 reloads shared
38
- * chat daemons after notification configuration parsing changes.
38
+ * chat daemons after notification configuration parsing changes. Generation 15
39
+ * applies the current notification configuration directly when starting chat
40
+ * daemon transports. Generation 16 applies Telegram sound-policy configuration
41
+ * through shared notification parsing.
39
42
  */
40
43
  export const CHAT_DAEMON_GENERATIONS: Readonly<Record<ChatDaemonKind, number>> = {
41
- discord: 14,
42
- slack: 14,
44
+ discord: 16,
45
+ slack: 16,
43
46
  };
44
47
 
45
48
  export function chatDaemonGeneration(kind: ChatDaemonKind): number {
@@ -55,6 +55,7 @@ export interface NotificationSettingsSnapshot {
55
55
  botToken?: string;
56
56
  chatId?: string;
57
57
  activation?: Record<string, unknown>;
58
+ sound: "all" | "important" | "none";
58
59
  btw: {
59
60
  enabled: boolean;
60
61
  };
@@ -160,6 +161,11 @@ export function parseNotificationSettingsSnapshot(rawConfig?: unknown): Notifica
160
161
  botToken: notificationSettingsString(telegram.botToken),
161
162
  chatId: notificationSettingsString(telegram.chatId),
162
163
  ...(Object.keys(activation).length === 0 ? {} : { activation }),
164
+ sound: notificationSettingsChoice<"all" | "important" | "none">(telegram.sound, "all", [
165
+ "all",
166
+ "important",
167
+ "none",
168
+ ]),
163
169
  btw: {
164
170
  enabled: notificationSettingsBoolean(btw.enabled, true),
165
171
  },
@@ -228,6 +234,7 @@ export interface NotificationConfig {
228
234
  * (those carrying {@link SPAWN_PROVENANCE_ENV}) unless they explicitly opt in.
229
235
  */
230
236
  sessionScope: "all" | "primary";
237
+ sound: "all" | "important" | "none";
231
238
  idleTimeoutMs: number;
232
239
  btw: {
233
240
  enabled: boolean;
@@ -270,6 +277,7 @@ export function getNotificationConfig(settings: NotificationSettingsReader): Not
270
277
  verbosity: snapshot.verbosity,
271
278
  sessionScope: snapshot.sessionScope,
272
279
  idleTimeoutMs: snapshot.idleTimeoutMs,
280
+ sound: snapshot.telegram.sound,
273
281
  rich: snapshot.telegram.rich,
274
282
  btw: snapshot.telegram.btw,
275
283
  richDraft: snapshot.telegram.richDraft,
@@ -358,7 +366,10 @@ export function isTelegramConfigured(
358
366
  }
359
367
 
360
368
  /** Is Discord configured with all credentials and routing identifiers required by its daemon. */
361
- export function isDiscordConfigured(cfg: NotificationConfig): cfg is NotificationConfig & {
369
+ export function isDiscordConfigured(cfg: Pick<NotificationConfig, "enabled" | "discord">): cfg is Pick<
370
+ NotificationConfig,
371
+ "enabled"
372
+ > & {
362
373
  discord: { botToken: string; applicationId: string; guildId: string; parentChannelId: string };
363
374
  } {
364
375
  return (
@@ -371,7 +382,10 @@ export function isDiscordConfigured(cfg: NotificationConfig): cfg is Notificatio
371
382
  }
372
383
 
373
384
  /** Is Slack configured with both SDK tokens and its workspace/channel routing identifiers. */
374
- export function isSlackConfigured(cfg: NotificationConfig): cfg is NotificationConfig & {
385
+ export function isSlackConfigured(cfg: Pick<NotificationConfig, "enabled" | "slack">): cfg is Pick<
386
+ NotificationConfig,
387
+ "enabled"
388
+ > & {
375
389
  slack: { botToken: string; appToken: string; workspaceId: string; channelId: string };
376
390
  } {
377
391
  return (
@@ -539,6 +553,8 @@ export interface RedactableAction {
539
553
  workflowGateId?: string;
540
554
  question?: string;
541
555
  options?: string[];
556
+ /** Selected zero-based option positions for transport-specific multi-select rendering. */
557
+ selectedOptionIndices?: number[];
542
558
  summary?: string;
543
559
  /** Optional zero-based recommendation into the authoritative raw options. */
544
560
  recommendedIndex?: number;
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Ordering seam for an in-band SDK identity transition.
3
+ *
4
+ * A request arrives through predecessor A, so a successful terminal response cannot
5
+ * be published until successor B is ready. Native builds may provide a true
6
+ * send-only connection lease; source/dev builds use the conservative fallback in
7
+ * which the predecessor server remains alive until the terminal write completes.
8
+ */
9
+
10
+ export type TerminalSendOutcome = "written" | "disconnected" | "write_failed";
11
+
12
+ /** Fence/capability hooks may return false to reject; undefined means ok. */
13
+ export type IdentityControlGateResult = boolean | undefined;
14
+ export type IdentityControlGate = () => IdentityControlGateResult | Promise<IdentityControlGateResult>;
15
+
16
+ export interface IdentityControlSuccessPathInput {
17
+ /** Fence predecessor inbound work. The fence must not close its response writer. */
18
+ fence: IdentityControlGate;
19
+ /** Optional explicit proof that the predecessor writer is still usable. */
20
+ ensurePredecessorSendCapable?: IdentityControlGate;
21
+ /** Start successor B and resolve only after its public endpoint is ready. */
22
+ startSuccessor: () => Promise<void>;
23
+ /** Write and flush either the success or non-success terminal response. */
24
+ sendTerminal: () => Promise<TerminalSendOutcome>;
25
+ /** Release predecessor A after the terminal response has settled. */
26
+ stopPredecessor: () => Promise<void>;
27
+ /** Set only when a caller cannot use the retained-writer fallback. */
28
+ requireNativeControlDrain?: boolean;
29
+ }
30
+
31
+ export interface IdentityControlTerminalPathInput {
32
+ fenceInbound: IdentityControlGate;
33
+ ensurePredecessorSendCapable?: IdentityControlGate;
34
+ startSuccessorReady: () => Promise<void>;
35
+ sendTerminal: () => Promise<TerminalSendOutcome>;
36
+ stopPredecessor: () => Promise<void>;
37
+ requireNativeControlDrain?: boolean;
38
+ }
39
+
40
+ /**
41
+ * Probe the loaded native addon, never an environment flag or a TypeScript shim.
42
+ * Older/source installs intentionally report false so callers can select the
43
+ * retained-writer fallback or fail closed when detach is mandatory.
44
+ */
45
+ export function isNativeControlDrainAvailable(): boolean {
46
+ try {
47
+ // Keep the addon lazy: importing the bus must continue to work without a
48
+ // compiled native artifact (tests and source distributions do that often).
49
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
50
+ const natives = require("@gajae-code/natives") as {
51
+ NotificationServer?: {
52
+ prototype?: Record<string, unknown>;
53
+ };
54
+ };
55
+ const prototype = natives.NotificationServer?.prototype;
56
+ return (
57
+ typeof prototype?.acquireControlDrain === "function" &&
58
+ typeof prototype?.sendTerminalAndWait === "function" &&
59
+ typeof prototype?.closeControlDrain === "function"
60
+ );
61
+ } catch {
62
+ return false;
63
+ }
64
+ }
65
+
66
+ /**
67
+ * Run the only safe ordering for a successful identity-control response.
68
+ *
69
+ * The `finally` is deliberately around both successor startup and terminal
70
+ * delivery: a failed startup must not leave the fenced predecessor alive, and a
71
+ * failed/disconnected terminal write must still release it. When native detach
72
+ * is unavailable the caller is expected to keep A's server up (not call
73
+ * `stopAndWait`) until `sendTerminal` settles.
74
+ */
75
+ export async function runIdentityControlSuccessPath(
76
+ input: IdentityControlSuccessPathInput,
77
+ ): Promise<TerminalSendOutcome> {
78
+ if (input.requireNativeControlDrain && !isNativeControlDrainAvailable())
79
+ throw new Error("SDK identity control requires the native control-drain lease.");
80
+
81
+ if ((await input.fence()) === false) throw new Error("SDK identity control predecessor fence was not acquired.");
82
+ if ((await input.ensurePredecessorSendCapable?.()) === false)
83
+ throw new Error("SDK identity control predecessor writer is not send-capable.");
84
+ try {
85
+ await input.startSuccessor();
86
+ return await input.sendTerminal();
87
+ } finally {
88
+ await input.stopPredecessor();
89
+ }
90
+ }
91
+
92
+ /** Compatibility spelling used by the host wiring design notes. */
93
+ export async function runIdentityControlTerminalPath(
94
+ input: IdentityControlTerminalPathInput,
95
+ ): Promise<TerminalSendOutcome> {
96
+ return runIdentityControlSuccessPath({
97
+ fence: input.fenceInbound,
98
+ ensurePredecessorSendCapable: input.ensurePredecessorSendCapable,
99
+ startSuccessor: input.startSuccessorReady,
100
+ sendTerminal: input.sendTerminal,
101
+ stopPredecessor: input.stopPredecessor,
102
+ requireNativeControlDrain: input.requireNativeControlDrain,
103
+ });
104
+ }