open-multi-agent-kit 0.98.2 → 0.98.4

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 (286) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/README.md +11 -2
  3. package/dist/cli/args.d.ts +1 -0
  4. package/dist/cli/args.d.ts.map +1 -1
  5. package/dist/cli/args.js +14 -0
  6. package/dist/cli/args.js.map +1 -1
  7. package/dist/cli/help.d.ts.map +1 -1
  8. package/dist/cli/help.js +3 -0
  9. package/dist/cli/help.js.map +1 -1
  10. package/dist/cli/mcp-attach.d.ts +3 -3
  11. package/dist/cli/mcp-attach.d.ts.map +1 -1
  12. package/dist/cli/mcp-attach.js +5 -4
  13. package/dist/cli/mcp-attach.js.map +1 -1
  14. package/dist/cli/model-contract.d.ts +5 -0
  15. package/dist/cli/model-contract.d.ts.map +1 -0
  16. package/dist/cli/model-contract.js +45 -0
  17. package/dist/cli/model-contract.js.map +1 -0
  18. package/dist/commands/adaptorch-doctor-cli.d.ts.map +1 -1
  19. package/dist/commands/adaptorch-doctor-cli.js +32 -10
  20. package/dist/commands/adaptorch-doctor-cli.js.map +1 -1
  21. package/dist/commands/init-cli.d.ts +12 -0
  22. package/dist/commands/init-cli.d.ts.map +1 -0
  23. package/dist/commands/init-cli.js +76 -0
  24. package/dist/commands/init-cli.js.map +1 -0
  25. package/dist/commands/provider-sync-cli.d.ts +27 -0
  26. package/dist/commands/provider-sync-cli.d.ts.map +1 -0
  27. package/dist/commands/provider-sync-cli.js +177 -0
  28. package/dist/commands/provider-sync-cli.js.map +1 -0
  29. package/dist/commands/run-command.d.ts +8 -0
  30. package/dist/commands/run-command.d.ts.map +1 -0
  31. package/dist/commands/run-command.js +26 -0
  32. package/dist/commands/run-command.js.map +1 -0
  33. package/dist/core/active-skill-state.d.ts +7 -0
  34. package/dist/core/active-skill-state.d.ts.map +1 -0
  35. package/dist/core/active-skill-state.js +25 -0
  36. package/dist/core/active-skill-state.js.map +1 -0
  37. package/dist/core/advisory-judge-model.d.ts.map +1 -1
  38. package/dist/core/advisory-judge-model.js +8 -1
  39. package/dist/core/advisory-judge-model.js.map +1 -1
  40. package/dist/core/advisory-judge-types.d.ts +18 -1
  41. package/dist/core/advisory-judge-types.d.ts.map +1 -1
  42. package/dist/core/advisory-judge-types.js.map +1 -1
  43. package/dist/core/advisory-judge.d.ts.map +1 -1
  44. package/dist/core/advisory-judge.js +41 -6
  45. package/dist/core/advisory-judge.js.map +1 -1
  46. package/dist/core/agent-session-services.d.ts +2 -0
  47. package/dist/core/agent-session-services.d.ts.map +1 -1
  48. package/dist/core/agent-session-services.js +2 -0
  49. package/dist/core/agent-session-services.js.map +1 -1
  50. package/dist/core/agent-session.d.ts +0 -1
  51. package/dist/core/agent-session.d.ts.map +1 -1
  52. package/dist/core/agent-session.js +30 -85
  53. package/dist/core/agent-session.js.map +1 -1
  54. package/dist/core/codex-chatgpt-web-bridge.d.ts +99 -0
  55. package/dist/core/codex-chatgpt-web-bridge.d.ts.map +1 -0
  56. package/dist/core/codex-chatgpt-web-bridge.js +192 -0
  57. package/dist/core/codex-chatgpt-web-bridge.js.map +1 -0
  58. package/dist/core/codex-chatgpt-web-sync.d.ts +50 -0
  59. package/dist/core/codex-chatgpt-web-sync.d.ts.map +1 -0
  60. package/dist/core/codex-chatgpt-web-sync.js +119 -0
  61. package/dist/core/codex-chatgpt-web-sync.js.map +1 -0
  62. package/dist/core/compaction/compaction-headroom.d.ts +30 -0
  63. package/dist/core/compaction/compaction-headroom.d.ts.map +1 -0
  64. package/dist/core/compaction/compaction-headroom.js +48 -0
  65. package/dist/core/compaction/compaction-headroom.js.map +1 -0
  66. package/dist/core/compaction/compaction.d.ts +2 -29
  67. package/dist/core/compaction/compaction.d.ts.map +1 -1
  68. package/dist/core/compaction/compaction.js +19 -47
  69. package/dist/core/compaction/compaction.js.map +1 -1
  70. package/dist/core/compaction/overflow-retry-guard.d.ts +20 -0
  71. package/dist/core/compaction/overflow-retry-guard.d.ts.map +1 -0
  72. package/dist/core/compaction/overflow-retry-guard.js +38 -0
  73. package/dist/core/compaction/overflow-retry-guard.js.map +1 -0
  74. package/dist/core/context-budget-headroom-types.d.ts.map +1 -1
  75. package/dist/core/context-budget-headroom-types.js +1 -1
  76. package/dist/core/context-budget-headroom-types.js.map +1 -1
  77. package/dist/core/context-budget-token-counter-types.d.ts +27 -0
  78. package/dist/core/context-budget-token-counter-types.d.ts.map +1 -0
  79. package/dist/core/context-budget-token-counter-types.js +2 -0
  80. package/dist/core/context-budget-token-counter-types.js.map +1 -0
  81. package/dist/core/context-budget-token-counter.d.ts +2 -26
  82. package/dist/core/context-budget-token-counter.d.ts.map +1 -1
  83. package/dist/core/context-budget-token-counter.js +2 -0
  84. package/dist/core/context-budget-token-counter.js.map +1 -1
  85. package/dist/core/context-budget-v2-scoring.d.ts.map +1 -1
  86. package/dist/core/context-budget-v2-scoring.js +14 -10
  87. package/dist/core/context-budget-v2-scoring.js.map +1 -1
  88. package/dist/core/domain-router.d.ts.map +1 -1
  89. package/dist/core/domain-router.js +1 -1
  90. package/dist/core/domain-router.js.map +1 -1
  91. package/dist/core/grok-harness-dispatch.d.ts +4 -0
  92. package/dist/core/grok-harness-dispatch.d.ts.map +1 -1
  93. package/dist/core/grok-harness-dispatch.js +20 -3
  94. package/dist/core/grok-harness-dispatch.js.map +1 -1
  95. package/dist/core/grok-harness.d.ts +15 -9
  96. package/dist/core/grok-harness.d.ts.map +1 -1
  97. package/dist/core/grok-harness.js +34 -8
  98. package/dist/core/grok-harness.js.map +1 -1
  99. package/dist/core/mcp/tools.d.ts +2 -2
  100. package/dist/core/mcp/tools.d.ts.map +1 -1
  101. package/dist/core/mcp/tools.js +29 -3
  102. package/dist/core/mcp/tools.js.map +1 -1
  103. package/dist/core/model-registry-schema.d.ts +1081 -0
  104. package/dist/core/model-registry-schema.d.ts.map +1 -0
  105. package/dist/core/model-registry-schema.js +148 -0
  106. package/dist/core/model-registry-schema.js.map +1 -0
  107. package/dist/core/model-registry.d.ts.map +1 -1
  108. package/dist/core/model-registry.js +1 -146
  109. package/dist/core/model-registry.js.map +1 -1
  110. package/dist/core/model-resolver.d.ts +2 -1
  111. package/dist/core/model-resolver.d.ts.map +1 -1
  112. package/dist/core/model-resolver.js +2 -1
  113. package/dist/core/model-resolver.js.map +1 -1
  114. package/dist/core/prompt-preset.d.ts +1 -1
  115. package/dist/core/prompt-preset.d.ts.map +1 -1
  116. package/dist/core/prompt-preset.js +16 -1
  117. package/dist/core/prompt-preset.js.map +1 -1
  118. package/dist/core/provider-display-names.d.ts.map +1 -1
  119. package/dist/core/provider-display-names.js +1 -0
  120. package/dist/core/provider-display-names.js.map +1 -1
  121. package/dist/core/provider-resilience.d.ts +8 -0
  122. package/dist/core/provider-resilience.d.ts.map +1 -1
  123. package/dist/core/provider-resilience.js +20 -3
  124. package/dist/core/provider-resilience.js.map +1 -1
  125. package/dist/core/provider-usage-types.d.ts +42 -0
  126. package/dist/core/provider-usage-types.d.ts.map +1 -0
  127. package/dist/core/provider-usage-types.js +2 -0
  128. package/dist/core/provider-usage-types.js.map +1 -0
  129. package/dist/core/provider-usage.d.ts +2 -31
  130. package/dist/core/provider-usage.d.ts.map +1 -1
  131. package/dist/core/provider-usage.js +4 -0
  132. package/dist/core/provider-usage.js.map +1 -1
  133. package/dist/core/redaction.d.ts.map +1 -1
  134. package/dist/core/redaction.js +18 -2
  135. package/dist/core/redaction.js.map +1 -1
  136. package/dist/core/sandbox/policy-merge.d.ts +6 -0
  137. package/dist/core/sandbox/policy-merge.d.ts.map +1 -0
  138. package/dist/core/sandbox/policy-merge.js +74 -0
  139. package/dist/core/sandbox/policy-merge.js.map +1 -0
  140. package/dist/core/sandbox/policy-paths.d.ts +4 -0
  141. package/dist/core/sandbox/policy-paths.d.ts.map +1 -0
  142. package/dist/core/sandbox/policy-paths.js +21 -0
  143. package/dist/core/sandbox/policy-paths.js.map +1 -0
  144. package/dist/core/sandbox/policy-types.d.ts +75 -0
  145. package/dist/core/sandbox/policy-types.d.ts.map +1 -0
  146. package/dist/core/sandbox/policy-types.js +2 -0
  147. package/dist/core/sandbox/policy-types.js.map +1 -0
  148. package/dist/core/sandbox/policy.d.ts +3 -77
  149. package/dist/core/sandbox/policy.d.ts.map +1 -1
  150. package/dist/core/sandbox/policy.js +3 -98
  151. package/dist/core/sandbox/policy.js.map +1 -1
  152. package/dist/core/sdk-provider-stream.d.ts +14 -0
  153. package/dist/core/sdk-provider-stream.d.ts.map +1 -0
  154. package/dist/core/sdk-provider-stream.js +38 -0
  155. package/dist/core/sdk-provider-stream.js.map +1 -0
  156. package/dist/core/sdk.d.ts +5 -1
  157. package/dist/core/sdk.d.ts.map +1 -1
  158. package/dist/core/sdk.js +17 -33
  159. package/dist/core/sdk.js.map +1 -1
  160. package/dist/core/session-bash-runtime.d.ts +7 -0
  161. package/dist/core/session-bash-runtime.d.ts.map +1 -1
  162. package/dist/core/session-bash-runtime.js +10 -1
  163. package/dist/core/session-bash-runtime.js.map +1 -1
  164. package/dist/core/session-failure-cause.d.ts.map +1 -1
  165. package/dist/core/session-failure-cause.js +10 -3
  166. package/dist/core/session-failure-cause.js.map +1 -1
  167. package/dist/core/session-run-termination.d.ts +18 -0
  168. package/dist/core/session-run-termination.d.ts.map +1 -0
  169. package/dist/core/session-run-termination.js +61 -0
  170. package/dist/core/session-run-termination.js.map +1 -0
  171. package/dist/core/session-termination.d.ts.map +1 -1
  172. package/dist/core/session-termination.js +1 -1
  173. package/dist/core/session-termination.js.map +1 -1
  174. package/dist/core/skill-selector.d.ts +40 -0
  175. package/dist/core/skill-selector.d.ts.map +1 -0
  176. package/dist/core/skill-selector.js +102 -0
  177. package/dist/core/skill-selector.js.map +1 -0
  178. package/dist/core/tools/render-utils.d.ts.map +1 -1
  179. package/dist/core/tools/render-utils.js +2 -4
  180. package/dist/core/tools/render-utils.js.map +1 -1
  181. package/dist/core/turn-metrics-record.d.ts +55 -0
  182. package/dist/core/turn-metrics-record.d.ts.map +1 -0
  183. package/dist/core/turn-metrics-record.js +149 -0
  184. package/dist/core/turn-metrics-record.js.map +1 -0
  185. package/dist/core/turn-metrics.d.ts +4 -56
  186. package/dist/core/turn-metrics.d.ts.map +1 -1
  187. package/dist/core/turn-metrics.js +12 -60
  188. package/dist/core/turn-metrics.js.map +1 -1
  189. package/dist/core/verified-bash-runtime.d.ts +40 -0
  190. package/dist/core/verified-bash-runtime.d.ts.map +1 -1
  191. package/dist/core/verified-bash-runtime.js +60 -13
  192. package/dist/core/verified-bash-runtime.js.map +1 -1
  193. package/dist/guardrails/evidence-system.d.ts +1 -1
  194. package/dist/guardrails/evidence-system.d.ts.map +1 -1
  195. package/dist/guardrails/evidence-system.js +18 -29
  196. package/dist/guardrails/evidence-system.js.map +1 -1
  197. package/dist/guardrails/merge-gate-result.d.ts +4 -0
  198. package/dist/guardrails/merge-gate-result.d.ts.map +1 -0
  199. package/dist/guardrails/merge-gate-result.js +32 -0
  200. package/dist/guardrails/merge-gate-result.js.map +1 -0
  201. package/dist/index.d.ts +2 -0
  202. package/dist/index.d.ts.map +1 -1
  203. package/dist/index.js +1 -0
  204. package/dist/index.js.map +1 -1
  205. package/dist/main.d.ts.map +1 -1
  206. package/dist/main.js +22 -22
  207. package/dist/main.js.map +1 -1
  208. package/dist/modes/interactive/interactive-login-options.d.ts +27 -0
  209. package/dist/modes/interactive/interactive-login-options.d.ts.map +1 -0
  210. package/dist/modes/interactive/interactive-login-options.js +54 -0
  211. package/dist/modes/interactive/interactive-login-options.js.map +1 -0
  212. package/dist/modes/interactive/interactive-mode.d.ts +7 -4
  213. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  214. package/dist/modes/interactive/interactive-mode.js +138 -140
  215. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  216. package/dist/modes/interactive/interactive-resume-command.d.ts +3 -0
  217. package/dist/modes/interactive/interactive-resume-command.d.ts.map +1 -0
  218. package/dist/modes/interactive/interactive-resume-command.js +24 -0
  219. package/dist/modes/interactive/interactive-resume-command.js.map +1 -0
  220. package/dist/modes/interactive/interactive-tool-result.d.ts +32 -0
  221. package/dist/modes/interactive/interactive-tool-result.d.ts.map +1 -0
  222. package/dist/modes/interactive/interactive-tool-result.js +59 -0
  223. package/dist/modes/interactive/interactive-tool-result.js.map +1 -0
  224. package/dist/modes/print-mode.d.ts.map +1 -1
  225. package/dist/modes/print-mode.js +22 -0
  226. package/dist/modes/print-mode.js.map +1 -1
  227. package/dist/utils/clipboard-image.d.ts.map +1 -1
  228. package/dist/utils/clipboard-image.js +10 -60
  229. package/dist/utils/clipboard-image.js.map +1 -1
  230. package/dist/utils/terminal-links.d.ts +13 -0
  231. package/dist/utils/terminal-links.d.ts.map +1 -0
  232. package/dist/utils/terminal-links.js +68 -0
  233. package/dist/utils/terminal-links.js.map +1 -0
  234. package/dist/utils/windows-clipboard-image.d.ts +16 -0
  235. package/dist/utils/windows-clipboard-image.d.ts.map +1 -0
  236. package/dist/utils/windows-clipboard-image.js +87 -0
  237. package/dist/utils/windows-clipboard-image.js.map +1 -0
  238. package/docs/adaptorch-onboarding.md +80 -0
  239. package/docs/advisory-selection.md +112 -0
  240. package/docs/containerization.md +12 -0
  241. package/docs/context-files.md +97 -0
  242. package/docs/correctness-wall.md +8 -0
  243. package/docs/custom-provider.md +35 -0
  244. package/docs/development.md +18 -3
  245. package/docs/environment-variables.md +2 -0
  246. package/docs/grok-harness.md +4 -0
  247. package/docs/harness-boundaries.md +154 -0
  248. package/docs/harness-improvements.md +90 -0
  249. package/docs/json.md +19 -0
  250. package/docs/keybindings.md +1 -1
  251. package/docs/mcp.md +22 -2
  252. package/docs/metrics.md +66 -16
  253. package/docs/model-catalog-refresh.md +190 -0
  254. package/docs/model-contract.md +168 -0
  255. package/docs/models.md +21 -4
  256. package/docs/provider-resilience.md +5 -3
  257. package/docs/providers.md +68 -1
  258. package/docs/quickstart.md +4 -0
  259. package/docs/release-audit-0.98.3.md +97 -0
  260. package/docs/release-audit-0.98.4.md +112 -0
  261. package/docs/review-bundle-followup.md +195 -0
  262. package/docs/run-protocol.md +3 -1
  263. package/docs/runtime-algorithms.md +38 -2
  264. package/docs/sdk.md +35 -3
  265. package/docs/sessions.md +1 -1
  266. package/docs/settings.md +17 -1
  267. package/docs/skills.md +2 -0
  268. package/docs/tb21-audit.md +131 -0
  269. package/docs/terminal-setup.md +20 -0
  270. package/docs/usage.md +23 -1
  271. package/docs/windows.md +48 -0
  272. package/examples/README.md +4 -0
  273. package/examples/context/AGENTS.md +64 -0
  274. package/examples/context/CLAUDE.md +17 -0
  275. package/examples/context/INTERNET.md +42 -0
  276. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  277. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  278. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  279. package/examples/extensions/gondolin/package-lock.json +2 -2
  280. package/examples/extensions/gondolin/package.json +1 -1
  281. package/examples/extensions/sandbox/package-lock.json +2 -2
  282. package/examples/extensions/sandbox/package.json +1 -1
  283. package/examples/extensions/with-deps/package-lock.json +2 -2
  284. package/examples/extensions/with-deps/package.json +1 -1
  285. package/npm-shrinkwrap.json +18 -18
  286. package/package.json +6 -6
@@ -7,10 +7,13 @@ import * as fs from "node:fs";
7
7
  import * as os from "node:os";
8
8
  import * as path from "node:path";
9
9
  import { spawn, spawnSync } from "child_process";
10
- import { getProviders, } from "omk-ai";
11
10
  import { AttachmentStore } from "../../core/attachment-store.js";
12
11
  import { describePromptImageAttachment } from "../../core/prompt-attachment.js";
13
12
  import { createAttachmentStrip } from "./components/attachment-strip.js";
13
+ export { formatResumeCommand } from "./interactive-resume-command.js";
14
+ import { getApiKeyLoginDisplayName, isApiKeyLoginProvider, resolveLoginProviderArg, } from "./interactive-login-options.js";
15
+ import { disposeComponent, ExpandableText, isExpandable, normalizeToolExecutionResult, } from "./interactive-tool-result.js";
16
+ export { getApiKeyLoginDisplayName, isApiKeyLoginProvider, resolveLoginProviderArg, } from "./interactive-login-options.js";
14
17
  import { CombinedAutocompleteProvider, Container, fuzzyFilter, getCapabilities, hyperlink, Loader, Markdown, matchesKey, ProcessTerminal, Spacer, setKeybindings, Text, TruncatedText, TUI, visibleWidth, } from "omk-tui";
15
18
  import { APP_NAME, APP_TITLE, getAgentDir, getAuthPath, getDebugLogPath, getDocsPath, getShareViewerUrl, VERSION, } from "../../config.js";
16
19
  import { parseSkillBlock } from "../../core/agent-session.js";
@@ -25,7 +28,6 @@ import { KeybindingsManager } from "../../core/keybindings.js";
25
28
  import { createCompactionSummaryMessage } from "../../core/messages.js";
26
29
  import { defaultModelPerProvider, findExactModelReferenceMatch, resolveModelScope } from "../../core/model-resolver.js";
27
30
  import { DefaultPackageManager } from "../../core/package-manager.js";
28
- import { BUILT_IN_PROVIDER_DISPLAY_NAMES } from "../../core/provider-display-names.js";
29
31
  import { decideResourceAdmission } from "../../core/resource-admission.js";
30
32
  import { formatResourcePolicyLines, formatResourceProbeLines, formatResourceSummaryLines, resolveResourceGovernorSettings, } from "../../core/resource-governor-settings.js";
31
33
  import { formatMissingSessionCwdPrompt, MissingSessionCwdError } from "../../core/session-cwd.js";
@@ -40,6 +42,7 @@ import { parseGitUrl } from "../../utils/git.js";
40
42
  import { openBrowser } from "../../utils/open-browser.js";
41
43
  import { getCwdRelativePath } from "../../utils/paths.js";
42
44
  import { killTrackedDetachedChildren } from "../../utils/shell.js";
45
+ import { terminalMarkdownLinks } from "../../utils/terminal-links.js";
43
46
  import { ensureTool } from "../../utils/tools-manager.js";
44
47
  import { checkForNewOmkVersion } from "../../utils/version-check.js";
45
48
  import { ArminComponent } from "./components/armin.js";
@@ -76,63 +79,6 @@ import { TreeSelectorComponent } from "./components/tree-selector.js";
76
79
  import { UserMessageComponent } from "./components/user-message.js";
77
80
  import { UserMessageSelectorComponent } from "./components/user-message-selector.js";
78
81
  import { getAvailableThemes, getAvailableThemesWithPaths, getEditorTheme, getMarkdownTheme, getThemeByName, initTheme, onThemeChange, setRegisteredThemes, setTheme, setThemeInstance, stopThemeWatcher, Theme, theme, } from "./theme/theme.js";
79
- function isExpandable(obj) {
80
- return typeof obj === "object" && obj !== null && "setExpanded" in obj && typeof obj.setExpanded === "function";
81
- }
82
- function disposeComponent(component) {
83
- if (typeof component === "object" &&
84
- component !== null &&
85
- "dispose" in component &&
86
- typeof component.dispose === "function") {
87
- component.dispose();
88
- }
89
- }
90
- function isRecord(value) {
91
- return typeof value === "object" && value !== null && !Array.isArray(value);
92
- }
93
- function isToolExecutionContent(value) {
94
- if (!isRecord(value))
95
- return false;
96
- if (value.type === "text")
97
- return typeof value.text === "string";
98
- return value.type === "image" && typeof value.data === "string" && typeof value.mimeType === "string";
99
- }
100
- function isToolExecutionResult(value) {
101
- return isRecord(value) && Array.isArray(value.content) && value.content.every(isToolExecutionContent);
102
- }
103
- function normalizeToolExecutionResult(result, isError) {
104
- try {
105
- if (isToolExecutionResult(result)) {
106
- return { content: result.content, details: result.details, isError };
107
- }
108
- }
109
- catch {
110
- // Treat inaccessible or malformed extension payloads as invalid results.
111
- }
112
- return {
113
- content: [{ type: "text", text: "Tool returned an invalid result." }],
114
- isError: true,
115
- };
116
- }
117
- class ExpandableText extends Text {
118
- getCollapsedText;
119
- getExpandedText;
120
- expanded;
121
- constructor(getCollapsedText, getExpandedText, expanded = false, paddingX = 0, paddingY = 0) {
122
- super(expanded ? getExpandedText() : getCollapsedText(), paddingX, paddingY);
123
- this.getCollapsedText = getCollapsedText;
124
- this.getExpandedText = getExpandedText;
125
- this.expanded = expanded;
126
- }
127
- setExpanded(expanded) {
128
- this.expanded = expanded;
129
- this.setText(expanded ? this.getExpandedText() : this.getCollapsedText());
130
- }
131
- invalidate() {
132
- this.setText(this.expanded ? this.getExpandedText() : this.getCollapsedText());
133
- super.invalidate();
134
- }
135
- }
136
82
  const DEAD_TERMINAL_ERROR_CODES = new Set(["EIO", "EPIPE", "ENOTCONN"]);
137
83
  /**
138
84
  * Pseudo-entry for the thinking selector/autocomplete representing auto mode.
@@ -155,41 +101,10 @@ function isAnthropicSubscriptionAuthKey(apiKey) {
155
101
  function isUnknownModel(model) {
156
102
  return !!model && model.provider === "unknown" && model.id === "unknown" && model.api === "unknown";
157
103
  }
158
- function quoteIfNeeded(value) {
159
- if (value.length > 0 && !/[^a-zA-Z0-9_\-./~:@]/.test(value)) {
160
- return value;
161
- }
162
- return `'${value.replace(/'/g, `'\\''`)}'`;
163
- }
164
- export function formatResumeCommand(sessionManager) {
165
- if (!process.stdout.isTTY)
166
- return undefined;
167
- if (!sessionManager.isPersisted())
168
- return undefined;
169
- const sessionFile = sessionManager.getSessionFile();
170
- if (!sessionFile || !fs.existsSync(sessionFile))
171
- return undefined;
172
- const args = [APP_NAME];
173
- if (!sessionManager.usesDefaultSessionDir()) {
174
- args.push("--session-dir", quoteIfNeeded(sessionManager.getSessionDir()));
175
- }
176
- args.push("--session", sessionManager.getSessionId());
177
- return args.join(" ");
178
- }
179
104
  function hasDefaultModelProvider(providerId) {
180
105
  return providerId in defaultModelPerProvider;
181
106
  }
182
107
  const BEDROCK_PROVIDER_ID = "amazon-bedrock";
183
- const BUILT_IN_MODEL_PROVIDERS = new Set(getProviders());
184
- export function isApiKeyLoginProvider(providerId, oauthProviderIds, builtInProviderIds = BUILT_IN_MODEL_PROVIDERS) {
185
- if (BUILT_IN_PROVIDER_DISPLAY_NAMES[providerId]) {
186
- return true;
187
- }
188
- if (builtInProviderIds.has(providerId)) {
189
- return false;
190
- }
191
- return !oauthProviderIds.has(providerId);
192
- }
193
108
  /** Placeholder shown in the empty editor to make core affordances discoverable. */
194
109
  const EDITOR_PLACEHOLDER = "Ask anything · / for commands · ! for skills/bash";
195
110
  /** How long transient info notices stay visible below the editor. */
@@ -434,6 +349,46 @@ export class InteractiveMode {
434
349
  });
435
350
  };
436
351
  }
352
+ const loginCommand = slashCommands.find((command) => command.name === "login");
353
+ if (loginCommand) {
354
+ loginCommand.argumentHint = "[provider]";
355
+ loginCommand.getArgumentCompletions = (prefix) => {
356
+ const options = this.getLoginProviderOptions();
357
+ // Dedupe ids that appear as both oauth and api_key (e.g.
358
+ // meta): keep the oauth (subscription) entry.
359
+ const byId = new Map();
360
+ for (const option of options) {
361
+ const existing = byId.get(option.id);
362
+ if (!existing || (existing.authType !== "oauth" && option.authType === "oauth")) {
363
+ byId.set(option.id, option);
364
+ }
365
+ }
366
+ const unique = [...byId.values()];
367
+ const filtered = fuzzyFilter(unique, prefix.trimStart(), (option) => `${option.id} ${option.name}`);
368
+ if (filtered.length === 0)
369
+ return null;
370
+ return filtered.map((option) => ({
371
+ value: option.id,
372
+ label: option.id,
373
+ description: option.name,
374
+ }));
375
+ };
376
+ }
377
+ const logoutCommand = slashCommands.find((command) => command.name === "logout");
378
+ if (logoutCommand) {
379
+ logoutCommand.argumentHint = "[provider]";
380
+ logoutCommand.getArgumentCompletions = (prefix) => {
381
+ const options = this.getLogoutProviderOptions();
382
+ const filtered = fuzzyFilter(options, prefix.trimStart(), (option) => `${option.id} ${option.name}`);
383
+ if (filtered.length === 0)
384
+ return null;
385
+ return filtered.map((option) => ({
386
+ value: option.id,
387
+ label: option.id,
388
+ description: option.name,
389
+ }));
390
+ };
391
+ }
437
392
  const modelCommand = slashCommands.find((command) => command.name === "model");
438
393
  if (modelCommand) {
439
394
  modelCommand.getArgumentCompletions = (prefix) => {
@@ -899,6 +854,7 @@ export class InteractiveMode {
899
854
  getMarkdownThemeWithSettings() {
900
855
  return {
901
856
  ...getMarkdownTheme(),
857
+ ...terminalMarkdownLinks(this.sessionManager.getCwd()),
902
858
  codeBlockIndent: this.settingsManager.getCodeBlockIndent(),
903
859
  };
904
860
  }
@@ -2217,7 +2173,7 @@ export class InteractiveMode {
2217
2173
  this.updateEditorBorderColor();
2218
2174
  }
2219
2175
  };
2220
- // Handle clipboard image paste (triggered on Ctrl+V)
2176
+ // Handle the configured clipboard image shortcut (Ctrl+V or Alt+V).
2221
2177
  this.defaultEditor.onPasteImage = () => {
2222
2178
  this.handleClipboardImagePaste();
2223
2179
  };
@@ -2226,18 +2182,13 @@ export class InteractiveMode {
2226
2182
  try {
2227
2183
  const image = await readClipboardImage();
2228
2184
  if (!image) {
2185
+ this.showStatus("No image in clipboard. Copy a screenshot, then press Alt+V (or Ctrl+V if forwarded by your terminal).");
2229
2186
  return;
2230
2187
  }
2231
- let attachment;
2232
- try {
2233
- attachment = this.attachmentStore.put(new Uint8Array(image.bytes), "clipboard");
2234
- }
2235
- catch (error) {
2236
- this.showWarning(error instanceof Error ? error.message : String(error));
2237
- return;
2238
- }
2188
+ const attachment = this.attachmentStore.put(new Uint8Array(image.bytes), "clipboard");
2239
2189
  this.draftAttachmentIds.push(attachment.id);
2240
2190
  this.refreshAttachmentStrip();
2191
+ this.showStatus("Image attached to the prompt. Submit when ready.");
2241
2192
  }
2242
2193
  catch (error) {
2243
2194
  this.showWarning(`Clipboard paste failed: ${error instanceof Error ? error.message : String(error)}`);
@@ -2433,13 +2384,25 @@ export class InteractiveMode {
2433
2384
  this.editor.setText("");
2434
2385
  return;
2435
2386
  }
2436
- if (text === "/login") {
2437
- this.showOAuthSelector("login");
2387
+ if (text === "/login" || text.startsWith("/login ")) {
2388
+ const providerArg = text.startsWith("/login ") ? text.slice("/login".length).trim() : undefined;
2389
+ if (providerArg) {
2390
+ await this.handleLoginProviderArg(providerArg);
2391
+ }
2392
+ else {
2393
+ this.showOAuthSelector("login");
2394
+ }
2438
2395
  this.editor.setText("");
2439
2396
  return;
2440
2397
  }
2441
- if (text === "/logout") {
2442
- this.showOAuthSelector("logout");
2398
+ if (text === "/logout" || text.startsWith("/logout ")) {
2399
+ const providerArg = text.startsWith("/logout ") ? text.slice("/logout".length).trim() : undefined;
2400
+ if (providerArg) {
2401
+ await this.handleLogoutProviderArg(providerArg);
2402
+ }
2403
+ else {
2404
+ this.showOAuthSelector("logout");
2405
+ }
2443
2406
  this.editor.setText("");
2444
2407
  return;
2445
2408
  }
@@ -4342,14 +4305,21 @@ export class InteractiveMode {
4342
4305
  if (!isApiKeyLoginProvider(providerId, oauthProviderIds)) {
4343
4306
  continue;
4344
4307
  }
4308
+ const displayName = this.session.modelRegistry.getProviderDisplayName(providerId);
4345
4309
  options.push({
4346
4310
  id: providerId,
4347
- name: this.session.modelRegistry.getProviderDisplayName(providerId),
4311
+ // The shared "meta" id resolves its display name to the oauth
4312
+ // entry, so label the API-key row distinctly.
4313
+ name: oauthProviderIds.has(providerId) && displayName !== providerId
4314
+ ? getApiKeyLoginDisplayName(providerId, displayName)
4315
+ : displayName,
4348
4316
  authType: "api_key",
4349
4317
  });
4350
4318
  }
4351
4319
  const filteredOptions = authType ? options.filter((option) => option.authType === authType) : options;
4352
- return filteredOptions.sort((a, b) => a.name.localeCompare(b.name));
4320
+ // Stable order: by name, then oauth before api_key so a shared id
4321
+ // (e.g. meta) lists the subscription entry first.
4322
+ return filteredOptions.sort((a, b) => a.name.localeCompare(b.name) || a.authType.localeCompare(b.authType));
4353
4323
  }
4354
4324
  getLogoutProviderOptions() {
4355
4325
  const authStorage = this.session.modelRegistry.authStorage;
@@ -4367,6 +4337,40 @@ export class InteractiveMode {
4367
4337
  }
4368
4338
  return options.sort((a, b) => a.name.localeCompare(b.name));
4369
4339
  }
4340
+ async handleLogoutProviderArg(providerArg) {
4341
+ const providerOptions = this.getLogoutProviderOptions();
4342
+ const match = resolveLoginProviderArg(providerArg, providerOptions);
4343
+ if (!match) {
4344
+ const hint = providerOptions.length > 0
4345
+ ? "Run /logout and pick from the list of stored credentials."
4346
+ : "No stored credentials to remove.";
4347
+ this.showWarning(`Unknown provider "${providerArg}". ${hint}`);
4348
+ return;
4349
+ }
4350
+ await this.logoutProvider(match);
4351
+ }
4352
+ async logoutProvider(providerOption) {
4353
+ try {
4354
+ const oauthAccountCount = this.session.modelRegistry.authStorage.getOAuthAccountCount(providerOption.id);
4355
+ this.session.modelRegistry.authStorage.logout(providerOption.id);
4356
+ this.session.modelRegistry.refresh();
4357
+ await this.updateAvailableProviderCount();
4358
+ let message;
4359
+ if (providerOption.authType === "oauth") {
4360
+ message =
4361
+ oauthAccountCount > 1
4362
+ ? `Logged out of ${providerOption.name}. Removed ${oauthAccountCount} subscription accounts.`
4363
+ : `Logged out of ${providerOption.name}`;
4364
+ }
4365
+ else {
4366
+ message = `Removed stored API key for ${providerOption.name}. Environment variables and models.json config are unchanged.`;
4367
+ }
4368
+ this.showStatus(message);
4369
+ }
4370
+ catch (error) {
4371
+ this.showError(`Logout failed: ${error instanceof Error ? error.message : String(error)}`);
4372
+ }
4373
+ }
4370
4374
  showLoginAuthTypeSelector() {
4371
4375
  const subscriptionLabel = "Use a subscription";
4372
4376
  const apiKeyLabel = "Use an API key";
@@ -4382,6 +4386,33 @@ export class InteractiveMode {
4382
4386
  return { component: selector, focus: selector };
4383
4387
  });
4384
4388
  }
4389
+ async handleLoginProviderArg(providerArg) {
4390
+ const providerOptions = this.getLoginProviderOptions();
4391
+ const match = resolveLoginProviderArg(providerArg, providerOptions);
4392
+ if (!match) {
4393
+ this.showWarning(`Unknown provider "${providerArg}". Run /login and pick from the list, or check /model for provider ids.`);
4394
+ return;
4395
+ }
4396
+ await this.startLoginForProvider(match);
4397
+ }
4398
+ async startLoginForProvider(providerOption) {
4399
+ if (providerOption.authType === "oauth") {
4400
+ const authStorage = this.session.modelRegistry.authStorage;
4401
+ const accounts = authStorage.listOAuthAccounts(providerOption.id);
4402
+ if (accounts.length > 0) {
4403
+ this.showOAuthAccountSelector(providerOption);
4404
+ }
4405
+ else {
4406
+ await this.showLoginDialog(providerOption.id, providerOption.name);
4407
+ }
4408
+ }
4409
+ else if (providerOption.id === BEDROCK_PROVIDER_ID) {
4410
+ this.showBedrockSetupDialog(providerOption.id, providerOption.name);
4411
+ }
4412
+ else {
4413
+ await this.showApiKeyLoginDialog(providerOption.id, providerOption.name);
4414
+ }
4415
+ }
4385
4416
  showLoginProviderSelector(authType) {
4386
4417
  const providerOptions = this.getLoginProviderOptions(authType);
4387
4418
  if (providerOptions.length === 0) {
@@ -4395,21 +4426,7 @@ export class InteractiveMode {
4395
4426
  if (!providerOption) {
4396
4427
  return;
4397
4428
  }
4398
- if (providerOption.authType === "oauth") {
4399
- const accounts = this.session.modelRegistry.authStorage.listOAuthAccounts(providerOption.id);
4400
- if (accounts.length > 0) {
4401
- this.showOAuthAccountSelector(providerOption);
4402
- }
4403
- else {
4404
- await this.showLoginDialog(providerOption.id, providerOption.name);
4405
- }
4406
- }
4407
- else if (providerOption.id === BEDROCK_PROVIDER_ID) {
4408
- this.showBedrockSetupDialog(providerOption.id, providerOption.name);
4409
- }
4410
- else {
4411
- await this.showApiKeyLoginDialog(providerOption.id, providerOption.name);
4412
- }
4429
+ await this.startLoginForProvider(providerOption);
4413
4430
  }, () => {
4414
4431
  done();
4415
4432
  this.showLoginAuthTypeSelector();
@@ -4467,26 +4484,7 @@ export class InteractiveMode {
4467
4484
  if (!providerOption) {
4468
4485
  return;
4469
4486
  }
4470
- try {
4471
- const oauthAccountCount = this.session.modelRegistry.authStorage.getOAuthAccountCount(providerOption.id);
4472
- this.session.modelRegistry.authStorage.logout(providerOption.id);
4473
- this.session.modelRegistry.refresh();
4474
- await this.updateAvailableProviderCount();
4475
- let message;
4476
- if (providerOption.authType === "oauth") {
4477
- message =
4478
- oauthAccountCount > 1
4479
- ? `Logged out of ${providerOption.name}. Removed ${oauthAccountCount} subscription accounts.`
4480
- : `Logged out of ${providerOption.name}`;
4481
- }
4482
- else {
4483
- message = `Removed stored API key for ${providerOption.name}. Environment variables and models.json config are unchanged.`;
4484
- }
4485
- this.showStatus(message);
4486
- }
4487
- catch (error) {
4488
- this.showError(`Logout failed: ${error instanceof Error ? error.message : String(error)}`);
4489
- }
4487
+ await this.logoutProvider(providerOption);
4490
4488
  }, () => {
4491
4489
  done();
4492
4490
  this.ui.requestRender();