@gajae-code/coding-agent 0.17.2 → 0.17.5

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 (390) hide show
  1. package/CHANGELOG.md +267 -0
  2. package/dist/types/cli/daemon-cli.d.ts +3 -1
  3. package/dist/types/cli/github-release.d.ts +17 -0
  4. package/dist/types/cli/public-command-entry.d.ts +56 -0
  5. package/dist/types/cli/public-command-errors.d.ts +126 -0
  6. package/dist/types/cli/public-command-evidence.d.ts +99 -0
  7. package/dist/types/cli/public-command-help.d.ts +65 -0
  8. package/dist/types/cli/public-command-registry.d.ts +69 -0
  9. package/dist/types/cli/session-picker.d.ts +1 -1
  10. package/dist/types/cli/setup-cli.d.ts +1 -0
  11. package/dist/types/cli/skills-cli.d.ts +5 -0
  12. package/dist/types/cli.d.ts +3 -0
  13. package/dist/types/commands/daemon.d.ts +4 -50
  14. package/dist/types/commands/sdk.d.ts +20 -37
  15. package/dist/types/commands/setup.d.ts +3 -0
  16. package/dist/types/commands/skills.d.ts +9 -0
  17. package/dist/types/config/autorouting-tier-map.d.ts +1049 -3
  18. package/dist/types/config/file-lock.d.ts +13 -3
  19. package/dist/types/config/model-profile-activation.d.ts +45 -1
  20. package/dist/types/config/model-registry.d.ts +14 -3
  21. package/dist/types/config/model-resolver.d.ts +1 -1
  22. package/dist/types/config/settings-schema.d.ts +11 -0
  23. package/dist/types/coordinator-mcp/question-state.d.ts +6 -1
  24. package/dist/types/daemon/operator-contract.d.ts +5 -1
  25. package/dist/types/eval/js/worker-protocol.d.ts +2 -0
  26. package/dist/types/exec/bash-executor.d.ts +2 -0
  27. package/dist/types/extensibility/extensions/types.d.ts +12 -0
  28. package/dist/types/extensibility/gjc-plugins/registry.d.ts +4 -0
  29. package/dist/types/extensibility/gjc-plugins/runtime-adapters.d.ts +11 -2
  30. package/dist/types/extensibility/runtime-skill-discovery.d.ts +18 -0
  31. package/dist/types/extensibility/shared-events.d.ts +3 -1
  32. package/dist/types/gjc-runtime/session-state-lock.d.ts +61 -0
  33. package/dist/types/gjc-runtime/state-writer.d.ts +14 -1
  34. package/dist/types/harness-control-plane/control-endpoint.d.ts +4 -1
  35. package/dist/types/harness-control-plane/finalize.d.ts +14 -3
  36. package/dist/types/internal-urls/embedded-protocol.d.ts +9 -0
  37. package/dist/types/internal-urls/index.d.ts +1 -0
  38. package/dist/types/internal-urls/parse.d.ts +9 -1
  39. package/dist/types/main.d.ts +23 -1
  40. package/dist/types/modes/acp/acp-agent.d.ts +55 -1
  41. package/dist/types/modes/acp/startup-provenance.d.ts +16 -0
  42. package/dist/types/modes/components/custom-provider-wizard.d.ts +19 -1
  43. package/dist/types/modes/components/session-selector.d.ts +5 -2
  44. package/dist/types/modes/components/user-message-selector.d.ts +5 -2
  45. package/dist/types/modes/controllers/command-controller.d.ts +1 -1
  46. package/dist/types/modes/controllers/selector-controller.d.ts +1 -1
  47. package/dist/types/modes/interactive-mode.d.ts +1 -1
  48. package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +11 -1
  49. package/dist/types/modes/shared/agent-wire/workflow-gate-types.d.ts +14 -1
  50. package/dist/types/modes/types.d.ts +2 -2
  51. package/dist/types/runtime/process-lifecycle.d.ts +2 -0
  52. package/dist/types/runtime-mcp/loader.d.ts +2 -0
  53. package/dist/types/runtime-mcp/manager.d.ts +69 -6
  54. package/dist/types/runtime-mcp/pool.d.ts +17 -0
  55. package/dist/types/runtime-mcp/redaction.d.ts +20 -0
  56. package/dist/types/runtime-mcp/startup-policy.d.ts +6 -0
  57. package/dist/types/runtime-mcp/tool-bridge.d.ts +9 -0
  58. package/dist/types/runtime-mcp/transports/http.d.ts +11 -0
  59. package/dist/types/sdk/broker/broker.d.ts +17 -4
  60. package/dist/types/sdk/broker/ensure.d.ts +3 -0
  61. package/dist/types/sdk/broker/identity.d.ts +5 -1
  62. package/dist/types/sdk/broker/lifecycle-ledger.d.ts +23 -3
  63. package/dist/types/sdk/broker/lifecycle.d.ts +15 -8
  64. package/dist/types/sdk/broker/managed-task-dag.d.ts +1335 -0
  65. package/dist/types/sdk/broker/managed-task-verification.d.ts +37 -0
  66. package/dist/types/sdk/broker/runtime.d.ts +1 -1
  67. package/dist/types/sdk/broker/session-index.d.ts +22 -3
  68. package/dist/types/sdk/broker/spawn-authority.d.ts +12 -0
  69. package/dist/types/sdk/broker/startup-failure.d.ts +4 -0
  70. package/dist/types/sdk/broker/stderr-drainer.d.ts +13 -0
  71. package/dist/types/sdk/bus/index.d.ts +19 -0
  72. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +7 -1
  73. package/dist/types/sdk/bus/telegram-daemon.d.ts +5 -0
  74. package/dist/types/sdk/cli/master-cli.d.ts +6 -10
  75. package/dist/types/sdk/cli/rows.d.ts +19 -1
  76. package/dist/types/sdk/cli/session-cli.d.ts +22 -5
  77. package/dist/types/sdk/client/client.d.ts +2 -0
  78. package/dist/types/sdk/guides/cli.d.ts +3 -4
  79. package/dist/types/sdk/guides/verify.d.ts +2 -0
  80. package/dist/types/sdk/host/host.d.ts +9 -0
  81. package/dist/types/sdk/host/session-runtime.d.ts +31 -0
  82. package/dist/types/sdk/host/types.d.ts +10 -0
  83. package/dist/types/sdk/index.d.ts +1 -0
  84. package/dist/types/sdk/prompt-deadline-flush.d.ts +85 -0
  85. package/dist/types/sdk/prompt-deadline-manager.d.ts +37 -0
  86. package/dist/types/sdk/prompt-tool-boundary.d.ts +73 -0
  87. package/dist/types/sdk/router/session-router.d.ts +2 -0
  88. package/dist/types/sdk/session.d.ts +3 -3
  89. package/dist/types/sdk/startup-capability.d.ts +2 -0
  90. package/dist/types/sdk/transport/relay.d.ts +1 -0
  91. package/dist/types/sdk/transport/serve-cli.d.ts +48 -4
  92. package/dist/types/sdk/transport/stdio.d.ts +5 -1
  93. package/dist/types/session/agent-session.d.ts +175 -23
  94. package/dist/types/session/fallback-chain-controller.d.ts +6 -6
  95. package/dist/types/session/fold-coordinator.d.ts +17 -3
  96. package/dist/types/session/internal/managed-session-storage.d.ts +7 -1
  97. package/dist/types/session/session-manager.d.ts +64 -1
  98. package/dist/types/session/session-work-lease.d.ts +14 -0
  99. package/dist/types/setup/model-onboarding-guidance.d.ts +1 -1
  100. package/dist/types/setup/provider-onboarding.d.ts +81 -1
  101. package/dist/types/task/types.d.ts +2 -0
  102. package/dist/types/tools/bash-interactive.d.ts +1 -0
  103. package/dist/types/tools/bash.d.ts +37 -11
  104. package/dist/types/tools/fetch.d.ts +10 -1
  105. package/dist/types/tools/job.d.ts +1 -1
  106. package/dist/types/tools/steer-fold.d.ts +31 -0
  107. package/dist/types/tools/subagent.d.ts +8 -1
  108. package/dist/types/utils/git.d.ts +28 -2
  109. package/dist/types/utils/mupdf-embedded.d.ts +2 -0
  110. package/dist/types/utils/mupdf.d.ts +4 -0
  111. package/dist/types/utils/session-title-generation.d.ts +6 -0
  112. package/dist/types/utils/title-generator.d.ts +11 -2
  113. package/dist/types/web/scrapers/types.d.ts +3 -0
  114. package/package.json +18 -10
  115. package/scripts/build-binary.ts +9 -3
  116. package/scripts/compile-args.ts +0 -9
  117. package/scripts/embed-mupdf.ts +52 -0
  118. package/scripts/generate-sdk-operation-inventory.ts +31 -1
  119. package/scripts/vendor-markit.ts +196 -0
  120. package/src/async/job-manager.ts +22 -1
  121. package/src/cli/daemon-cli.ts +53 -18
  122. package/src/cli/github-release.ts +87 -5
  123. package/src/cli/mcp-cli.ts +38 -4
  124. package/src/cli/public-command-entry.ts +450 -0
  125. package/src/cli/public-command-errors.ts +581 -0
  126. package/src/cli/public-command-evidence.ts +717 -0
  127. package/src/cli/public-command-help.ts +360 -0
  128. package/src/cli/public-command-registry.ts +541 -0
  129. package/src/cli/session-picker.ts +2 -1
  130. package/src/cli/setup-cli.ts +10 -1
  131. package/src/cli/skills-cli.ts +46 -2
  132. package/src/cli/stats-cli.ts +11 -1
  133. package/src/cli.ts +61 -1
  134. package/src/commands/daemon.ts +65 -69
  135. package/src/commands/sdk.ts +175 -117
  136. package/src/commands/setup.ts +2 -0
  137. package/src/commands/skills.ts +11 -0
  138. package/src/config/autorouting-tier-map.ts +543 -3
  139. package/src/config/file-lock.ts +206 -65
  140. package/src/config/model-discovery-manager.ts +4 -4
  141. package/src/config/model-profile-activation.ts +417 -66
  142. package/src/config/model-registry.ts +254 -36
  143. package/src/config/model-resolver.ts +6 -1
  144. package/src/config/settings-schema.ts +26 -2
  145. package/src/coordinator-mcp/policy.ts +10 -5
  146. package/src/coordinator-mcp/question-gate-codec.ts +17 -0
  147. package/src/coordinator-mcp/question-state.ts +179 -9
  148. package/src/coordinator-mcp/server.ts +521 -87
  149. package/src/coordinator-mcp/session-reaper.ts +6 -4
  150. package/src/crash/record-loader.ts +6 -2
  151. package/src/daemon/operator-contract.ts +26 -12
  152. package/src/defaults/gjc/skills/ultragoal/SKILL.md +1 -1
  153. package/src/eval/js/context-manager.ts +8 -8
  154. package/src/eval/js/worker-core.ts +9 -4
  155. package/src/eval/js/worker-protocol.ts +2 -0
  156. package/src/exec/bash-executor.ts +3 -0
  157. package/src/extensibility/extensions/runner.ts +52 -4
  158. package/src/extensibility/extensions/types.ts +10 -0
  159. package/src/extensibility/gjc-plugins/registry.ts +196 -37
  160. package/src/extensibility/gjc-plugins/runtime-adapters.ts +46 -8
  161. package/src/extensibility/runtime-skill-discovery.ts +61 -3
  162. package/src/extensibility/shared-events.ts +3 -1
  163. package/src/gjc-runtime/session-state-lock.ts +165 -24
  164. package/src/gjc-runtime/state-writer.ts +317 -6
  165. package/src/gjc-runtime/ultragoal-succession.ts +31 -3
  166. package/src/harness-control-plane/control-endpoint.ts +24 -6
  167. package/src/harness-control-plane/finalize.ts +312 -25
  168. package/src/harness-control-plane/owner.ts +323 -89
  169. package/src/internal-urls/docs-index.generated.ts +23 -20
  170. package/src/internal-urls/embedded-protocol.ts +83 -0
  171. package/src/internal-urls/index.ts +1 -0
  172. package/src/internal-urls/parse.ts +21 -1
  173. package/src/internal-urls/router.ts +4 -2
  174. package/src/main.ts +192 -74
  175. package/src/modes/acp/acp-agent.ts +973 -56
  176. package/src/modes/acp/startup-provenance.ts +59 -0
  177. package/src/modes/components/custom-provider-wizard.ts +308 -7
  178. package/src/modes/components/gjc-bundle-settings.ts +21 -1
  179. package/src/modes/components/oauth-selector.ts +9 -0
  180. package/src/modes/components/session-selector.ts +47 -4
  181. package/src/modes/components/tool-status-header.ts +72 -6
  182. package/src/modes/components/user-message-selector.ts +57 -15
  183. package/src/modes/controllers/command-controller.ts +58 -32
  184. package/src/modes/controllers/extension-ui-controller.ts +33 -7
  185. package/src/modes/controllers/input-controller.ts +4 -0
  186. package/src/modes/controllers/runtime-mcp-command-controller.ts +1 -1
  187. package/src/modes/controllers/selector-controller.ts +161 -15
  188. package/src/modes/interactive-mode.ts +21 -7
  189. package/src/modes/runtime-init.ts +1 -0
  190. package/src/modes/shared/agent-wire/workflow-gate-broker.ts +124 -7
  191. package/src/modes/shared/agent-wire/workflow-gate-types.ts +16 -2
  192. package/src/modes/types.ts +2 -2
  193. package/src/prompts/agent-fragments/browser-aside.md +1 -0
  194. package/src/prompts/system/title-system.md +1 -1
  195. package/src/prompts/tools/bash.md +1 -1
  196. package/src/prompts/tools/job.md +1 -1
  197. package/src/prompts/tools/read.md +2 -0
  198. package/src/runtime/network-prewarm-service.test.ts +36 -1
  199. package/src/runtime/network-prewarm-service.ts +28 -3
  200. package/src/runtime/process-lifecycle.ts +22 -11
  201. package/src/runtime-mcp/config.ts +16 -1
  202. package/src/runtime-mcp/loader.ts +6 -3
  203. package/src/runtime-mcp/manager.ts +845 -109
  204. package/src/runtime-mcp/pool.test.ts +31 -0
  205. package/src/runtime-mcp/pool.ts +304 -28
  206. package/src/runtime-mcp/redaction.ts +42 -0
  207. package/src/runtime-mcp/startup-policy.ts +7 -0
  208. package/src/runtime-mcp/tool-bridge.ts +71 -0
  209. package/src/runtime-mcp/transports/http.ts +108 -25
  210. package/src/sdk/acp/adapter.ts +27 -8
  211. package/src/sdk/broker/broker.ts +1431 -198
  212. package/src/sdk/broker/ensure.ts +21 -3
  213. package/src/sdk/broker/identity.ts +22 -1
  214. package/src/sdk/broker/lifecycle-ledger.ts +95 -31
  215. package/src/sdk/broker/lifecycle.ts +690 -141
  216. package/src/sdk/broker/managed-task-dag.ts +1927 -0
  217. package/src/sdk/broker/managed-task-verification.ts +642 -0
  218. package/src/sdk/broker/runtime.ts +1 -1
  219. package/src/sdk/broker/session-index.ts +97 -4
  220. package/src/sdk/broker/spawn-authority.ts +175 -14
  221. package/src/sdk/broker/startup-failure.ts +80 -1
  222. package/src/sdk/broker/stderr-drainer.ts +59 -0
  223. package/src/sdk/broker/transport.ts +1 -0
  224. package/src/sdk/bus/chat-daemon-control.ts +2 -2
  225. package/src/sdk/bus/chat-daemon-runtime.ts +1 -0
  226. package/src/sdk/bus/index.ts +707 -81
  227. package/src/sdk/bus/telegram-daemon-cli.ts +31 -2
  228. package/src/sdk/bus/telegram-daemon-contract.ts +7 -1
  229. package/src/sdk/bus/telegram-daemon.ts +10 -3
  230. package/src/sdk/cli/master-cli.ts +47 -36
  231. package/src/sdk/cli/rows.ts +30 -7
  232. package/src/sdk/cli/session-cli.ts +705 -184
  233. package/src/sdk/client/client.ts +18 -0
  234. package/src/sdk/guides/catalog.ts +2 -2
  235. package/src/sdk/guides/cli.ts +20 -62
  236. package/src/sdk/guides/verify.ts +14 -0
  237. package/src/sdk/host/host.ts +49 -5
  238. package/src/sdk/host/session-runtime.test.ts +184 -2
  239. package/src/sdk/host/session-runtime.ts +322 -101
  240. package/src/sdk/host/types.ts +12 -1
  241. package/src/sdk/host/websocket-transport.lifecycle.test.ts +84 -0
  242. package/src/sdk/host/websocket-transport.ts +40 -6
  243. package/src/sdk/index.ts +11 -0
  244. package/src/sdk/lifecycle/service.ts +2 -0
  245. package/src/sdk/prompt-deadline-flush.ts +356 -0
  246. package/src/sdk/prompt-deadline-manager.ts +133 -1
  247. package/src/sdk/prompt-tool-boundary.ts +121 -0
  248. package/src/sdk/protocol/operation-inventory.generated.json +106 -0
  249. package/src/sdk/router/session-router.ts +9 -1
  250. package/src/sdk/session.ts +763 -116
  251. package/src/sdk/startup-capability.ts +1 -1
  252. package/src/sdk/transport/relay.ts +71 -6
  253. package/src/sdk/transport/serve-cli.ts +397 -42
  254. package/src/sdk/transport/socket.ts +12 -11
  255. package/src/sdk/transport/stdio.ts +7 -3
  256. package/src/session/agent-session.ts +2472 -407
  257. package/src/session/fallback-chain-controller.ts +6 -7
  258. package/src/session/fold-coordinator.ts +24 -5
  259. package/src/session/internal/managed-session-scope.ts +68 -18
  260. package/src/session/internal/managed-session-storage.ts +334 -12
  261. package/src/session/session-manager.ts +382 -44
  262. package/src/session/session-work-lease.ts +34 -0
  263. package/src/setup/model-onboarding-guidance.ts +1 -1
  264. package/src/setup/provider-onboarding.ts +397 -24
  265. package/src/setup/provider-presets.json +2 -1
  266. package/src/slash-commands/builtin-registry.ts +259 -15
  267. package/src/task/executor.ts +46 -17
  268. package/src/task/index.ts +14 -2
  269. package/src/task/types.ts +2 -0
  270. package/src/tools/bash-interactive.ts +2 -0
  271. package/src/tools/bash.ts +118 -78
  272. package/src/tools/fetch.ts +140 -25
  273. package/src/tools/job.ts +151 -25
  274. package/src/tools/output-meta.ts +15 -2
  275. package/src/tools/path-utils.ts +27 -3
  276. package/src/tools/read.ts +3 -3
  277. package/src/tools/steer-fold.ts +107 -0
  278. package/src/tools/subagent-render.ts +24 -1
  279. package/src/tools/subagent.ts +27 -1
  280. package/src/tools/tool-catalog.generated.ts +29 -2
  281. package/src/tools/tool-errors.ts +4 -0
  282. package/src/utils/git.ts +53 -3
  283. package/src/utils/markit.ts +55 -41
  284. package/src/utils/mupdf-assets.d.ts +4 -0
  285. package/src/utils/mupdf-embedded.ts +4 -0
  286. package/src/utils/mupdf.ts +136 -0
  287. package/src/utils/session-title-generation.ts +29 -0
  288. package/src/utils/title-generator.ts +46 -2
  289. package/src/web/scrapers/types.ts +24 -3
  290. package/vendor/markit-ai/LICENSE +21 -0
  291. package/vendor/markit-ai/MANIFEST.json +412 -0
  292. package/vendor/markit-ai/dist/commands/config.d.ts +4 -0
  293. package/vendor/markit-ai/dist/commands/config.js +139 -0
  294. package/vendor/markit-ai/dist/commands/convert.d.ts +6 -0
  295. package/vendor/markit-ai/dist/commands/convert.js +113 -0
  296. package/vendor/markit-ai/dist/commands/formats.d.ts +2 -0
  297. package/vendor/markit-ai/dist/commands/formats.js +92 -0
  298. package/vendor/markit-ai/dist/commands/init.d.ts +2 -0
  299. package/vendor/markit-ai/dist/commands/init.js +29 -0
  300. package/vendor/markit-ai/dist/commands/onboard.d.ts +2 -0
  301. package/vendor/markit-ai/dist/commands/onboard.js +61 -0
  302. package/vendor/markit-ai/dist/commands/plugin.d.ts +4 -0
  303. package/vendor/markit-ai/dist/commands/plugin.js +58 -0
  304. package/vendor/markit-ai/dist/config.d.ts +26 -0
  305. package/vendor/markit-ai/dist/config.js +42 -0
  306. package/vendor/markit-ai/dist/converters/audio.d.ts +7 -0
  307. package/vendor/markit-ai/dist/converters/audio.js +104 -0
  308. package/vendor/markit-ai/dist/converters/csv.d.ts +7 -0
  309. package/vendor/markit-ai/dist/converters/csv.js +83 -0
  310. package/vendor/markit-ai/dist/converters/docx.d.ts +6 -0
  311. package/vendor/markit-ai/dist/converters/docx.js +57 -0
  312. package/vendor/markit-ai/dist/converters/epub.d.ts +8 -0
  313. package/vendor/markit-ai/dist/converters/epub.js +128 -0
  314. package/vendor/markit-ai/dist/converters/github.d.ts +18 -0
  315. package/vendor/markit-ai/dist/converters/github.js +148 -0
  316. package/vendor/markit-ai/dist/converters/html.d.ts +6 -0
  317. package/vendor/markit-ai/dist/converters/html.js +30 -0
  318. package/vendor/markit-ai/dist/converters/image.d.ts +6 -0
  319. package/vendor/markit-ai/dist/converters/image.js +124 -0
  320. package/vendor/markit-ai/dist/converters/ipynb.d.ts +6 -0
  321. package/vendor/markit-ai/dist/converters/ipynb.js +75 -0
  322. package/vendor/markit-ai/dist/converters/iwork.d.ts +20 -0
  323. package/vendor/markit-ai/dist/converters/iwork.js +391 -0
  324. package/vendor/markit-ai/dist/converters/json.d.ts +6 -0
  325. package/vendor/markit-ai/dist/converters/json.js +21 -0
  326. package/vendor/markit-ai/dist/converters/pdf/columns.d.ts +35 -0
  327. package/vendor/markit-ai/dist/converters/pdf/columns.js +93 -0
  328. package/vendor/markit-ai/dist/converters/pdf/extract.d.ts +19 -0
  329. package/vendor/markit-ai/dist/converters/pdf/extract.js +514 -0
  330. package/vendor/markit-ai/dist/converters/pdf/grid.d.ts +25 -0
  331. package/vendor/markit-ai/dist/converters/pdf/grid.js +795 -0
  332. package/vendor/markit-ai/dist/converters/pdf/headers.d.ts +24 -0
  333. package/vendor/markit-ai/dist/converters/pdf/headers.js +108 -0
  334. package/vendor/markit-ai/dist/converters/pdf/index.d.ts +19 -0
  335. package/vendor/markit-ai/dist/converters/pdf/index.js +136 -0
  336. package/vendor/markit-ai/dist/converters/pdf/mupdf-loader.js +9 -0
  337. package/vendor/markit-ai/dist/converters/pdf/render.d.ts +24 -0
  338. package/vendor/markit-ai/dist/converters/pdf/render.js +513 -0
  339. package/vendor/markit-ai/dist/converters/pdf/types.d.ts +75 -0
  340. package/vendor/markit-ai/dist/converters/pdf/types.js +1 -0
  341. package/vendor/markit-ai/dist/converters/plain-text.d.ts +6 -0
  342. package/vendor/markit-ai/dist/converters/plain-text.js +87 -0
  343. package/vendor/markit-ai/dist/converters/pptx.d.ts +8 -0
  344. package/vendor/markit-ai/dist/converters/pptx.js +289 -0
  345. package/vendor/markit-ai/dist/converters/rss.d.ts +11 -0
  346. package/vendor/markit-ai/dist/converters/rss.js +138 -0
  347. package/vendor/markit-ai/dist/converters/wikipedia.d.ts +6 -0
  348. package/vendor/markit-ai/dist/converters/wikipedia.js +33 -0
  349. package/vendor/markit-ai/dist/converters/xlsx.d.ts +8 -0
  350. package/vendor/markit-ai/dist/converters/xlsx.js +147 -0
  351. package/vendor/markit-ai/dist/converters/xml.d.ts +6 -0
  352. package/vendor/markit-ai/dist/converters/xml.js +18 -0
  353. package/vendor/markit-ai/dist/converters/yaml.d.ts +6 -0
  354. package/vendor/markit-ai/dist/converters/yaml.js +17 -0
  355. package/vendor/markit-ai/dist/converters/zip.d.ts +8 -0
  356. package/vendor/markit-ai/dist/converters/zip.js +57 -0
  357. package/vendor/markit-ai/dist/index.d.ts +30 -0
  358. package/vendor/markit-ai/dist/index.js +26 -0
  359. package/vendor/markit-ai/dist/main.d.ts +2 -0
  360. package/vendor/markit-ai/dist/main.js +191 -0
  361. package/vendor/markit-ai/dist/markit.d.ts +45 -0
  362. package/vendor/markit-ai/dist/markit.js +267 -0
  363. package/vendor/markit-ai/dist/plugins/api.d.ts +7 -0
  364. package/vendor/markit-ai/dist/plugins/api.js +42 -0
  365. package/vendor/markit-ai/dist/plugins/index.d.ts +4 -0
  366. package/vendor/markit-ai/dist/plugins/index.js +3 -0
  367. package/vendor/markit-ai/dist/plugins/installer.d.ts +25 -0
  368. package/vendor/markit-ai/dist/plugins/installer.js +176 -0
  369. package/vendor/markit-ai/dist/plugins/loader.d.ts +6 -0
  370. package/vendor/markit-ai/dist/plugins/loader.js +61 -0
  371. package/vendor/markit-ai/dist/plugins/types.d.ts +25 -0
  372. package/vendor/markit-ai/dist/plugins/types.js +1 -0
  373. package/vendor/markit-ai/dist/providers/anthropic.d.ts +2 -0
  374. package/vendor/markit-ai/dist/providers/anthropic.js +47 -0
  375. package/vendor/markit-ai/dist/providers/index.d.ts +21 -0
  376. package/vendor/markit-ai/dist/providers/index.js +56 -0
  377. package/vendor/markit-ai/dist/providers/openai.d.ts +2 -0
  378. package/vendor/markit-ai/dist/providers/openai.js +76 -0
  379. package/vendor/markit-ai/dist/providers/types.d.ts +26 -0
  380. package/vendor/markit-ai/dist/providers/types.js +1 -0
  381. package/vendor/markit-ai/dist/types.d.ts +36 -0
  382. package/vendor/markit-ai/dist/types.js +1 -0
  383. package/vendor/markit-ai/dist/utils/exit-codes.d.ts +4 -0
  384. package/vendor/markit-ai/dist/utils/exit-codes.js +4 -0
  385. package/vendor/markit-ai/dist/utils/output.d.ts +22 -0
  386. package/vendor/markit-ai/dist/utils/output.js +31 -0
  387. package/vendor/markit-ai/dist/utils/turndown.d.ts +8 -0
  388. package/vendor/markit-ai/dist/utils/turndown.js +70 -0
  389. package/vendor/markit-ai/package.json +74 -0
  390. package/vendor/markit-ai.patch +49 -0
@@ -0,0 +1,59 @@
1
+ import { AcpSdkAdapterError } from "../../sdk/acp";
2
+
3
+ type JsonObject = Record<string, unknown>;
4
+
5
+ export type PrimaryControlSurface = "cli" | "sdk";
6
+
7
+ /**
8
+ * Startup-control provenance is the authority record ACP needs before it may take
9
+ * permission, provider, and lifecycle ownership of a session. Hosts serving that
10
+ * record report capabilities carrying `promptTerminalOutcomeVersion`
11
+ * and `primaryControlSurface`; a host that predates the record reports neither, and a
12
+ * host that cannot answer at all reports nothing. Those are three different operator
13
+ * problems, so they get three different messages instead of one "restart the session".
14
+ */
15
+ export function resolveStartupProvenance(input: {
16
+ sessionId: string;
17
+ capabilities: JsonObject | undefined;
18
+ queryFailure: unknown;
19
+ }): PrimaryControlSurface {
20
+ const { sessionId, capabilities, queryFailure } = input;
21
+ if (!capabilities)
22
+ throw new AcpSdkAdapterError(
23
+ "unavailable",
24
+ `ACP session ${sessionId} did not answer runtime.capabilities, so its startup control provenance is unknown${describeFailure(queryFailure)}.`,
25
+ );
26
+ const surface =
27
+ capabilities.primaryControlSurface === "sdk"
28
+ ? "sdk"
29
+ : capabilities.primaryControlSurface === "cli"
30
+ ? "cli"
31
+ : undefined;
32
+ if (capabilities.promptTerminalOutcomeVersion !== 1 || surface === undefined)
33
+ throw new AcpSdkAdapterError(
34
+ "unavailable",
35
+ `ACP session ${sessionId} is served by a live GJC host that predates startup control provenance. Upgrading the client does not upgrade that already-running host: stop it, then reopen the session so the current build resumes it from its stored record.`,
36
+ );
37
+ return surface;
38
+ }
39
+
40
+ function describeFailure(failure: unknown): string {
41
+ if (failure === undefined) return "";
42
+ let code: unknown;
43
+ try {
44
+ if ((typeof failure !== "object" || failure === null) && typeof failure !== "function") return " (query failed)";
45
+ code = (failure as { code?: unknown }).code;
46
+ } catch {
47
+ return " (query failed)";
48
+ }
49
+ switch (code) {
50
+ case "connection_closed":
51
+ return " (connection closed)";
52
+ case "timeout":
53
+ return " (query timed out)";
54
+ case "uncertain_after_send":
55
+ return " (query outcome uncertain)";
56
+ default:
57
+ return " (query failed)";
58
+ }
59
+ }
@@ -1,3 +1,4 @@
1
+ import * as crypto from "node:crypto";
1
2
  import { Container, Input, matchesKey, SecretInput, Spacer, Text, TruncatedText } from "@gajae-code/tui";
2
3
  import type { ProviderCompatibility, ProviderSetupInput } from "../../setup/provider-onboarding";
3
4
  import { theme } from "../theme/theme";
@@ -12,6 +13,7 @@ type WizardStep =
12
13
  | "base-url"
13
14
  | "credential-source"
14
15
  | "credential"
16
+ | "discover"
15
17
  | "models"
16
18
  | "confirm"
17
19
  | "force-confirm";
@@ -22,11 +24,33 @@ interface WizardState {
22
24
  baseUrl: string;
23
25
  credentialSource: CustomProviderCredentialSource;
24
26
  credential: string;
27
+ discoverModels: boolean;
28
+ discoveredModels: string[];
29
+ /** Inputs that produced discoveredModels; empty when results are stale/unprobed. */
30
+ discoveredForBaseUrl: string;
31
+ /** SHA-256 of the credential that produced the results — never the secret itself. */
32
+ discoveredForCredentialHash: string;
33
+ discoveredForCredentialSource: CustomProviderCredentialSource;
34
+ discoveryError: string | null;
25
35
  models: string;
26
36
  }
27
37
 
28
38
  export type CustomProviderWizardSubmit = ProviderSetupInput;
29
39
 
40
+ export interface CustomProviderWizardDiscoveryDeps {
41
+ discoverModels?: (input: {
42
+ baseUrl: string;
43
+ apiKeyEnv?: string;
44
+ apiKey?: string;
45
+ signal?: AbortSignal;
46
+ }) => Promise<{ models: string[] }>;
47
+ }
48
+
49
+ /** Non-secret fingerprint binding probe results to the credential that produced them. */
50
+ function fingerprintCredential(credential: string): string {
51
+ return `sha256:${crypto.createHash("sha256").update(credential, "utf8").digest("hex")}`;
52
+ }
53
+
30
54
  export class CustomProviderWizardComponent extends Container {
31
55
  #contentContainer: Container;
32
56
  #input: Input | SecretInput | null = null;
@@ -39,22 +63,37 @@ export class CustomProviderWizardComponent extends Container {
39
63
  baseUrl: "",
40
64
  credentialSource: "env",
41
65
  credential: "",
66
+ discoverModels: false,
67
+ discoveredModels: [],
68
+ discoveredForBaseUrl: "",
69
+ discoveredForCredentialHash: "",
70
+ discoveredForCredentialSource: "env",
71
+ discoveryError: null,
42
72
  models: "",
43
73
  };
44
74
  #submitInFlight = false;
75
+ #discoveryInFlight = false;
76
+ #discoveryGeneration = 0;
77
+ #submitGeneration = 0;
78
+ #discoveryAbort: AbortController | null = null;
79
+ #submitAbort: AbortController | null = null;
80
+ #dismissed = false;
45
81
  #onSubmit: (input: CustomProviderWizardSubmit) => void;
46
82
  #onCancel: () => void;
47
83
  #onRender: () => void;
84
+ #discoveryDeps: CustomProviderWizardDiscoveryDeps = {};
48
85
 
49
86
  constructor(
50
87
  onSubmit: (input: CustomProviderWizardSubmit) => void,
51
88
  onCancel: () => void,
52
89
  onRender: () => void = () => {},
90
+ discoveryDeps: CustomProviderWizardDiscoveryDeps = {},
53
91
  ) {
54
92
  super();
55
93
  this.#onSubmit = onSubmit;
56
94
  this.#onCancel = onCancel;
57
95
  this.#onRender = onRender;
96
+ this.#discoveryDeps = discoveryDeps;
58
97
 
59
98
  this.addChild(new DynamicBorder());
60
99
  this.addChild(new Spacer(1));
@@ -83,6 +122,8 @@ export class CustomProviderWizardComponent extends Container {
83
122
  handleInput(keyData: string): void {
84
123
  if (matchesAppInterrupt(keyData)) {
85
124
  if (this.#step === "compatibility") {
125
+ this.#dismissed = true;
126
+ this.#cancelDiscovery();
86
127
  this.#clearLiteralCredential();
87
128
  this.#onCancel();
88
129
  return;
@@ -155,6 +196,9 @@ export class CustomProviderWizardComponent extends Container {
155
196
  this.#renderSecretInputStep();
156
197
  }
157
198
  break;
199
+ case "discover":
200
+ this.#renderDiscoverStep();
201
+ break;
158
202
  case "models":
159
203
  this.#renderInputStep(
160
204
  "Step 6: Model id(s)",
@@ -204,6 +248,49 @@ export class CustomProviderWizardComponent extends Container {
204
248
  this.#addHelp("[Enter to continue, Esc to go back]");
205
249
  }
206
250
 
251
+ #renderDiscoverStep(): void {
252
+ this.#contentContainer.addChild(new Text(theme.fg("accent", "Step 6: Model discovery")));
253
+ this.#contentContainer.addChild(new Spacer(1));
254
+ if (this.#state.compatibility !== "openai") {
255
+ this.#contentContainer.addChild(
256
+ new Text("Model discovery needs an OpenAI-compatible endpoint. Continue with manual model ids.", 0, 0),
257
+ );
258
+ this.#contentContainer.addChild(new Spacer(1));
259
+ this.#addOption(0, "Enter model ids manually");
260
+ this.#addHelp("[Enter to continue, Esc to go back]");
261
+ return;
262
+ }
263
+ if (this.#discoveryInFlight) {
264
+ this.#contentContainer.addChild(new Text("Discovering models from the provider /v1/models endpoint…", 0, 0));
265
+ this.#contentContainer.addChild(new Spacer(1));
266
+ this.#addHelp("The API key is sent only to your configured base URL.");
267
+ return;
268
+ }
269
+ if (this.#state.discoveryError) {
270
+ this.#contentContainer.addChild(
271
+ new Text(theme.fg("warning", `Discovery failed: ${this.#state.discoveryError}`), 0, 0),
272
+ );
273
+ this.#contentContainer.addChild(new Spacer(1));
274
+ }
275
+ if (this.#state.discoveredModels.length > 0) {
276
+ const preview = this.#state.discoveredModels.slice(0, 10).join(", ");
277
+ const extra =
278
+ this.#state.discoveredModels.length > 10 ? ` (+${this.#state.discoveredModels.length - 10} more)` : "";
279
+ this.#contentContainer.addChild(
280
+ new Text(`Discovered ${this.#state.discoveredModels.length} model(s): ${preview}${extra}`, 0, 0),
281
+ );
282
+ this.#contentContainer.addChild(new Spacer(1));
283
+ } else if (!this.#state.discoveryError) {
284
+ this.#contentContainer.addChild(
285
+ new Text("Probe the provider /v1/models endpoint, or enter model ids manually.", 0, 0),
286
+ );
287
+ this.#contentContainer.addChild(new Spacer(1));
288
+ }
289
+ this.#addOption(0, this.#state.discoveredModels.length > 0 ? "Use discovered models" : "Discover models now");
290
+ this.#addOption(1, "Enter model ids manually");
291
+ this.#addHelp("[↑↓ to navigate, Enter to select, Esc to go back]");
292
+ }
293
+
207
294
  #renderSecretInputStep(): void {
208
295
  this.#contentContainer.addChild(new Text(theme.fg("accent", "Step 5: Credential")));
209
296
  this.#contentContainer.addChild(new Spacer(1));
@@ -214,9 +301,7 @@ export class CustomProviderWizardComponent extends Container {
214
301
  const credential = secret.consume().trim();
215
302
  if (!credential) return;
216
303
  this.#state.credential = credential;
217
- this.#step = "models";
218
- this.#renderStep();
219
- this.#onRender();
304
+ this.#enterDiscovery();
220
305
  };
221
306
  this.#input = input;
222
307
  this.#contentContainer.addChild(input);
@@ -267,16 +352,25 @@ export class CustomProviderWizardComponent extends Container {
267
352
  if (!value) return;
268
353
  if (this.#step === "provider-id") {
269
354
  this.#state.providerId = value;
355
+ // A provider-ID revision invalidates pending submits exactly
356
+ // like URL/credential revisions do.
357
+ this.#clearStaleDiscovery();
270
358
  this.#step = "base-url";
271
359
  } else if (this.#step === "base-url") {
272
360
  this.#state.baseUrl = value;
361
+ this.#clearStaleDiscovery();
273
362
  this.#step = "credential-source";
274
363
  this.#selectedIndex = 0;
275
364
  } else if (this.#step === "credential") {
276
365
  this.#state.credential = value;
277
- this.#step = "models";
366
+ this.#enterDiscovery();
367
+ return;
278
368
  } else if (this.#step === "models") {
279
369
  this.#state.models = value;
370
+ // Manual entry supersedes any accepted discovery (clearStale
371
+ // also resets discoverModels): submitting both would silently
372
+ // persist live discovery the manual screen never disclosed.
373
+ this.#clearStaleDiscovery();
280
374
  this.#step = "confirm";
281
375
  this.#selectedIndex = 0;
282
376
  this.#lastSubmitError = null;
@@ -285,6 +379,18 @@ export class CustomProviderWizardComponent extends Container {
285
379
  this.#onRender();
286
380
  }
287
381
 
382
+ #enterDiscovery(): void {
383
+ this.#clearStaleDiscovery();
384
+ this.#step = "discover";
385
+ this.#selectedIndex = 0;
386
+ if (this.#state.compatibility === "openai" && this.#discoveryDeps.discoverModels) {
387
+ this.#runDiscovery();
388
+ } else {
389
+ this.#renderStep();
390
+ this.#onRender();
391
+ }
392
+ }
393
+
288
394
  #selectCurrentOption(): void {
289
395
  if (this.#step === "compatibility") {
290
396
  this.#state.compatibility = this.#selectedIndex === 0 ? "openai" : "anthropic";
@@ -293,37 +399,189 @@ export class CustomProviderWizardComponent extends Container {
293
399
  this.#state.credentialSource = this.#selectedIndex === 0 ? "env" : "literal";
294
400
  this.#state.credential = "";
295
401
  this.#step = "credential";
402
+ } else if (this.#step === "discover") {
403
+ if (this.#state.compatibility !== "openai") {
404
+ this.#step = "models";
405
+ } else if (this.#selectedIndex === 0) {
406
+ if (this.#state.discoveredModels.length > 0 && this.#discoveryResultsAreFresh()) {
407
+ this.#state.discoverModels = true;
408
+ this.#state.models = "";
409
+ this.#step = "confirm";
410
+ this.#selectedIndex = 0;
411
+ this.#lastSubmitError = null;
412
+ } else {
413
+ this.#runDiscovery();
414
+ return;
415
+ }
416
+ } else {
417
+ this.#state.discoverModels = false;
418
+ this.#cancelDiscovery();
419
+ this.#step = "models";
420
+ }
296
421
  } else if (this.#step === "confirm" || this.#step === "force-confirm") {
297
422
  if (this.#selectedIndex === 0) {
298
423
  this.#submit();
299
424
  return;
300
425
  }
301
- this.#step = "models";
426
+ this.#goBack();
427
+ return;
302
428
  }
303
429
  this.#renderStep();
304
430
  this.#onRender();
305
431
  }
306
432
 
433
+ #clearStaleDiscovery(): void {
434
+ this.#discoveryGeneration += 1;
435
+ this.#submitGeneration += 1;
436
+ this.#discoveryAbort?.abort();
437
+ this.#discoveryAbort = null;
438
+ // A revision also invalidates an in-flight submit: without this,
439
+ // a submit-time probe started before the edit could still persist
440
+ // the old URL/key and close the wizard as successful.
441
+ this.#submitAbort?.abort();
442
+ this.#submitAbort = null;
443
+ this.#discoveryInFlight = false;
444
+ this.#state.discoveredModels = [];
445
+ this.#state.discoveredForBaseUrl = "";
446
+ this.#state.discoveredForCredentialHash = "";
447
+ this.#state.discoverModels = false;
448
+ this.#state.discoveryError = null;
449
+ }
450
+
451
+ #discoveryResultsAreFresh(): boolean {
452
+ return (
453
+ this.#state.discoveredForBaseUrl !== "" &&
454
+ this.#state.discoveredForBaseUrl === this.#state.baseUrl.trim() &&
455
+ this.#state.discoveredForCredentialHash !== "" &&
456
+ this.#state.discoveredForCredentialHash === fingerprintCredential(this.#state.credential.trim()) &&
457
+ this.#state.discoveredForCredentialSource === this.#state.credentialSource
458
+ );
459
+ }
460
+
461
+ #runDiscovery(): void {
462
+ const discover = this.#discoveryDeps.discoverModels;
463
+ if (!discover || this.#discoveryInFlight) return;
464
+ this.#discoveryAbort?.abort();
465
+ const controller = new AbortController();
466
+ this.#discoveryAbort = controller;
467
+ this.#discoveryInFlight = true;
468
+ this.#discoveryGeneration += 1;
469
+ const generation = this.#discoveryGeneration;
470
+ this.#state.discoveryError = null;
471
+ this.#renderStep();
472
+ this.#onRender();
473
+ // Immutable fingerprint of the inputs being probed: completions are
474
+ // accepted only when both the generation and the live inputs still
475
+ // match, so an edit made while the request was in flight cannot
476
+ // inherit a catalog fetched for different inputs.
477
+ const credential = this.#state.credential.trim();
478
+ const fingerprint = {
479
+ baseUrl: this.#state.baseUrl.trim(),
480
+ credential,
481
+ credentialSource: this.#state.credentialSource,
482
+ };
483
+ const request = {
484
+ baseUrl: fingerprint.baseUrl,
485
+ apiKeyEnv: fingerprint.credentialSource === "env" ? fingerprint.credential : undefined,
486
+ apiKey: fingerprint.credentialSource === "literal" ? fingerprint.credential : undefined,
487
+ signal: controller.signal,
488
+ };
489
+ void Promise.resolve()
490
+ .then(() => discover(request))
491
+ .then(
492
+ result => {
493
+ if (!this.#isCurrentDiscoveryGeneration(generation)) return;
494
+ this.#discoveryInFlight = false;
495
+ if (!this.#discoveryFingerprintMatches(fingerprint)) {
496
+ if (this.#step === "discover") {
497
+ this.#renderStep();
498
+ this.#onRender();
499
+ }
500
+ return;
501
+ }
502
+ const models = [...new Set(result.models.map(model => model.trim()).filter(Boolean))].sort((a, b) =>
503
+ a.localeCompare(b),
504
+ );
505
+ this.#state.discoveredModels = models;
506
+ this.#state.discoveredForBaseUrl = fingerprint.baseUrl;
507
+ this.#state.discoveredForCredentialHash = fingerprintCredential(fingerprint.credential);
508
+ this.#state.discoveredForCredentialSource = fingerprint.credentialSource;
509
+ this.#state.discoveryError = models.length === 0 ? "The endpoint returned no models." : null;
510
+ this.#selectedIndex = 0;
511
+ if (this.#step === "discover") {
512
+ this.#renderStep();
513
+ this.#onRender();
514
+ }
515
+ },
516
+ error => {
517
+ if (!this.#isCurrentDiscoveryGeneration(generation)) return;
518
+ this.#discoveryInFlight = false;
519
+ if (!this.#discoveryFingerprintMatches(fingerprint)) {
520
+ if (this.#step === "discover") {
521
+ this.#renderStep();
522
+ this.#onRender();
523
+ }
524
+ return;
525
+ }
526
+ this.#state.discoveredModels = [];
527
+ this.#state.discoveredForBaseUrl = "";
528
+ this.#state.discoveredForCredentialHash = "";
529
+ this.#state.discoveryError = error instanceof Error ? error.message : String(error);
530
+ this.#selectedIndex = 1;
531
+ if (this.#step === "discover") {
532
+ this.#renderStep();
533
+ this.#onRender();
534
+ }
535
+ },
536
+ );
537
+ }
538
+
539
+ #isCurrentDiscoveryGeneration(generation: number): boolean {
540
+ return generation === this.#discoveryGeneration;
541
+ }
542
+
543
+ #discoveryFingerprintMatches(fingerprint: {
544
+ baseUrl: string;
545
+ credential: string;
546
+ credentialSource: CustomProviderCredentialSource;
547
+ }): boolean {
548
+ return (
549
+ fingerprint.baseUrl === this.#state.baseUrl.trim() &&
550
+ fingerprint.credential === this.#state.credential.trim() &&
551
+ fingerprint.credentialSource === this.#state.credentialSource
552
+ );
553
+ }
554
+
307
555
  #submit(): void {
308
556
  if (this.#submitInFlight) return;
309
557
  this.#submitInFlight = true;
558
+ // Own the submit-time pre-write probe lifecycle: Esc-cancel during a
559
+ // stalled submit aborts the probe via #cancelDiscovery so the
560
+ // provider cannot be written after dismissal.
561
+ this.#submitAbort?.abort();
562
+ this.#submitAbort = new AbortController();
563
+ this.#submitGeneration += 1;
310
564
  let submission: unknown;
311
565
  try {
312
566
  submission = this.#onSubmit(this.#buildInput(this.#step === "force-confirm"));
313
567
  } catch (error) {
314
568
  this.#submitInFlight = false;
569
+ this.#endSubmitDiscovery();
315
570
  throw error;
316
571
  }
317
572
  if (!(submission instanceof Promise)) {
318
573
  this.#submitInFlight = false;
574
+ this.#endSubmitDiscovery();
319
575
  return;
320
576
  }
321
577
  void submission.then(
322
578
  () => {
323
579
  this.#submitInFlight = false;
580
+ this.#endSubmitDiscovery();
324
581
  },
325
582
  () => {
326
583
  this.#submitInFlight = false;
584
+ this.#endSubmitDiscovery();
327
585
  },
328
586
  );
329
587
  }
@@ -339,6 +597,8 @@ export class CustomProviderWizardComponent extends Container {
339
597
  .split(",")
340
598
  .map(model => model.trim())
341
599
  .filter(Boolean),
600
+ discover: this.#state.compatibility === "openai" ? this.#state.discoverModels : false,
601
+ discoverySignal: this.#submitAbort?.signal,
342
602
  force,
343
603
  };
344
604
 
@@ -346,9 +606,44 @@ export class CustomProviderWizardComponent extends Container {
346
606
  }
347
607
 
348
608
  complete(): void {
609
+ this.#cancelDiscovery();
349
610
  this.#clearLiteralCredential();
350
611
  }
351
612
 
613
+ /**
614
+ * Abort any in-flight probe and invalidate its generation so a late
615
+ * completion cannot render into (or retain credentials from) a
616
+ * dismissed wizard. Used by both submit and cancel paths.
617
+ */
618
+ #cancelDiscovery(): void {
619
+ this.#discoveryGeneration += 1;
620
+ this.#submitGeneration += 1;
621
+ this.#discoveryAbort?.abort();
622
+ this.#discoveryAbort = null;
623
+ this.#submitAbort?.abort();
624
+ this.#submitAbort = null;
625
+ this.#discoveryInFlight = false;
626
+ }
627
+
628
+ /** Clear the settled submit controller without aborting (submit finished). */
629
+ #endSubmitDiscovery(): void {
630
+ this.#submitAbort = null;
631
+ }
632
+
633
+ /** Generation token for the latest submit attempt. */
634
+ currentSubmitGeneration(): number {
635
+ return this.#submitGeneration;
636
+ }
637
+
638
+ /**
639
+ * Whether a submit attempt is still current: same generation and not
640
+ * dismissed. Revision or cancel invalidates pending completions so a
641
+ * stale refresh cannot report success or rerender over new inputs.
642
+ */
643
+ isSubmitCurrent(generation: number): boolean {
644
+ return generation === this.#submitGeneration && !this.#dismissed;
645
+ }
646
+
352
647
  #clearLiteralCredential(): void {
353
648
  if (this.#state.credentialSource === "literal") this.#state.credential = "";
354
649
  }
@@ -358,7 +653,8 @@ export class CustomProviderWizardComponent extends Container {
358
653
  this.#step === "confirm" ||
359
654
  this.#step === "force-confirm" ||
360
655
  this.#step === "compatibility" ||
361
- this.#step === "credential-source"
656
+ this.#step === "credential-source" ||
657
+ this.#step === "discover"
362
658
  ? 1
363
659
  : 0;
364
660
  this.#selectedIndex = (this.#selectedIndex + delta + maxIndex + 1) % (maxIndex + 1);
@@ -367,11 +663,16 @@ export class CustomProviderWizardComponent extends Container {
367
663
  }
368
664
 
369
665
  #goBack(): void {
666
+ if (this.#step === "discover" || this.#step === "confirm" || this.#step === "force-confirm") {
667
+ // Revision starts on entry to the editor, not when its new value is saved.
668
+ this.#cancelDiscovery();
669
+ }
370
670
  if (this.#step === "provider-id") this.#step = "compatibility";
371
671
  else if (this.#step === "base-url") this.#step = "provider-id";
372
672
  else if (this.#step === "credential-source") this.#step = "base-url";
373
673
  else if (this.#step === "credential") this.#step = "credential-source";
374
- else if (this.#step === "models") this.#step = "credential";
674
+ else if (this.#step === "discover") this.#step = "credential";
675
+ else if (this.#step === "models") this.#step = "discover";
375
676
  else if (this.#step === "confirm" || this.#step === "force-confirm") this.#step = "models";
376
677
  this.#selectedIndex = 0;
377
678
  this.#renderStep();
@@ -1,4 +1,4 @@
1
- import { Container, type SelectItem, SelectList, Spacer, Text } from "@gajae-code/tui";
1
+ import { Container, type SelectItem, SelectList, Spacer, Text, truncateToWidth } from "@gajae-code/tui";
2
2
  import {
3
3
  applyGjcBundleUpdate,
4
4
  type GjcLifecycleContext,
@@ -20,8 +20,11 @@ import type {
20
20
  GjcUpdatePreview,
21
21
  } from "../../extensibility/gjc-plugins/types";
22
22
  import { getSelectListTheme, theme } from "../../modes/theme/theme";
23
+ import { sanitizeStatusText } from "../shared";
23
24
  import { DynamicBorder } from "./dynamic-border";
24
25
 
26
+ const MAX_RUNTIME_FINDING_DISPLAY_WIDTH = 120;
27
+
25
28
  /** Injectable lifecycle boundary; Settings never reads registries or executes bundle code. */
26
29
  export interface GjcBundleLifecyclePort {
27
30
  listGjcBundles(ctx: GjcLifecycleContext): Promise<GjcBundleSummary[]>;
@@ -244,6 +247,23 @@ export class GjcBundleSettingsComponent extends Container {
244
247
  ),
245
248
  );
246
249
  }
250
+ const runtime = findingsForBundle(
251
+ this.dependencies.runtimeSnapshotProvider,
252
+ bundle.identity,
253
+ this.dependencies.activationGeneration ?? 0,
254
+ );
255
+ if (runtime.status === "current") {
256
+ for (const finding of runtime.findings) {
257
+ const detail = truncateToWidth(
258
+ sanitizeStatusText(`${finding.surfaceId}: ${finding.message}`),
259
+ MAX_RUNTIME_FINDING_DISPLAY_WIDTH,
260
+ );
261
+ const label = finding.decision === "error" ? "Runtime error" : "Runtime finding";
262
+ this.addChild(
263
+ new Text(theme.fg(finding.decision === "error" ? "error" : "warning", ` ${label}: ${detail}`), 0, 0),
264
+ );
265
+ }
266
+ }
247
267
  if (this.#message) this.addChild(new Text(theme.fg("warning", ` ${this.#message}`), 0, 0));
248
268
  const actions: SelectItem[] = [];
249
269
  if (bundle.enabled || !bundle.quarantined) {
@@ -164,6 +164,15 @@ export class OAuthSelectorComponent extends Container {
164
164
  { kind: "auto", selectable: true },
165
165
  { kind: "add", selectable: this.#onAddAccount !== undefined },
166
166
  );
167
+ const firstAccount = this.#accountEntries.find(entry => entry.kind === "account");
168
+ if (firstAccount && !firstAccount.selectable) {
169
+ const addAccountIndex =
170
+ firstAccount.row.disabled && this.#onAddAccount !== undefined
171
+ ? this.#accountEntries.findIndex(entry => entry.kind === "add" && entry.selectable)
172
+ : -1;
173
+ this.#selectedIndex =
174
+ addAccountIndex >= 0 ? addAccountIndex : this.#accountEntries.findIndex(entry => entry.selectable);
175
+ }
167
176
  } else if (this.#accountEntries.some(entry => entry.kind === "account" && entry.selectable)) {
168
177
  this.#accountEntries.push({ kind: "all", selectable: this.#onAccountRemove !== undefined });
169
178
  }