@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
@@ -1,5 +1,6 @@
1
1
  import { sanitizeText } from "@gajae-code/utils";
2
2
  import type { GjcModelAssignmentTargetId } from "./model-registry";
3
+ import { type ModelSelectorValue, normalizeModelSelectorValue } from "./model-selector-value";
3
4
  import type { ModelsConfig } from "./models-config-schema";
4
5
 
5
6
  export type ModelProfileRole = GjcModelAssignmentTargetId;
@@ -18,14 +19,14 @@ export interface ModelProfileDefinition {
18
19
  * means any single xiaomi credential satisfies the group.
19
20
  */
20
21
  alternativeProviderGroups?: readonly (readonly string[])[];
21
- modelMapping: Partial<Record<ModelProfileRole, string>>;
22
+ modelMapping: Partial<Record<ModelProfileRole, ModelSelectorValue>>;
22
23
  source: "builtin" | "user";
23
24
  }
24
25
 
25
26
  export interface ResolvedProfileBinding {
26
- defaultSelector?: string;
27
- modelRoles: Record<string, string>;
28
- agentModelOverrides: Partial<Record<Exclude<ModelProfileRole, "default">, string>>;
27
+ defaultSelector?: ModelSelectorValue;
28
+ modelRoles: Record<string, ModelSelectorValue>;
29
+ agentModelOverrides: Partial<Record<Exclude<ModelProfileRole, "default">, ModelSelectorValue>>;
29
30
  }
30
31
 
31
32
  function parseModelSelectorProvider(selector: string): string | undefined {
@@ -36,29 +37,31 @@ function parseModelSelectorProvider(selector: string): string | undefined {
36
37
 
37
38
  export function deriveModelProfileMappedProviders(definition: Pick<ModelProfileDefinition, "modelMapping">): string[] {
38
39
  const providers = new Set<string>();
39
- for (const selector of Object.values(definition.modelMapping)) {
40
- if (!selector) continue;
41
- const provider = parseModelSelectorProvider(selector);
42
- if (provider) providers.add(provider);
40
+ for (const selectorValue of Object.values(definition.modelMapping)) {
41
+ for (const selector of normalizeModelSelectorValue(selectorValue)) {
42
+ const provider = parseModelSelectorProvider(selector);
43
+ if (provider) providers.add(provider);
44
+ }
43
45
  }
44
46
  return [...providers].sort((a, b) => a.localeCompare(b));
45
47
  }
46
48
 
49
+ /**
50
+ * Return the providers explicitly declared as hard prerequisites.
51
+ * Model mappings may reference fallback providers, but those references are
52
+ * resolution-time candidates rather than activation requirements.
53
+ */
47
54
  export function aggregateModelProfileRequiredProviders(
48
55
  requiredProviders: readonly string[],
49
- definition: Pick<ModelProfileDefinition, "modelMapping">,
56
+ _definition: Pick<ModelProfileDefinition, "modelMapping">,
50
57
  ): string[] {
51
- const providers = new Set(requiredProviders);
52
- for (const provider of deriveModelProfileMappedProviders(definition)) {
53
- providers.add(provider);
54
- }
55
- return [...providers];
58
+ return [...new Set(requiredProviders)];
56
59
  }
57
60
 
58
61
  const profile = (
59
62
  name: string,
60
63
  requiredProviders: string[],
61
- modelMapping: Partial<Record<ModelProfileRole, string>>,
64
+ modelMapping: Partial<Record<ModelProfileRole, ModelSelectorValue>>,
62
65
  alternativeProviderGroups?: readonly (readonly string[])[],
63
66
  ): ModelProfileDefinition => ({
64
67
  name,
@@ -70,25 +73,25 @@ const profile = (
70
73
 
71
74
  export const BUILTIN_MODEL_PROFILES: readonly ModelProfileDefinition[] = [
72
75
  profile("codex-eco", ["openai-codex"], {
73
- default: "openai-codex/gpt-5.6-terra:high",
74
- executor: "openai-codex/gpt-5.6-luna:high",
75
- planner: "openai-codex/gpt-5.6-terra:medium",
76
- critic: "openai-codex/gpt-5.6-terra:high",
77
- architect: "openai-codex/gpt-5.6-sol:medium",
76
+ default: "openai-codex/gpt-5.6-terra:low",
77
+ executor: "openai-codex/gpt-5.6-luna:low",
78
+ planner: "openai-codex/gpt-5.6-luna:high",
79
+ critic: "openai-codex/gpt-5.6-terra:xhigh",
80
+ architect: "openai-codex/gpt-5.6-terra:high",
78
81
  }),
79
82
  profile("codex-medium", ["openai-codex"], {
80
- default: "openai-codex/gpt-5.6-sol:medium",
81
- executor: "openai-codex/gpt-5.6-terra:xhigh",
83
+ default: "openai-codex/gpt-5.6-sol:low",
84
+ executor: "openai-codex/gpt-5.6-terra:low",
82
85
  planner: "openai-codex/gpt-5.6-terra:high",
83
- critic: "openai-codex/gpt-5.6-terra:xhigh",
86
+ critic: "openai-codex/gpt-5.6-sol:xhigh",
84
87
  architect: "openai-codex/gpt-5.6-sol:high",
85
88
  }),
86
89
  profile("codex-pro", ["openai-codex"], {
87
- default: "openai-codex/gpt-5.6-sol:xhigh",
88
- executor: "openai-codex/gpt-5.6-terra:xhigh",
90
+ default: "openai-codex/gpt-5.6-sol:medium",
91
+ executor: "openai-codex/gpt-5.6-terra:medium",
89
92
  planner: "openai-codex/gpt-5.6-sol:high",
90
- critic: "openai-codex/gpt-5.6-sol:xhigh",
91
- architect: "openai-codex/gpt-5.6-sol:max",
93
+ critic: "openai-codex/gpt-5.6-sol:max",
94
+ architect: "openai-codex/gpt-5.6-sol:xhigh",
92
95
  }),
93
96
  profile("opencodego", ["opencode-go"], {
94
97
  default: "opencode-go/kimi-k2.6",
@@ -256,21 +259,21 @@ export const BUILTIN_MODEL_PROFILES: readonly ModelProfileDefinition[] = [
256
259
  }),
257
260
  profile("opus-codex", ["anthropic", "openai-codex"], {
258
261
  default: "anthropic/claude-opus-4-8:xhigh",
259
- executor: "openai-codex/gpt-5.6-terra:xhigh",
260
- planner: "openai-codex/gpt-5.6-terra:high",
261
- critic: "openai-codex/gpt-5.6-terra:xhigh",
262
- architect: "openai-codex/gpt-5.6-sol:xhigh",
262
+ executor: "openai-codex/gpt-5.6-terra:low",
263
+ planner: "anthropic/claude-sonnet-5",
264
+ critic: "openai-codex/gpt-5.6-sol:xhigh",
265
+ architect: "openai-codex/gpt-5.6-sol:high",
263
266
  }),
264
267
  profile("codex-opencodego", ["openai-codex", "opencode-go"], {
265
- default: "openai-codex/gpt-5.6-terra:xhigh",
268
+ default: "openai-codex/gpt-5.6-sol:low",
266
269
  executor: "opencode-go/deepseek-v4-pro",
267
270
  planner: "opencode-go/kimi-k2.6",
268
271
  critic: "opencode-go/mimo-v2.5-pro",
269
- architect: "openai-codex/gpt-5.6-sol:xhigh",
272
+ architect: "openai-codex/gpt-5.6-sol:high",
270
273
  }),
271
274
  profile("fable-opus-codex", ["anthropic", "openai-codex"], {
272
275
  default: "anthropic/claude-fable-5:high",
273
- executor: "openai-codex/gpt-5.6-terra:xhigh",
276
+ executor: "openai-codex/gpt-5.6-terra:medium",
274
277
  planner: "anthropic/claude-opus-4-8:medium",
275
278
  critic: "anthropic/claude-opus-4-8:high",
276
279
  architect: "openai-codex/gpt-5.6-sol:xhigh",
@@ -4,6 +4,7 @@ import {
4
4
  type Api,
5
5
  type AssistantMessageEventStream,
6
6
  type AuthCredentialSelector,
7
+ applyFinalCodexGpt56ContextCap,
7
8
  type CacheRetention,
8
9
  type Context,
9
10
  createModelManager,
@@ -52,6 +53,7 @@ import {
52
53
  type ModelProfileDefinition,
53
54
  mergeModelProfiles,
54
55
  } from "./model-profiles";
56
+ import { type ModelSelectorValue, normalizeModelSelectorValue } from "./model-selector-value";
55
57
  import {
56
58
  type ModelOverride,
57
59
  type ModelProfileConfig,
@@ -1019,10 +1021,10 @@ export class ModelRegistry {
1019
1021
  #modelBindingsTargetSettings: Settings | undefined;
1020
1022
  #appliedModelBindingRoles = new Set<string>();
1021
1023
  #appliedAgentModelBindingOverrides = new Set<string>();
1022
- #modelBindingRoleBaselines = new Map<string, string | undefined>();
1023
- #agentModelBindingBaselines = new Map<string, string | undefined>();
1024
- #lastAppliedModelBindingRoles = new Map<string, string>();
1025
- #lastAppliedAgentModelBindingOverrides = new Map<string, string>();
1024
+ #modelBindingRoleBaselines = new Map<string, ModelSelectorValue | undefined>();
1025
+ #agentModelBindingBaselines = new Map<string, ModelSelectorValue | undefined>();
1026
+ #lastAppliedModelBindingRoles = new Map<string, ModelSelectorValue>();
1027
+ #lastAppliedAgentModelBindingOverrides = new Map<string, ModelSelectorValue>();
1026
1028
  #configError: ConfigError | undefined = undefined;
1027
1029
  #modelsConfigFile: ConfigFile<ModelsConfig>;
1028
1030
  #lastStaticLoadMtime: number | null = null;
@@ -1181,7 +1183,7 @@ export class ModelRegistry {
1181
1183
  // Merge runtime extension models so they survive refresh() cycles
1182
1184
  const combined = this.#mergeCustomModels(withConfigModels, this.#runtimeModelOverlays);
1183
1185
  const withModelOverrides = this.#applyModelOverrides(combined, this.#modelOverrides);
1184
- this.#models = this.#applyRuntimeProviderOverrides(withModelOverrides);
1186
+ this.#models = applyFinalCodexGpt56ContextCap(this.#applyRuntimeProviderOverrides(withModelOverrides));
1185
1187
  this.#rebuildCanonicalIndex();
1186
1188
  this.#lastStaticLoadMtime = this.#modelsConfigFile.getMtimeMs();
1187
1189
  }
@@ -1698,6 +1700,19 @@ export class ModelRegistry {
1698
1700
  this.#applyConfiguredModelBindingsToTarget();
1699
1701
  }
1700
1702
 
1703
+ #cloneModelSelectorValue(value: ModelSelectorValue | undefined): ModelSelectorValue | undefined {
1704
+ return Array.isArray(value) ? [...value] : value;
1705
+ }
1706
+
1707
+ #modelSelectorValuesEqual(left: ModelSelectorValue | undefined, right: ModelSelectorValue | undefined): boolean {
1708
+ const leftSelectors = normalizeModelSelectorValue(left);
1709
+ const rightSelectors = normalizeModelSelectorValue(right);
1710
+ return (
1711
+ leftSelectors.length === rightSelectors.length &&
1712
+ leftSelectors.every((selector, index) => selector === rightSelectors[index])
1713
+ );
1714
+ }
1715
+
1701
1716
  #applyConfiguredModelBindingsToTarget(): void {
1702
1717
  const targetSettings = this.#modelBindingsTargetSettings;
1703
1718
  if (!targetSettings) return;
@@ -1708,26 +1723,25 @@ export class ModelRegistry {
1708
1723
  for (const role of this.#appliedModelBindingRoles) {
1709
1724
  if (configuredModelRoleKeys.has(role)) continue;
1710
1725
  const lastApplied = this.#lastAppliedModelBindingRoles.get(role);
1711
- if (lastApplied !== undefined && nextModelRoles[role] === lastApplied) {
1726
+ if (lastApplied !== undefined && this.#modelSelectorValuesEqual(nextModelRoles[role], lastApplied)) {
1712
1727
  const baseline = this.#modelBindingRoleBaselines.get(role);
1713
1728
  if (baseline === undefined) {
1714
1729
  delete nextModelRoles[role];
1715
1730
  } else {
1716
- nextModelRoles[role] = baseline;
1731
+ nextModelRoles[role] = this.#cloneModelSelectorValue(baseline)!;
1717
1732
  }
1718
1733
  }
1719
1734
  this.#modelBindingRoleBaselines.delete(role);
1720
1735
  this.#lastAppliedModelBindingRoles.delete(role);
1721
1736
  }
1722
- for (const [role, modelId] of Object.entries(configuredModelRoles)) {
1723
- if (!modelId) continue;
1737
+ for (const [role, selector] of Object.entries(configuredModelRoles)) {
1724
1738
  const previousApplied = this.#lastAppliedModelBindingRoles.get(role);
1725
1739
  if (!this.#modelBindingRoleBaselines.has(role)) {
1726
- this.#modelBindingRoleBaselines.set(role, nextModelRoles[role]);
1740
+ this.#modelBindingRoleBaselines.set(role, this.#cloneModelSelectorValue(nextModelRoles[role]));
1727
1741
  }
1728
- if (previousApplied === undefined || nextModelRoles[role] === previousApplied) {
1729
- nextModelRoles[role] = modelId;
1730
- this.#lastAppliedModelBindingRoles.set(role, modelId);
1742
+ if (previousApplied === undefined || this.#modelSelectorValuesEqual(nextModelRoles[role], previousApplied)) {
1743
+ nextModelRoles[role] = this.#cloneModelSelectorValue(selector)!;
1744
+ this.#lastAppliedModelBindingRoles.set(role, this.#cloneModelSelectorValue(selector)!);
1731
1745
  }
1732
1746
  }
1733
1747
  targetSettings.override("modelRoles", nextModelRoles);
@@ -1739,26 +1753,34 @@ export class ModelRegistry {
1739
1753
  for (const agentName of this.#appliedAgentModelBindingOverrides) {
1740
1754
  if (configuredAgentModelOverrideKeys.has(agentName)) continue;
1741
1755
  const lastApplied = this.#lastAppliedAgentModelBindingOverrides.get(agentName);
1742
- if (lastApplied !== undefined && nextAgentModelOverrides[agentName] === lastApplied) {
1756
+ if (
1757
+ lastApplied !== undefined &&
1758
+ this.#modelSelectorValuesEqual(nextAgentModelOverrides[agentName], lastApplied)
1759
+ ) {
1743
1760
  const baseline = this.#agentModelBindingBaselines.get(agentName);
1744
1761
  if (baseline === undefined) {
1745
1762
  delete nextAgentModelOverrides[agentName];
1746
1763
  } else {
1747
- nextAgentModelOverrides[agentName] = baseline;
1764
+ nextAgentModelOverrides[agentName] = this.#cloneModelSelectorValue(baseline)!;
1748
1765
  }
1749
1766
  }
1750
1767
  this.#agentModelBindingBaselines.delete(agentName);
1751
1768
  this.#lastAppliedAgentModelBindingOverrides.delete(agentName);
1752
1769
  }
1753
- for (const [agentName, modelId] of Object.entries(configuredAgentModelOverrides)) {
1754
- if (!modelId) continue;
1770
+ for (const [agentName, selector] of Object.entries(configuredAgentModelOverrides)) {
1755
1771
  const previousApplied = this.#lastAppliedAgentModelBindingOverrides.get(agentName);
1756
1772
  if (!this.#agentModelBindingBaselines.has(agentName)) {
1757
- this.#agentModelBindingBaselines.set(agentName, nextAgentModelOverrides[agentName]);
1773
+ this.#agentModelBindingBaselines.set(
1774
+ agentName,
1775
+ this.#cloneModelSelectorValue(nextAgentModelOverrides[agentName]),
1776
+ );
1758
1777
  }
1759
- if (previousApplied === undefined || nextAgentModelOverrides[agentName] === previousApplied) {
1760
- nextAgentModelOverrides[agentName] = modelId;
1761
- this.#lastAppliedAgentModelBindingOverrides.set(agentName, modelId);
1778
+ if (
1779
+ previousApplied === undefined ||
1780
+ this.#modelSelectorValuesEqual(nextAgentModelOverrides[agentName], previousApplied)
1781
+ ) {
1782
+ nextAgentModelOverrides[agentName] = this.#cloneModelSelectorValue(selector)!;
1783
+ this.#lastAppliedAgentModelBindingOverrides.set(agentName, this.#cloneModelSelectorValue(selector)!);
1762
1784
  }
1763
1785
  }
1764
1786
  targetSettings.override("task.agentModelOverrides", nextAgentModelOverrides);
@@ -1803,7 +1825,7 @@ export class ModelRegistry {
1803
1825
  // Merge runtime extension models so they survive online discovery completion
1804
1826
  const combined = this.#mergeCustomModels(withConfigModels, this.#runtimeModelOverlays);
1805
1827
  const withModelOverrides = this.#applyModelOverrides(combined, this.#modelOverrides);
1806
- this.#models = this.#applyRuntimeProviderOverrides(withModelOverrides);
1828
+ this.#models = applyFinalCodexGpt56ContextCap(this.#applyRuntimeProviderOverrides(withModelOverrides));
1807
1829
  this.#rebuildCanonicalIndex();
1808
1830
  }
1809
1831
 
@@ -1812,6 +1834,7 @@ export class ModelRegistry {
1812
1834
  strategy: ModelRefreshStrategy,
1813
1835
  ): Promise<Model<Api>[]> {
1814
1836
  const cached = readModelCache<Api>(providerConfig.provider, 24 * 60 * 60 * 1000, Date.now, this.#cacheDbPath);
1837
+ const cachedModels = applyFinalCodexGpt56ContextCap(cached?.models ?? []);
1815
1838
  const requiresAuth = !this.#keylessProviders.has(providerConfig.provider);
1816
1839
  if (requiresAuth) {
1817
1840
  const apiKey = await this.#peekApiKeyForProvider(providerConfig.provider);
@@ -1822,10 +1845,10 @@ export class ModelRegistry {
1822
1845
  optional: providerConfig.optional ?? false,
1823
1846
  stale: cached !== null,
1824
1847
  fetchedAt: cached?.updatedAt,
1825
- models: cached?.models.map(model => model.id) ?? [],
1848
+ models: cachedModels.map(model => model.id),
1826
1849
  });
1827
1850
  this.#lastDiscoveryWarnings.delete(providerConfig.provider);
1828
- return cached?.models ?? [];
1851
+ return cachedModels;
1829
1852
  }
1830
1853
  }
1831
1854
 
@@ -2878,13 +2901,15 @@ export class ModelRegistry {
2878
2901
  if (config.oauth?.modifyModels) {
2879
2902
  const credential = this.authStorage.getOAuthCredential(providerName);
2880
2903
  if (credential) {
2881
- this.#models = config.oauth.modifyModels(withRuntimeTransportOverride, credential);
2904
+ this.#models = applyFinalCodexGpt56ContextCap(
2905
+ config.oauth.modifyModels(withRuntimeTransportOverride, credential),
2906
+ );
2882
2907
  this.#rebuildCanonicalIndex();
2883
2908
  return;
2884
2909
  }
2885
2910
  }
2886
2911
 
2887
- this.#models = withRuntimeTransportOverride;
2912
+ this.#models = applyFinalCodexGpt56ContextCap(withRuntimeTransportOverride);
2888
2913
  this.#rebuildCanonicalIndex();
2889
2914
  return;
2890
2915
  }
@@ -9,11 +9,22 @@ import { logger } from "@gajae-code/utils";
9
9
  import chalk from "chalk";
10
10
  import { parseThinkingLevel, resolveThinkingLevelForModel } from "../thinking";
11
11
  import { isAuthenticated, kNoAuth, MODEL_ROLE_IDS, type ModelRegistry, type ModelRole } from "./model-registry";
12
+ import { type ModelSelectorValue, normalizeModelSelectorValue } from "./model-selector-value";
12
13
  import type { Settings } from "./settings";
13
14
 
14
15
  /** Default model IDs for each known provider */
15
16
  export const defaultModelPerProvider: Record<KnownProvider, string> = DEFAULT_MODEL_PER_PROVIDER;
16
17
 
18
+ /**
19
+ * Cursor's current RPC transport executes its exec protocol while streaming and
20
+ * has no client-side tool-call mode. Managed fallback attempts must not enable
21
+ * that irreversible path.
22
+ */
23
+ export function managedCursorFallbackUnavailableReason(model: Model<Api>, selector: string): string | undefined {
24
+ if (model.api !== "cursor-agent") return undefined;
25
+ return `Cursor model ${selector} requires provider-side tool execution and cannot be used in a retryable fallback chain`;
26
+ }
27
+
17
28
  export interface ScopedModelSelection {
18
29
  model: Model<Api>;
19
30
  thinkingLevel?: ThinkingLevel;
@@ -524,10 +535,8 @@ function getModelRoleAlias(value: string): ModelRole | undefined {
524
535
  return undefined;
525
536
  }
526
537
 
527
- function normalizeModelPatternList(value: string | string[] | undefined): string[] {
528
- if (!value) return [];
529
- const patterns = Array.isArray(value) ? value : value.split(",");
530
- return patterns.map(pattern => pattern.trim()).filter(Boolean);
538
+ function normalizeModelPatternList(value: ModelSelectorValue | undefined): string[] {
539
+ return normalizeModelSelectorValue(value);
531
540
  }
532
541
 
533
542
  function isSessionInheritedAgentPattern(value: string): boolean {
@@ -545,7 +554,7 @@ function resolveConfiguredRolePattern(value: string, settings?: Settings): strin
545
554
  const role = getModelRoleAlias(aliasCandidate);
546
555
  if (!role) return [normalized];
547
556
 
548
- const configured = settings?.getModelRole(role)?.trim();
557
+ const configured = settings?.getModelRole(role);
549
558
  const resolved = configured ? normalizeModelPatternList(configured) : undefined;
550
559
  if (!resolved || resolved.length === 0) {
551
560
  return undefined;
@@ -560,14 +569,14 @@ function resolveConfiguredRolePattern(value: string, settings?: Settings): strin
560
569
  export function expandRoleAlias(value: string, settings?: Settings): string {
561
570
  const normalized = value.trim();
562
571
  if (normalized === DEFAULT_MODEL_ROLE) {
563
- return settings?.getModelRole("default") ?? value;
572
+ return normalizeModelPatternList(settings?.getModelRole("default"))[0] ?? value;
564
573
  }
565
574
 
566
575
  const resolved = resolveConfiguredRolePattern(value, settings)?.[0];
567
576
  return resolved ?? value;
568
577
  }
569
578
 
570
- export function resolveConfiguredModelPatterns(value: string | string[] | undefined, settings?: Settings): string[] {
579
+ export function resolveConfiguredModelPatterns(value: ModelSelectorValue | undefined, settings?: Settings): string[] {
571
580
  const patterns = normalizeModelPatternList(value);
572
581
  return patterns.flatMap(pattern => {
573
582
  const resolved = resolveConfiguredRolePattern(pattern, settings);
@@ -575,8 +584,8 @@ export function resolveConfiguredModelPatterns(value: string | string[] | undefi
575
584
  });
576
585
  }
577
586
  export interface AgentModelPatternResolutionOptions {
578
- settingsOverride?: string | string[];
579
- agentModel?: string | string[];
587
+ settingsOverride?: ModelSelectorValue;
588
+ agentModel?: ModelSelectorValue;
580
589
  settings?: Settings;
581
590
  activeModelPattern?: string;
582
591
  fallbackModelPattern?: string;
@@ -597,7 +606,10 @@ export function resolveAgentModelPatterns(options: AgentModelPatternResolutionOp
597
606
  }
598
607
 
599
608
  const fallback =
600
- activeModelPattern?.trim() || fallbackModelPattern?.trim() || settings?.getModelRole("default")?.trim() || "";
609
+ activeModelPattern?.trim() ||
610
+ fallbackModelPattern?.trim() ||
611
+ normalizeModelPatternList(settings?.getModelRole("default"))[0] ||
612
+ "";
601
613
  return resolveConfiguredModelPatterns(fallback, settings);
602
614
  }
603
615
 
@@ -612,21 +624,14 @@ export interface ResolvedModelRoleValue {
612
624
  }
613
625
 
614
626
  export function resolveModelRoleValue(
615
- roleValue: string | undefined,
627
+ roleValue: ModelSelectorValue | undefined,
616
628
  availableModels: Model<Api>[],
617
629
  options?: { settings?: Settings; matchPreferences?: ModelMatchPreferences; modelRegistry?: CanonicalModelRegistry },
618
630
  ): ResolvedModelRoleValue {
619
- if (!roleValue) {
620
- return { model: undefined, thinkingLevel: undefined, explicitThinkingLevel: false, warning: undefined };
621
- }
622
-
623
- const normalized = roleValue.trim();
624
- if (!normalized || normalized === DEFAULT_MODEL_ROLE) {
625
- return { model: undefined, thinkingLevel: undefined, explicitThinkingLevel: false, warning: undefined };
626
- }
627
-
628
- const effectivePatterns = resolveConfiguredRolePattern(normalized, options?.settings);
629
- if (!effectivePatterns || effectivePatterns.length === 0) {
631
+ const effectivePatterns = normalizeModelPatternList(roleValue).flatMap(
632
+ pattern => resolveConfiguredRolePattern(pattern, options?.settings) ?? [],
633
+ );
634
+ if (effectivePatterns.length === 0) {
630
635
  return { model: undefined, thinkingLevel: undefined, explicitThinkingLevel: false, warning: undefined };
631
636
  }
632
637
 
@@ -654,11 +659,10 @@ export function resolveModelRoleValue(
654
659
  }
655
660
 
656
661
  export function extractExplicitThinkingSelector(
657
- value: string | undefined,
662
+ value: ModelSelectorValue | undefined,
658
663
  settings?: Settings,
659
664
  ): ThinkingLevel | undefined {
660
- if (!value) return undefined;
661
- const normalized = value.trim();
665
+ const normalized = normalizeModelPatternList(value)[0];
662
666
  if (!normalized || normalized === DEFAULT_MODEL_ROLE) return undefined;
663
667
 
664
668
  const visited = new Set<string>();
@@ -712,12 +716,13 @@ export function resolveModelFromSettings(options: {
712
716
  let sawConfiguredProviderQualifiedRole = false;
713
717
  for (const role of roles) {
714
718
  const configured = settings.getModelRole(role);
715
- if (!configured) continue;
716
- const expanded = expandRoleAlias(configured, settings).trim();
719
+ const expanded = normalizeModelPatternList(configured)[0];
720
+ if (!expanded) continue;
721
+ const resolvedValue = expandRoleAlias(expanded, settings).trim();
717
722
  if (expanded.includes("/")) {
718
723
  sawConfiguredProviderQualifiedRole = true;
719
724
  }
720
- const resolved = resolveModelFromString(expanded, availableModels, matchPreferences, modelRegistry);
725
+ const resolved = resolveModelFromString(resolvedValue, availableModels, matchPreferences, modelRegistry);
721
726
  if (resolved) return resolved;
722
727
  }
723
728
  return sawConfiguredProviderQualifiedRole ? undefined : availableModels[0];
@@ -747,6 +752,56 @@ export function resolveModelOverride(
747
752
  return { explicitThinkingLevel: false };
748
753
  }
749
754
 
755
+ /**
756
+ * Resolve a configured fallback chain to its first callable entry without
757
+ * charging requests. For retryable chains, consumers MUST pass
758
+ * `{ managedFallback: true }` so unsuitable entries (including Cursor's
759
+ * provider-side tool mode) fail closed during resolution before any request
760
+ * is attempted. Single-entry chains remain non-managed selections.
761
+ */
762
+ export interface ModelChainResolutionOptions {
763
+ managedFallback?: boolean;
764
+ }
765
+
766
+ export async function resolveModelChainWithAuth(
767
+ modelPatterns: readonly string[],
768
+ modelRegistry: ModelLookupRegistry & Pick<ModelRegistry, "getApiKey">,
769
+ settings?: Settings,
770
+ sessionId?: string,
771
+ options?: ModelChainResolutionOptions,
772
+ ): Promise<{
773
+ model?: Model<Api>;
774
+ thinkingLevel?: ThinkingLevel;
775
+ explicitThinkingLevel: boolean;
776
+ activeIndex: number;
777
+ skips: Array<{ selector: string; reason: string }>;
778
+ }> {
779
+ const availableModels = modelRegistry.getAvailable();
780
+ const matchPreferences = { usageOrder: settings?.getStorage()?.getModelUsageOrder() };
781
+ const skips: Array<{ selector: string; reason: string }> = [];
782
+ for (let activeIndex = 0; activeIndex < modelPatterns.length; activeIndex += 1) {
783
+ const selector = modelPatterns[activeIndex];
784
+ const candidate = resolveModelRoleValue(selector, availableModels, { settings, matchPreferences, modelRegistry });
785
+ if (!candidate.model) {
786
+ skips.push({ selector, reason: "unknown_model" });
787
+ continue;
788
+ }
789
+ if (options?.managedFallback && modelPatterns.length > 1) {
790
+ const cursorReason = managedCursorFallbackUnavailableReason(candidate.model, selector);
791
+ if (cursorReason) {
792
+ skips.push({ selector, reason: cursorReason });
793
+ continue;
794
+ }
795
+ }
796
+ const key = await modelRegistry.getApiKey(candidate.model, sessionId);
797
+ if (key === kNoAuth || isAuthenticated(key)) {
798
+ return { ...candidate, activeIndex, skips };
799
+ }
800
+ skips.push({ selector, reason: "unauthenticated" });
801
+ }
802
+ return { explicitThinkingLevel: false, activeIndex: modelPatterns.length, skips };
803
+ }
804
+
750
805
  /**
751
806
  * Resolve a list of override patterns to the first matching model, with an
752
807
  * auth-aware fallback to the parent session's active model.
@@ -774,6 +829,7 @@ export async function resolveModelOverrideWithAuthFallback(
774
829
  modelRegistry: ModelLookupRegistry & Pick<ModelRegistry, "getApiKey">,
775
830
  settings?: Settings,
776
831
  sessionId?: string,
832
+ options?: ModelChainResolutionOptions,
777
833
  ): Promise<{
778
834
  model?: Model<Api>;
779
835
  thinkingLevel?: ThinkingLevel;
@@ -781,31 +837,62 @@ export async function resolveModelOverrideWithAuthFallback(
781
837
  authFallbackUsed: boolean;
782
838
  requestedModel?: Model<Api>;
783
839
  fallbackReason?: "auth_unavailable";
840
+ activeIndex?: number;
841
+ parentFallbackSelector?: string;
842
+ skips: Array<{ selector: string; reason: string }>;
784
843
  }> {
785
- const primary = resolveModelOverride(modelPatterns, modelRegistry, settings);
786
- const unchanged = { ...primary, requestedModel: primary.model, authFallbackUsed: false };
787
- if (!primary.model || !parentActiveModelPattern) {
788
- return unchanged;
789
- }
790
-
791
- const primaryKey = await modelRegistry.getApiKey(primary.model, sessionId);
792
- if (primaryKey === kNoAuth || isAuthenticated(primaryKey)) {
793
- return unchanged;
794
- }
795
-
796
- const fallback = resolveModelOverride([parentActiveModelPattern], modelRegistry, settings);
797
- if (!fallback.model) {
798
- return unchanged;
799
- }
800
- if (modelsAreEqual(fallback.model, primary.model)) {
801
- return unchanged;
802
- }
803
- const fallbackKey = await modelRegistry.getApiKey(fallback.model, sessionId);
804
- if (!isAuthenticated(fallbackKey)) {
805
- return unchanged;
844
+ const availableModels = modelRegistry.getAvailable();
845
+ const matchPreferences = { usageOrder: settings?.getStorage()?.getModelUsageOrder() };
846
+ let requestedModel: Model<Api> | undefined;
847
+ let requestedResolution: ResolvedModelRoleValue | undefined;
848
+ const skips: Array<{ selector: string; reason: string }> = [];
849
+ let activeIndex = 0;
850
+ for (const pattern of modelPatterns) {
851
+ const candidate = resolveModelRoleValue(pattern, availableModels, { settings, matchPreferences, modelRegistry });
852
+ if (!requestedModel && candidate.model) {
853
+ requestedModel = candidate.model;
854
+ requestedResolution = candidate;
855
+ }
856
+ if (!candidate.model) {
857
+ skips.push({ selector: pattern, reason: "unknown_model" });
858
+ activeIndex += 1;
859
+ continue;
860
+ }
861
+ if (options?.managedFallback && modelPatterns.length > 1) {
862
+ const cursorReason = managedCursorFallbackUnavailableReason(candidate.model, pattern);
863
+ if (cursorReason) {
864
+ skips.push({ selector: pattern, reason: cursorReason });
865
+ activeIndex += 1;
866
+ continue;
867
+ }
868
+ }
869
+ const key = await modelRegistry.getApiKey(candidate.model, sessionId);
870
+ if (key === kNoAuth || isAuthenticated(key)) {
871
+ return { ...candidate, requestedModel: candidate.model, authFallbackUsed: false, activeIndex, skips };
872
+ }
873
+ skips.push({ selector: pattern, reason: "unauthenticated" });
874
+ activeIndex += 1;
875
+ }
876
+ const fallback = parentActiveModelPattern
877
+ ? resolveModelOverride([parentActiveModelPattern], modelRegistry, settings)
878
+ : { explicitThinkingLevel: false };
879
+ if (fallback.model) {
880
+ const fallbackKey = await modelRegistry.getApiKey(fallback.model, sessionId);
881
+ if (fallbackKey === kNoAuth || isAuthenticated(fallbackKey)) {
882
+ const isParentSubstitution = requestedModel === undefined || !modelsAreEqual(fallback.model, requestedModel);
883
+ return {
884
+ ...fallback,
885
+ requestedModel,
886
+ authFallbackUsed: requestedModel !== undefined && isParentSubstitution,
887
+ fallbackReason: requestedModel && isParentSubstitution ? "auth_unavailable" : undefined,
888
+ parentFallbackSelector: isParentSubstitution ? formatModelString(fallback.model) : undefined,
889
+ skips,
890
+ };
891
+ }
806
892
  }
807
-
808
- return { ...fallback, requestedModel: primary.model, authFallbackUsed: true, fallbackReason: "auth_unavailable" };
893
+ return requestedResolution
894
+ ? { ...requestedResolution, requestedModel, authFallbackUsed: false, activeIndex, skips }
895
+ : { explicitThinkingLevel: false, requestedModel, authFallbackUsed: false, activeIndex, skips };
809
896
  }
810
897
 
811
898
  /**
@@ -0,0 +1,50 @@
1
+ import * as z from "zod/v4";
2
+
3
+ /** A model selector or an ordered fallback chain of selectors. */
4
+ export type ModelSelectorValue = string | readonly string[];
5
+
6
+ /**
7
+ * Accept one validated selector or a non-empty ordered chain of validated selectors.
8
+ * Element schemas own each configuration surface's selector grammar.
9
+ */
10
+ export function stringOrNonEmptyArray<T extends z.ZodType<string>>(elementSchema: T) {
11
+ return z.union([elementSchema, z.array(elementSchema).min(1)]);
12
+ }
13
+
14
+ /** Return whether a value is a non-blank selector or a non-empty selector chain. */
15
+ export function isModelSelectorValue(value: unknown): value is ModelSelectorValue {
16
+ return (
17
+ (typeof value === "string" && value.trim().length > 0) ||
18
+ (Array.isArray(value) &&
19
+ value.length > 0 &&
20
+ value.every(item => typeof item === "string" && item.trim().length > 0))
21
+ );
22
+ }
23
+
24
+ /**
25
+ * Preserve compatibility with comma-delimited selector strings while flattening
26
+ * configured chains in their declared order.
27
+ */
28
+ export function normalizeModelSelectorValue(value: ModelSelectorValue | undefined): string[] {
29
+ if (value === undefined) return [];
30
+ if (typeof value === "string") {
31
+ return value
32
+ .split(",")
33
+ .map(part => part.trim())
34
+ .filter(Boolean);
35
+ }
36
+ if (!Array.isArray(value)) return [];
37
+ return value
38
+ .filter((selector): selector is string => typeof selector === "string")
39
+ .flatMap(selector =>
40
+ selector
41
+ .split(",")
42
+ .map(part => part.trim())
43
+ .filter(Boolean),
44
+ );
45
+ }
46
+
47
+ /** Return the first configured selector for consumers that need one selector. */
48
+ export function selectorHead(value: ModelSelectorValue | undefined): string | undefined {
49
+ return normalizeModelSelectorValue(value)[0];
50
+ }