@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
@@ -198,7 +198,10 @@ export function mapAgentSessionEventToAcpSessionUpdates(
198
198
  }
199
199
  case "tool_execution_end": {
200
200
  const args = getToolExecutionEndArgs(event, options);
201
- const resultContent = [...extractDiffToolCallContent(event.result), ...extractToolCallContent(event.result)];
201
+ const resultContent = [
202
+ ...extractDiffToolCallContent(event.result, options.cwd),
203
+ ...extractToolCallContent(event.result),
204
+ ];
202
205
  const content = mergeToolUpdateContent(buildToolStartContent(event.toolName, args), resultContent);
203
206
  const update: SessionUpdate = {
204
207
  sessionUpdate: "tool_call_update",
@@ -207,8 +210,9 @@ export function mapAgentSessionEventToAcpSessionUpdates(
207
210
  rawOutput: event.result,
208
211
  };
209
212
  if (event.isError) {
213
+ // Failure is carried by `status`; `kind` stays the tool's real category so
214
+ // clients keep the icon/treatment established by the initial `tool_call`.
210
215
  update.title = `Failed: ${buildToolTitle(event.toolName, args, undefined)}`;
211
- update.kind = "other";
212
216
  }
213
217
  if (content.length > 0) {
214
218
  update.content = content;
@@ -713,7 +717,7 @@ function extractToolLocationsFromResult(result: unknown, cwd?: string): ToolCall
713
717
  }
714
718
 
715
719
  /** Emit a `diff` ToolCallContent for each per-file edit result that carries oldText/newText. */
716
- function extractDiffToolCallContent(result: unknown): ToolCallContent[] {
720
+ function extractDiffToolCallContent(result: unknown, cwd?: string): ToolCallContent[] {
717
721
  if (typeof result !== "object" || result === null) return [];
718
722
  const details = (result as { details?: unknown }).details;
719
723
  if (typeof details !== "object" || details === null) return [];
@@ -721,13 +725,13 @@ function extractDiffToolCallContent(result: unknown): ToolCallContent[] {
721
725
  const perFile = (details as { perFileResults?: unknown }).perFileResults;
722
726
  const entries: unknown[] = Array.isArray(perFile) ? perFile : [details];
723
727
  for (const entry of entries) {
724
- const block = buildDiffContent(entry);
728
+ const block = buildDiffContent(entry, cwd);
725
729
  if (block) blocks.push(block);
726
730
  }
727
731
  return blocks;
728
732
  }
729
733
 
730
- function buildDiffContent(entry: unknown): ToolCallContent | undefined {
734
+ function buildDiffContent(entry: unknown, cwd?: string): ToolCallContent | undefined {
731
735
  if (typeof entry !== "object" || entry === null) return undefined;
732
736
  const candidate = entry as { path?: unknown; oldText?: unknown; newText?: unknown; isError?: unknown };
733
737
  if (candidate.isError === true) return undefined;
@@ -738,7 +742,8 @@ function buildDiffContent(entry: unknown): ToolCallContent | undefined {
738
742
  if (oldText === undefined && newText === undefined) return undefined;
739
743
  return {
740
744
  type: "diff",
741
- path,
745
+ // `Diff.path` is specified as an absolute path, same as ToolCallLocation.
746
+ path: toAcpLocationPath(path, cwd),
742
747
  oldText: oldText ?? null,
743
748
  newText: newText ?? "",
744
749
  };
@@ -859,7 +864,9 @@ function toToolCallContent(value: unknown): ToolCallContent | undefined {
859
864
  resourceLinkContent.mimeType = mimeType;
860
865
  }
861
866
  const size = extractNumberProperty<ResourceLinkLikeContent>(value, "size");
862
- if (size !== undefined) {
867
+ // `ResourceLink.size` is a byte count typed as int64; drop fractional, negative,
868
+ // or non-representable values rather than emitting a block clients must reject.
869
+ if (size !== undefined && Number.isSafeInteger(size) && size >= 0) {
863
870
  resourceLinkContent.size = size;
864
871
  }
865
872
  return {
@@ -1,6 +1,6 @@
1
1
  import * as stream from "node:stream";
2
- import { AgentSideConnection, ndJsonStream, type Stream } from "@agentclientprotocol/sdk";
3
- import { AcpAgent } from "./acp-agent";
2
+ import { type Agent, AgentSideConnection, ndJsonStream, type Stream } from "@agentclientprotocol/sdk";
3
+ import { AcpAgent, acpRequestFailure } from "./acp-agent";
4
4
  import type { AcpStartupOptions } from "./startup-options";
5
5
 
6
6
  export interface AcpModeOptions {
@@ -8,8 +8,44 @@ export interface AcpModeOptions {
8
8
  startupOptions?: AcpStartupOptions;
9
9
  }
10
10
 
11
+ /**
12
+ * Every agent method reports failures to the client, and the SDK only derives a
13
+ * JSON-RPC code from a `RequestError` — anything else collapses to an opaque
14
+ * `-32603 Internal error` with the reason buried in `data`. Translating once at the
15
+ * connection boundary keeps that contract in one place instead of asking each method
16
+ * to remember it.
17
+ */
18
+ function withAcpRequestFailures(agent: AcpAgent): Agent {
19
+ const wrapped = new Map<string | symbol, (...args: unknown[]) => unknown>();
20
+ return new Proxy(agent, {
21
+ get(target, property) {
22
+ // Read against the target, not the proxy: `signal`/`closed` are getters that
23
+ // touch private fields, and the proxy carries no private-field brand.
24
+ const value = Reflect.get(target, property, target);
25
+ if (typeof value !== "function") return value;
26
+ const cached = wrapped.get(property);
27
+ if (cached) return cached;
28
+ // Cache per property so repeated reads keep a stable method identity.
29
+ const wrapper = (...args: unknown[]) => {
30
+ try {
31
+ const result = (value as (...a: unknown[]) => unknown).apply(target, args);
32
+ return result instanceof Promise
33
+ ? result.catch((error: unknown) => {
34
+ throw acpRequestFailure(error);
35
+ })
36
+ : result;
37
+ } catch (error) {
38
+ throw acpRequestFailure(error);
39
+ }
40
+ };
41
+ wrapped.set(property, wrapper);
42
+ return wrapper;
43
+ },
44
+ }) as unknown as Agent;
45
+ }
46
+
11
47
  export function createAcpConnection(transport: Stream, options: AcpModeOptions = {}): AgentSideConnection {
12
- return new AgentSideConnection(conn => new AcpAgent(conn, options), transport);
48
+ return new AgentSideConnection(conn => withAcpRequestFailures(new AcpAgent(conn, options)), transport);
13
49
  }
14
50
 
15
51
  export async function runAcpMode(options: AcpModeOptions = {}): Promise<never> {
@@ -84,8 +84,10 @@ export class AssistantMessageComponent extends Container {
84
84
  #lastMessage?: AssistantMessage;
85
85
  #toolImagesByCallId = new Map<string, ImageContent[]>();
86
86
  #usageInfo?: Usage;
87
- #convertedKittyImages = new Map<string, ImageContent>();
88
- #kittyConversionsInFlight = new Set<string>();
87
+ #convertedKittyImages = new Map<string, ImageContent & { source: string }>();
88
+ #kittyConversionsInFlight = new Map<string, string>();
89
+ #toolImageGenerations = new Map<string, number>();
90
+
89
91
  #responseHeader = new Text(theme.bold(theme.fg("statusLineModel", "gajae")), 1, 0);
90
92
  #contentBlocksCache = new WeakMap<object, { source: string; component: Component }>();
91
93
  #lastStreaming = false;
@@ -94,11 +96,17 @@ export class AssistantMessageComponent extends Container {
94
96
  #nextContentBlockKey = 0;
95
97
  #reusableChildren = new WeakSet<Component>();
96
98
  #viewportAnchorId?: string;
99
+ #visibleSignature = "";
100
+ #visibleSignatureInitialized = false;
101
+ #toolImagesRevision = 0;
102
+ #convertedToolImagesRevision = 0;
103
+ #disposed = false;
97
104
  constructor(
98
105
  message?: AssistantMessage,
99
106
  private hideThinkingBlock = false,
100
107
  private readonly onImageUpdate?: () => void,
101
108
  viewportAnchorId?: string,
109
+ private readonly onVisibleMutation?: () => void,
102
110
  ) {
103
111
  super();
104
112
  this.#viewportAnchorId = viewportAnchorId;
@@ -109,6 +117,56 @@ export class AssistantMessageComponent extends Container {
109
117
  if (message) {
110
118
  this.updateContent(message);
111
119
  }
120
+ this.#visibleSignature = this.#visibleContentSignature();
121
+ this.#visibleSignatureInitialized = true;
122
+ }
123
+
124
+ #visibleContentSignature(): string {
125
+ const message = this.#lastMessage;
126
+ const content: string[] = [];
127
+ let hasMarkdownContent = false;
128
+ for (const block of message?.content ?? []) {
129
+ if (block.type === "text" && block.text.trim()) {
130
+ content.push(`text:${block.text.trim()}`);
131
+ hasMarkdownContent = true;
132
+ } else if (block.type === "thinking" && block.thinking.trim()) {
133
+ content.push(
134
+ this.hideThinkingBlock
135
+ ? "thinking"
136
+ : `thinking:${elideRunawayThinkingRepetition(block.thinking.trim())}`,
137
+ );
138
+ if (!this.hideThinkingBlock) hasMarkdownContent = true;
139
+ }
140
+ }
141
+ if (hasMarkdownContent) {
142
+ content.unshift(this.#lastStreaming ? "streaming" : "final");
143
+ }
144
+ const hasToolCalls = message?.content.some(block => block.type === "toolCall") ?? false;
145
+ if (!hasToolCalls && message?.stopReason === "aborted" && !isSilentAbort(message.errorMessage)) {
146
+ content.push(`aborted:${message.errorMessage ?? ""}`);
147
+ } else if (!hasToolCalls && message?.stopReason === "error") {
148
+ content.push(`error:${message.errorMessage ?? ""}`);
149
+ } else if (
150
+ message?.errorMessage &&
151
+ !isSilentAbort(message.errorMessage) &&
152
+ message.stopReason !== "aborted" &&
153
+ message.stopReason !== "error"
154
+ ) {
155
+ content.push(`message-error:${message.errorMessage}`);
156
+ }
157
+ if (settings.get("display.showTokenUsage") && this.#usageInfo) {
158
+ const usage = this.#usageInfo;
159
+ content.push(`usage:${usage.input}:${usage.cacheWrite}:${usage.output}:${usage.cacheRead}`);
160
+ }
161
+ content.push(`images:${this.#toolImagesRevision}:${this.#convertedToolImagesRevision}`);
162
+ return content.join("\u0000");
163
+ }
164
+
165
+ #notifyVisibleMutation(): void {
166
+ const after = this.#visibleContentSignature();
167
+ if (after === this.#visibleSignature) return;
168
+ this.#visibleSignature = after;
169
+ if (this.#visibleSignatureInitialized) this.onVisibleMutation?.();
112
170
  }
113
171
 
114
172
  #contentAnchorSource(
@@ -126,22 +184,36 @@ export class AssistantMessageComponent extends Container {
126
184
  }
127
185
 
128
186
  setHideThinkingBlock(hide: boolean): void {
187
+ if (this.hideThinkingBlock === hide) return;
129
188
  this.hideThinkingBlock = hide;
189
+ this.#notifyVisibleMutation();
130
190
  }
131
191
 
132
192
  setToolResultImages(toolCallId: string, images: ImageContent[]): void {
133
193
  if (!toolCallId) return;
134
194
  const validImages = images.filter(img => img.type === "image" && img.data && img.mimeType);
195
+ const previousImages = this.#toolImagesByCallId.get(toolCallId);
196
+ if (
197
+ (previousImages?.length ?? 0) === validImages.length &&
198
+ (previousImages?.every(
199
+ (image, index) =>
200
+ image.type === validImages[index]?.type &&
201
+ image.data === validImages[index]?.data &&
202
+ image.mimeType === validImages[index]?.mimeType,
203
+ ) ??
204
+ true)
205
+ ) {
206
+ return;
207
+ }
135
208
  for (const key of Array.from(this.#convertedKittyImages.keys())) {
136
- if (key.startsWith(`${toolCallId}:`)) {
137
- this.#convertedKittyImages.delete(key);
138
- }
209
+ if (key.startsWith(`${toolCallId}:`)) this.#convertedKittyImages.delete(key);
139
210
  }
140
- for (const key of Array.from(this.#kittyConversionsInFlight)) {
141
- if (key.startsWith(`${toolCallId}:`)) {
142
- this.#kittyConversionsInFlight.delete(key);
143
- }
211
+ for (const key of Array.from(this.#kittyConversionsInFlight.keys())) {
212
+ if (key.startsWith(`${toolCallId}:`)) this.#kittyConversionsInFlight.delete(key);
144
213
  }
214
+ this.#toolImageGenerations.set(toolCallId, (this.#toolImageGenerations.get(toolCallId) ?? 0) + 1);
215
+
216
+ this.#toolImagesRevision += 1;
145
217
  if (validImages.length === 0) {
146
218
  this.#toolImagesByCallId.delete(toolCallId);
147
219
  } else {
@@ -153,30 +225,49 @@ export class AssistantMessageComponent extends Container {
153
225
  }
154
226
  }
155
227
 
228
+ #toolImageSource(image: ImageContent): string {
229
+ return `${image.mimeType}\u0000${image.data}`;
230
+ }
231
+
156
232
  #convertToolImagesForKitty(toolCallId: string, images: ImageContent[]): void {
157
233
  if (TERMINAL.imageProtocol !== ImageProtocol.Kitty) return;
158
- for (let index = 0; index < images.length; index++) {
159
- const image = images[index];
160
- if (!image || image.mimeType === "image/png") continue;
234
+ const generation = this.#toolImageGenerations.get(toolCallId) ?? 0;
235
+ for (const [index, image] of images.entries()) {
236
+ if (image.mimeType === "image/png") continue;
161
237
  const key = `${toolCallId}:${index}`;
162
- if (this.#convertedKittyImages.has(key) || this.#kittyConversionsInFlight.has(key)) continue;
163
- this.#kittyConversionsInFlight.add(key);
238
+ const source = this.#toolImageSource(image);
239
+ if (
240
+ this.#convertedKittyImages.get(key)?.source === source ||
241
+ this.#kittyConversionsInFlight.get(key) === source
242
+ )
243
+ continue;
244
+ this.#kittyConversionsInFlight.set(key, source);
164
245
  new Bun.Image(Buffer.from(image.data, "base64"))
165
246
  .png()
166
247
  .toBase64()
167
248
  .then(data => {
249
+ const currentImage = this.#toolImagesByCallId.get(toolCallId)?.[index];
250
+ if (
251
+ this.#disposed ||
252
+ this.#toolImageGenerations.get(toolCallId) !== generation ||
253
+ this.#kittyConversionsInFlight.get(key) !== source ||
254
+ !currentImage ||
255
+ this.#toolImageSource(currentImage) !== source
256
+ )
257
+ return;
168
258
  this.#kittyConversionsInFlight.delete(key);
169
- this.#convertedKittyImages.set(key, {
170
- type: "image",
171
- data,
172
- mimeType: "image/png",
173
- });
174
- if (this.#lastMessage) {
175
- this.updateContent(this.#lastMessage, { streaming: this.#lastStreaming });
176
- }
259
+ this.#convertedKittyImages.set(key, { type: "image", data, mimeType: "image/png", source });
260
+ this.#convertedToolImagesRevision += 1;
261
+ if (this.#lastMessage) this.updateContent(this.#lastMessage, { streaming: this.#lastStreaming });
177
262
  this.onImageUpdate?.();
178
263
  })
179
264
  .catch(() => {
265
+ if (
266
+ this.#disposed ||
267
+ this.#toolImageGenerations.get(toolCallId) !== generation ||
268
+ this.#kittyConversionsInFlight.get(key) !== source
269
+ )
270
+ return;
180
271
  this.#kittyConversionsInFlight.delete(key);
181
272
  });
182
273
  }
@@ -487,5 +578,15 @@ export class AssistantMessageComponent extends Container {
487
578
  }
488
579
 
489
580
  this.#reconcileChildren(descriptors);
581
+ this.#notifyVisibleMutation();
582
+ }
583
+
584
+ override dispose(): void {
585
+ if (this.#disposed) return;
586
+ this.#disposed = true;
587
+ this.#toolImageGenerations.clear();
588
+ this.#kittyConversionsInFlight.clear();
589
+ this.#convertedKittyImages.clear();
590
+ super.dispose();
490
591
  }
491
592
  }