@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
@@ -0,0 +1,867 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import * as fs from "node:fs/promises";
4
+ import * as path from "node:path";
5
+ import { ADAPTERS, OPERATIONS, type Operation } from "../src/sdk/protocol/operation-registry";
6
+
7
+ const repoRoot = path.resolve(import.meta.dir, "..", "..", "..");
8
+ const inventoryPath = process.env.GJC_SDK_OPERATION_INVENTORY
9
+ ? path.resolve(process.env.GJC_SDK_OPERATION_INVENTORY)
10
+ : path.join(repoRoot, "packages/coding-agent/src/sdk/protocol/operation-inventory.generated.json");
11
+
12
+ /** Reviewed seams deliberately excluded from the public SDK operation surface. */
13
+ const LOCKED_EXCLUSIONS: Readonly<Record<string, string>> = {
14
+ "slash_command:settings": "visual/local-only command, not a user-facing SDK control seam",
15
+ "slash_command:theme": "visual/local-only command, not a user-facing SDK control seam",
16
+ "slash_command:copy": "visual/local-only command, not a user-facing SDK control seam",
17
+ "slash_command:changelog": "visual/local-only command, not a user-facing SDK control seam",
18
+ "slash_command:help": "visual/local-only command, not a user-facing SDK control seam",
19
+ "slash_command:hotkeys": "visual/local-only command, not a user-facing SDK control seam",
20
+ "slash_command:agents": "visual/local-only command, not a user-facing SDK control seam",
21
+ "slash_command:monitors": "visual/local-only command, not a user-facing SDK control seam",
22
+ "slash_command:tree": "visual/local-only command, not a user-facing SDK control seam",
23
+ "slash_command:provider": "visual/local-only command, not a user-facing SDK control seam",
24
+ "slash_command:logout": "visual/local-only command, not a user-facing SDK control seam",
25
+ "slash_command:ssh": "visual/local-only command, not a user-facing SDK control seam",
26
+ "slash_command:drop": "visual/local-only command, not a user-facing SDK control seam",
27
+ "slash_command:contribute-pr": "visual/local-only command, not a user-facing SDK control seam",
28
+ "slash_command:btw": "visual/local-only command, not a user-facing SDK control seam",
29
+ "slash_command:debug": "visual/local-only command, not a user-facing SDK control seam",
30
+ "slash_command:memory": "visual/local-only command, not a user-facing SDK control seam",
31
+ "slash_command:exit": "visual/local-only command, not a user-facing SDK control seam",
32
+ "slash_command:notify":
33
+ "interactive diagnostics command; session on/off delegate to the notifications extension, not an SDK ingress seam",
34
+ "slash_command:pet": "visual/local-only command, not a user-facing SDK control seam",
35
+ "agent_session:constructor": "internal accessor/plumbing, not a user-facing control seam",
36
+ "agent_session:nextToolChoice": "internal accessor/plumbing, not a user-facing control seam",
37
+ "agent_session:setForcedToolChoice": "internal accessor/plumbing, not a user-facing control seam",
38
+ "agent_session:getActiveSkillState": "internal accessor/plumbing, not a user-facing control seam",
39
+ "agent_session:getActiveSkillPhase": "internal accessor/plumbing, not a user-facing control seam",
40
+ "agent_session:peekQueueInvoker": "internal accessor/plumbing, not a user-facing control seam",
41
+ "agent_session:peekStandingResolveHandler": "internal accessor/plumbing, not a user-facing control seam",
42
+ "agent_session:setStandingResolveHandler": "internal accessor/plumbing, not a user-facing control seam",
43
+ "agent_session:buildForkContextSeed": "internal accessor/plumbing, not a user-facing control seam",
44
+ "agent_session:getHindsightSessionState": "internal accessor/plumbing, not a user-facing control seam",
45
+ "agent_session:setHindsightSessionState": "internal accessor/plumbing, not a user-facing control seam",
46
+ "agent_session:markPlanCompactAbortPending": "internal accessor/plumbing, not a user-facing control seam",
47
+ "agent_session:clearPlanCompactAbortPending": "internal accessor/plumbing, not a user-facing control seam",
48
+ "agent_session:enqueueCustomMessageDisplay": "internal accessor/plumbing, not a user-facing control seam",
49
+ "agent_session:runMidRunMaintenanceForTests": "test-only maintenance seam, not a user-facing SDK control seam",
50
+ "agent_session:estimateMidRunContextTokensForTests": "test-only estimator seam, not a user-facing SDK control seam",
51
+ "agent_session:activeMidRunBarrierCountForTests": "read-only test seam, not a user-facing SDK control seam",
52
+ "agent_session:activeMidRunMaintenanceCountForTests": "read-only test seam, not a user-facing SDK control seam",
53
+ "agent_session:getAgentId": "internal accessor/plumbing, not a user-facing control seam",
54
+ "agent_session:emitNotice": "internal accessor/plumbing, not a user-facing control seam",
55
+ "agent_session:subscribe": "internal accessor/plumbing, not a user-facing control seam",
56
+ "agent_session:dispose": "internal accessor/plumbing, not a user-facing control seam",
57
+ "agent_session:closeWriterStrict": "internal ACP lifecycle teardown plumbing, not a user-facing control seam",
58
+ "agent_session:disposeChildSubprocesses": "internal accessor/plumbing, not a user-facing control seam",
59
+ "agent_session:waitForIdle": "internal accessor/plumbing, not a user-facing control seam",
60
+ "agent_session:drainAsyncJobDeliveriesForAcp": "internal accessor/plumbing, not a user-facing control seam",
61
+ "agent_session:getAsyncDeliveryStateForAcp":
62
+ "internal ACP lifecycle quiescence plumbing, not a user-facing control seam",
63
+ "agent_session:getToolByName": "internal accessor/plumbing, not a user-facing control seam",
64
+ "agent_session:registerForegroundBashBackgroundRequestHandler":
65
+ "internal accessor/plumbing, not a user-facing control seam",
66
+ "agent_session:hasForegroundBashBackgroundRequestHandler":
67
+ "internal accessor/plumbing, not a user-facing control seam",
68
+ "agent_session:requestForegroundBashBackground": "internal accessor/plumbing, not a user-facing control seam",
69
+ "agent_session:isMCPDiscoveryEnabled": "internal accessor/plumbing, not a user-facing control seam",
70
+ "agent_session:getDiscoverableMCPSearchIndex": "internal accessor/plumbing, not a user-facing control seam",
71
+ "agent_session:getSelectedMCPToolNames": "internal accessor/plumbing, not a user-facing control seam",
72
+ "agent_session:activateDiscoveredMCPTools": "internal accessor/plumbing, not a user-facing control seam",
73
+ "agent_session:isToolDiscoveryEnabled": "internal accessor/plumbing, not a user-facing control seam",
74
+ "agent_session:getDiscoverableToolSearchIndex": "internal accessor/plumbing, not a user-facing control seam",
75
+ "agent_session:getSelectedDiscoveredToolNames": "internal accessor/plumbing, not a user-facing control seam",
76
+ "agent_session:activateDiscoveredTools": "internal accessor/plumbing, not a user-facing control seam",
77
+ "agent_session:refreshSshTool": "internal accessor/plumbing, not a user-facing control seam",
78
+ "agent_session:refreshBaseSystemPrompt": "internal accessor/plumbing, not a user-facing control seam",
79
+ "agent_session:refreshMCPTools": "internal accessor/plumbing, not a user-facing control seam",
80
+ "agent_session:refreshGjcSubskillTools": "internal accessor/plumbing, not a user-facing control seam",
81
+ "agent_session:buildDisplaySessionContext": "internal accessor/plumbing, not a user-facing control seam",
82
+ "agent_session:convertMessagesToLlm": "internal accessor/plumbing, not a user-facing control seam",
83
+ "agent_session:prepareSimpleStreamOptions": "internal accessor/plumbing, not a user-facing control seam",
84
+ "agent_session:getPlanModeState": "internal accessor/plumbing, not a user-facing control seam",
85
+ "agent_session:setPlanModeState": "internal accessor/plumbing, not a user-facing control seam",
86
+ "agent_session:getGoalModeState": "internal accessor/plumbing, not a user-facing control seam",
87
+ "agent_session:setGoalModeState": "internal accessor/plumbing, not a user-facing control seam",
88
+ "agent_session:getWorkflowGateEmitter": "internal accessor/plumbing, not a user-facing control seam",
89
+ "agent_session:getAskAnswerSource": "internal accessor/plumbing, not a user-facing control seam",
90
+ "agent_session:setWorkflowGateEmitter": "internal accessor/plumbing, not a user-facing control seam",
91
+ "agent_session:markPlanReferenceSent": "internal accessor/plumbing, not a user-facing control seam",
92
+ "agent_session:setPlanReferencePath": "internal accessor/plumbing, not a user-facing control seam",
93
+ "agent_session:setClientBridge": "internal accessor/plumbing, not a user-facing control seam",
94
+ "agent_session:getCheckpointState": "internal accessor/plumbing, not a user-facing control seam",
95
+ "agent_session:setCheckpointState": "internal accessor/plumbing, not a user-facing control seam",
96
+ "agent_session:sendPlanModeContext": "internal accessor/plumbing, not a user-facing control seam",
97
+ "agent_session:sendGoalModeContext": "internal accessor/plumbing, not a user-facing control seam",
98
+ "agent_session:resolveRoleModel": "internal accessor/plumbing, not a user-facing control seam",
99
+ "agent_session:resolveRoleModelWithThinking": "internal accessor/plumbing, not a user-facing control seam",
100
+ "agent_session:setSlashCommands": "internal accessor/plumbing, not a user-facing control seam",
101
+ "agent_session:setMCPPromptCommands": "internal accessor/plumbing, not a user-facing control seam",
102
+ "agent_session:queueDeferredMessage": "internal accessor/plumbing, not a user-facing control seam",
103
+ "agent_session:queueDeferredMessageForTests": "internal accessor/plumbing, not a user-facing control seam",
104
+ "agent_session:getContextUsageObservabilityForTests": "test-only observability, not a user-facing control seam",
105
+ "agent_session:purgeQueuedCustomMessages": "internal accessor/plumbing, not a user-facing control seam",
106
+ "agent_session:clearQueue": "internal accessor/plumbing, not a user-facing control seam",
107
+ "agent_session:popLastQueuedMessage": "internal accessor/plumbing, not a user-facing control seam",
108
+ "agent_session:applyCompactionPostAppendForTests": "internal accessor/plumbing, not a user-facing control seam",
109
+ "agent_session:continuePersistedHistory": "internal startup lifecycle plumbing, not a user-facing control seam",
110
+ "agent_session:setActiveModelProfile": "internal accessor/plumbing, not a user-facing control seam",
111
+ "agent_session:getActiveModelProfile": "internal accessor/plumbing, not a user-facing control seam",
112
+ "agent_session:getSessionDefaultModelSelector": "internal accessor/plumbing, not a user-facing control seam",
113
+ "agent_session:recordResumeDefaultModel": "internal accessor/plumbing, not a user-facing control seam",
114
+ "agent_session:setModelTemporary": "internal accessor/plumbing, not a user-facing control seam",
115
+ "agent_session:setModelTemporaryForControl":
116
+ "internal Telegram control wrapper over the reviewed model.set seam, not an independent public SDK operation",
117
+ "agent_session:setThinkingLevelForControl":
118
+ "internal Telegram control wrapper over the reviewed thinking.set seam, not an independent public SDK operation",
119
+ "agent_session:getThinkingScopeForControl":
120
+ "internal Telegram control status accessor, not a user-facing SDK operation seam",
121
+ "agent_session:getThinkingVisibility":
122
+ "internal extension and Telegram display accessor, not a user-facing SDK operation seam",
123
+ "agent_session:setThinkingVisibility": "internal extension display mutation without a public SDK registry operation",
124
+ "agent_session:setThinkingVisibilityForControl":
125
+ "internal Telegram control wrapper over display state, not an independent public SDK operation",
126
+ "agent_session:fetchUsageReportsForControl":
127
+ "internal Telegram control wrapper over the reviewed usage.get seam, not an independent public SDK operation",
128
+ "agent_session:cycleRoleModels": "internal accessor/plumbing, not a user-facing control seam",
129
+ "agent_session:isFastModeEnabled": "internal accessor/plumbing, not a user-facing control seam",
130
+ "agent_session:isFastForProvider": "internal accessor/plumbing, not a user-facing control seam",
131
+ "agent_session:isFastForSubagentProvider": "internal accessor/plumbing, not a user-facing control seam",
132
+ "agent_session:isFastModeActive": "internal accessor/plumbing, not a user-facing control seam",
133
+ "agent_session:getAvailableThinkingLevels": "internal accessor/plumbing, not a user-facing control seam",
134
+ "agent_session:abortCompaction": "internal accessor/plumbing, not a user-facing control seam",
135
+ "agent_session:runIdleCompaction": "internal accessor/plumbing, not a user-facing control seam",
136
+ "agent_session:abortBranchSummary": "internal accessor/plumbing, not a user-facing control seam",
137
+ "agent_session:abortHandoff": "internal accessor/plumbing, not a user-facing control seam",
138
+ "agent_session:prepareContributionPrep": "internal accessor/plumbing, not a user-facing control seam",
139
+ "agent_session:setResourceSampler": "internal accessor/plumbing, not a user-facing control seam",
140
+ "agent_session:setRetainedMemorySampler": "internal accessor/plumbing, not a user-facing control seam",
141
+ "agent_session:recordBashResult": "internal accessor/plumbing, not a user-facing control seam",
142
+ "agent_session:executePython": "internal accessor/plumbing, not a user-facing control seam",
143
+ "agent_session:assertEvalExecutionAllowed": "internal accessor/plumbing, not a user-facing control seam",
144
+ "agent_session:promptCustomMessage": "internal custom-message plumbing, not a user-facing SDK control seam",
145
+ "agent_session:sendCustomMessage": "internal custom-message plumbing, not a user-facing SDK control seam",
146
+ "agent_session:trackEvalExecution": "internal execution bookkeeping, not a user-facing SDK control seam",
147
+ "agent_session:recordPythonResult": "internal accessor/plumbing, not a user-facing control seam",
148
+ "agent_session:abortEval": "internal accessor/plumbing, not a user-facing control seam",
149
+ "agent_session:respondAsBackground": "internal accessor/plumbing, not a user-facing control seam",
150
+ "agent_session:emitIrcRelayObservation": "internal accessor/plumbing, not a user-facing control seam",
151
+ "agent_session:emitSubagentSteerObservation": "internal accessor/plumbing, not a user-facing control seam",
152
+ "agent_session:emitSubagentSteerRelayObservation": "internal accessor/plumbing, not a user-facing control seam",
153
+ "agent_session:runEphemeralTurn": "internal accessor/plumbing, not a user-facing control seam",
154
+ "agent_session:navigateTree": "internal accessor/plumbing, not a user-facing control seam",
155
+ "agent_session:hasCopyCandidateAssistantMessage": "internal accessor/plumbing, not a user-facing control seam",
156
+ "agent_session:getLastVisibleHandoffText": "internal accessor/plumbing, not a user-facing control seam",
157
+ "agent_session:hasExtensionHandlers": "internal accessor/plumbing, not a user-facing control seam",
158
+ "agent_session:registerBeforeAgentStartContributor": "internal accessor/plumbing, not a user-facing control seam",
159
+ "agent_session:setSdkPermissionProvider": "internal reverse-provider plumbing, not a user-facing SDK control seam",
160
+ "agent_session:beginTemporaryProviderSessionScope":
161
+ "internal temporary model/provider restoration scope, not a user-facing SDK control seam",
162
+ "agent_session:restoreTemporaryProviderSessionScope":
163
+ "internal temporary model/provider restoration scope, not a user-facing SDK control seam",
164
+ "agent_session:commitTemporaryProviderSessionScope":
165
+ "internal temporary model/provider restoration scope, not a user-facing SDK control seam",
166
+ "agent_session:getConfiguredModelChain":
167
+ "internal profile and fallback-chain state, not a user-facing SDK control seam",
168
+ "agent_session:setConfiguredModelChain":
169
+ "internal profile and fallback-chain state, not a user-facing SDK control seam",
170
+ "agent_session:setDefaultFallbackRuntimeModel":
171
+ "internal fallback runtime bookkeeping, not a user-facing SDK control seam",
172
+ "agent_session:seedDefaultFallbackResolution":
173
+ "internal fallback resolution bookkeeping, not a user-facing SDK control seam",
174
+ };
175
+ /** Maps reviewed source seams to registry SDK operation IDs. */
176
+ const SEAM_TO_SDK: Readonly<Record<string, string>> = {
177
+ "agent_session:prompt": "turn.prompt",
178
+ "agent_session:steer": "turn.steer",
179
+ "agent_session:followUp": "turn.follow_up",
180
+ "agent_session:abort": "turn.abort",
181
+ "agent_session:newSession": "session.new",
182
+ "agent_session:fork": "session.fork",
183
+ "agent_session:clearContext": "context.clear",
184
+ "agent_session:setSessionName": "session.rename",
185
+ "agent_session:setModel": "model.set",
186
+ "agent_session:setDefaultModelSelection": "model.set",
187
+ "agent_session:cycleModel": "model.cycle",
188
+ "agent_session:setThinkingLevel": "thinking.set",
189
+ "agent_session:cycleThinkingLevel": "thinking.cycle",
190
+ "agent_session:setSteeringMode": "queue.steering_mode.set",
191
+ "agent_session:setFollowUpMode": "queue.follow_up_mode.set",
192
+ "agent_session:setInterruptMode": "queue.interrupt_mode.set",
193
+ "agent_session:compact": "compaction.run",
194
+ "agent_session:setAutoCompactionEnabled": "compaction.auto.set",
195
+ "agent_session:setAutoRetryEnabled": "retry.auto.set",
196
+ "agent_session:abortRetry": "retry.abort",
197
+ "agent_session:retry": "retry.last",
198
+ "agent_session:retryNow": "retry.now",
199
+ "agent_session:setActiveToolsByName": "tools.active.set",
200
+ "agent_session:removeQueuedMessageForEditing": "queue.message.remove",
201
+ "agent_session:moveQueuedMessageForEditing": "queue.message.move",
202
+ "agent_session:executeBash": "bash.execute",
203
+ "agent_session:abortBash": "bash.abort",
204
+ "agent_session:switchSession": "session.switch",
205
+ "agent_session:branch": "session.branch",
206
+ "agent_session:handoff": "session.handoff",
207
+ "agent_session:exportToHtml": "session.export_html",
208
+ "agent_session:getAvailableModels": "models.list/current",
209
+ "agent_session:getSdkConfigItems": "config.list/get",
210
+ "agent_session:getActiveToolNames": "tools.list",
211
+ "agent_session:getQueuedMessages": "queue.messages.list",
212
+ "agent_session:getTodoPhases": "todo.list",
213
+ "agent_session:getContextUsage": "context.get",
214
+ "agent_session:getTranscript": "transcript.list",
215
+ "agent_session:getTranscriptBody": "transcript.body",
216
+ "agent_session:getSessionStats": "session.stats",
217
+ "agent_session:getLastAssistantMessage": "session.last_assistant",
218
+ "agent_session:getUserMessagesForBranching": "session.branch_candidates",
219
+ "agent_session:getAsyncJobSnapshot": "runtime.jobs.list",
220
+ "agent_session:fetchUsageReports": "usage.get",
221
+ "agent_session:setTodoPhases": "todo.replace",
222
+ "agent_session:getQueuedMessageEntries": "queue.messages.list",
223
+ "agent_session:getAllToolNames": "tools.list",
224
+ "agent_session:getDiscoverableMCPTools": "tools.list",
225
+ "agent_session:getDiscoverableTools": "tools.list",
226
+ "agent_session:sendUserMessage": "turn.steer",
227
+ "agent_session:reload": "runtime.reload",
228
+ "agent_session:setSdkPermissionMode": "permission_mode.set",
229
+ "agent_session:invokeSkill": "skill.invoke",
230
+ "agent_session:setSdkPlanMode": "mode.plan.set",
231
+ "agent_session:operateGoal": "mode.goal.operate",
232
+ "agent_session:setServiceTier": "service_tier.set",
233
+ "agent_session:setFastMode": "service_tier.set",
234
+ "agent_session:toggleFastMode": "service_tier.set",
235
+ "agent_session:getLastAssistantText": "session.last_assistant",
236
+ "agent_session:formatSessionAsText": "transcript.body",
237
+ "agent_session:formatCompactContext": "context.get",
238
+ "slash_command:goal": "mode.goal.operate",
239
+ "slash_command:model": "model.set",
240
+ "slash_command:effort": "thinking.set",
241
+ "slash_command:fast": "service_tier.set",
242
+ "slash_command:export": "session.export_html",
243
+ "slash_command:dump": "transcript.body",
244
+ "slash_command:session": "session.list",
245
+ "slash_command:jobs": "runtime.jobs.list",
246
+ "slash_command:context": "context.get",
247
+ "slash_command:usage": "usage.get",
248
+ "slash_command:tools": "tools.list",
249
+ "slash_command:login": "auth.login",
250
+ "slash_command:clear": "context.clear",
251
+ "slash_command:new": "session.new",
252
+ "slash_command:compact": "compaction.run",
253
+ "slash_command:resume": "session.resume",
254
+ "slash_command:retry": "retry.last",
255
+ "slash_command:background": "bash.background",
256
+ "slash_command:rename": "session.rename",
257
+ "slash_command:move": "session.cwd.move",
258
+ };
259
+
260
+ /** Genuine action seams awaiting a reviewed registry mapping or exclusion. */
261
+ const PENDING_REVIEW: Readonly<Record<string, string>> = {};
262
+
263
+ function lockedExclusion(sourceId: string): string | undefined {
264
+ return LOCKED_EXCLUSIONS[sourceId];
265
+ }
266
+
267
+ export type SourceKind = "registry" | "controller" | "agent_session" | "slash_command" | "acp" | "locked_exclusion";
268
+ export interface SourceSeam {
269
+ sourceId: string;
270
+ sourceFile: string;
271
+ sourceKind: SourceKind;
272
+ }
273
+ interface InventoryRecord {
274
+ sourceId: string;
275
+ sourceFile: string;
276
+ sourceKind: SourceKind;
277
+ decision: "include" | "exclude";
278
+ rationale?: string;
279
+ sdkId?: string;
280
+ adapterMappings: Operation["adapterDispositions"];
281
+ testIds: string[];
282
+ }
283
+
284
+ function repoPath(file: string): string {
285
+ return path.relative(repoRoot, file).split(path.sep).join("/");
286
+ }
287
+
288
+ /** Controller seam adapter. Semantic IDs never depend on line numbers. */
289
+ function collectCaseSeams(source: string, prefix: string): string[] {
290
+ return [...source.matchAll(/case\s+["']([^"']+)["']/g)].map(match => `${prefix}:${match[1]}`);
291
+ }
292
+
293
+ export function scanSlashCommands(sourceText: string): string[] {
294
+ const builtinRegistry = sourceText.slice(sourceText.indexOf("const BUILTIN_SLASH_COMMAND_REGISTRY"));
295
+ return [...builtinRegistry.matchAll(/^\t\tname:\s*["']([^"']+)["']/gm)].map(match => `slash_command:${match[1]}`);
296
+ }
297
+
298
+ type TokenKind = "identifier" | "number" | "punctuation" | "string" | "template";
299
+ type Token = {
300
+ kind: TokenKind;
301
+ text: string;
302
+ value?: string;
303
+ hasSubstitution?: boolean;
304
+ };
305
+
306
+ const METHOD_MODIFIERS = new Set([
307
+ "public",
308
+ "protected",
309
+ "private",
310
+ "static",
311
+ "override",
312
+ "abstract",
313
+ "declare",
314
+ "readonly",
315
+ ]);
316
+
317
+ function isIdentifierStart(char: string): boolean {
318
+ return (char >= "a" && char <= "z") || (char >= "A" && char <= "Z") || char === "_" || char === "$";
319
+ }
320
+
321
+ function isIdentifierPart(char: string): boolean {
322
+ return isIdentifierStart(char) || (char >= "0" && char <= "9");
323
+ }
324
+
325
+ function skipLineComment(sourceText: string, start: number): number {
326
+ const newline = sourceText.indexOf("\n", start + 2);
327
+ return newline === -1 ? sourceText.length : newline + 1;
328
+ }
329
+
330
+ function skipBlockComment(sourceText: string, start: number): number {
331
+ const end = sourceText.indexOf("*/", start + 2);
332
+ return end === -1 ? sourceText.length : end + 2;
333
+ }
334
+
335
+ function decodeEscape(sourceText: string, index: number): { next: number; value: string } {
336
+ const char = sourceText[index];
337
+ if (char === undefined) return { next: index, value: "" };
338
+ const simpleEscapes: Readonly<Record<string, string>> = {
339
+ b: "\b",
340
+ f: "\f",
341
+ n: "\n",
342
+ r: "\r",
343
+ t: "\t",
344
+ v: "\v",
345
+ "0": "\0",
346
+ };
347
+ if (char in simpleEscapes) return { next: index + 1, value: simpleEscapes[char]! };
348
+ if (char === "\r") return { next: sourceText[index + 1] === "\n" ? index + 2 : index + 1, value: "" };
349
+ if (char === "\n") return { next: index + 1, value: "" };
350
+ if (char === "x") {
351
+ const code = Number.parseInt(sourceText.slice(index + 1, index + 3), 16);
352
+ return { next: index + 3, value: Number.isNaN(code) ? "" : String.fromCodePoint(code) };
353
+ }
354
+ if (char === "u") {
355
+ const braced = sourceText[index + 1] === "{";
356
+ const end = braced ? sourceText.indexOf("}", index + 2) : index + 5;
357
+ const hex = braced ? sourceText.slice(index + 2, end) : sourceText.slice(index + 1, end);
358
+ const code = Number.parseInt(hex, 16);
359
+ return {
360
+ next: braced ? (end === -1 ? index + 2 : end + 1) : end,
361
+ value: Number.isNaN(code) ? "" : String.fromCodePoint(code),
362
+ };
363
+ }
364
+ return { next: index + 1, value: char };
365
+ }
366
+
367
+ function readQuotedToken(sourceText: string, start: number): { next: number; value: string } {
368
+ const quote = sourceText[start]!;
369
+ let value = "";
370
+ let index = start + 1;
371
+ while (index < sourceText.length) {
372
+ const char = sourceText[index]!;
373
+ if (char === quote) return { next: index + 1, value };
374
+ if (char === "\\") {
375
+ const escapeSequence = decodeEscape(sourceText, index + 1);
376
+ value += escapeSequence.value;
377
+ index = escapeSequence.next;
378
+ continue;
379
+ }
380
+ value += char;
381
+ index++;
382
+ }
383
+ return { next: index, value };
384
+ }
385
+
386
+ function skipRegularExpression(sourceText: string, start: number): number {
387
+ let inCharacterClass = false;
388
+ for (let index = start + 1; index < sourceText.length; index++) {
389
+ const char = sourceText[index]!;
390
+ if (char === "\\") {
391
+ index++;
392
+ continue;
393
+ }
394
+ if (char === "[") inCharacterClass = true;
395
+ else if (char === "]") inCharacterClass = false;
396
+ else if (char === "/" && !inCharacterClass) {
397
+ index++;
398
+ while (isIdentifierPart(sourceText[index] ?? "")) index++;
399
+ return index;
400
+ } else if (char === "\n" || char === "\r") return index;
401
+ }
402
+ return sourceText.length;
403
+ }
404
+
405
+ function tokenCanPrecedeRegularExpression(token: Token | undefined): boolean {
406
+ return (
407
+ !token ||
408
+ ["(", "[", "{", "=", ":", ",", ";", "!", "?", "&&", "||", "=>", "return", "case", "throw"].includes(token.text)
409
+ );
410
+ }
411
+
412
+ function skipTemplateExpression(sourceText: string, start: number): number {
413
+ let depth = 1;
414
+ for (let index = start; index < sourceText.length; index++) {
415
+ const char = sourceText[index]!;
416
+ if (char === "'" || char === '"') {
417
+ index = readQuotedToken(sourceText, index).next - 1;
418
+ continue;
419
+ }
420
+ if (char === "`") {
421
+ index = readTemplateToken(sourceText, index).next - 1;
422
+ continue;
423
+ }
424
+ if (char === "/" && sourceText[index + 1] === "/") {
425
+ index = skipLineComment(sourceText, index) - 1;
426
+ continue;
427
+ }
428
+ if (char === "/" && sourceText[index + 1] === "*") {
429
+ index = skipBlockComment(sourceText, index) - 1;
430
+ continue;
431
+ }
432
+ if (char === "{") depth++;
433
+ else if (char === "}" && --depth === 0) return index + 1;
434
+ }
435
+ return sourceText.length;
436
+ }
437
+
438
+ function readTemplateToken(
439
+ sourceText: string,
440
+ start: number,
441
+ ): { next: number; value: string; hasSubstitution: boolean } {
442
+ let hasSubstitution = false;
443
+ let index = start + 1;
444
+ let value = "";
445
+ while (index < sourceText.length) {
446
+ const char = sourceText[index]!;
447
+ if (char === "`") return { next: index + 1, value, hasSubstitution };
448
+ if (char === "\\") {
449
+ const escapeSequence = decodeEscape(sourceText, index + 1);
450
+ value += escapeSequence.value;
451
+ index = escapeSequence.next;
452
+ continue;
453
+ }
454
+ if (char === "$" && sourceText[index + 1] === "{") {
455
+ hasSubstitution = true;
456
+ index = skipTemplateExpression(sourceText, index + 2);
457
+ continue;
458
+ }
459
+ value += char;
460
+ index++;
461
+ }
462
+ return { next: index, value, hasSubstitution };
463
+ }
464
+
465
+ function tokenize(sourceText: string): Token[] {
466
+ const tokens: Token[] = [];
467
+ for (let index = 0; index < sourceText.length; ) {
468
+ const char = sourceText[index]!;
469
+ if (/\s/.test(char)) {
470
+ index++;
471
+ continue;
472
+ }
473
+ if (char === "/" && sourceText[index + 1] === "/") {
474
+ index = skipLineComment(sourceText, index);
475
+ continue;
476
+ }
477
+ if (char === "/" && sourceText[index + 1] === "*") {
478
+ index = skipBlockComment(sourceText, index);
479
+ continue;
480
+ }
481
+ if (char === "'" || char === '"') {
482
+ const token = readQuotedToken(sourceText, index);
483
+ tokens.push({ kind: "string", text: sourceText.slice(index, token.next), value: token.value });
484
+ index = token.next;
485
+ continue;
486
+ }
487
+ if (char === "`") {
488
+ const token = readTemplateToken(sourceText, index);
489
+ tokens.push({
490
+ kind: "template",
491
+ text: sourceText.slice(index, token.next),
492
+ value: token.value,
493
+ hasSubstitution: token.hasSubstitution,
494
+ });
495
+ index = token.next;
496
+ continue;
497
+ }
498
+ if (char === "/" && tokenCanPrecedeRegularExpression(tokens.at(-1))) {
499
+ index = skipRegularExpression(sourceText, index);
500
+ continue;
501
+ }
502
+ if (isIdentifierStart(char)) {
503
+ const start = index++;
504
+ while (isIdentifierPart(sourceText[index] ?? "")) index++;
505
+ tokens.push({ kind: "identifier", text: sourceText.slice(start, index) });
506
+ continue;
507
+ }
508
+ if (char >= "0" && char <= "9") {
509
+ const start = index++;
510
+ while (/[0-9A-Za-z._]/.test(sourceText[index] ?? "")) index++;
511
+ tokens.push({ kind: "number", text: sourceText.slice(start, index) });
512
+ continue;
513
+ }
514
+ const punctuation =
515
+ sourceText.slice(index, index + 3) === "..."
516
+ ? "..."
517
+ : sourceText.slice(index, index + 2) === "=>"
518
+ ? "=>"
519
+ : char;
520
+ tokens.push({ kind: "punctuation", text: punctuation });
521
+ index += punctuation.length;
522
+ }
523
+ return tokens;
524
+ }
525
+
526
+ function matchingToken(tokens: readonly Token[], start: number, open: string, close: string): number | undefined {
527
+ if (tokens[start]?.text !== open) return undefined;
528
+ let depth = 0;
529
+ for (let index = start; index < tokens.length; index++) {
530
+ if (tokens[index]!.text === open) depth++;
531
+ else if (tokens[index]!.text === close && --depth === 0) return index;
532
+ }
533
+ return undefined;
534
+ }
535
+
536
+ function skipTypeParameters(tokens: readonly Token[], start: number): number {
537
+ if (tokens[start]?.text !== "<") return start;
538
+ let depth = 0;
539
+ for (let index = start; index < tokens.length; index++) {
540
+ if (tokens[index]!.text === "<") depth++;
541
+ else if (tokens[index]!.text === ">" && --depth === 0) return index + 1;
542
+ }
543
+ return start;
544
+ }
545
+
546
+ function isMemberName(token: Token | undefined): boolean {
547
+ return token?.kind === "identifier" || token?.kind === "string" || token?.kind === "number";
548
+ }
549
+
550
+ function memberName(token: Token): string | undefined {
551
+ return token.kind === "string"
552
+ ? token.value
553
+ : token.kind === "identifier" || token.kind === "number"
554
+ ? token.text
555
+ : undefined;
556
+ }
557
+
558
+ function skipDecorators(tokens: readonly Token[], start: number): number {
559
+ let index = start;
560
+ while (tokens[index]?.text === "@") {
561
+ index++;
562
+ if (tokens[index]?.kind !== "identifier") return index;
563
+ index++;
564
+ while (tokens[index]?.text === "." && tokens[index + 1]?.kind === "identifier") index += 2;
565
+ index = skipTypeParameters(tokens, index);
566
+ if (tokens[index]?.text === "(") {
567
+ const close = matchingToken(tokens, index, "(", ")");
568
+ if (close === undefined) return tokens.length;
569
+ index = close + 1;
570
+ }
571
+ }
572
+ return index;
573
+ }
574
+
575
+ function memberEnd(tokens: readonly Token[], start: number, classEnd: number): number {
576
+ for (let index = start; index < classEnd; index++) {
577
+ if (tokens[index]!.text === ";") return index + 1;
578
+ if (tokens[index]!.text === "{") {
579
+ const close = matchingToken(tokens, index, "{", "}");
580
+ return close === undefined ? classEnd : close + 1;
581
+ }
582
+ }
583
+ return classEnd;
584
+ }
585
+
586
+ function nextMemberStart(tokens: readonly Token[], start: number, classEnd: number): number {
587
+ let braceDepth = 0;
588
+ let bracketDepth = 0;
589
+ let parenDepth = 0;
590
+ for (let index = start; index < classEnd; index++) {
591
+ const token = tokens[index]!.text;
592
+ if (token === "(") parenDepth++;
593
+ else if (token === ")" && parenDepth > 0) parenDepth--;
594
+ else if (token === "[") bracketDepth++;
595
+ else if (token === "]" && bracketDepth > 0) bracketDepth--;
596
+ else if (token === "{") braceDepth++;
597
+ else if (token === "}" && braceDepth > 0) {
598
+ braceDepth--;
599
+ if (parenDepth === 0 && bracketDepth === 0 && braceDepth === 0) return index + 1;
600
+ } else if (token === ";" && parenDepth === 0 && bracketDepth === 0 && braceDepth === 0) return index + 1;
601
+ }
602
+ return classEnd;
603
+ }
604
+
605
+ type MethodDeclaration = { end: number; name?: string };
606
+
607
+ type ParsedMemberName = { computed: boolean; end: number; name?: string };
608
+
609
+ function parseMemberName(tokens: readonly Token[], start: number): ParsedMemberName | undefined {
610
+ const direct = tokens[start];
611
+ if (isMemberName(direct)) return { computed: false, end: start + 1, name: memberName(direct!) };
612
+ if (direct?.text !== "[" || tokens[start + 2]?.text !== "]") return undefined;
613
+ const computed = tokens[start + 1];
614
+ if (computed?.kind === "string" || computed?.kind === "number") {
615
+ return { computed: true, end: start + 3, name: memberName(computed) };
616
+ }
617
+ if (computed?.kind === "template" && !computed.hasSubstitution) {
618
+ return { computed: true, end: start + 3, name: computed.value };
619
+ }
620
+ return undefined;
621
+ }
622
+
623
+ function scanMethodDeclaration(
624
+ tokens: readonly Token[],
625
+ start: number,
626
+ classEnd: number,
627
+ ): MethodDeclaration | undefined {
628
+ let index = skipDecorators(tokens, start);
629
+ while (tokens[index]?.kind === "identifier" && METHOD_MODIFIERS.has(tokens[index]!.text)) index++;
630
+ if (tokens[index]?.text === "async" && tokens[index + 1]?.text !== "(") index++;
631
+ if (tokens[index]?.text === "*") index++;
632
+ const candidate = tokens[index];
633
+ if (candidate?.text === "get" || candidate?.text === "set") {
634
+ const accessor = parseMemberName(tokens, index + 1);
635
+ if (!accessor) return undefined;
636
+ const accessorEnd = skipTypeParameters(tokens, accessor.end);
637
+ if (tokens[accessorEnd]?.text !== "(") return undefined;
638
+ const close = matchingToken(tokens, accessorEnd, "(", ")");
639
+ if (close === undefined) return undefined;
640
+ return {
641
+ end: memberEnd(tokens, close + 1, classEnd),
642
+ name: accessor.name?.endsWith("ForTests") ? accessor.name : undefined,
643
+ };
644
+ }
645
+
646
+ const method = parseMemberName(tokens, index);
647
+ if (!method) return undefined;
648
+ const afterName = skipTypeParameters(tokens, method.end);
649
+ if (tokens[afterName]?.text !== "(") return undefined;
650
+ const close = matchingToken(tokens, afterName, "(", ")");
651
+ if (close === undefined) return undefined;
652
+ return {
653
+ end: memberEnd(tokens, close + 1, classEnd),
654
+ name: method.computed && !method.name?.endsWith("ForTests") ? undefined : method.name,
655
+ };
656
+ }
657
+
658
+ export function scanAgentSessionMethods(sourceText: string): string[] {
659
+ const tokens = tokenize(sourceText);
660
+ for (let index = 0; index < tokens.length - 2; index++) {
661
+ if (tokens[index]!.text !== "class" || tokens[index + 1]?.text !== "AgentSession") continue;
662
+ let angleDepth = 0;
663
+ let bodyStart: number | undefined;
664
+ for (let bodyIndex = index + 2; bodyIndex < tokens.length; bodyIndex++) {
665
+ if (tokens[bodyIndex]!.text === "<") angleDepth++;
666
+ else if (tokens[bodyIndex]!.text === ">" && angleDepth > 0) angleDepth--;
667
+ else if (tokens[bodyIndex]!.text === "{" && angleDepth === 0) {
668
+ bodyStart = bodyIndex;
669
+ break;
670
+ }
671
+ }
672
+ if (bodyStart === undefined) return [];
673
+ const bodyEnd = matchingToken(tokens, bodyStart, "{", "}");
674
+ if (bodyEnd === undefined) return [];
675
+
676
+ const methods: string[] = [];
677
+ for (let memberStart = bodyStart + 1; memberStart < bodyEnd; ) {
678
+ const declaration = scanMethodDeclaration(tokens, memberStart, bodyEnd);
679
+ if (declaration) {
680
+ if (declaration.name) methods.push(`agent_session:${declaration.name}`);
681
+ memberStart = Math.max(memberStart + 1, declaration.end);
682
+ continue;
683
+ }
684
+ memberStart = Math.max(memberStart + 1, nextMemberStart(tokens, memberStart, bodyEnd));
685
+ }
686
+ return methods;
687
+ }
688
+ return [];
689
+ }
690
+
691
+ export function scanAcpMethods(sourceText: string): string[] {
692
+ const tokens = tokenize(sourceText);
693
+ const methods: string[] = [];
694
+ for (let index = 0; index < tokens.length - 4; index++) {
695
+ if (tokens[index]!.text !== "switch" || tokens[index + 1]?.text !== "(") continue;
696
+ const expressionEnd = matchingToken(tokens, index + 1, "(", ")");
697
+ if (
698
+ expressionEnd === undefined ||
699
+ expressionEnd !== index + 3 ||
700
+ tokens[index + 2]?.text !== "method" ||
701
+ tokens[expressionEnd + 1]?.text !== "{"
702
+ )
703
+ continue;
704
+ const switchEnd = matchingToken(tokens, expressionEnd + 1, "{", "}");
705
+ if (switchEnd === undefined) continue;
706
+ let braceDepth = 0;
707
+ for (let caseIndex = expressionEnd + 2; caseIndex < switchEnd; caseIndex++) {
708
+ const token = tokens[caseIndex]!;
709
+ if (braceDepth === 0 && token.text === "case") {
710
+ const label = tokens[caseIndex + 1];
711
+ if (
712
+ (label?.kind === "string" || (label?.kind === "template" && !label.hasSubstitution)) &&
713
+ tokens[caseIndex + 2]?.text === ":"
714
+ )
715
+ methods.push(`acp:${label.value}`);
716
+ }
717
+ if (token.text === "{") braceDepth++;
718
+ else if (token.text === "}" && braceDepth > 0) braceDepth--;
719
+ }
720
+ }
721
+ return methods;
722
+ }
723
+
724
+ async function scanSeams(): Promise<SourceSeam[]> {
725
+ const root = process.env.GJC_SDK_SEAM_SCAN_ROOT;
726
+ if (root) {
727
+ const files = await fs.readdir(root, { recursive: true });
728
+ const seams: SourceSeam[] = [];
729
+ for (const relative of files) {
730
+ if (typeof relative !== "string" || !relative.endsWith(".ts")) continue;
731
+ const file = path.join(root, relative);
732
+ for (const sourceId of collectCaseSeams(await Bun.file(file).text(), `controller:${relative}`))
733
+ seams.push({ sourceId, sourceFile: file, sourceKind: "controller" });
734
+ }
735
+ return seams;
736
+ }
737
+
738
+ const builtinFile = path.join(repoRoot, "packages/coding-agent/src/slash-commands/builtin-registry.ts");
739
+ const sessionFile = path.join(repoRoot, "packages/coding-agent/src/session/agent-session.ts");
740
+ const acpFile = path.join(repoRoot, "packages/coding-agent/src/modes/acp/acp-agent.ts");
741
+ const [builtinSource, sessionSource, acpSource] = await Promise.all([
742
+ Bun.file(builtinFile).text(),
743
+ Bun.file(sessionFile).text(),
744
+ Bun.file(acpFile).text(),
745
+ ]);
746
+ return [
747
+ ...scanSlashCommands(builtinSource).map(sourceId => ({
748
+ sourceId,
749
+ sourceFile: repoPath(builtinFile),
750
+ sourceKind: "slash_command" as const,
751
+ })),
752
+ ...scanAgentSessionMethods(sessionSource).map(sourceId => ({
753
+ sourceId,
754
+ sourceFile: repoPath(sessionFile),
755
+ sourceKind: "agent_session" as const,
756
+ })),
757
+ ...scanAcpMethods(acpSource).map(sourceId => ({
758
+ sourceId,
759
+ sourceFile: repoPath(acpFile),
760
+ sourceKind: "acp" as const,
761
+ })),
762
+ ];
763
+ }
764
+
765
+ function generatedRecords(seams: Awaited<ReturnType<typeof scanSeams>>): InventoryRecord[] {
766
+ const records: InventoryRecord[] = OPERATIONS.map(operation => ({
767
+ sourceId: `registry:${operation.id}`,
768
+ sourceFile: "packages/coding-agent/src/sdk/protocol/operation-registry.ts",
769
+ sourceKind: "registry" as const,
770
+ decision: "include" as const,
771
+ sdkId: operation.sdkId,
772
+ adapterMappings: operation.adapterDispositions,
773
+ testIds: operation.testIds,
774
+ }));
775
+ for (const seam of seams) {
776
+ const sdkId = SEAM_TO_SDK[seam.sourceId];
777
+ const rationale = lockedExclusion(seam.sourceId);
778
+ if (!sdkId && !rationale) continue;
779
+ const operation = sdkId ? OPERATIONS.find(candidate => candidate.sdkId === sdkId) : undefined;
780
+ if (sdkId && !operation) throw new Error(`SEAM_TO_SDK maps ${seam.sourceId} to unknown SDK ID: ${sdkId}`);
781
+ records.push({
782
+ ...seam,
783
+ decision: (sdkId ? "include" : "exclude") as "include" | "exclude",
784
+ ...(sdkId ? { sdkId } : { rationale }),
785
+ adapterMappings: operation?.adapterDispositions ?? OPERATIONS[0]!.adapterDispositions,
786
+ testIds: operation?.testIds ?? ["packages/coding-agent/test/sdk-operation-inventory.test.ts"],
787
+ });
788
+ }
789
+ return records;
790
+ }
791
+
792
+ function validateRegistry(records: InventoryRecord[]): string[] {
793
+ const errors: string[] = [];
794
+ const ids = new Set<string>();
795
+ const sdkIds = new Set<string>();
796
+ for (const operation of OPERATIONS) {
797
+ if (ids.has(operation.id)) errors.push(`Duplicate operation ID: ${operation.id}`);
798
+ ids.add(operation.id);
799
+ const operationKey = `${operation.kind}:${operation.sdkId}`;
800
+ if (sdkIds.has(operationKey)) errors.push(`Duplicate sdkId in ${operation.kind}: ${operation.sdkId}`);
801
+ sdkIds.add(operationKey);
802
+ if (ADAPTERS.some(adapter => !operation.adapterDispositions[adapter]))
803
+ errors.push(`${operation.id} is missing adapter dispositions.`);
804
+ if (operation.testIds.length === 0) errors.push(`${operation.id} is missing test IDs.`);
805
+ }
806
+ for (const record of records) {
807
+ if (record.decision === "exclude" && !record.rationale)
808
+ errors.push(`${record.sourceId} exclusion lacks a locked rationale.`);
809
+ if (ADAPTERS.some(adapter => !record.adapterMappings[adapter]))
810
+ errors.push(`${record.sourceId} is missing adapter mappings.`);
811
+ if (record.testIds.length === 0) errors.push(`${record.sourceId} is missing test IDs.`);
812
+ }
813
+ return errors;
814
+ }
815
+
816
+ export function pendingReviewErrors(seams: readonly Pick<SourceSeam, "sourceId">[]): string[] {
817
+ return seams
818
+ .filter(seam => !SEAM_TO_SDK[seam.sourceId] && !lockedExclusion(seam.sourceId))
819
+ .map(seam => `Pending review source seam: ${seam.sourceId}. Add it to SEAM_TO_SDK or LOCKED_EXCLUSIONS.`);
820
+ }
821
+
822
+ async function check(records: InventoryRecord[], seams: Awaited<ReturnType<typeof scanSeams>>): Promise<void> {
823
+ const errors = [...validateRegistry(records), ...pendingReviewErrors(seams)];
824
+ for (const sourceId of Object.keys(PENDING_REVIEW))
825
+ errors.push(`Pending review source seam: ${sourceId}. ${PENDING_REVIEW[sourceId]}`);
826
+ let checkedIn: InventoryRecord[];
827
+ try {
828
+ checkedIn = await Bun.file(inventoryPath).json();
829
+ } catch (error) {
830
+ throw new Error(
831
+ `Unable to read ${repoPath(inventoryPath)}: ${error instanceof Error ? error.message : String(error)}`,
832
+ );
833
+ }
834
+ const expected = JSON.stringify(records);
835
+ const actual = JSON.stringify(checkedIn);
836
+ if (actual !== expected) {
837
+ const expectedSources = new Set(records.map(record => record.sourceId));
838
+ const actualSources = new Set(checkedIn.map(record => record.sourceId));
839
+ for (const sourceId of expectedSources)
840
+ if (!actualSources.has(sourceId)) errors.push(`Unreviewed addition: ${sourceId}`);
841
+ for (const sourceId of actualSources)
842
+ if (!expectedSources.has(sourceId)) errors.push(`Disappeared source: ${sourceId}`);
843
+ errors.push("Generated operation inventory drifts from OPERATIONS.");
844
+ }
845
+ if (errors.length > 0) throw new Error(errors.join("\n"));
846
+ }
847
+
848
+ if (import.meta.main) {
849
+ const seams = await scanSeams();
850
+ const records = generatedRecords(seams);
851
+ const pending = pendingReviewErrors(seams);
852
+ if (process.argv.slice(2).includes("--check")) {
853
+ try {
854
+ await check(records, seams);
855
+ } catch (error) {
856
+ process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
857
+ process.exit(1);
858
+ }
859
+ } else {
860
+ await Bun.write(inventoryPath, `${JSON.stringify(records, null, "\t")}\n`);
861
+ const included = records.filter(record => record.decision === "include").length;
862
+ const excluded = records.filter(record => record.decision === "exclude").length;
863
+ process.stderr.write(
864
+ `Generated ${repoPath(inventoryPath)} (${records.length} records): include=${included}, exclude=${excluded}, pending=${pending.length}.\n`,
865
+ );
866
+ }
867
+ }