@gajae-code/coding-agent 0.10.1 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (474) hide show
  1. package/CHANGELOG.md +70 -2
  2. package/dist/types/append-only-mode.d.ts +1 -1
  3. package/dist/types/cli/args.d.ts +4 -5
  4. package/dist/types/cli/daemon-cli.d.ts +12 -1
  5. package/dist/types/cli/notify-cli.d.ts +21 -1
  6. package/dist/types/cli.d.ts +3 -0
  7. package/dist/types/commands/daemon.d.ts +39 -0
  8. package/dist/types/commands/launch.d.ts +3 -0
  9. package/dist/types/commands/notify.d.ts +28 -1
  10. package/dist/types/commands/sdk.d.ts +33 -0
  11. package/dist/types/config/atomic-yaml-patch.d.ts +85 -0
  12. package/dist/types/config/model-profile-activation.d.ts +35 -15
  13. package/dist/types/config/model-profiles.d.ts +11 -5
  14. package/dist/types/config/model-registry.d.ts +3 -3
  15. package/dist/types/config/model-resolver.d.ts +39 -6
  16. package/dist/types/config/model-selector-value.d.ts +17 -0
  17. package/dist/types/config/models-config-schema.d.ts +10 -6
  18. package/dist/types/config/settings-schema.d.ts +133 -6
  19. package/dist/types/config/settings.d.ts +63 -35
  20. package/dist/types/coordinator-mcp/model-preset.d.ts +7 -6
  21. package/dist/types/coordinator-mcp/server.d.ts +6 -49
  22. package/dist/types/daemon/builtin.d.ts +6 -5
  23. package/dist/types/daemon/control-types.d.ts +1 -1
  24. package/dist/types/discovery/mcp-json.d.ts +12 -1
  25. package/dist/types/extensibility/custom-tools/types.d.ts +1 -1
  26. package/dist/types/extensibility/extensions/compact-handler.d.ts +4 -2
  27. package/dist/types/extensibility/extensions/get-commands-handler.d.ts +2 -2
  28. package/dist/types/extensibility/extensions/loader.d.ts +10 -1
  29. package/dist/types/extensibility/extensions/runner.d.ts +3 -3
  30. package/dist/types/extensibility/extensions/types.d.ts +141 -16
  31. package/dist/types/extensibility/hooks/types.d.ts +1 -1
  32. package/dist/types/gjc-runtime/launch-tmux.d.ts +3 -2
  33. package/dist/types/gjc-runtime/psmux-detect.d.ts +3 -0
  34. package/dist/types/gjc-runtime/session-state-sidecar.d.ts +3 -0
  35. package/dist/types/gjc-runtime/team-runtime.d.ts +3 -4
  36. package/dist/types/gjc-runtime/tmux-owner-isolation-cli.d.ts +13 -0
  37. package/dist/types/gjc-runtime/tmux-sessions.d.ts +4 -1
  38. package/dist/types/gjc-runtime/windows-powershell-command.d.ts +9 -0
  39. package/dist/types/harness-control-plane/operate.d.ts +5 -5
  40. package/dist/types/harness-control-plane/owner.d.ts +18 -4
  41. package/dist/types/harness-control-plane/receipts.d.ts +0 -1
  42. package/dist/types/harness-control-plane/sdk-transport.d.ts +43 -0
  43. package/dist/types/harness-control-plane/session-transport.d.ts +48 -0
  44. package/dist/types/harness-control-plane/types.d.ts +3 -4
  45. package/dist/types/lsp/index.d.ts +1 -1
  46. package/dist/types/main.d.ts +32 -38
  47. package/dist/types/modes/acp/acp-agent.d.ts +224 -53
  48. package/dist/types/modes/acp/acp-client-bridge.d.ts +1 -0
  49. package/dist/types/modes/acp/acp-mode.d.ts +6 -15
  50. package/dist/types/modes/acp/permission-mode.d.ts +4 -0
  51. package/dist/types/modes/acp/startup-options.d.ts +6 -0
  52. package/dist/types/modes/components/agent-dashboard.d.ts +3 -0
  53. package/dist/types/modes/components/gajae-pet-widget.d.ts +1 -0
  54. package/dist/types/modes/components/model-selector.d.ts +1 -0
  55. package/dist/types/modes/components/notifications-settings-editor.d.ts +135 -0
  56. package/dist/types/modes/components/pet-capability.d.ts +37 -0
  57. package/dist/types/modes/components/pet-selector.d.ts +1 -1
  58. package/dist/types/modes/components/settings-selector.d.ts +15 -4
  59. package/dist/types/modes/components/welcome.d.ts +1 -1
  60. package/dist/types/modes/controllers/selector-controller.d.ts +35 -1
  61. package/dist/types/modes/index.d.ts +0 -4
  62. package/dist/types/modes/interactive-mode.d.ts +5 -1
  63. package/dist/types/modes/runtime-init.d.ts +2 -2
  64. package/dist/types/modes/shared/agent-wire/approval-gate.d.ts +6 -9
  65. package/dist/types/modes/shared/agent-wire/deep-interview-gate.d.ts +4 -6
  66. package/dist/types/modes/shared/agent-wire/event-contract.d.ts +6 -6
  67. package/dist/types/modes/shared/agent-wire/event-envelope.d.ts +4 -9
  68. package/dist/types/modes/shared/agent-wire/event-observation.d.ts +1 -1
  69. package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +169 -30
  70. package/dist/types/modes/shared/agent-wire/workflow-gate-schema.d.ts +7 -7
  71. package/dist/types/modes/shared/agent-wire/workflow-gate-types.d.ts +105 -0
  72. package/dist/types/modes/types.d.ts +16 -1
  73. package/dist/types/runtime-mcp/client.d.ts +2 -0
  74. package/dist/types/runtime-mcp/config.d.ts +5 -1
  75. package/dist/types/runtime-mcp/manager.d.ts +8 -1
  76. package/dist/types/runtime-mcp/types.d.ts +4 -0
  77. package/dist/types/sdk/acp/adapter.d.ts +67 -0
  78. package/dist/types/sdk/acp/index.d.ts +2 -0
  79. package/dist/types/sdk/broker/broker.d.ts +53 -0
  80. package/dist/types/sdk/broker/discovery.d.ts +30 -0
  81. package/dist/types/sdk/broker/ensure.d.ts +33 -0
  82. package/dist/types/sdk/broker/identity.d.ts +3 -0
  83. package/dist/types/sdk/broker/index.d.ts +8 -0
  84. package/dist/types/sdk/broker/lifecycle-ledger.d.ts +95 -0
  85. package/dist/types/sdk/broker/lifecycle.d.ts +85 -0
  86. package/dist/types/sdk/broker/process-incarnation.d.ts +14 -0
  87. package/dist/types/sdk/broker/runtime.d.ts +33 -0
  88. package/dist/types/sdk/broker/session-index.d.ts +57 -0
  89. package/dist/types/sdk/broker/state-version.d.ts +8 -0
  90. package/dist/types/sdk/broker/transport.d.ts +9 -0
  91. package/dist/types/sdk/bus/chat-command-policy.d.ts +49 -0
  92. package/dist/types/sdk/bus/chat-daemon-cli.d.ts +21 -0
  93. package/dist/types/sdk/bus/chat-daemon-control.d.ts +111 -0
  94. package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +77 -0
  95. package/dist/types/sdk/bus/chat-effect-journal.d.ts +84 -0
  96. package/dist/types/{notifications → sdk/bus}/config-commands.d.ts +7 -2
  97. package/dist/types/sdk/bus/config.d.ts +274 -0
  98. package/dist/types/sdk/bus/conversation-store.d.ts +72 -0
  99. package/dist/types/sdk/bus/discord-conversation.d.ts +58 -0
  100. package/dist/types/sdk/bus/discord-daemon.d.ts +45 -0
  101. package/dist/types/sdk/bus/discord-live-provider.d.ts +70 -0
  102. package/dist/types/sdk/bus/discord-provider.d.ts +85 -0
  103. package/dist/types/{notifications → sdk/bus}/html-format.d.ts +2 -2
  104. package/dist/types/{notifications → sdk/bus}/index.d.ts +113 -13
  105. package/dist/types/{notifications → sdk/bus}/lifecycle-control-runtime.d.ts +4 -2
  106. package/dist/types/{notifications → sdk/bus}/lifecycle-orchestrator.d.ts +18 -21
  107. package/dist/types/{notifications → sdk/bus}/managed-daemon.d.ts +1 -1
  108. package/dist/types/sdk/bus/native-runtime-compatibility.d.ts +13 -0
  109. package/dist/types/sdk/bus/notification-orchestration.d.ts +170 -0
  110. package/dist/types/{notifications → sdk/bus}/notification-service.d.ts +7 -1
  111. package/dist/types/sdk/bus/session-control.d.ts +83 -0
  112. package/dist/types/sdk/bus/slack-conversation.d.ts +56 -0
  113. package/dist/types/sdk/bus/slack-daemon.d.ts +60 -0
  114. package/dist/types/sdk/bus/slack-live-provider.d.ts +59 -0
  115. package/dist/types/sdk/bus/slack-provider.d.ts +55 -0
  116. package/dist/types/{notifications → sdk/bus}/telegram-cli.d.ts +4 -4
  117. package/dist/types/{notifications → sdk/bus}/telegram-daemon-cli.d.ts +14 -5
  118. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +12 -0
  119. package/dist/types/{notifications → sdk/bus}/telegram-daemon-control.d.ts +2 -2
  120. package/dist/types/{notifications → sdk/bus}/telegram-daemon.d.ts +55 -17
  121. package/dist/types/{notifications → sdk/bus}/telegram-reference.d.ts +2 -2
  122. package/dist/types/sdk/bus/telegram-setup.d.ts +128 -0
  123. package/dist/types/{notifications → sdk/bus}/topic-registry.d.ts +11 -0
  124. package/dist/types/sdk/cli/index.d.ts +1 -0
  125. package/dist/types/sdk/cli/session-cli.d.ts +19 -0
  126. package/dist/types/sdk/client/client.d.ts +1 -0
  127. package/dist/types/sdk/client/discovery.d.ts +27 -0
  128. package/dist/types/sdk/client/index.d.ts +2 -0
  129. package/dist/types/sdk/host/control/dispatch.d.ts +34 -0
  130. package/dist/types/sdk/host/control/index.d.ts +2 -0
  131. package/dist/types/sdk/host/control/operations.d.ts +65 -0
  132. package/dist/types/sdk/host/events.d.ts +35 -0
  133. package/dist/types/sdk/host/host.d.ts +35 -0
  134. package/dist/types/sdk/host/index.d.ts +4 -0
  135. package/dist/types/sdk/host/query/cursor.d.ts +62 -0
  136. package/dist/types/sdk/host/query/handlers.d.ts +70 -0
  137. package/dist/types/sdk/host/query/index.d.ts +3 -0
  138. package/dist/types/sdk/host/query/revision-store.d.ts +60 -0
  139. package/dist/types/sdk/host/reverse-leases.d.ts +45 -0
  140. package/dist/types/sdk/host/types.d.ts +32 -0
  141. package/dist/types/sdk/index.d.ts +6 -0
  142. package/dist/types/sdk/lifecycle-session.d.ts +14 -0
  143. package/dist/types/sdk/mcp/index.d.ts +1 -0
  144. package/dist/types/sdk/mcp/server.d.ts +37 -0
  145. package/dist/types/sdk/models.d.ts +44 -0
  146. package/dist/types/sdk/protocol/adapter-validation.d.ts +14 -0
  147. package/dist/types/sdk/protocol/operation-registry.d.ts +24 -0
  148. package/dist/types/{sdk.d.ts → sdk/session.d.ts} +44 -38
  149. package/dist/types/sdk/startup-capability.d.ts +50 -0
  150. package/dist/types/session/agent-session.d.ts +114 -21
  151. package/dist/types/session/default-model-selection.d.ts +25 -0
  152. package/dist/types/session/fallback-chain-controller.d.ts +52 -0
  153. package/dist/types/session/session-manager.d.ts +58 -1
  154. package/dist/types/setup/credential-auto-import.d.ts +36 -6
  155. package/dist/types/tools/ask-answer-registry.d.ts +1 -1
  156. package/dist/types/tools/browser/benchmark/detector-report.d.ts +63 -0
  157. package/dist/types/tools/browser/benchmark/run-suite.d.ts +18 -0
  158. package/dist/types/tools/browser/launch.d.ts +22 -0
  159. package/dist/types/tools/browser/profile-discovery.d.ts +31 -0
  160. package/dist/types/tools/browser/profile-posture.d.ts +37 -0
  161. package/dist/types/tools/browser/profile-reuse.d.ts +39 -0
  162. package/dist/types/tools/browser/profile-warmup.d.ts +39 -0
  163. package/dist/types/tools/browser/registry.d.ts +19 -0
  164. package/dist/types/tools/browser/tab-protocol.d.ts +4 -0
  165. package/dist/types/tools/index.d.ts +8 -8
  166. package/package.json +34 -13
  167. package/scripts/build-sdk-package-smoke.ts +94 -0
  168. package/scripts/capture-notifications-settings-showcase.ts +435 -0
  169. package/scripts/compile-args.ts +4 -2
  170. package/scripts/g005-daemon-smoke.ts +4 -5
  171. package/scripts/g011-daemon-path-smoke.ts +5 -5
  172. package/scripts/generate-sdk-adapter-parity-manifest.ts +163 -0
  173. package/scripts/generate-sdk-operation-inventory.ts +867 -0
  174. package/scripts/generate-telegram-baseline-manifest.ts +128 -0
  175. package/scripts/manifest-schema.ts +124 -0
  176. package/scripts/run-test-manifest.ts +153 -0
  177. package/scripts/run-threat-model-check.ts +157 -0
  178. package/scripts/verify-gjc-sdk-canonicalization.ts +3467 -0
  179. package/scripts/verify-gjc-sdk-rename.ts +90 -0
  180. package/src/append-only-mode.ts +1 -1
  181. package/src/cli/args.ts +43 -12
  182. package/src/cli/auth-gateway-cli.ts +2 -2
  183. package/src/cli/config-cli.ts +2 -1
  184. package/src/cli/daemon-cli.ts +63 -14
  185. package/src/cli/list-models.ts +1 -1
  186. package/src/cli/notify-cli.ts +288 -286
  187. package/src/cli.ts +21 -2
  188. package/src/commands/daemon.ts +50 -6
  189. package/src/commands/harness.ts +93 -36
  190. package/src/commands/launch.ts +5 -2
  191. package/src/commands/mcp-serve.ts +19 -12
  192. package/src/commands/notify.ts +36 -3
  193. package/src/commands/sdk.ts +426 -0
  194. package/src/commit/agentic/agent.ts +1 -0
  195. package/src/config/atomic-yaml-patch.ts +423 -0
  196. package/src/config/model-profile-activation.ts +240 -89
  197. package/src/config/model-profiles.ts +37 -34
  198. package/src/config/model-registry.ts +51 -26
  199. package/src/config/model-resolver.ts +138 -51
  200. package/src/config/model-selector-value.ts +50 -0
  201. package/src/config/models-config-schema.ts +14 -21
  202. package/src/config/settings-schema.ts +128 -10
  203. package/src/config/settings.ts +1120 -158
  204. package/src/coordinator-mcp/model-preset.ts +74 -20
  205. package/src/coordinator-mcp/server.ts +1597 -3052
  206. package/src/daemon/builtin.ts +8 -5
  207. package/src/daemon/control-types.ts +1 -1
  208. package/src/defaults/gjc/skills/team/SKILL.md +4 -4
  209. package/src/discovery/mcp-json.ts +327 -20
  210. package/src/extensibility/custom-tools/types.ts +1 -1
  211. package/src/extensibility/extensions/compact-handler.ts +3 -3
  212. package/src/extensibility/extensions/get-commands-handler.ts +2 -2
  213. package/src/extensibility/extensions/loader.ts +69 -5
  214. package/src/extensibility/extensions/runner.ts +112 -4
  215. package/src/extensibility/extensions/types.ts +176 -17
  216. package/src/extensibility/hooks/types.ts +1 -1
  217. package/src/extensibility/slash-commands.ts +3 -3
  218. package/src/gjc-runtime/launch-tmux.ts +170 -86
  219. package/src/gjc-runtime/psmux-detect.ts +82 -4
  220. package/src/gjc-runtime/session-state-sidecar.ts +41 -31
  221. package/src/gjc-runtime/team-runtime.ts +54 -35
  222. package/src/gjc-runtime/tmux-owner-isolation-cli.ts +53 -17
  223. package/src/gjc-runtime/tmux-owner-isolation.ts +5 -2
  224. package/src/gjc-runtime/tmux-sessions.ts +19 -13
  225. package/src/gjc-runtime/ultragoal-guard.ts +53 -6
  226. package/src/gjc-runtime/ultragoal-runtime.ts +155 -3
  227. package/src/gjc-runtime/windows-powershell-command.ts +58 -0
  228. package/src/harness-control-plane/operate.ts +9 -9
  229. package/src/harness-control-plane/owner.ts +283 -39
  230. package/src/harness-control-plane/receipts.ts +0 -1
  231. package/src/harness-control-plane/sdk-transport.ts +395 -0
  232. package/src/harness-control-plane/session-transport.ts +94 -0
  233. package/src/harness-control-plane/types.ts +1 -1
  234. package/src/internal-urls/docs-index.generated.ts +36 -37
  235. package/src/lsp/client.ts +42 -6
  236. package/src/lsp/index.ts +2 -2
  237. package/src/main.ts +299 -204
  238. package/src/modes/DESIGN.md +258 -0
  239. package/src/modes/acp/acp-agent.ts +1228 -2612
  240. package/src/modes/acp/acp-client-bridge.ts +2 -20
  241. package/src/modes/acp/acp-event-mapper.ts +18 -2
  242. package/src/modes/acp/acp-mode.ts +8 -36
  243. package/src/modes/acp/permission-mode.ts +25 -0
  244. package/src/modes/acp/startup-options.ts +6 -0
  245. package/src/modes/components/agent-dashboard.ts +37 -17
  246. package/src/modes/components/custom-editor.ts +1 -0
  247. package/src/modes/components/gajae-pet-widget.ts +169 -20
  248. package/src/modes/components/model-selector.ts +93 -35
  249. package/src/modes/components/notifications-settings-editor.ts +1379 -0
  250. package/src/modes/components/pet-capability.ts +115 -0
  251. package/src/modes/components/pet-selector.ts +4 -6
  252. package/src/modes/components/settings-selector.ts +86 -11
  253. package/src/modes/components/welcome.ts +4 -4
  254. package/src/modes/controllers/command-controller.ts +1 -2
  255. package/src/modes/controllers/event-controller.ts +11 -16
  256. package/src/modes/controllers/extension-ui-controller.ts +357 -12
  257. package/src/modes/controllers/input-controller.ts +43 -13
  258. package/src/modes/controllers/selector-controller.ts +671 -44
  259. package/src/modes/index.ts +0 -22
  260. package/src/modes/interactive-mode.ts +108 -24
  261. package/src/modes/runtime-init.ts +298 -6
  262. package/src/modes/shared/agent-wire/approval-gate.ts +9 -11
  263. package/src/modes/shared/agent-wire/deep-interview-gate.ts +10 -11
  264. package/src/modes/shared/agent-wire/event-contract.ts +7 -8
  265. package/src/modes/shared/agent-wire/event-envelope.ts +9 -17
  266. package/src/modes/shared/agent-wire/event-observation.ts +16 -7
  267. package/src/modes/shared/agent-wire/workflow-gate-broker.ts +1254 -87
  268. package/src/modes/shared/agent-wire/workflow-gate-schema.ts +15 -15
  269. package/src/modes/shared/agent-wire/workflow-gate-types.ts +113 -0
  270. package/src/modes/types.ts +16 -1
  271. package/src/runtime-mcp/client.ts +94 -19
  272. package/src/runtime-mcp/config.ts +27 -15
  273. package/src/runtime-mcp/manager.ts +343 -105
  274. package/src/runtime-mcp/oauth-flow.ts +42 -12
  275. package/src/runtime-mcp/transports/http.ts +49 -19
  276. package/src/runtime-mcp/transports/stdio.ts +47 -28
  277. package/src/runtime-mcp/types.ts +10 -0
  278. package/src/sdk/acp/adapter.ts +418 -0
  279. package/src/sdk/acp/index.ts +2 -0
  280. package/src/sdk/broker/broker.ts +642 -0
  281. package/src/sdk/broker/discovery.ts +94 -0
  282. package/src/sdk/broker/ensure.ts +249 -0
  283. package/src/sdk/broker/identity.ts +42 -0
  284. package/src/sdk/broker/index.ts +8 -0
  285. package/src/sdk/broker/internal-source-marker-2178.txt +1 -0
  286. package/src/sdk/broker/internal-source.bunfig.toml +1 -0
  287. package/src/sdk/broker/lifecycle-ledger.ts +286 -0
  288. package/src/sdk/broker/lifecycle.ts +2157 -0
  289. package/src/sdk/broker/process-incarnation.ts +159 -0
  290. package/src/sdk/broker/runtime.ts +164 -0
  291. package/src/sdk/broker/session-index.ts +318 -0
  292. package/src/sdk/broker/state-version.ts +23 -0
  293. package/src/sdk/broker/transport.ts +125 -0
  294. package/src/sdk/bus/chat-command-policy.ts +107 -0
  295. package/src/sdk/bus/chat-daemon-cli.ts +214 -0
  296. package/src/sdk/bus/chat-daemon-control.ts +713 -0
  297. package/src/sdk/bus/chat-daemon-runtime.ts +526 -0
  298. package/src/sdk/bus/chat-effect-journal.ts +353 -0
  299. package/src/{notifications → sdk/bus}/config-commands.ts +39 -10
  300. package/src/sdk/bus/config.ts +433 -0
  301. package/src/sdk/bus/conversation-store.ts +391 -0
  302. package/src/sdk/bus/discord-conversation.ts +85 -0
  303. package/src/sdk/bus/discord-daemon.ts +2275 -0
  304. package/src/sdk/bus/discord-live-provider.ts +521 -0
  305. package/src/sdk/bus/discord-provider.ts +56 -0
  306. package/src/{notifications → sdk/bus}/html-format.ts +2 -2
  307. package/src/sdk/bus/index.ts +3943 -0
  308. package/src/{notifications → sdk/bus}/lifecycle-commands.ts +2 -0
  309. package/src/{notifications → sdk/bus}/lifecycle-control-runtime.ts +225 -196
  310. package/src/{notifications → sdk/bus}/lifecycle-orchestrator.ts +161 -74
  311. package/src/{notifications → sdk/bus}/managed-daemon.ts +2 -2
  312. package/src/sdk/bus/native-runtime-compatibility.ts +42 -0
  313. package/src/sdk/bus/natives-augment.d.ts +38 -0
  314. package/src/sdk/bus/notification-orchestration.ts +535 -0
  315. package/src/{notifications → sdk/bus}/notification-service.ts +106 -12
  316. package/src/sdk/bus/session-control.ts +333 -0
  317. package/src/sdk/bus/slack-conversation.ts +74 -0
  318. package/src/sdk/bus/slack-daemon.ts +2144 -0
  319. package/src/sdk/bus/slack-live-provider.ts +380 -0
  320. package/src/sdk/bus/slack-provider.ts +76 -0
  321. package/src/{notifications → sdk/bus}/telegram-cli.ts +8 -8
  322. package/src/sdk/bus/telegram-daemon-cli.ts +330 -0
  323. package/src/sdk/bus/telegram-daemon-contract.ts +14 -0
  324. package/src/{notifications → sdk/bus}/telegram-daemon-control.ts +4 -4
  325. package/src/{notifications → sdk/bus}/telegram-daemon.ts +502 -54
  326. package/src/{notifications → sdk/bus}/telegram-reference.ts +2 -2
  327. package/src/sdk/bus/telegram-setup.ts +663 -0
  328. package/src/{notifications → sdk/bus}/topic-registry.ts +32 -0
  329. package/src/sdk/cli/index.ts +1 -0
  330. package/src/sdk/cli/session-cli.ts +275 -0
  331. package/src/sdk/client/client.ts +1 -0
  332. package/src/sdk/client/discovery.ts +108 -0
  333. package/src/sdk/client/index.ts +2 -0
  334. package/src/sdk/host/control/dispatch.ts +367 -0
  335. package/src/sdk/host/control/index.ts +10 -0
  336. package/src/sdk/host/control/operations.ts +63 -0
  337. package/src/sdk/host/events.ts +91 -0
  338. package/src/sdk/host/host.ts +296 -0
  339. package/src/sdk/host/index.ts +4 -0
  340. package/src/sdk/host/query/cursor.ts +189 -0
  341. package/src/sdk/host/query/handlers.ts +533 -0
  342. package/src/sdk/host/query/index.ts +3 -0
  343. package/src/sdk/host/query/revision-store.ts +1126 -0
  344. package/src/sdk/host/reverse-leases.ts +325 -0
  345. package/src/sdk/host/types.ts +29 -0
  346. package/src/sdk/index.ts +13 -0
  347. package/src/sdk/lifecycle-session.ts +39 -0
  348. package/src/sdk/mcp/index.ts +1 -0
  349. package/src/sdk/mcp/server.ts +332 -0
  350. package/src/sdk/models.ts +168 -0
  351. package/src/sdk/protocol/adapter-validation.ts +48 -0
  352. package/src/sdk/protocol/operation-inventory.generated.json +5654 -0
  353. package/src/sdk/protocol/operation-registry.ts +312 -0
  354. package/src/{sdk.ts → sdk/session.ts} +339 -212
  355. package/src/sdk/startup-capability.ts +189 -0
  356. package/src/session/agent-session.ts +2470 -866
  357. package/src/session/default-model-selection.ts +93 -0
  358. package/src/session/fallback-chain-controller.ts +136 -0
  359. package/src/session/session-manager.ts +447 -13
  360. package/src/session/session-storage.ts +8 -1
  361. package/src/setup/credential-auto-import.ts +290 -35
  362. package/src/setup/hermes/templates/operator-instructions.v1.md +3 -5
  363. package/src/slash-commands/builtin-registry.ts +33 -30
  364. package/src/task/executor.ts +62 -13
  365. package/src/tools/ask-answer-registry.ts +1 -1
  366. package/src/tools/ask.ts +13 -8
  367. package/src/tools/browser/STEALTH-THIRD-PARTY-NOTICES.md +26 -0
  368. package/src/tools/browser/benchmark/detector-report.ts +157 -0
  369. package/src/tools/browser/benchmark/run-suite.ts +39 -0
  370. package/src/tools/browser/launch.ts +124 -19
  371. package/src/tools/browser/profile-discovery.ts +63 -0
  372. package/src/tools/browser/profile-posture.ts +59 -0
  373. package/src/tools/browser/profile-reuse.ts +102 -0
  374. package/src/tools/browser/profile-warmup.ts +109 -0
  375. package/src/tools/browser/registry.ts +87 -11
  376. package/src/tools/browser/tab-protocol.ts +1 -0
  377. package/src/tools/browser/tab-supervisor.ts +1 -0
  378. package/src/tools/browser/tab-worker.ts +1 -1
  379. package/src/tools/browser.ts +6 -0
  380. package/src/tools/index.ts +8 -8
  381. package/src/tools/puppeteer/14_stealth_permissions.txt +57 -0
  382. package/src/tools/puppeteer/15_stealth_webrtc.txt +60 -0
  383. package/src/tools/telegram-send.ts +2 -2
  384. package/vendor/insane-search/MANIFEST.json +2 -1
  385. package/vendor/insane-search/engine/bias_check.py +4 -1
  386. package/vendor/insane-search/engine/phase0.py +26 -1
  387. package/dist/types/harness-control-plane/rpc-adapter.d.ts +0 -69
  388. package/dist/types/modes/bridge/auth.d.ts +0 -12
  389. package/dist/types/modes/bridge/bridge-client-bridge.d.ts +0 -9
  390. package/dist/types/modes/bridge/bridge-mode.d.ts +0 -47
  391. package/dist/types/modes/bridge/bridge-ui-context.d.ts +0 -88
  392. package/dist/types/modes/bridge/event-stream.d.ts +0 -8
  393. package/dist/types/modes/rpc/host-tools.d.ts +0 -1
  394. package/dist/types/modes/rpc/host-uris.d.ts +0 -1
  395. package/dist/types/modes/rpc/rpc-client.d.ts +0 -299
  396. package/dist/types/modes/rpc/rpc-mode.d.ts +0 -86
  397. package/dist/types/modes/rpc/rpc-socket-security.d.ts +0 -10
  398. package/dist/types/modes/rpc/rpc-types.d.ts +0 -810
  399. package/dist/types/modes/shared/agent-wire/command-contract.d.ts +0 -18
  400. package/dist/types/modes/shared/agent-wire/command-dispatch.d.ts +0 -37
  401. package/dist/types/modes/shared/agent-wire/command-validation.d.ts +0 -2
  402. package/dist/types/modes/shared/agent-wire/handshake.d.ts +0 -56
  403. package/dist/types/modes/shared/agent-wire/host-tool-bridge.d.ts +0 -16
  404. package/dist/types/modes/shared/agent-wire/host-uri-bridge.d.ts +0 -17
  405. package/dist/types/modes/shared/agent-wire/protocol.d.ts +0 -25
  406. package/dist/types/modes/shared/agent-wire/responses.d.ts +0 -4
  407. package/dist/types/modes/shared/agent-wire/scopes.d.ts +0 -18
  408. package/dist/types/modes/shared/agent-wire/session-registry.d.ts +0 -25
  409. package/dist/types/modes/shared/agent-wire/ui-request-broker.d.ts +0 -42
  410. package/dist/types/modes/shared/agent-wire/ui-result.d.ts +0 -27
  411. package/dist/types/modes/shared/agent-wire/unattended-action-policy.d.ts +0 -29
  412. package/dist/types/modes/shared/agent-wire/unattended-audit.d.ts +0 -68
  413. package/dist/types/modes/shared/agent-wire/unattended-run-controller.d.ts +0 -166
  414. package/dist/types/modes/shared/agent-wire/unattended-session.d.ts +0 -127
  415. package/dist/types/notifications/config.d.ts +0 -132
  416. package/src/harness-control-plane/rpc-adapter.ts +0 -290
  417. package/src/modes/bridge/auth.ts +0 -41
  418. package/src/modes/bridge/bridge-client-bridge.ts +0 -47
  419. package/src/modes/bridge/bridge-mode.ts +0 -675
  420. package/src/modes/bridge/bridge-ui-context.ts +0 -200
  421. package/src/modes/bridge/event-stream.ts +0 -70
  422. package/src/modes/rpc/host-tools.ts +0 -1
  423. package/src/modes/rpc/host-uris.ts +0 -1
  424. package/src/modes/rpc/rpc-client.ts +0 -1166
  425. package/src/modes/rpc/rpc-mode.ts +0 -1029
  426. package/src/modes/rpc/rpc-socket-security.ts +0 -115
  427. package/src/modes/rpc/rpc-types.ts +0 -637
  428. package/src/modes/shared/agent-wire/command-contract.ts +0 -18
  429. package/src/modes/shared/agent-wire/command-dispatch.ts +0 -498
  430. package/src/modes/shared/agent-wire/command-validation.ts +0 -181
  431. package/src/modes/shared/agent-wire/handshake.ts +0 -157
  432. package/src/modes/shared/agent-wire/host-tool-bridge.ts +0 -197
  433. package/src/modes/shared/agent-wire/host-uri-bridge.ts +0 -236
  434. package/src/modes/shared/agent-wire/protocol.ts +0 -46
  435. package/src/modes/shared/agent-wire/responses.ts +0 -17
  436. package/src/modes/shared/agent-wire/scopes.ts +0 -94
  437. package/src/modes/shared/agent-wire/session-registry.ts +0 -109
  438. package/src/modes/shared/agent-wire/ui-request-broker.ts +0 -150
  439. package/src/modes/shared/agent-wire/ui-result.ts +0 -48
  440. package/src/modes/shared/agent-wire/unattended-action-policy.ts +0 -365
  441. package/src/modes/shared/agent-wire/unattended-audit.ts +0 -176
  442. package/src/modes/shared/agent-wire/unattended-run-controller.ts +0 -426
  443. package/src/modes/shared/agent-wire/unattended-session.ts +0 -528
  444. package/src/notifications/config.ts +0 -219
  445. package/src/notifications/index.ts +0 -1835
  446. package/src/notifications/telegram-daemon-cli.ts +0 -243
  447. package/src/tools/puppeteer/09_stealth_locale.txt +0 -46
  448. /package/dist/types/{notifications → sdk/bus}/attachment-registry.d.ts +0 -0
  449. /package/dist/types/{notifications → sdk/bus}/chat-adapters.d.ts +0 -0
  450. /package/dist/types/{notifications → sdk/bus}/daemon-paths.d.ts +0 -0
  451. /package/dist/types/{notifications → sdk/bus}/engine.d.ts +0 -0
  452. /package/dist/types/{notifications → sdk/bus}/helpers.d.ts +0 -0
  453. /package/dist/types/{notifications → sdk/bus}/lifecycle-commands.d.ts +0 -0
  454. /package/dist/types/{notifications → sdk/bus}/operator-runtime.d.ts +0 -0
  455. /package/dist/types/{notifications → sdk/bus}/rate-limit-pool.d.ts +0 -0
  456. /package/dist/types/{notifications → sdk/bus}/recent-activity.d.ts +0 -0
  457. /package/dist/types/{notifications → sdk/bus}/reply-sent-store.d.ts +0 -0
  458. /package/dist/types/{notifications → sdk/bus}/rich-draft.d.ts +0 -0
  459. /package/dist/types/{notifications → sdk/bus}/rich-render.d.ts +0 -0
  460. /package/dist/types/{notifications → sdk/bus}/threaded-inbound.d.ts +0 -0
  461. /package/dist/types/{notifications → sdk/bus}/threaded-render.d.ts +0 -0
  462. /package/src/{notifications → sdk/bus}/attachment-registry.ts +0 -0
  463. /package/src/{notifications → sdk/bus}/chat-adapters.ts +0 -0
  464. /package/src/{notifications → sdk/bus}/daemon-paths.ts +0 -0
  465. /package/src/{notifications → sdk/bus}/engine.ts +0 -0
  466. /package/src/{notifications → sdk/bus}/helpers.ts +0 -0
  467. /package/src/{notifications → sdk/bus}/operator-runtime.ts +0 -0
  468. /package/src/{notifications → sdk/bus}/rate-limit-pool.ts +0 -0
  469. /package/src/{notifications → sdk/bus}/recent-activity.ts +0 -0
  470. /package/src/{notifications → sdk/bus}/reply-sent-store.ts +0 -0
  471. /package/src/{notifications → sdk/bus}/rich-draft.ts +0 -0
  472. /package/src/{notifications → sdk/bus}/rich-render.ts +0 -0
  473. /package/src/{notifications → sdk/bus}/threaded-inbound.ts +0 -0
  474. /package/src/{notifications → sdk/bus}/threaded-render.ts +0 -0
@@ -5,30 +5,8 @@ import { postmortem } from "@gajae-code/utils";
5
5
  * Run modes for the coding agent.
6
6
  */
7
7
  export { runAcpMode } from "./acp";
8
- export { runBridgeMode } from "./bridge/bridge-mode";
9
8
  export { InteractiveMode, type InteractiveModeOptions } from "./interactive-mode";
10
9
  export { type PrintModeOptions, runPrintMode } from "./print-mode";
11
- export {
12
- defineRpcClientTool,
13
- type ModelInfo,
14
- RpcClient,
15
- type RpcClientCustomTool,
16
- type RpcClientOptions,
17
- type RpcClientToolContext,
18
- type RpcClientToolResult,
19
- type RpcEventListener,
20
- } from "./rpc/rpc-client";
21
- export { runRpcMode } from "./rpc/rpc-mode";
22
- export type {
23
- RpcCommand,
24
- RpcHostToolCallRequest,
25
- RpcHostToolCancelRequest,
26
- RpcHostToolDefinition,
27
- RpcHostToolResult,
28
- RpcHostToolUpdate,
29
- RpcResponse,
30
- RpcSessionState,
31
- } from "./rpc/rpc-types";
32
10
 
33
11
  postmortem.register("terminal-restore", () => {
34
12
  emergencyTerminalRestore();
@@ -62,7 +62,8 @@ import {
62
62
  scheduleLaunchStarReminderAfterFirstRender,
63
63
  starReminderLaunchGate,
64
64
  } from "../reminders/star-reminder";
65
- import type { AgentSession, AgentSessionEvent } from "../session/agent-session";
65
+ import type { NotificationSessionReconcileResult, NotificationSessionStatus } from "../sdk/bus/session-control";
66
+ import type { AgentSession, AgentSessionEvent, TemporaryProviderSessionScope } from "../session/agent-session";
66
67
  import { HistoryStorage } from "../session/history-storage";
67
68
  import type { SessionContext, SessionManager } from "../session/session-manager";
68
69
  import { getRecentSessions } from "../session/session-manager";
@@ -87,6 +88,12 @@ import type { HookEditorComponent } from "./components/hook-editor";
87
88
  import type { HookInputComponent } from "./components/hook-input";
88
89
  import type { HookSelectorComponent } from "./components/hook-selector";
89
90
  import { IrcSplitViewComponent } from "./components/irc-sidebar";
91
+ import {
92
+ getPetUnavailableWarning,
93
+ isPetAvailable,
94
+ isPetCapabilityProbePending,
95
+ warnWhenPetCapabilitySettled,
96
+ } from "./components/pet-capability";
90
97
  import { StatusLineComponent } from "./components/status-line";
91
98
  import type { ToolExecutionHandle } from "./components/tool-execution";
92
99
  import {
@@ -389,6 +396,8 @@ export class InteractiveMode implements InteractiveModeContext {
389
396
  #cleanupUnsubscribe?: () => void;
390
397
  #subprocessTeardownUnsubscribe?: () => void;
391
398
  #petProtocolUnsubscribe?: () => void;
399
+ /** Cancels a startup pet-unavailable warning still awaiting probe settlement. */
400
+ #petUnavailableWarningDisposer?: () => void;
392
401
  readonly #version: string;
393
402
  readonly #changelogMarkdown: string | undefined;
394
403
  #planModePreviousTools: string[] | undefined;
@@ -399,6 +408,7 @@ export class InteractiveMode implements InteractiveModeContext {
399
408
  #goalSuppressNextContinuation = false;
400
409
  #planModePreviousModelState: { model: Model; thinkingLevel?: ThinkingLevel } | undefined;
401
410
  #pendingModelSwitch: { model: Model; thinkingLevel?: ThinkingLevel } | undefined;
411
+ #planModeProviderSessionScope: TemporaryProviderSessionScope | undefined;
402
412
  #planModeHasEntered = false;
403
413
  #planReviewContainer: Container | undefined;
404
414
  readonly lspServers: LspStartupServerInfo[] | undefined = undefined;
@@ -535,6 +545,19 @@ export class InteractiveMode implements InteractiveModeContext {
535
545
  this.#observerRegistry = new SessionObserverRegistry();
536
546
  }
537
547
 
548
+ getCurrentSessionNotificationStatus(): NotificationSessionStatus | undefined {
549
+ return this.session.notificationSessionController?.query({ sessionManager: this.sessionManager });
550
+ }
551
+
552
+ async setCurrentSessionNotificationsEnabled(
553
+ enabled: boolean,
554
+ ): Promise<NotificationSessionReconcileResult | undefined> {
555
+ return await this.session.notificationSessionController?.setLocalEnabled(
556
+ { sessionManager: this.sessionManager },
557
+ enabled,
558
+ );
559
+ }
560
+
538
561
  async init(): Promise<void> {
539
562
  if (this.isInitialized) return;
540
563
 
@@ -617,8 +640,10 @@ export class InteractiveMode implements InteractiveModeContext {
617
640
  this.ui.addChild(this.hookWidgetContainerBelow);
618
641
  this.ui.setBottomPinnedComponent(this.statusLine);
619
642
  this.ui.setFocus(this.editor);
643
+ this.petWidget?.dispose();
620
644
  this.petWidget = this.#createPetWidget(this.editor);
621
- this.petWidget.setMode(settings.get("pet.mode"));
645
+ const configuredPetMode = settings.get("pet.mode");
646
+ this.petWidget.setMode(configuredPetMode);
622
647
  // The async sixel capability probe can enable graphics after the saved
623
648
  // pet mode was applied and dropped (no protocol yet at startup).
624
649
  // Re-apply the configured mode when capability arrives so the pet
@@ -631,6 +656,19 @@ export class InteractiveMode implements InteractiveModeContext {
631
656
  this.petWidget.setMode(saved);
632
657
  }
633
658
  });
659
+ if (configuredPetMode !== "off" && !isPetAvailable()) {
660
+ // The async Sixel capability probe (started by TUI.start()) may still
661
+ // enable graphics; warn only once the capability question is settled
662
+ // so a supported terminal is never told it is incompatible.
663
+ this.#petUnavailableWarningDisposer?.();
664
+ this.#petUnavailableWarningDisposer = warnWhenPetCapabilitySettled({
665
+ probePending: isPetCapabilityProbePending(),
666
+ onUnavailable: () => {
667
+ this.showStatus(theme.fg("warning", getPetUnavailableWarning()), { dim: false });
668
+ this.ui.requestRender();
669
+ },
670
+ });
671
+ }
634
672
 
635
673
  this.#inputController.setupKeyHandlers();
636
674
  this.#inputController.setupEditorSubmitHandler();
@@ -1078,10 +1116,26 @@ export class InteractiveMode implements InteractiveModeContext {
1078
1116
  this.editor.setTopBorder(undefined);
1079
1117
  }
1080
1118
 
1081
- setPetMode(mode: PetMode): void {
1082
- this.petWidget?.setMode(mode);
1119
+ /**
1120
+ * Single result-returning pet commit policy shared by every entry path
1121
+ * (`/pet`, the pet selector, and the Settings submenu). Capability is
1122
+ * rechecked immediately before mutation, and the preference persists only
1123
+ * after the commit is accepted.
1124
+ */
1125
+ #commitPetMode(mode: PetMode, apply: (mode: PetMode) => void): boolean {
1126
+ if (mode !== "off" && !isPetAvailable()) {
1127
+ this.showStatus(theme.fg("warning", getPetUnavailableWarning()), { dim: false });
1128
+ this.ui.requestRender();
1129
+ return false;
1130
+ }
1131
+ apply(mode);
1083
1132
  settings.set("pet.mode", mode);
1084
1133
  this.ui.requestRender();
1134
+ return true;
1135
+ }
1136
+
1137
+ setPetMode(mode: PetMode): boolean {
1138
+ return this.#commitPetMode(mode, next => this.petWidget?.setMode(next));
1085
1139
  }
1086
1140
 
1087
1141
  previewPetMode(mode: PetMode): void {
@@ -1089,6 +1143,10 @@ export class InteractiveMode implements InteractiveModeContext {
1089
1143
  this.ui.requestRender();
1090
1144
  }
1091
1145
 
1146
+ commitPetPreviewMode(mode: PetMode): boolean {
1147
+ return this.#commitPetMode(mode, next => this.petWidget?.commitPreviewMode(next));
1148
+ }
1149
+
1092
1150
  restoreComposer(): void {
1093
1151
  if (this.petWidget) {
1094
1152
  this.petWidget.remountComposer();
@@ -1310,8 +1368,18 @@ export class InteractiveMode implements InteractiveModeContext {
1310
1368
  return;
1311
1369
  }
1312
1370
  try {
1313
- await this.session.setModelTemporary(resolved.model, planThinkingLevel);
1371
+ this.#planModeProviderSessionScope = this.session.beginTemporaryProviderSessionScope("plan-mode");
1372
+ await this.session.setModelTemporary(resolved.model, planThinkingLevel, {
1373
+ cause: "temporary-operation",
1374
+ reason: "plan-mode",
1375
+ providerSessionScope: this.#planModeProviderSessionScope,
1376
+ });
1314
1377
  } catch (error) {
1378
+ const scope = this.#planModeProviderSessionScope;
1379
+ if (scope) {
1380
+ this.session.restoreTemporaryProviderSessionScope(scope);
1381
+ this.#planModeProviderSessionScope = undefined;
1382
+ }
1315
1383
  this.showWarning(
1316
1384
  `Failed to switch to plan model for plan mode: ${error instanceof Error ? error.message : String(error)}`,
1317
1385
  );
@@ -1327,8 +1395,18 @@ export class InteractiveMode implements InteractiveModeContext {
1327
1395
  if (!pending) return;
1328
1396
  this.#pendingModelSwitch = undefined;
1329
1397
  try {
1330
- await this.session.setModelTemporary(pending.model, pending.thinkingLevel);
1398
+ this.#planModeProviderSessionScope ??= this.session.beginTemporaryProviderSessionScope("plan-mode");
1399
+ await this.session.setModelTemporary(pending.model, pending.thinkingLevel, {
1400
+ cause: "temporary-operation",
1401
+ reason: "plan-mode",
1402
+ providerSessionScope: this.#planModeProviderSessionScope,
1403
+ });
1331
1404
  } catch (error) {
1405
+ const scope = this.#planModeProviderSessionScope;
1406
+ if (scope) {
1407
+ this.session.restoreTemporaryProviderSessionScope(scope);
1408
+ this.#planModeProviderSessionScope = undefined;
1409
+ }
1332
1410
  this.showWarning(
1333
1411
  `Failed to switch model after streaming: ${error instanceof Error ? error.message : String(error)}`,
1334
1412
  );
@@ -1485,30 +1563,34 @@ export class InteractiveMode implements InteractiveModeContext {
1485
1563
  if (previousTools && previousTools.length > 0) {
1486
1564
  await this.session.setActiveToolsByName(previousTools);
1487
1565
  }
1488
- if (this.#planModePreviousModelState) {
1566
+ const scope = this.#planModeProviderSessionScope;
1567
+ if (scope && !this.session.isStreaming) {
1568
+ const restored = this.session.restoreTemporaryProviderSessionScope(scope);
1569
+ if (restored) this.#planModeProviderSessionScope = undefined;
1570
+ } else if (this.#planModePreviousModelState) {
1489
1571
  const prev = this.#planModePreviousModelState;
1490
1572
  if (modelsAreEqual(this.session.model, prev.model)) {
1491
- // Same model — only thinking level may differ. Avoid setModelTemporary()
1492
- // which would reset provider-side sessions (openai-responses/OpenAI code backend) and
1493
- // break conversation continuity.
1494
1573
  this.session.setThinkingLevel(prev.thinkingLevel);
1495
1574
  } else if (this.session.isStreaming) {
1496
1575
  this.#pendingModelSwitch = { model: prev.model, thinkingLevel: prev.thinkingLevel };
1497
1576
  } else {
1498
- await this.session.setModelTemporary(prev.model, prev.thinkingLevel);
1577
+ await this.session.setModelTemporary(prev.model, prev.thinkingLevel, {
1578
+ cause: "restore",
1579
+ reason: "plan-mode",
1580
+ });
1499
1581
  }
1500
- // If #applyPlanModeModel queued a deferred switch to the plan-role model
1501
- // (because the session was streaming on entry), drop it now: we are
1502
- // leaving plan mode, so flushing it on the next agent_end would land the
1503
- // session on the plan-role model after the user has exited plan mode
1504
- // (issue #816). Only clear when the pending target matches the plan-role
1505
- // model — leave any unrelated user-queued switch intact.
1506
- const pending = this.#pendingModelSwitch;
1507
- if (pending) {
1508
- const planResolution = this.session.resolveRoleModelWithThinking("plan");
1509
- if (planResolution.model && modelsAreEqual(pending.model, planResolution.model)) {
1510
- this.#pendingModelSwitch = undefined;
1511
- }
1582
+ }
1583
+ // If #applyPlanModeModel queued a deferred switch to the plan-role model
1584
+ // (because the session was streaming on entry), drop it now: we are
1585
+ // leaving plan mode, so flushing it on the next agent_end would land the
1586
+ // session on the plan-role model after the user has exited plan mode
1587
+ // (issue #816). Only clear when the pending target matches the plan-role
1588
+ // model — leave any unrelated user-queued switch intact.
1589
+ const pending = this.#pendingModelSwitch;
1590
+ if (pending) {
1591
+ const planResolution = this.session.resolveRoleModelWithThinking("plan");
1592
+ if (planResolution.model && modelsAreEqual(pending.model, planResolution.model)) {
1593
+ this.#pendingModelSwitch = undefined;
1512
1594
  }
1513
1595
  }
1514
1596
  this.session.setStandingResolveHandler?.(null);
@@ -2090,6 +2172,8 @@ export class InteractiveMode implements InteractiveModeContext {
2090
2172
  stop(): void {
2091
2173
  this.#petProtocolUnsubscribe?.();
2092
2174
  this.#petProtocolUnsubscribe = undefined;
2175
+ this.#petUnavailableWarningDisposer?.();
2176
+ this.#petUnavailableWarningDisposer = undefined;
2093
2177
  this.petWidget?.dispose();
2094
2178
  this.petWidget = undefined;
2095
2179
  if (this.loadingAnimation) {
@@ -2223,7 +2307,7 @@ export class InteractiveMode implements InteractiveModeContext {
2223
2307
  nextEditor.setText(previousText);
2224
2308
  previousEditor.dispose();
2225
2309
 
2226
- const petMode = this.petWidget?.mode ?? settings.get("pet.mode");
2310
+ const petMode = settings.get("pet.mode");
2227
2311
  this.petWidget?.dispose();
2228
2312
 
2229
2313
  this.editorContainer.clear();
@@ -1,16 +1,21 @@
1
1
  /**
2
- * Shared extension runtime wiring for print and RPC modes.
2
+ * Shared extension runtime wiring for non-interactive session callers.
3
3
  *
4
- * Both modes initialize the extension runner with the same action handlers
4
+ * These callers initialize the extension runner with the same action handlers
5
5
  * that delegate to the {@link AgentSession}. Only error reporting, shutdown
6
6
  * behavior, and UI context differ between callers — those stay as
7
7
  * caller-supplied hooks.
8
8
  */
9
+ import * as path from "node:path";
10
+ import { ThinkingLevel } from "@gajae-code/agent-core";
9
11
  import { runExtensionCompact, runExtensionSetModel } from "../extensibility/extensions/compact-handler";
10
12
  import { getSessionSlashCommands } from "../extensibility/extensions/get-commands-handler";
11
13
  import type { ExtensionError, ExtensionUIContext } from "../extensibility/extensions/types";
12
14
  import type { AgentSession } from "../session/agent-session";
13
15
 
16
+ import { parseThinkingLevel } from "../thinking";
17
+ import type { TodoPhase } from "../tools/todo-write";
18
+
14
19
  /** Action name for an extension-originated send failure. */
15
20
  export type ExtensionSendAction = "extension_send" | "extension_send_user";
16
21
 
@@ -19,9 +24,9 @@ export interface InitializeExtensionsOptions {
19
24
  reportSendError: (action: ExtensionSendAction, error: Error) => void;
20
25
  /** Reports a runtime error surfaced through {@link ExtensionRunner.onError}. */
21
26
  reportRuntimeError: (error: ExtensionError) => void;
22
- /** Optional shutdown hook (rpc mode signals its loop; print mode is a no-op). */
27
+ /** Optional shutdown hook for caller-specific lifecycle signaling. */
23
28
  onShutdown?: () => void;
24
- /** Optional UI context (rpc supplies one; print runs headless). */
29
+ /** Optional interactive UI context; omitted for headless callers. */
25
30
  uiContext?: ExtensionUIContext;
26
31
  }
27
32
 
@@ -47,9 +52,11 @@ export async function initializeExtensions(session: AgentSession, options: Initi
47
52
  });
48
53
  },
49
54
  sendUserMessage: (content, sendOptions) => {
50
- session.sendUserMessage(content, sendOptions).catch(e => {
55
+ const send = session.sendUserMessage(content, sendOptions);
56
+ void send.catch(e => {
51
57
  reportSendError("extension_send_user", e instanceof Error ? e : new Error(String(e)));
52
58
  });
59
+ return send;
53
60
  },
54
61
  appendEntry: (customType, data) => {
55
62
  session.sessionManager.appendCustomEntry(customType, data);
@@ -63,7 +70,17 @@ export async function initializeExtensions(session: AgentSession, options: Initi
63
70
  getCommands: () => getSessionSlashCommands(session),
64
71
  setModel: model => runExtensionSetModel(session, model),
65
72
  getThinkingLevel: () => session.thinkingLevel,
66
- setThinkingLevel: level => session.setThinkingLevel(level),
73
+ setThinkingLevel: (level, persist) => session.setThinkingLevel(level, persist),
74
+ getThinkingVisibility: () => session.getThinkingVisibility(),
75
+ setThinkingVisibility: (visibility, persist) => session.setThinkingVisibility(visibility, persist),
76
+ cycleThinkingLevel: () => session.cycleThinkingLevel(),
77
+ setThinkingLevelForControl: (level, persist) => session.setThinkingLevelForControl(level, persist),
78
+ setThinkingVisibilityForControl: (visibility, persist) =>
79
+ session.setThinkingVisibilityForControl(visibility, persist),
80
+ setModelTemporaryForControl: (model, expectedSessionId) =>
81
+ session.setModelTemporaryForControl(model, expectedSessionId),
82
+ fetchUsageReportsForControl: () => session.fetchUsageReportsForControl(),
83
+ getThinkingScopeForControl: () => session.getThinkingScopeForControl(),
67
84
  getSessionName: () => session.sessionManager.getSessionName(),
68
85
  setSessionName: async name => {
69
86
  await session.sessionManager.setSessionName(name, "user");
@@ -75,11 +92,286 @@ export async function initializeExtensions(session: AgentSession, options: Initi
75
92
  isIdle: () => !session.isStreaming,
76
93
  abort: () => session.abort(),
77
94
  hasPendingMessages: () => session.queuedMessageCount > 0,
95
+ getPendingMessageCounts: () => session.pendingMessageCounts,
96
+ getTranscript: () => session.getTranscript(),
97
+ getTranscriptBody: entryId => session.getTranscriptBody(entryId),
98
+ getGoalState: () => session.getGoalModeState(),
99
+ getTodoState: () => session.getTodoPhases(),
100
+ getQueuedMessages: () => session.getQueuedMessageEntries(),
101
+ getActiveTools: () => session.getActiveToolNames(),
102
+ getAllTools: () => session.getAllToolNames(),
78
103
  shutdown,
79
104
  getContextUsage: () => session.getContextUsage(),
80
105
  getSystemPrompt: () => session.systemPrompt,
81
106
  getWorkflowGate: () => session.getWorkflowGateEmitter(),
82
107
  compact: instructionsOrOptions => runExtensionCompact(session, instructionsOrOptions),
108
+ clearContext: () => session.clearContext(),
109
+ cycleModel: () => session.cycleModel(),
110
+ cycleThinkingLevel: () => session.cycleThinkingLevel(),
111
+ setQueueMode: (kind, mode) => {
112
+ if (kind === "steering" && (mode === "all" || mode === "one-at-a-time")) {
113
+ session.setSteeringMode(mode);
114
+ return true;
115
+ }
116
+ if (kind === "follow_up" && (mode === "all" || mode === "one-at-a-time")) {
117
+ session.setFollowUpMode(mode);
118
+ return true;
119
+ }
120
+ if (kind === "interrupt" && (mode === "immediate" || mode === "wait")) {
121
+ session.setInterruptMode(mode);
122
+ return true;
123
+ }
124
+ return false;
125
+ },
126
+ invokeSkill: (name, args) => session.invokeSkill(name, args),
127
+ setPlanMode: on => session.setSdkPlanMode(on),
128
+ operateGoal: (op, objective) => session.operateGoal(op, objective),
129
+ getSkillState: () => session.skills.map(skill => ({ name: skill.name, description: skill.description })),
130
+ getConfigItems: () => session.getSdkConfigItems(),
131
+ getBranchCandidates: () => session.sessionManager.getTree(),
132
+ getExtensions: () => session.extensionRunner?.getExtensionPaths() ?? [],
133
+ getArtifact: async id => {
134
+ const artifactsDir = session.sessionManager.getArtifactsDir();
135
+ if (!artifactsDir || !id) return undefined;
136
+ const candidate = path.resolve(artifactsDir, id);
137
+ const root = `${path.resolve(artifactsDir)}${path.sep}`;
138
+ if (!candidate.startsWith(root))
139
+ throw Object.assign(new Error("Artifact path escapes the session artifact directory."), {
140
+ code: "invalid_input",
141
+ });
142
+ const file = Bun.file(candidate);
143
+ return (await file.exists()) ? new Uint8Array(await file.arrayBuffer()) : undefined;
144
+ },
145
+ getArtifactRange: async (id, offset, length) => {
146
+ const artifactsDir = session.sessionManager.getArtifactsDir();
147
+ if (!artifactsDir || !id) return undefined;
148
+ const candidate = path.resolve(artifactsDir, id);
149
+ const root = `${path.resolve(artifactsDir)}${path.sep}`;
150
+ if (!candidate.startsWith(root))
151
+ throw Object.assign(new Error("Artifact path escapes the session artifact directory."), {
152
+ code: "invalid_input",
153
+ });
154
+ const file = Bun.file(candidate);
155
+ if (!(await file.exists())) return undefined;
156
+ const start = Math.min(Math.max(0, offset), file.size);
157
+ const end = Math.min(file.size, start + Math.max(0, length));
158
+ return { bytes: new Uint8Array(await file.slice(start, end).arrayBuffer()), totalBytes: file.size };
159
+ },
160
+ getJobs: () => session.getAsyncJobSnapshot(),
161
+ setSdkPermissionProvider: provider => session.setSdkPermissionProvider(provider),
162
+ sdkControl: async (operation, input) => {
163
+ switch (operation) {
164
+ case "model.set": {
165
+ const selector = typeof input.id === "string" ? input.id : "";
166
+ const slashIndex = selector.indexOf("/");
167
+ const model =
168
+ slashIndex > 0
169
+ ? session.modelRegistry.find(selector.slice(0, slashIndex), selector.slice(slashIndex + 1))
170
+ : undefined;
171
+ const thinkingLevel =
172
+ typeof input.thinkingLevel === "string" ? parseThinkingLevel(input.thinkingLevel) : undefined;
173
+ if (!model || !thinkingLevel || thinkingLevel === ThinkingLevel.Inherit)
174
+ throw Object.assign(new Error("model.set requires a valid model id and concrete thinkingLevel."), {
175
+ code: "invalid_input",
176
+ });
177
+ return await session.setDefaultModelSelection(model, thinkingLevel);
178
+ }
179
+ case "todo.replace": {
180
+ const phases = input.items;
181
+ if (
182
+ !Array.isArray(phases) ||
183
+ !phases.every((phase: unknown) => {
184
+ if (!phase || typeof phase !== "object") return false;
185
+ const candidate = phase as { name?: unknown; tasks?: unknown };
186
+ return (
187
+ typeof candidate.name === "string" &&
188
+ Array.isArray(candidate.tasks) &&
189
+ candidate.tasks.every((task: unknown) => {
190
+ if (!task || typeof task !== "object") return false;
191
+ const item = task as { content?: unknown; status?: unknown };
192
+ return (
193
+ typeof item.content === "string" &&
194
+ ["pending", "in_progress", "completed", "abandoned"].includes(String(item.status))
195
+ );
196
+ })
197
+ );
198
+ })
199
+ ) {
200
+ throw Object.assign(new Error("todo.replace requires TodoPhase items."), {
201
+ code: "invalid_input",
202
+ });
203
+ }
204
+ session.setTodoPhases(phases as TodoPhase[]);
205
+ return { replaced: session.getTodoPhases() };
206
+ }
207
+ case "permission_mode.set": {
208
+ const requested = input.mode;
209
+ const mode =
210
+ requested === "allow" || requested === "always-allow"
211
+ ? "allow"
212
+ : requested === "deny" || requested === "always-deny"
213
+ ? "deny"
214
+ : requested === "prompt"
215
+ ? "prompt"
216
+ : undefined;
217
+ if (!mode)
218
+ throw Object.assign(new Error("permission_mode.set requires prompt, allow, or deny."), {
219
+ code: "invalid_input",
220
+ });
221
+ session.setSdkPermissionMode(mode);
222
+ return { changed: true, mode: session.sdkPermissionMode };
223
+ }
224
+ case "bash.execute": {
225
+ if (typeof input.cmd !== "string" || input.cmd.trim() === "")
226
+ throw Object.assign(new Error("bash.execute requires a command."), { code: "invalid_input" });
227
+ const result = await session.executeBash(input.cmd, undefined, { excludeFromContext: true });
228
+ return {
229
+ exitCode: result.exitCode,
230
+ cancelled: result.cancelled,
231
+ output: result.output,
232
+ truncated: result.truncated,
233
+ };
234
+ }
235
+ case "bash.abort": {
236
+ if (!session.isBashRunning) return { aborted: false };
237
+ session.abortBash();
238
+ return { aborted: true };
239
+ }
240
+ case "retry.last": {
241
+ if (!(await session.retry()))
242
+ throw Object.assign(new Error("There is no failed or interrupted turn to retry."), {
243
+ code: "nothing_to_retry",
244
+ });
245
+ return { retried: true };
246
+ }
247
+ case "retry.now": {
248
+ if (!session.isRetrying)
249
+ throw Object.assign(new Error("No retry backoff is pending."), { code: "retry_not_pending" });
250
+ session.retryNow();
251
+ return { retried: true, immediate: true };
252
+ }
253
+ case "bash.background": {
254
+ if (!session.requestForegroundBashBackground())
255
+ throw Object.assign(
256
+ new Error("The active bash command cannot be moved to a managed background job."),
257
+ { code: "not_foldable" },
258
+ );
259
+ return { backgrounded: true };
260
+ }
261
+ case "compaction.auto.set":
262
+ session.setAutoCompactionEnabled(input.on === true);
263
+ return { changed: true };
264
+ case "retry.auto.set":
265
+ session.setAutoRetryEnabled(input.on === true);
266
+ return { changed: true };
267
+ case "retry.abort":
268
+ session.abortRetry();
269
+ return { aborted: true };
270
+ case "session.new":
271
+ return { created: await session.newSession() };
272
+ case "session.fork":
273
+ return { session: await session.fork() };
274
+ case "session.resume":
275
+ return { resumed: await session.switchSession(String(input.id)) };
276
+ case "session.close":
277
+ await session.sessionManager.flush();
278
+ return { closed: true };
279
+ case "session.switch":
280
+ return { switched: await session.switchSession(String(input.id)) };
281
+ case "session.branch":
282
+ try {
283
+ return await session.branch(String(input.entryId));
284
+ } catch (error) {
285
+ throw Object.assign(
286
+ new Error(error instanceof Error ? error.message : "Branch entry was not found."),
287
+ { code: "resource_gone" },
288
+ );
289
+ }
290
+ case "session.rename":
291
+ return { renamed: await session.setSessionName(String(input.name), "user") };
292
+ case "session.handoff":
293
+ try {
294
+ return {
295
+ handoff: await session.handoff(
296
+ typeof input.instructions === "string" ? input.instructions : undefined,
297
+ ),
298
+ };
299
+ } catch (error) {
300
+ throw Object.assign(
301
+ new Error(
302
+ error instanceof Error ? error.message : "Handoff is unavailable for the current state.",
303
+ ),
304
+ { code: "invalid_request" },
305
+ );
306
+ }
307
+ case "session.export_html":
308
+ try {
309
+ return {
310
+ path: await session.exportToHtml(typeof input.path === "string" ? input.path : undefined),
311
+ };
312
+ } catch (error) {
313
+ throw Object.assign(
314
+ new Error(
315
+ error instanceof Error
316
+ ? error.message
317
+ : "Session export is unavailable for the current state.",
318
+ ),
319
+ { code: "invalid_request" },
320
+ );
321
+ }
322
+ case "runtime.reload":
323
+ await session.reload();
324
+ return { reloaded: true };
325
+ case "service_tier.set":
326
+ session.setServiceTier(input.tier as never);
327
+ return { changed: true };
328
+ case "queue.message.remove": {
329
+ const removed = session.removeQueuedMessageForEditing(String(input.id));
330
+ if (removed === undefined)
331
+ throw Object.assign(new Error("Queued message was not found."), { code: "resource_gone" });
332
+ return { removed };
333
+ }
334
+ case "queue.message.move": {
335
+ const id = String(input.id);
336
+ const moved =
337
+ input.before !== undefined
338
+ ? session.moveQueuedMessageForEditing(id, "up")
339
+ : session.moveQueuedMessageForEditing(id, "down");
340
+ if (!moved)
341
+ throw Object.assign(new Error("Queue position is invalid."), { code: "invalid_position" });
342
+ return { moved };
343
+ }
344
+ case "queue.message.update": {
345
+ const id = String(input.id);
346
+ const old = session.removeQueuedMessageForEditing(id);
347
+ const patch = input.patch as { text?: unknown };
348
+ if (old === undefined || typeof patch?.text !== "string")
349
+ throw Object.assign(new Error("Queued message update is invalid."), { code: "invalid_message" });
350
+ await session.sendUserMessage(patch.text, {
351
+ deliverAs: id.startsWith("steer:") ? "steer" : "followUp",
352
+ });
353
+ return { updated: true };
354
+ }
355
+ case "extension.set_enabled": {
356
+ const id = String(input.id);
357
+ const disabled = [...(session.settings.get("disabledExtensions") ?? [])];
358
+ const on = input.on === true;
359
+ const next = on ? disabled.filter(value => value !== id) : [...new Set([...disabled, id])];
360
+ session.settings.set("disabledExtensions", next);
361
+ return { changed: true, enabled: on };
362
+ }
363
+ case "session.delete":
364
+ await session.sessionManager.dropSession(String(input.id));
365
+ return { deleted: true };
366
+ case "session.cwd.move":
367
+ await session.sessionManager.moveTo(String(input.path));
368
+ return { moved: true, cwd: session.sessionManager.getCwd() };
369
+ default:
370
+ throw Object.assign(new Error(`${operation} has no AgentSession implementation.`), {
371
+ code: "unavailable",
372
+ });
373
+ }
374
+ },
83
375
  },
84
376
  // ExtensionCommandContextActions — commands invokable via prompt("/command")
85
377
  {
@@ -7,16 +7,14 @@
7
7
  * - ultragoal execution sign-off -> `workflow_gate` { kind: "execution" } whose
8
8
  * answer is approve / decline (+ optional reason).
9
9
  *
10
- * Gates remain mandatory; the external agent substitutes for the human at the
11
- * answer boundary only. Declining / requesting changes is honored and is NEVER
12
- * silently treated as approval.
10
+ * Gates remain mandatory; the remote SDK client answers at the gate boundary.
11
+ * Declining / requesting changes is honored and is NEVER silently treated as approval.
13
12
  *
14
- * This is the pure mapping primitive; routing ralplan/ultragoal through it when
15
- * an unattended controller + gate broker are attached is wired with the transport
16
- * in #321 and exercised end-to-end by #323.
13
+ * This is the pure mapping primitive used by SDK-native workflow gate emitters.
17
14
  */
18
- import type { RpcJsonSchema, RpcWorkflowGateContext } from "../../rpc/rpc-types";
15
+
19
16
  import type { OpenGateInput } from "./workflow-gate-broker";
17
+ import type { JsonSchema, WorkflowGateContext } from "./workflow-gate-types";
20
18
 
21
19
  export type ApprovalDecision = "approve" | "request-changes" | "reject";
22
20
  export type ExecutionDecision = "approve" | "decline";
@@ -57,8 +55,8 @@ const APPROVAL_DECISIONS: ApprovalDecision[] = ["approve", "request-changes", "r
57
55
  const EXECUTION_DECISIONS: ExecutionDecision[] = ["approve", "decline"];
58
56
 
59
57
  /** Build the ralplan `pending approval` -> `workflow_gate { kind: "approval" }` open-input. */
60
- export function approvalGate(context: RpcWorkflowGateContext = {}): OpenGateInput {
61
- const schema: RpcJsonSchema = {
58
+ export function approvalGate(context: WorkflowGateContext = {}): OpenGateInput {
59
+ const schema: JsonSchema = {
62
60
  type: "object",
63
61
  properties: {
64
62
  decision: { type: "string", enum: APPROVAL_DECISIONS },
@@ -77,8 +75,8 @@ export function approvalGate(context: RpcWorkflowGateContext = {}): OpenGateInpu
77
75
  }
78
76
 
79
77
  /** Build the ultragoal execution sign-off -> `workflow_gate { kind: "execution" }` open-input. */
80
- export function executionGate(context: RpcWorkflowGateContext = {}): OpenGateInput {
81
- const schema: RpcJsonSchema = {
78
+ export function executionGate(context: WorkflowGateContext = {}): OpenGateInput {
79
+ const schema: JsonSchema = {
82
80
  type: "object",
83
81
  properties: {
84
82
  decision: { type: "string", enum: EXECUTION_DECISIONS },