@gajae-code/coding-agent 0.11.0 → 0.11.2

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 (418) hide show
  1. package/CHANGELOG.md +63 -1
  2. package/dist/types/async/job-manager.d.ts +46 -7
  3. package/dist/types/cli/config-cli.d.ts +11 -1
  4. package/dist/types/cli/notify-cli.d.ts +1 -0
  5. package/dist/types/cli/session-picker.d.ts +2 -1
  6. package/dist/types/cli/setup-cli.d.ts +1 -1
  7. package/dist/types/commands/mcp-serve.d.ts +33 -0
  8. package/dist/types/commands/mcp.d.ts +1 -1
  9. package/dist/types/commands/notify.d.ts +0 -2
  10. package/dist/types/commands/sdk.d.ts +1 -1
  11. package/dist/types/config/atomic-yaml-patch.d.ts +18 -0
  12. package/dist/types/config/file-lock.d.ts +14 -4
  13. package/dist/types/config/keybindings.d.ts +42 -1
  14. package/dist/types/config/model-auth.d.ts +3 -0
  15. package/dist/types/config/model-bindings-applier.d.ts +13 -0
  16. package/dist/types/config/model-discovery-manager.d.ts +49 -0
  17. package/dist/types/config/model-equivalence.d.ts +20 -0
  18. package/dist/types/config/model-registry.d.ts +16 -15
  19. package/dist/types/config/model-resolver.d.ts +28 -18
  20. package/dist/types/config/models-config-schema.d.ts +11 -0
  21. package/dist/types/config/settings-schema.d.ts +56 -1
  22. package/dist/types/config/settings.d.ts +14 -11
  23. package/dist/types/coordinator-mcp/policy.d.ts +5 -0
  24. package/dist/types/coordinator-mcp/question-gate-codec.d.ts +129 -0
  25. package/dist/types/coordinator-mcp/question-state.d.ts +356 -0
  26. package/dist/types/coordinator-mcp/server.d.ts +4 -0
  27. package/dist/types/discovery/helpers.d.ts +0 -6
  28. package/dist/types/edit/index.d.ts +3 -0
  29. package/dist/types/eval/py/env.d.ts +9 -0
  30. package/dist/types/extensibility/extensions/loader.d.ts +2 -1
  31. package/dist/types/extensibility/extensions/runner.d.ts +2 -2
  32. package/dist/types/extensibility/extensions/types.d.ts +34 -3
  33. package/dist/types/extensibility/hooks/runner.d.ts +1 -1
  34. package/dist/types/extensibility/shared-events.d.ts +2 -0
  35. package/dist/types/gjc-runtime/deep-interview-recorder.d.ts +10 -1
  36. package/dist/types/gjc-runtime/deep-interview-state.d.ts +44 -0
  37. package/dist/types/gjc-runtime/goal-mode-request.d.ts +11 -1
  38. package/dist/types/gjc-runtime/launch-worktree.d.ts +4 -2
  39. package/dist/types/gjc-runtime/linux-proc.d.ts +29 -0
  40. package/dist/types/gjc-runtime/session-resolution.d.ts +2 -2
  41. package/dist/types/gjc-runtime/state-migrations.d.ts +1 -1
  42. package/dist/types/gjc-runtime/state-writer.d.ts +2 -1
  43. package/dist/types/gjc-runtime/team-launch.d.ts +59 -0
  44. package/dist/types/gjc-runtime/team-notify.d.ts +45 -0
  45. package/dist/types/gjc-runtime/team-runtime.d.ts +29 -121
  46. package/dist/types/gjc-runtime/team-store.d.ts +160 -0
  47. package/dist/types/gjc-runtime/team-workers.d.ts +78 -0
  48. package/dist/types/gjc-runtime/tmux-owner-isolation.d.ts +8 -0
  49. package/dist/types/gjc-runtime/ultragoal-change-set.d.ts +13 -0
  50. package/dist/types/gjc-runtime/ultragoal-evidence.d.ts +38 -0
  51. package/dist/types/gjc-runtime/ultragoal-guard.d.ts +7 -0
  52. package/dist/types/gjc-runtime/ultragoal-pipeline.d.ts +23 -0
  53. package/dist/types/gjc-runtime/ultragoal-receipt-freshness.d.ts +11 -0
  54. package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +55 -33
  55. package/dist/types/gjc-runtime/workflow-cli-common.d.ts +8 -0
  56. package/dist/types/gjc-runtime/workflow-manifest.d.ts +3 -0
  57. package/dist/types/goals/continuation-timeout-guard.d.ts +22 -0
  58. package/dist/types/goals/runtime.d.ts +1 -0
  59. package/dist/types/goals/state.d.ts +8 -0
  60. package/dist/types/harness-control-plane/lifecycle-reconciliation.d.ts +17 -0
  61. package/dist/types/harness-control-plane/phase-rollup.d.ts +4 -7
  62. package/dist/types/harness-control-plane/receipt-ingest.d.ts +5 -0
  63. package/dist/types/harness-control-plane/receipt-spool.d.ts +4 -0
  64. package/dist/types/hindsight/state.d.ts +11 -4
  65. package/dist/types/lsp/lspmux.d.ts +5 -3
  66. package/dist/types/lsp/path-trust.d.ts +1 -0
  67. package/dist/types/main.d.ts +3 -2
  68. package/dist/types/memories/storage.d.ts +1 -0
  69. package/dist/types/modes/action-registry.d.ts +29 -0
  70. package/dist/types/modes/components/chrome.d.ts +14 -0
  71. package/dist/types/modes/components/command-palette.d.ts +27 -0
  72. package/dist/types/modes/components/custom-provider-wizard.d.ts +1 -0
  73. package/dist/types/modes/components/index.d.ts +2 -1
  74. package/dist/types/modes/components/pet-selector.d.ts +1 -1
  75. package/dist/types/modes/components/plan-preview-overlay.d.ts +43 -0
  76. package/dist/types/modes/components/queue-mode-selector.d.ts +1 -1
  77. package/dist/types/modes/components/queue-pane.d.ts +12 -0
  78. package/dist/types/modes/components/read-tool-group.d.ts +6 -0
  79. package/dist/types/modes/components/session-observer-overlay.d.ts +3 -4
  80. package/dist/types/modes/components/sessions-dashboard.d.ts +32 -0
  81. package/dist/types/modes/components/settings-selector.d.ts +1 -1
  82. package/dist/types/modes/components/show-images-selector.d.ts +1 -1
  83. package/dist/types/modes/components/status-line/types.d.ts +1 -1
  84. package/dist/types/modes/components/status-line.d.ts +1 -94
  85. package/dist/types/modes/components/tasks-pane.d.ts +15 -0
  86. package/dist/types/modes/components/theme-selector.d.ts +1 -1
  87. package/dist/types/modes/components/tool-execution.d.ts +15 -0
  88. package/dist/types/modes/components/tool-status-header.d.ts +111 -0
  89. package/dist/types/modes/components/transcript-viewer-overlay.d.ts +42 -0
  90. package/dist/types/modes/controllers/command-controller.d.ts +2 -2
  91. package/dist/types/modes/controllers/extension-ui-controller.d.ts +1 -0
  92. package/dist/types/modes/controllers/goal-mode-controller.d.ts +62 -0
  93. package/dist/types/modes/controllers/input-controller.d.ts +8 -1
  94. package/dist/types/modes/controllers/mode-gate.d.ts +8 -0
  95. package/dist/types/modes/controllers/plan-mode-controller.d.ts +65 -0
  96. package/dist/types/modes/controllers/selector-controller.d.ts +15 -3
  97. package/dist/types/modes/controllers/stt-controller.d.ts +26 -0
  98. package/dist/types/modes/interactive-mode.d.ts +21 -19
  99. package/dist/types/modes/jobs-observer.d.ts +2 -0
  100. package/dist/types/modes/shared/agent-wire/deep-interview-gate.d.ts +4 -11
  101. package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +21 -2
  102. package/dist/types/modes/shared/agent-wire/workflow-gate-types.d.ts +31 -0
  103. package/dist/types/modes/tasks-aggregator.d.ts +39 -0
  104. package/dist/types/modes/transcript-item-registry.d.ts +60 -0
  105. package/dist/types/modes/types.d.ts +22 -15
  106. package/dist/types/modes/utils/ui-helpers.d.ts +2 -2
  107. package/dist/types/runtime-mcp/manager.d.ts +1 -1
  108. package/dist/types/sdk/broker/broker.d.ts +78 -12
  109. package/dist/types/sdk/broker/ensure.d.ts +9 -0
  110. package/dist/types/sdk/broker/lifecycle-codec.d.ts +4 -0
  111. package/dist/types/sdk/broker/lifecycle-ledger.d.ts +15 -1
  112. package/dist/types/sdk/broker/lifecycle.d.ts +6 -2
  113. package/dist/types/sdk/broker/process-incarnation.d.ts +2 -0
  114. package/dist/types/sdk/broker/session-index.d.ts +0 -1
  115. package/dist/types/sdk/broker/state-version.d.ts +2 -0
  116. package/dist/types/sdk/bus/chat-effect-journal.d.ts +1 -0
  117. package/dist/types/sdk/bus/config-commands.d.ts +1 -1
  118. package/dist/types/sdk/bus/config.d.ts +11 -0
  119. package/dist/types/sdk/bus/daemon-paths.d.ts +1 -0
  120. package/dist/types/sdk/bus/discord-daemon.d.ts +5 -0
  121. package/dist/types/sdk/bus/html-format.d.ts +3 -2
  122. package/dist/types/sdk/bus/index.d.ts +27 -0
  123. package/dist/types/sdk/bus/lifecycle-control-runtime.d.ts +4 -0
  124. package/dist/types/sdk/bus/notification-service.d.ts +20 -0
  125. package/dist/types/sdk/bus/rate-limit-pool.d.ts +13 -2
  126. package/dist/types/sdk/bus/recent-activity.d.ts +21 -12
  127. package/dist/types/sdk/bus/rich-document.d.ts +7 -0
  128. package/dist/types/sdk/bus/rich-render.d.ts +18 -41
  129. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +9 -4
  130. package/dist/types/sdk/bus/telegram-daemon.d.ts +69 -3
  131. package/dist/types/sdk/bus/threaded-inbound.d.ts +1 -1
  132. package/dist/types/sdk/bus/threaded-render.d.ts +13 -0
  133. package/dist/types/sdk/bus/topic-registry.d.ts +24 -2
  134. package/dist/types/sdk/host/control/operations.d.ts +1 -1
  135. package/dist/types/sdk/host/host.d.ts +2 -0
  136. package/dist/types/sdk/index.d.ts +1 -0
  137. package/dist/types/sdk/session-directory.d.ts +56 -0
  138. package/dist/types/session/agent-session.d.ts +82 -47
  139. package/dist/types/session/agent-storage.d.ts +7 -0
  140. package/dist/types/session/fallback-chain-controller.d.ts +10 -2
  141. package/dist/types/session/internal/managed-session-scope.d.ts +102 -0
  142. package/dist/types/session/internal/managed-session-storage.d.ts +38 -0
  143. package/dist/types/session/messages.d.ts +16 -0
  144. package/dist/types/session/session-manager-internal.d.ts +14 -0
  145. package/dist/types/session/session-manager.d.ts +82 -12
  146. package/dist/types/session/session-storage.d.ts +43 -3
  147. package/dist/types/session/volatile-context-pruning.d.ts +15 -0
  148. package/dist/types/skill-state/{deep-interview-mutation-guard.d.ts → workflow-mutation-guard.d.ts} +24 -8
  149. package/dist/types/skill-state/workflow-state-contract.d.ts +1 -3
  150. package/dist/types/slash-commands/builtin-registry.d.ts +4 -1
  151. package/dist/types/system-prompt.d.ts +2 -11
  152. package/dist/types/task/executor.d.ts +3 -1
  153. package/dist/types/thinking.d.ts +7 -0
  154. package/dist/types/tool-discovery/tool-index.d.ts +1 -50
  155. package/dist/types/tools/ask.d.ts +64 -2
  156. package/dist/types/tools/bash.d.ts +3 -0
  157. package/dist/types/tools/browser/dead-tab-recovery.d.ts +24 -0
  158. package/dist/types/tools/browser/tab-supervisor.d.ts +21 -0
  159. package/dist/types/tools/cron.d.ts +2 -0
  160. package/dist/types/tools/fetch.d.ts +1 -0
  161. package/dist/types/tools/index.d.ts +30 -15
  162. package/dist/types/tools/output-meta.d.ts +1 -0
  163. package/dist/types/tools/read.d.ts +3 -0
  164. package/dist/types/tools/search-tool-bm25.d.ts +3 -4
  165. package/dist/types/tools/subagent-render.d.ts +1 -0
  166. package/dist/types/tools/subagent.d.ts +6 -1
  167. package/dist/types/utils/event-bus.d.ts +1 -1
  168. package/dist/types/web/search/index.d.ts +3 -1
  169. package/package.json +21 -9
  170. package/scripts/build-sdk-package-smoke.ts +39 -1
  171. package/scripts/generate-hotkeys-docs.ts +74 -0
  172. package/scripts/generate-sdk-operation-inventory.ts +64 -20
  173. package/scripts/verify-gjc-sdk-canonicalization.ts +182 -2
  174. package/src/async/job-manager.ts +455 -69
  175. package/src/cli/config-cli.ts +75 -2
  176. package/src/cli/notify-cli.ts +92 -26
  177. package/src/cli/session-picker.ts +20 -3
  178. package/src/cli/setup-cli.ts +1 -1
  179. package/src/cli.ts +1 -1
  180. package/src/commands/config.ts +1 -1
  181. package/src/commands/harness.ts +34 -106
  182. package/src/commands/launch.ts +6 -4
  183. package/src/commands/mcp-serve.ts +85 -8
  184. package/src/commands/mcp.ts +2 -2
  185. package/src/commands/notify.ts +8 -4
  186. package/src/commands/sdk.ts +61 -40
  187. package/src/commands/ultragoal.ts +4 -1
  188. package/src/config/atomic-yaml-patch.ts +80 -13
  189. package/src/config/file-lock.ts +105 -43
  190. package/src/config/keybindings.ts +64 -20
  191. package/src/config/model-auth.ts +9 -0
  192. package/src/config/model-bindings-applier.ts +139 -0
  193. package/src/config/model-discovery-manager.ts +224 -0
  194. package/src/config/model-equivalence.ts +66 -0
  195. package/src/config/model-registry.ts +169 -302
  196. package/src/config/model-resolver.ts +361 -369
  197. package/src/config/models-config-schema.ts +5 -4
  198. package/src/config/settings-schema.ts +159 -2
  199. package/src/config/settings.ts +458 -482
  200. package/src/coordinator-mcp/policy.ts +76 -11
  201. package/src/coordinator-mcp/question-gate-codec.ts +274 -0
  202. package/src/coordinator-mcp/question-state.ts +778 -0
  203. package/src/coordinator-mcp/server.ts +1702 -238
  204. package/src/debug/index.ts +1 -1
  205. package/src/defaults/gjc/skills/deep-interview/SKILL.md +13 -1
  206. package/src/defaults/gjc/skills/team/SKILL.md +16 -0
  207. package/src/discovery/helpers.ts +1 -50
  208. package/src/edit/index.ts +64 -0
  209. package/src/eval/py/env.ts +26 -0
  210. package/src/eval/py/kernel.ts +5 -3
  211. package/src/extensibility/extensions/loader.ts +9 -1
  212. package/src/extensibility/extensions/runner.ts +12 -3
  213. package/src/extensibility/extensions/types.ts +39 -1
  214. package/src/extensibility/gjc-plugins/installer.ts +16 -16
  215. package/src/extensibility/hooks/runner.ts +2 -2
  216. package/src/extensibility/runtime-skill-discovery.ts +33 -13
  217. package/src/extensibility/shared-events.ts +2 -0
  218. package/src/gjc-runtime/deep-interview-recorder.ts +63 -3
  219. package/src/gjc-runtime/deep-interview-runtime.ts +76 -27
  220. package/src/gjc-runtime/deep-interview-state.ts +317 -5
  221. package/src/gjc-runtime/goal-mode-request.ts +55 -8
  222. package/src/gjc-runtime/launch-tmux.ts +2 -5
  223. package/src/gjc-runtime/launch-worktree.ts +5 -5
  224. package/src/gjc-runtime/linux-proc.ts +71 -0
  225. package/src/gjc-runtime/ralplan-runtime.ts +74 -90
  226. package/src/gjc-runtime/session-resolution.ts +18 -3
  227. package/src/gjc-runtime/session-state-sidecar.ts +6 -107
  228. package/src/gjc-runtime/state-migrations.ts +1 -1
  229. package/src/gjc-runtime/state-runtime.ts +320 -249
  230. package/src/gjc-runtime/state-writer.ts +36 -40
  231. package/src/gjc-runtime/team-launch.ts +319 -0
  232. package/src/gjc-runtime/team-notify.ts +326 -0
  233. package/src/gjc-runtime/team-runtime.ts +1099 -1482
  234. package/src/gjc-runtime/team-store.ts +828 -0
  235. package/src/gjc-runtime/team-workers.ts +962 -0
  236. package/src/gjc-runtime/tmux-owner-isolation-cli.ts +2 -11
  237. package/src/gjc-runtime/tmux-owner-isolation.ts +14 -9
  238. package/src/gjc-runtime/tmux-sessions.ts +4 -21
  239. package/src/gjc-runtime/ultragoal-change-set.ts +172 -0
  240. package/src/gjc-runtime/ultragoal-evidence.ts +874 -0
  241. package/src/gjc-runtime/ultragoal-guard.ts +83 -12
  242. package/src/gjc-runtime/ultragoal-pipeline.ts +306 -0
  243. package/src/gjc-runtime/ultragoal-receipt-freshness.ts +102 -1
  244. package/src/gjc-runtime/ultragoal-runtime.ts +156 -1319
  245. package/src/gjc-runtime/workflow-cli-common.ts +30 -0
  246. package/src/gjc-runtime/workflow-manifest.generated.json +58 -0
  247. package/src/gjc-runtime/workflow-manifest.ts +18 -0
  248. package/src/goals/continuation-timeout-guard.ts +79 -0
  249. package/src/goals/runtime.ts +7 -5
  250. package/src/goals/state.ts +18 -0
  251. package/src/harness-control-plane/lifecycle-reconciliation.ts +64 -0
  252. package/src/harness-control-plane/phase-rollup.ts +4 -7
  253. package/src/harness-control-plane/receipt-ingest.ts +5 -0
  254. package/src/harness-control-plane/receipt-spool.ts +51 -7
  255. package/src/harness-control-plane/session-lease.ts +12 -130
  256. package/src/hindsight/backend.ts +26 -27
  257. package/src/hindsight/state.ts +101 -32
  258. package/src/hooks/skill-state.ts +17 -11
  259. package/src/internal-urls/docs-index.generated.ts +21 -18
  260. package/src/lsp/client.ts +1 -1
  261. package/src/lsp/config.ts +145 -26
  262. package/src/lsp/index.ts +1 -1
  263. package/src/lsp/lspmux.ts +39 -10
  264. package/src/lsp/path-trust.ts +81 -0
  265. package/src/main.ts +28 -8
  266. package/src/memories/index.ts +1 -0
  267. package/src/memories/storage.ts +6 -2
  268. package/src/modes/action-registry.ts +165 -0
  269. package/src/modes/components/chrome.ts +40 -0
  270. package/src/modes/components/command-palette.ts +168 -0
  271. package/src/modes/components/custom-editor.ts +1 -1
  272. package/src/modes/components/custom-provider-wizard.ts +51 -14
  273. package/src/modes/components/index.ts +2 -1
  274. package/src/modes/components/pet-selector.ts +11 -17
  275. package/src/modes/components/plan-preview-overlay.ts +295 -0
  276. package/src/modes/components/queue-mode-selector.ts +10 -27
  277. package/src/modes/components/queue-pane.ts +79 -0
  278. package/src/modes/components/read-tool-group.ts +13 -0
  279. package/src/modes/components/session-observer-overlay.ts +207 -772
  280. package/src/modes/components/sessions-dashboard.ts +181 -0
  281. package/src/modes/components/settings-selector.ts +1 -1
  282. package/src/modes/components/show-images-selector.ts +10 -24
  283. package/src/modes/components/status-line/types.ts +1 -1
  284. package/src/modes/components/status-line.ts +1 -969
  285. package/src/modes/components/tasks-pane.ts +73 -0
  286. package/src/modes/components/theme-selector.ts +11 -31
  287. package/src/modes/components/tool-execution.ts +22 -0
  288. package/src/modes/components/tool-status-header.ts +1056 -0
  289. package/src/modes/components/transcript-viewer-overlay.ts +384 -0
  290. package/src/modes/controllers/btw-controller.ts +1 -0
  291. package/src/modes/controllers/command-controller.ts +9 -15
  292. package/src/modes/controllers/event-controller.ts +3 -2
  293. package/src/modes/controllers/extension-ui-controller.ts +72 -25
  294. package/src/modes/controllers/goal-mode-controller.ts +474 -0
  295. package/src/modes/controllers/input-controller.ts +764 -229
  296. package/src/modes/controllers/mode-gate.ts +24 -0
  297. package/src/modes/controllers/plan-mode-controller.ts +517 -0
  298. package/src/modes/controllers/selector-controller.ts +225 -10
  299. package/src/modes/controllers/stt-controller.ts +125 -0
  300. package/src/modes/interactive-mode.ts +302 -1151
  301. package/src/modes/jobs-observer.ts +3 -0
  302. package/src/modes/runtime-init.ts +8 -0
  303. package/src/modes/shared/agent-wire/deep-interview-gate.ts +31 -106
  304. package/src/modes/shared/agent-wire/workflow-gate-broker.ts +78 -19
  305. package/src/modes/shared/agent-wire/workflow-gate-types.ts +177 -0
  306. package/src/modes/tasks-aggregator.ts +199 -0
  307. package/src/modes/transcript-item-registry.ts +229 -0
  308. package/src/modes/types.ts +47 -20
  309. package/src/modes/utils/ui-helpers.ts +17 -9
  310. package/src/prompts/agent-fragments/ralplan-persistence.md +6 -0
  311. package/src/prompts/agent-fragments/restricted-bash.md +1 -0
  312. package/src/prompts/agents/architect.md +2 -8
  313. package/src/prompts/agents/critic.md +2 -8
  314. package/src/prompts/agents/executor.md +3 -0
  315. package/src/prompts/agents/planner.md +4 -12
  316. package/src/prompts/system/custom-system-prompt.md +1 -23
  317. package/src/prompts/system/plan-mode-approved.md +8 -0
  318. package/src/prompts/system/system-prompt.md +17 -96
  319. package/src/prompts/tools/bash.md +4 -4
  320. package/src/prompts/tools/browser.md +15 -52
  321. package/src/prompts/tools/find.md +2 -2
  322. package/src/prompts/tools/hashline.md +13 -55
  323. package/src/prompts/tools/read.md +3 -6
  324. package/src/prompts/tools/search-tool-bm25.md +0 -2
  325. package/src/prompts/tools/search.md +2 -4
  326. package/src/prompts/tools/skill-discovery.md +1 -2
  327. package/src/prompts/tools/task.md +1 -1
  328. package/src/runtime-mcp/manager.ts +1 -1
  329. package/src/sdk/broker/broker.ts +206 -78
  330. package/src/sdk/broker/discovery.ts +21 -2
  331. package/src/sdk/broker/ensure.ts +85 -25
  332. package/src/sdk/broker/lifecycle-codec.ts +11 -0
  333. package/src/sdk/broker/lifecycle-ledger.ts +371 -74
  334. package/src/sdk/broker/lifecycle.ts +1399 -142
  335. package/src/sdk/broker/process-incarnation.ts +5 -13
  336. package/src/sdk/broker/session-index.ts +145 -56
  337. package/src/sdk/broker/state-version.ts +21 -0
  338. package/src/sdk/broker/transport.ts +1 -1
  339. package/src/sdk/bus/chat-daemon-cli.ts +2 -0
  340. package/src/sdk/bus/chat-daemon-control.ts +8 -28
  341. package/src/sdk/bus/chat-effect-journal.ts +14 -4
  342. package/src/sdk/bus/config-commands.ts +5 -4
  343. package/src/sdk/bus/config.ts +98 -0
  344. package/src/sdk/bus/conversation-store.ts +5 -29
  345. package/src/sdk/bus/daemon-paths.ts +2 -0
  346. package/src/sdk/bus/discord-daemon.ts +25 -8
  347. package/src/sdk/bus/html-format.ts +20 -3
  348. package/src/sdk/bus/index.ts +834 -113
  349. package/src/sdk/bus/lifecycle-control-runtime.ts +91 -33
  350. package/src/sdk/bus/native-runtime-compatibility.ts +1 -1
  351. package/src/sdk/bus/natives-augment.d.ts +26 -1
  352. package/src/sdk/bus/notification-service.ts +168 -20
  353. package/src/sdk/bus/rate-limit-pool.ts +58 -14
  354. package/src/sdk/bus/recent-activity.ts +188 -74
  355. package/src/sdk/bus/rich-document.ts +258 -0
  356. package/src/sdk/bus/rich-render.ts +62 -70
  357. package/src/sdk/bus/telegram-daemon-cli.ts +15 -59
  358. package/src/sdk/bus/telegram-daemon-contract.ts +9 -4
  359. package/src/sdk/bus/telegram-daemon.ts +1491 -247
  360. package/src/sdk/bus/threaded-inbound.ts +8 -3
  361. package/src/sdk/bus/threaded-render.ts +57 -1
  362. package/src/sdk/bus/topic-registry.ts +120 -13
  363. package/src/sdk/host/control/dispatch.ts +14 -2
  364. package/src/sdk/host/control/operations.ts +6 -1
  365. package/src/sdk/host/host.ts +31 -1
  366. package/src/sdk/host/query/handlers.ts +20 -22
  367. package/src/sdk/host/query/revision-store.ts +80 -57
  368. package/src/sdk/index.ts +1 -0
  369. package/src/sdk/protocol/operation-inventory.generated.json +943 -1907
  370. package/src/sdk/session-directory.ts +141 -0
  371. package/src/sdk/session.ts +458 -479
  372. package/src/session/agent-session.ts +1901 -637
  373. package/src/session/agent-storage.ts +18 -0
  374. package/src/session/cache-economics.ts +25 -8
  375. package/src/session/fallback-chain-controller.ts +53 -3
  376. package/src/session/internal/managed-session-scope.ts +2226 -0
  377. package/src/session/internal/managed-session-storage.ts +453 -0
  378. package/src/session/messages.ts +91 -2
  379. package/src/session/session-manager-internal.ts +33 -0
  380. package/src/session/session-manager.ts +1112 -333
  381. package/src/session/session-storage.ts +444 -39
  382. package/src/session/volatile-context-pruning.ts +78 -0
  383. package/src/setup/credential-auto-import.ts +2 -1
  384. package/src/setup/hermes/templates/operator-instructions.v1.md +1 -1
  385. package/src/setup/provider-onboarding.ts +36 -61
  386. package/src/setup/provider-presets.json +5 -0
  387. package/src/skill-state/active-state.ts +3 -13
  388. package/src/skill-state/{deep-interview-mutation-guard.ts → workflow-mutation-guard.ts} +47 -29
  389. package/src/skill-state/workflow-state-contract.ts +6 -41
  390. package/src/slash-commands/builtin-registry.ts +46 -11
  391. package/src/system-prompt.ts +37 -44
  392. package/src/task/agents.ts +19 -1
  393. package/src/task/executor.ts +90 -6
  394. package/src/task/index.ts +62 -37
  395. package/src/thinking.ts +21 -6
  396. package/src/tool-discovery/tool-index.ts +2 -134
  397. package/src/tools/ask.ts +157 -21
  398. package/src/tools/ast-edit.ts +1 -1
  399. package/src/tools/bash.ts +38 -0
  400. package/src/tools/browser/dead-tab-recovery.ts +78 -0
  401. package/src/tools/browser/tab-supervisor.ts +282 -36
  402. package/src/tools/computer.ts +10 -3
  403. package/src/tools/cron.ts +30 -16
  404. package/src/tools/eval.ts +1 -2
  405. package/src/tools/fetch.ts +11 -4
  406. package/src/tools/index.ts +76 -24
  407. package/src/tools/output-meta.ts +13 -5
  408. package/src/tools/read.ts +37 -1
  409. package/src/tools/resource-gc.ts +2 -2
  410. package/src/tools/search-tool-bm25.ts +11 -74
  411. package/src/tools/subagent-render.ts +19 -8
  412. package/src/tools/subagent.ts +84 -32
  413. package/src/utils/event-bus.ts +9 -4
  414. package/src/web/search/index.ts +3 -3
  415. package/dist/types/discovery/plugin-dir-roots.d.ts +0 -15
  416. package/dist/types/runtime-mcp/discoverable-tool-metadata.d.ts +0 -7
  417. package/src/discovery/plugin-dir-roots.ts +0 -28
  418. package/src/runtime-mcp/discoverable-tool-metadata.ts +0 -25
@@ -0,0 +1,199 @@
1
+ import type { AsyncJob, AsyncJobManager, SubagentRecord } from "../async/job-manager";
2
+ import type { CronJobView, JobsObserver } from "./jobs-observer";
3
+ import type { ObservableSession, SessionObserverRegistry } from "./session-observer-registry";
4
+
5
+ export type TaskStatus = "running" | "waiting" | "done" | "failed" | "cancelled";
6
+ export type TaskKind = "bash" | "subagent" | "cron";
7
+
8
+ export interface TaskRow {
9
+ id: string;
10
+ kind: TaskKind;
11
+ label: string;
12
+ status: TaskStatus;
13
+ startedAt: number;
14
+ resumable?: boolean;
15
+ monitorOutputLines?: number;
16
+ }
17
+
18
+ export interface TasksSnapshot {
19
+ rows: TaskRow[];
20
+ worstState: TaskStatus | "none";
21
+ failedUnacknowledged: boolean;
22
+ }
23
+
24
+ export const EMPTY_TASKS_SNAPSHOT: TasksSnapshot = { rows: [], worstState: "none", failedUnacknowledged: false };
25
+
26
+ const ASYNC_STATUS: Record<AsyncJob["status"], TaskStatus> = {
27
+ running: "running",
28
+ paused: "waiting",
29
+ completed: "done",
30
+ failed: "failed",
31
+ cancelled: "cancelled",
32
+ };
33
+ const SESSION_STATUS: Record<ObservableSession["status"], TaskStatus> = {
34
+ active: "running",
35
+ completed: "done",
36
+ failed: "failed",
37
+ aborted: "cancelled",
38
+ };
39
+ const SUBAGENT_STATUS: Record<SubagentRecord["status"], TaskStatus> = {
40
+ running: "running",
41
+ queued: "waiting",
42
+ paused: "waiting",
43
+ completed: "done",
44
+ failed: "failed",
45
+ cancelled: "cancelled",
46
+ };
47
+ const STATUS_RANK: Record<TaskStatus, number> = { done: 1, cancelled: 2, waiting: 3, running: 4, failed: 5 };
48
+
49
+ const MAX_TERMINAL_HISTORY_ROWS = 100;
50
+
51
+ export function mapAsyncJobStatus(status: AsyncJob["status"]): TaskStatus {
52
+ return ASYNC_STATUS[status];
53
+ }
54
+
55
+ export function mapSessionStatus(status: ObservableSession["status"]): TaskStatus {
56
+ return SESSION_STATUS[status];
57
+ }
58
+
59
+ export function mapSubagentStatus(status: SubagentRecord["status"]): TaskStatus {
60
+ return SUBAGENT_STATUS[status];
61
+ }
62
+
63
+ export function mapCronStatus(cron: Pick<CronJobView, "firing">): TaskStatus {
64
+ return cron.firing ? "running" : "waiting";
65
+ }
66
+
67
+ /** Joins manager jobs, monitor/cron views, and live session metadata. Stable
68
+ * subagent records are canonical for lifecycle state; the registry contributes
69
+ * only the current display label and timestamp. */
70
+ export class TasksAggregator {
71
+ readonly #listeners = new Set<() => void>();
72
+ readonly #unsubscribers: Array<() => void> = [];
73
+ #snapshot: TasksSnapshot = EMPTY_TASKS_SNAPSHOT;
74
+ #scheduled = false;
75
+ #disposed = false;
76
+
77
+ constructor(
78
+ readonly manager: AsyncJobManager,
79
+ readonly jobsObserver: JobsObserver,
80
+ readonly sessions: SessionObserverRegistry,
81
+ readonly ownerId?: string,
82
+ ) {
83
+ this.#unsubscribers.push(manager.onChange(() => this.#changed()));
84
+ this.#unsubscribers.push(jobsObserver.onChange(() => this.#changed()));
85
+ this.#unsubscribers.push(sessions.onChange(() => this.#changed()));
86
+ this.#recompute();
87
+ }
88
+
89
+ onChange(cb: () => void): () => void {
90
+ this.#listeners.add(cb);
91
+ return () => this.#listeners.delete(cb);
92
+ }
93
+
94
+ getSnapshot(): TasksSnapshot {
95
+ return this.#snapshot;
96
+ }
97
+
98
+ acknowledgeFailures(): void {
99
+ this.jobsObserver.acknowledgeFailures();
100
+ this.#recompute();
101
+ }
102
+
103
+ #changed(): void {
104
+ if (this.#disposed) return;
105
+ this.#recompute();
106
+ if (this.#scheduled) return;
107
+ this.#scheduled = true;
108
+ queueMicrotask(() => {
109
+ this.#scheduled = false;
110
+ if (!this.#disposed) for (const listener of this.#listeners) listener();
111
+ });
112
+ }
113
+
114
+ #recompute(): void {
115
+ const rows: TaskRow[] = [];
116
+ const filter = this.ownerId ? { ownerId: this.ownerId } : undefined;
117
+ const jobs = this.manager.getAllJobs(filter);
118
+ const monitorIds = new Set(this.jobsObserver.getSnapshot().monitors.map(monitor => monitor.id));
119
+ for (const job of jobs) {
120
+ // A subagent task is represented by its stable control-plane record.
121
+ if (job.metadata?.subagent) continue;
122
+ if (job.type !== "bash") continue;
123
+ rows.push({
124
+ id: `bash:${job.id}`,
125
+ kind: "bash",
126
+ label: job.label,
127
+ status: ASYNC_STATUS[job.status],
128
+ startedAt: job.startTime,
129
+ monitorOutputLines: monitorIds.has(job.id)
130
+ ? lineCount(this.jobsObserver.getMonitorOutput(job.id))
131
+ : undefined,
132
+ });
133
+ }
134
+
135
+ const records = new Map(this.manager.getSubagentRecords(filter).map(record => [record.subagentId, record]));
136
+ const liveIds = new Set<string>();
137
+ for (const session of this.sessions.getSessions()) {
138
+ if (session.kind !== "subagent") continue;
139
+ liveIds.add(session.id);
140
+ const record = records.get(session.id);
141
+ rows.push({
142
+ id: `subagent:${session.id}`,
143
+ kind: "subagent",
144
+ label: session.label,
145
+ status: record ? SUBAGENT_STATUS[record.status] : SESSION_STATUS[session.status],
146
+ startedAt: session.lastUpdate,
147
+ resumable: record?.resumable,
148
+ });
149
+ }
150
+ for (const record of records.values()) {
151
+ if (liveIds.has(record.subagentId)) continue;
152
+ rows.push({
153
+ id: `subagent:${record.subagentId}`,
154
+ kind: "subagent",
155
+ label: record.subagentId,
156
+ status: SUBAGENT_STATUS[record.status],
157
+ startedAt: record.queued?.createdAt ?? 0,
158
+ resumable: record.resumable,
159
+ });
160
+ }
161
+ for (const cron of this.jobsObserver.getSnapshot().crons) rows.push(cronRow(cron));
162
+ rows.sort((a, b) => b.startedAt - a.startedAt || a.id.localeCompare(b.id));
163
+ let terminalRows = 0;
164
+ const boundedRows = rows.filter(row => {
165
+ if (row.status !== "done" && row.status !== "failed" && row.status !== "cancelled") return true;
166
+ terminalRows++;
167
+ return terminalRows <= MAX_TERMINAL_HISTORY_ROWS;
168
+ });
169
+ const failedUnacknowledged = this.jobsObserver.getSnapshot().failedUnacknowledged;
170
+ const worstState = failedUnacknowledged
171
+ ? "failed"
172
+ : boundedRows.reduce<TasksSnapshot["worstState"]>(
173
+ (worst, row) => (worst === "none" || STATUS_RANK[row.status] > STATUS_RANK[worst] ? row.status : worst),
174
+ "none",
175
+ );
176
+ this.#snapshot = { rows: boundedRows, worstState, failedUnacknowledged };
177
+ }
178
+
179
+ dispose(): void {
180
+ this.#disposed = true;
181
+ for (const unsubscribe of this.#unsubscribers) unsubscribe();
182
+ this.#unsubscribers.length = 0;
183
+ this.#listeners.clear();
184
+ }
185
+ }
186
+
187
+ function cronRow(cron: CronJobView): TaskRow {
188
+ return {
189
+ id: `cron:${cron.id}`,
190
+ kind: "cron",
191
+ label: cron.humanSchedule,
192
+ status: cron.firing ? "running" : "waiting",
193
+ startedAt: cron.createdAt,
194
+ };
195
+ }
196
+
197
+ function lineCount(output: string): number {
198
+ return output.length === 0 ? 0 : output.split("\n").length;
199
+ }
@@ -0,0 +1,229 @@
1
+ export type TranscriptItemKind = "user" | "assistant-text" | "assistant-thinking" | "tool" | "read-group" | "custom";
2
+
3
+ export type TranscriptItemCapabilities = {
4
+ copyable: boolean;
5
+ foldable: boolean;
6
+ rawViewable: boolean;
7
+ };
8
+
9
+ export type TranscriptSourcePayload = {
10
+ text: string;
11
+ metadata: Readonly<Record<string, unknown>>;
12
+ source: unknown;
13
+ };
14
+
15
+ export type TranscriptItem = {
16
+ id: string;
17
+ kind: TranscriptItemKind;
18
+ source: unknown;
19
+ getPayload?: (source: unknown) => TranscriptSourcePayload;
20
+ capabilities?: Partial<TranscriptItemCapabilities>;
21
+ };
22
+
23
+ export type RegisterTranscriptItem = Omit<TranscriptItem, "id"> & { id?: string };
24
+
25
+ export type StreamingItemOptions = Omit<RegisterTranscriptItem, "id" | "kind"> & {
26
+ promptGeneration: number | string;
27
+ messageOrdinal: number;
28
+ kind?: "assistant-text" | "assistant-thinking";
29
+ };
30
+
31
+ const DEFAULT_CAPABILITIES: Record<TranscriptItemKind, TranscriptItemCapabilities> = {
32
+ user: { copyable: true, foldable: false, rawViewable: true },
33
+ "assistant-text": { copyable: true, foldable: false, rawViewable: true },
34
+ "assistant-thinking": { copyable: true, foldable: true, rawViewable: true },
35
+ tool: { copyable: true, foldable: true, rawViewable: true },
36
+ "read-group": { copyable: true, foldable: true, rawViewable: true },
37
+ custom: { copyable: true, foldable: false, rawViewable: true },
38
+ };
39
+
40
+ /** Stable transcript identities shared by the inline and overlay projections. */
41
+ export const transcriptItemId = {
42
+ entry: (entryId: string): string => `entry:${entryId}`,
43
+ assistantContent: (entryId: string, contentIndex: number): string => `entry:${entryId}:content:${contentIndex}`,
44
+ tool: (toolCallId: string): string => `tool:${toolCallId}`,
45
+ readGroup: (groupId: string): string => `read-group:${groupId}`,
46
+ custom: (customId: string): string => `custom:${customId}`,
47
+ stream: (promptGeneration: number | string, messageOrdinal: number): string =>
48
+ `stream:${promptGeneration}:${messageOrdinal}`,
49
+ };
50
+
51
+ function defaultPayload(source: unknown): TranscriptSourcePayload {
52
+ if (typeof source === "string") return { text: source, metadata: {}, source };
53
+ if (!source || typeof source !== "object") return { text: "", metadata: {}, source };
54
+
55
+ const record = source as Record<string, unknown>;
56
+ const text = typeof record.text === "string" ? record.text : extractContentText(record.content);
57
+ const metadata = Object.fromEntries(Object.entries(record).filter(([key]) => key !== "text" && key !== "content"));
58
+ return { text, metadata, source };
59
+ }
60
+
61
+ function extractContentText(content: unknown): string {
62
+ if (typeof content === "string") return content;
63
+ if (!Array.isArray(content)) return "";
64
+ return content
65
+ .map(item => {
66
+ if (!item || typeof item !== "object") return "";
67
+ const record = item as Record<string, unknown>;
68
+ if (typeof record.text === "string") return record.text;
69
+ if (typeof record.thinking === "string") return record.thinking;
70
+ return "";
71
+ })
72
+ .join("");
73
+ }
74
+
75
+ /**
76
+ * A session-local index of transcript projection items. It deliberately stores only
77
+ * structural sources, allowing interactive mode to supply live streaming objects
78
+ * and persisted session records without importing either implementation here.
79
+ */
80
+ export class TranscriptItemRegistry {
81
+ #items = new Map<string, TranscriptItem>();
82
+ #aliases = new Map<string, string>();
83
+ #sessionId: string | undefined;
84
+
85
+ get sessionId(): string | undefined {
86
+ return this.#sessionId;
87
+ }
88
+
89
+ /** Ordered snapshot for read-only transcript projections. */
90
+ items(): readonly TranscriptItem[] {
91
+ return [...this.#items.values()];
92
+ }
93
+
94
+ register(item: RegisterTranscriptItem): string {
95
+ const id = item.id ?? this.#idForKind(item.kind, item.source);
96
+ if (this.#items.has(id)) throw new Error(`Transcript item already registered: ${id}`);
97
+ this.#items.set(id, { ...item, id });
98
+ return id;
99
+ }
100
+
101
+ replace(id: string, item: Omit<TranscriptItem, "id">): boolean {
102
+ const canonicalId = this.#resolveId(id);
103
+ if (!canonicalId || !this.#items.has(canonicalId)) return false;
104
+ this.#items.set(canonicalId, { ...item, id: canonicalId });
105
+ return true;
106
+ }
107
+
108
+ startStream(options: StreamingItemOptions): string {
109
+ const id = transcriptItemId.stream(options.promptGeneration, options.messageOrdinal);
110
+ if (this.#items.has(id) || this.#aliases.has(id)) throw new Error(`Transcript stream already registered: ${id}`);
111
+ this.#items.set(id, { ...options, id, kind: options.kind ?? "assistant-text" });
112
+ return id;
113
+ }
114
+
115
+ /** Reconciles one exact live stream with its persisted canonical item. */
116
+ endStream(streamId: string, item: RegisterTranscriptItem): string | undefined {
117
+ if (!streamId.startsWith("stream:") || !this.#items.has(streamId)) return undefined;
118
+ const canonicalId = item.id ?? this.#idForKind(item.kind, item.source);
119
+ if (canonicalId !== streamId && this.#items.has(canonicalId)) return undefined;
120
+ if (canonicalId === streamId) {
121
+ this.#items.set(streamId, { ...item, id: streamId });
122
+ return streamId;
123
+ }
124
+ this.#items.set(canonicalId, { ...item, id: canonicalId });
125
+ this.#items.delete(streamId);
126
+ this.#aliases.set(streamId, canonicalId);
127
+ return canonicalId;
128
+ }
129
+
130
+ retireStream(id: string): boolean {
131
+ if (!id.startsWith("stream:") || !this.#items.delete(id)) return false;
132
+ this.#aliases.delete(id);
133
+ return true;
134
+ }
135
+
136
+ coalesceReadGroup(groupId: string, source: unknown, toolCallIds: readonly string[] = []): string {
137
+ const id = transcriptItemId.readGroup(groupId);
138
+ this.#items.set(id, {
139
+ id,
140
+ kind: "read-group",
141
+ source,
142
+ getPayload: value => {
143
+ const payload = defaultPayload(value);
144
+ return { ...payload, metadata: { ...payload.metadata, groupId, toolCallIds } };
145
+ },
146
+ });
147
+ return id;
148
+ }
149
+
150
+ rebuild(items: readonly RegisterTranscriptItem[]): void {
151
+ this.#items.clear();
152
+ this.#aliases.clear();
153
+ for (const item of items) this.register(item);
154
+ }
155
+
156
+ evict(id: string): boolean {
157
+ const canonicalId = this.#resolveId(id);
158
+ if (!canonicalId || !this.#items.delete(canonicalId)) return false;
159
+ for (const [alias, target] of this.#aliases) {
160
+ if (target === canonicalId) this.#aliases.delete(alias);
161
+ }
162
+ return true;
163
+ }
164
+
165
+ switchSession(sessionId: string): void {
166
+ if (this.#sessionId === sessionId) return;
167
+ this.#sessionId = sessionId;
168
+ this.#items.clear();
169
+ this.#aliases.clear();
170
+ }
171
+
172
+ resolveSourcePayload(id: string): TranscriptSourcePayload | undefined {
173
+ const canonicalId = this.#resolveId(id);
174
+ const item = canonicalId ? this.#items.get(canonicalId) : undefined;
175
+ if (!item) return undefined;
176
+ return (item.getPayload ?? defaultPayload)(item.source);
177
+ }
178
+
179
+ capabilities(id: string): TranscriptItemCapabilities | undefined {
180
+ const canonicalId = this.#resolveId(id);
181
+ const item = canonicalId ? this.#items.get(canonicalId) : undefined;
182
+ if (!item) return undefined;
183
+ return { ...DEFAULT_CAPABILITIES[item.kind], ...item.capabilities };
184
+ }
185
+
186
+ has(id: string): boolean {
187
+ const canonicalId = this.#resolveId(id);
188
+ return canonicalId !== undefined && this.#items.has(canonicalId);
189
+ }
190
+
191
+ canonicalId(id: string): string | undefined {
192
+ return this.#resolveId(id);
193
+ }
194
+
195
+ #resolveId(id: string): string | undefined {
196
+ let resolved = id;
197
+ const seen = new Set<string>();
198
+ while (this.#aliases.has(resolved) && !seen.has(resolved)) {
199
+ seen.add(resolved);
200
+ resolved = this.#aliases.get(resolved)!;
201
+ }
202
+ return this.#items.has(resolved) ? resolved : undefined;
203
+ }
204
+
205
+ #idForKind(kind: TranscriptItemKind, source: unknown): string {
206
+ const record = source && typeof source === "object" ? (source as Record<string, unknown>) : {};
207
+ switch (kind) {
208
+ case "user":
209
+ if (typeof record.entryId === "string") return transcriptItemId.entry(record.entryId);
210
+ break;
211
+ case "assistant-text":
212
+ case "assistant-thinking":
213
+ if (typeof record.entryId === "string" && typeof record.contentIndex === "number") {
214
+ return transcriptItemId.assistantContent(record.entryId, record.contentIndex);
215
+ }
216
+ break;
217
+ case "tool":
218
+ if (typeof record.toolCallId === "string") return transcriptItemId.tool(record.toolCallId);
219
+ break;
220
+ case "read-group":
221
+ if (typeof record.groupId === "string") return transcriptItemId.readGroup(record.groupId);
222
+ break;
223
+ case "custom":
224
+ if (typeof record.id === "string") return transcriptItemId.custom(record.id);
225
+ break;
226
+ }
227
+ throw new Error(`Transcript item ${kind} requires an explicit id or canonical source identity.`);
228
+ }
229
+ }
@@ -1,7 +1,7 @@
1
1
  import type { AgentMessage } from "@gajae-code/agent-core";
2
2
  import type { CompactionOutcome } from "@gajae-code/agent-core/compaction";
3
3
  import type { AssistantMessage, ImageContent, Message, UsageReport } from "@gajae-code/ai";
4
- import type { Component, Container, EditorTheme, Loader, Spacer, Text, TUI } from "@gajae-code/tui";
4
+ import type { Component, Container, EditorTheme, Loader, SlashCommand, Spacer, Text, TUI } from "@gajae-code/tui";
5
5
  import type { KeybindingsManager } from "../config/keybindings";
6
6
  import type { Settings } from "../config/settings";
7
7
  import type {
@@ -12,7 +12,6 @@ import type {
12
12
  } from "../extensibility/extensions";
13
13
  import type { CompactOptions } from "../extensibility/extensions/types";
14
14
  import type { Skill } from "../extensibility/skills";
15
- import type { PlanApprovalDetails } from "../plan-mode/approved-plan";
16
15
  import type { MCPManager } from "../runtime-mcp";
17
16
  import type { NotificationSessionReconcileResult, NotificationSessionStatus } from "../sdk/bus/session-control";
18
17
  import type { AgentSession, AgentSessionEvent } from "../session/agent-session";
@@ -22,14 +21,15 @@ import type { CredentialAutoImportOptions } from "../setup/credential-auto-impor
22
21
  import type { LspStartupServerInfo } from "../tools";
23
22
  import type { AssistantMessageComponent } from "./components/assistant-message";
24
23
  import type { BashExecutionComponent } from "./components/bash-execution";
24
+ import type { CommandPaletteAction } from "./components/command-palette";
25
25
  import type { CustomEditor } from "./components/custom-editor";
26
26
  import type { EvalExecutionComponent } from "./components/eval-execution";
27
27
  import type { PetMode } from "./components/gajae-pet-widget";
28
28
  import type { HookEditorComponent } from "./components/hook-editor";
29
29
  import type { HookInputComponent } from "./components/hook-input";
30
30
  import type { HookSelectorComponent } from "./components/hook-selector";
31
- import type { StatusLineComponent } from "./components/status-line";
32
31
  import type { ToolExecutionHandle } from "./components/tool-execution";
32
+ import type { StatusLineComponent } from "./components/tool-status-header";
33
33
  import type { IrcObservationLedger } from "./irc-observation-ledger";
34
34
  import type { OAuthManualInputManager } from "./oauth-manual-input";
35
35
  import type { Theme } from "./theme/theme";
@@ -51,6 +51,17 @@ export type SubmittedUserInput = {
51
51
  started: boolean;
52
52
  };
53
53
 
54
+ export type ComposerSubmissionOptions = Readonly<{
55
+ ownsComposer: boolean;
56
+ editor: CustomEditor;
57
+ }>;
58
+
59
+ export function canApplyComposerSubmission(
60
+ options: ComposerSubmissionOptions | undefined,
61
+ editor: CustomEditor,
62
+ ): boolean {
63
+ return options === undefined || (options.ownsComposer && editor === options.editor);
64
+ }
54
65
  export type TodoStatus = "pending" | "in_progress" | "completed" | "abandoned";
55
66
 
56
67
  export type TodoItem = {
@@ -109,10 +120,6 @@ export interface InteractiveModeContext {
109
120
  isBashNoContext: boolean;
110
121
  toolOutputExpanded: boolean;
111
122
  todoExpanded: boolean;
112
- planModeEnabled: boolean;
113
- goalModeEnabled: boolean;
114
- goalModePaused: boolean;
115
- planModePlanFilePath?: string;
116
123
  hideThinkingBlock: boolean;
117
124
  pendingImages: ImageContent[];
118
125
  compactionQueuedMessages: CompactionQueuedMessage[];
@@ -174,10 +181,9 @@ export interface InteractiveModeContext {
174
181
  showNewVersionNotification(newVersion: string): void;
175
182
  clearEditor(): void;
176
183
  updatePendingMessagesDisplay(): void;
177
- queueCompactionMessage(text: string, mode: "steer" | "followUp"): void;
184
+ queueCompactionMessage(text: string, mode: "steer" | "followUp", options?: ComposerSubmissionOptions): void;
178
185
  flushCompactionQueue(options?: { willRetry?: boolean }): Promise<void>;
179
186
  flushPendingBashComponents(): void;
180
- flushPendingModelSwitch(): Promise<void>;
181
187
  setWorkingMessage(message?: string): void;
182
188
  applyPendingWorkingMessage(): void;
183
189
  ensureLoadingAnimation(): void;
@@ -196,12 +202,15 @@ export interface InteractiveModeContext {
196
202
  commitPetPreviewMode(mode: PetMode): boolean;
197
203
  /** Re-mount the composer (pet-aware) after an overlay/selector closes. */
198
204
  restoreComposer(): void;
199
- startPendingSubmission(input: {
200
- text: string;
201
- images?: ImageContent[];
202
- customType?: string;
203
- display?: boolean;
204
- }): SubmittedUserInput;
205
+ startPendingSubmission(
206
+ input: {
207
+ text: string;
208
+ images?: ImageContent[];
209
+ customType?: string;
210
+ display?: boolean;
211
+ },
212
+ options?: ComposerSubmissionOptions,
213
+ ): SubmittedUserInput;
205
214
  cancelPendingSubmission(): boolean;
206
215
  markPendingSubmissionStarted(input: SubmittedUserInput): boolean;
207
216
  finishPendingSubmission(input: SubmittedUserInput): void;
@@ -263,9 +272,9 @@ export interface InteractiveModeContext {
263
272
  handleContextCommand(): void;
264
273
  handleDumpCommand(): void;
265
274
  handleDebugTranscriptCommand(): Promise<void>;
266
- handleClearCommand(): Promise<void>;
275
+ handleClearCommand(): Promise<boolean>;
267
276
  handleContextClearCommand(): Promise<void>;
268
- handleDropCommand(): Promise<void>;
277
+ handleDropCommand(): Promise<boolean>;
269
278
  handleForkCommand(): Promise<void>;
270
279
  handleBashCommand(command: string, excludeFromContext?: boolean): Promise<void>;
271
280
  handlePythonCommand(code: string, excludeFromContext?: boolean): Promise<void>;
@@ -282,10 +291,18 @@ export interface InteractiveModeContext {
282
291
  customInstructionsOrOptions?: string | CompactOptions,
283
292
  isAuto?: boolean,
284
293
  ): Promise<CompactionOutcome>;
294
+
285
295
  openInBrowser(urlOrPath: string): void;
296
+ /** Resolved source of truth for slash autocomplete and command palette entries. */
297
+ getSlashCommands?(): readonly SlashCommand[];
286
298
  refreshSlashCommandState(cwd?: string): Promise<void>;
287
299
 
288
300
  // Selector handling
301
+ showCommandPalette(
302
+ commands: SlashCommand[],
303
+ actions: CommandPaletteAction[],
304
+ executeSlashCommand: (name: string) => Promise<void>,
305
+ ): void;
289
306
  showSettingsSelector(): void;
290
307
  showThemeSelector(): void;
291
308
  showPetSelector(): void;
@@ -299,6 +316,7 @@ export interface InteractiveModeContext {
299
316
  showUserMessageSelector(): void;
300
317
  showTreeSelector(): void;
301
318
  showSessionSelector(): void;
319
+ showSessionsDashboard(): void;
302
320
  handleResumeSession(sessionPath: string): Promise<void>;
303
321
  handleSessionDeleteCommand(): Promise<void>;
304
322
  showOAuthSelector(mode: "login" | "logout", providerId?: string, options?: OAuthSelectorOptions): Promise<void>;
@@ -306,6 +324,10 @@ export interface InteractiveModeContext {
306
324
  showDebugSelector(): void;
307
325
  showSessionObserver(): void;
308
326
  showJobsOverlay(): void;
327
+ showTasksPane(): void;
328
+ showTranscriptViewer(): void;
329
+ isTranscriptViewerOpen(): boolean;
330
+ refreshTranscriptViewer(): void;
309
331
  resetObserverRegistry(): void;
310
332
 
311
333
  // Input handling
@@ -325,9 +347,6 @@ export interface InteractiveModeContext {
325
347
  toggleThinkingBlockVisibility(): void;
326
348
  openExternalEditor(): void;
327
349
  registerExtensionShortcuts(): void;
328
- handlePlanModeCommand(initialPrompt?: string): Promise<void>;
329
- handleGoalModeCommand(rest?: string): Promise<void>;
330
- handlePlanApproval(details: PlanApprovalDetails): Promise<void>;
331
350
 
332
351
  // Hook UI methods
333
352
  initHooksAndCustomTools(): Promise<void>;
@@ -335,6 +354,14 @@ export interface InteractiveModeContext {
335
354
  reason: "start" | "switch" | "branch" | "tree" | "shutdown",
336
355
  previousSessionFile?: string,
337
356
  ): Promise<void>;
357
+ planModeController: Pick<
358
+ import("./controllers/plan-mode-controller").PlanModeController,
359
+ "enabled" | "paused" | "planFilePath" | "handleCommand" | "handleApproval" | "flushPendingModelSwitch"
360
+ >;
361
+ goalModeController: Pick<
362
+ import("./controllers/goal-mode-controller").GoalModeController,
363
+ "enabled" | "paused" | "handleCommand"
364
+ >;
338
365
  setHookWidget(key: string, content: ExtensionWidgetContent, options?: ExtensionWidgetOptions): void;
339
366
  setHookStatus(key: string, text: string | undefined): void;
340
367
  showHookSelector(
@@ -20,11 +20,13 @@ import { SkillMessageComponent } from "../../modes/components/skill-message";
20
20
  import { ToolExecutionComponent } from "../../modes/components/tool-execution";
21
21
  import { UserMessageComponent } from "../../modes/components/user-message";
22
22
  import { theme } from "../../modes/theme/theme";
23
- import type {
24
- CompactionQueuedMessage,
25
- InteractiveModeContext,
26
- IrcArrivalSnapshot,
27
- TranscriptRebuildPolicy,
23
+ import {
24
+ type CompactionQueuedMessage,
25
+ type ComposerSubmissionOptions,
26
+ canApplyComposerSubmission,
27
+ type InteractiveModeContext,
28
+ type IrcArrivalSnapshot,
29
+ type TranscriptRebuildPolicy,
28
30
  } from "../../modes/types";
29
31
  import {
30
32
  type CustomMessage,
@@ -290,7 +292,11 @@ export class UiHelpers {
290
292
  const semanticId = getSessionMessageViewportAnchorId(message);
291
293
  if (semanticId) return semanticId;
292
294
  const entryId = getSessionMessageEntryId(message);
293
- if (entryId) return `user:entry:${entryId}`;
295
+ if (entryId) {
296
+ const id = `user:entry:${entryId}`;
297
+ associateSessionMessageViewportAnchorId(message, id);
298
+ return id;
299
+ }
294
300
  const base = `user:local:${message.timestamp}:${stableSemanticIdPart(JSON.stringify(message.content))}`;
295
301
  const id = this.#viewportAnchorOccurrenceId(message, base);
296
302
  associateSessionMessageViewportAnchorId(message, id);
@@ -916,14 +922,16 @@ export class UiHelpers {
916
922
  }
917
923
  }
918
924
 
919
- queueCompactionMessage(text: string, mode: "steer" | "followUp"): void {
925
+ queueCompactionMessage(text: string, mode: "steer" | "followUp", options?: ComposerSubmissionOptions): void {
920
926
  const entry: CompactionQueuedMessage = { text, mode };
921
927
  if (mode === "followUp") {
922
928
  entry.followUpQueuePolicy = "sequential";
923
929
  }
924
930
  this.ctx.compactionQueuedMessages.push(entry);
925
- this.ctx.editor.addToHistory(text);
926
- this.ctx.editor.setText("");
931
+ if (canApplyComposerSubmission(options, this.ctx.editor)) {
932
+ this.ctx.editor.addToHistory(text);
933
+ this.ctx.editor.setText("");
934
+ }
927
935
  this.ctx.updatePendingMessagesDisplay();
928
936
  this.ctx.showStatus("Queued message for after compaction");
929
937
  }
@@ -0,0 +1,6 @@
1
+ Persistence (ralplan runs only):
2
+ - Only when the assignment references a ralplan stage or `stage_n`, persist the full artifact through:
3
+
4
+ gjc ralplan --write --stage {{stage}} --stage_n <N> --artifact-env GJC_RALPLAN_ARTIFACT --json
5
+
6
+ Use the assignment-provided `stage_n`; on a duplicate-write error retry with the incremented N. Return the write receipt (`run_id`, `path`, `sha256`, `stage`, `stage_n`) and the role's compact verdict only. Otherwise, do not call `gjc ralplan --write`; return the full result in `yield.result.data`.
@@ -0,0 +1 @@
1
+ - Exception: restricted `bash` is only for sanctioned GJC workflow persistence (`gjc ralplan --write ...`) and GJC workflow state commands (`gjc state ...`). Pass artifacts through `GJC_RALPLAN_ARTIFACT` with `--artifact-env GJC_RALPLAN_ARTIFACT`; never use bash for product-source writes or general shell work.
@@ -27,7 +27,7 @@ You may receive a forked parent-conversation snapshot as background. Your read-o
27
27
 
28
28
  <constraints>
29
29
  - Read-only: never write, edit, format, commit, push, or mutate files.
30
- - Exception: you may use restricted `bash` only for sanctioned GJC workflow CLI persistence (`gjc ralplan --write ...`) and GJC workflow state read/write/contract commands (`gjc state ...`). For `gjc ralplan --write`, pass review markdown through `GJC_RALPLAN_ARTIFACT` and `--artifact-env GJC_RALPLAN_ARTIFACT`, not as a file path. Do not use bash for product-source writes, direct handoffs, state clears, or general shell work.
30
+ {{restrictedBash}}
31
31
  - Never approve code or plans you have not grounded in inspected files.
32
32
  - Never give generic advice detached from this codebase.
33
33
  - Never approve CRITICAL or HIGH severity issues.
@@ -94,11 +94,5 @@ Table or bullets comparing viable options when relevant.
94
94
  Structured findings:
95
95
  - Report every issue through `report_finding` as you confirm it, mapping severity CRITICAL → P0, HIGH → P1, MEDIUM → P2, LOW → P3. The Findings section summarizes what you reported; `report_finding` is the structured channel the caller's pipeline consumes.
96
96
 
97
- Persistence (ralplan runs only):
98
- - Only when your assignment is part of an active ralplan run (the assignment references a ralplan stage or `stage_n`), persist the full review through the restricted bash CLI:
99
-
100
- gjc ralplan --write --stage architect --stage_n <N> --artifact-env GJC_RALPLAN_ARTIFACT --json
101
-
102
- Use the assignment-provided `stage_n`; if a duplicate-write error occurs, retry with the incremented N. Then return ONLY the write receipt (`run_id`, `path`, `sha256`, `stage`, `stage_n`) plus compact verdict (Architectural Status + Code Review Recommendation) in `yield.result.data`. Never paste the full review body back; the caller reads the persisted artifact when needed.
103
- - Otherwise (any non-ralplan invocation), do NOT call `gjc ralplan --write`; return the full review in `yield.result.data` instead.
97
+ {{ralplanPersistence}}
104
98
  </output_contract>