@ponythewhite/base-context 1.0.0 → 1.0.2

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 (285) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/NOTICE +0 -5
  3. package/README.md +44 -27
  4. package/dist/NOTICE +0 -5
  5. package/dist/base-context-runtime/pyproject.toml +1 -1
  6. package/dist/base-context-runtime/src/rlm/__init__.py +7 -5
  7. package/dist/base-context-runtime/test/test_subagent_registry.py +28 -1
  8. package/dist/base-context-runtime/uv.lock +1 -1
  9. package/dist/build-info.json +1 -1
  10. package/dist/bundle/amazon-bedrock.js +21 -0
  11. package/dist/bundle/{anthropic-YY4S534V.js → anthropic-UV5GZDGU.js} +5 -5
  12. package/dist/bundle/{azure-openai-responses-JRP6MIM3.js → azure-openai-responses-WSNPXLYC.js} +6 -6
  13. package/dist/bundle/{bundled-modules-P5HARVZA.js → bundled-modules-PWOGKUQQ.js} +71 -16
  14. package/dist/bundle/chunk-27QCJ2AZ.js +2578 -0
  15. package/dist/bundle/{chunk-BYVP7LWV.js → chunk-44PEHPOG.js} +1916 -4689
  16. package/dist/bundle/{chunk-MZHTNNVA.js → chunk-4GXPNXOJ.js} +8 -0
  17. package/dist/bundle/{chunk-SC5KG5R4.js → chunk-DGNX7HQ3.js} +1 -7
  18. package/dist/bundle/{chunk-A53O363M.js → chunk-GRJFXLBM.js} +0 -1
  19. package/dist/bundle/chunk-HKINIBP4.js +29 -0
  20. package/dist/bundle/{chunk-73DCPU3D.js → chunk-IADCPVEI.js} +1019 -3427
  21. package/dist/bundle/{chunk-UDSW6FNG.js → chunk-KTNETTHI.js} +1 -1
  22. package/dist/bundle/{chunk-U7AUVG3B.js → chunk-VSIYFWYI.js} +24 -6
  23. package/dist/bundle/{chunk-IW77OXFS.js → chunk-W46VZFI6.js} +0 -2099
  24. package/dist/bundle/{cli-main-O4X7GFGY.js → cli-main-4DS7Y3PI.js} +8 -6
  25. package/dist/bundle/cli.js +2 -2
  26. package/dist/bundle/{google-AUTVGDGZ.js → google-T32FMD4G.js} +6 -6
  27. package/dist/bundle/{google-vertex-Q75D7RKS.js → google-vertex-56KP6I3B.js} +3 -3
  28. package/dist/bundle/{main-XKOW2BV6.js → main-SV7JLVEB.js} +7 -5
  29. package/dist/bundle/{mistral-7ESB7QUD.js → mistral-WGBMYIVU.js} +5 -5
  30. package/dist/bundle/{openai-codex-responses-LV3QRPN4.js → openai-codex-responses-PIV2RQ3G.js} +6 -6
  31. package/dist/bundle/{openai-completions-OJECLPXJ.js → openai-completions-64C3JPR4.js} +11 -22
  32. package/dist/bundle/{openai-responses-FN6HZMBC.js → openai-responses-UI7RSTDV.js} +6 -6
  33. package/dist/cli/args.d.ts.map +1 -1
  34. package/dist/cli/args.js +108 -59
  35. package/dist/cli/args.js.map +1 -1
  36. package/dist/cli/daemon-ps.d.ts +4 -3
  37. package/dist/cli/daemon-ps.d.ts.map +1 -1
  38. package/dist/cli/daemon-ps.js +6 -1
  39. package/dist/cli/daemon-ps.js.map +1 -1
  40. package/dist/cli/product-doctor.d.ts +0 -1
  41. package/dist/cli/product-doctor.d.ts.map +1 -1
  42. package/dist/cli/product-doctor.js +6 -3
  43. package/dist/cli/product-doctor.js.map +1 -1
  44. package/dist/config.d.ts +0 -3
  45. package/dist/config.d.ts.map +1 -1
  46. package/dist/config.js +0 -8
  47. package/dist/config.js.map +1 -1
  48. package/dist/core/agent-session-config.d.ts +1 -2
  49. package/dist/core/agent-session-config.d.ts.map +1 -1
  50. package/dist/core/agent-session-config.js +0 -3
  51. package/dist/core/agent-session-config.js.map +1 -1
  52. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  53. package/dist/core/agent-session-runtime.js +5 -4
  54. package/dist/core/agent-session-runtime.js.map +1 -1
  55. package/dist/core/agent-session-services.d.ts +5 -3
  56. package/dist/core/agent-session-services.d.ts.map +1 -1
  57. package/dist/core/agent-session-services.js +2 -27
  58. package/dist/core/agent-session-services.js.map +1 -1
  59. package/dist/core/agent-session.d.ts +10 -6
  60. package/dist/core/agent-session.d.ts.map +1 -1
  61. package/dist/core/agent-session.js +107 -107
  62. package/dist/core/agent-session.js.map +1 -1
  63. package/dist/core/auth-storage.d.ts +8 -35
  64. package/dist/core/auth-storage.d.ts.map +1 -1
  65. package/dist/core/auth-storage.js +33 -243
  66. package/dist/core/auth-storage.js.map +1 -1
  67. package/dist/core/cron-jobs.d.ts.map +1 -1
  68. package/dist/core/cron-jobs.js +7 -1
  69. package/dist/core/cron-jobs.js.map +1 -1
  70. package/dist/core/inference-coordinator.d.ts +6 -1
  71. package/dist/core/inference-coordinator.d.ts.map +1 -1
  72. package/dist/core/inference-coordinator.js +18 -2
  73. package/dist/core/inference-coordinator.js.map +1 -1
  74. package/dist/core/kernel/bootstrap.d.ts.map +1 -1
  75. package/dist/core/kernel/bootstrap.js +2 -2
  76. package/dist/core/kernel/bootstrap.js.map +1 -1
  77. package/dist/core/kernel/repl-manager.d.ts +2 -0
  78. package/dist/core/kernel/repl-manager.d.ts.map +1 -1
  79. package/dist/core/kernel/repl-manager.js +44 -1
  80. package/dist/core/kernel/repl-manager.js.map +1 -1
  81. package/dist/core/logging.d.ts +4 -3
  82. package/dist/core/logging.d.ts.map +1 -1
  83. package/dist/core/logging.js +6 -6
  84. package/dist/core/logging.js.map +1 -1
  85. package/dist/core/mcp/mcp-manager.d.ts.map +1 -1
  86. package/dist/core/mcp/mcp-manager.js +3 -3
  87. package/dist/core/mcp/mcp-manager.js.map +1 -1
  88. package/dist/core/model-registry.d.ts +1 -16
  89. package/dist/core/model-registry.d.ts.map +1 -1
  90. package/dist/core/model-registry.js +88 -196
  91. package/dist/core/model-registry.js.map +1 -1
  92. package/dist/core/model-resolver.d.ts +2 -19
  93. package/dist/core/model-resolver.d.ts.map +1 -1
  94. package/dist/core/model-resolver.js +36 -266
  95. package/dist/core/model-resolver.js.map +1 -1
  96. package/dist/core/provider-contracts.d.ts +5 -6
  97. package/dist/core/provider-contracts.d.ts.map +1 -1
  98. package/dist/core/provider-contracts.js +25 -36
  99. package/dist/core/provider-contracts.js.map +1 -1
  100. package/dist/core/provider-display-names.d.ts.map +1 -1
  101. package/dist/core/provider-display-names.js +0 -2
  102. package/dist/core/provider-display-names.js.map +1 -1
  103. package/dist/core/rlm-max-subagents.d.ts +32 -0
  104. package/dist/core/rlm-max-subagents.d.ts.map +1 -0
  105. package/dist/core/rlm-max-subagents.js +50 -0
  106. package/dist/core/rlm-max-subagents.js.map +1 -0
  107. package/dist/core/rlm-runtime.d.ts +3 -3
  108. package/dist/core/rlm-runtime.d.ts.map +1 -1
  109. package/dist/core/rlm-runtime.js.map +1 -1
  110. package/dist/core/sdk.d.ts +4 -3
  111. package/dist/core/sdk.d.ts.map +1 -1
  112. package/dist/core/sdk.js +27 -14
  113. package/dist/core/sdk.js.map +1 -1
  114. package/dist/core/settings-manager.d.ts +3 -16
  115. package/dist/core/settings-manager.d.ts.map +1 -1
  116. package/dist/core/settings-manager.js +12 -44
  117. package/dist/core/settings-manager.js.map +1 -1
  118. package/dist/core/slash-commands.d.ts.map +1 -1
  119. package/dist/core/slash-commands.js +6 -6
  120. package/dist/core/slash-commands.js.map +1 -1
  121. package/dist/index.d.ts +1 -1
  122. package/dist/index.d.ts.map +1 -1
  123. package/dist/index.js.map +1 -1
  124. package/dist/installer.mjs +2 -3
  125. package/dist/main.d.ts.map +1 -1
  126. package/dist/main.js +39 -34
  127. package/dist/main.js.map +1 -1
  128. package/dist/modes/acp/acp-mode.d.ts.map +1 -1
  129. package/dist/modes/acp/acp-mode.js +1 -1
  130. package/dist/modes/acp/acp-mode.js.map +1 -1
  131. package/dist/modes/agent-connection/daemon-agent-connection.d.ts +6 -2
  132. package/dist/modes/agent-connection/daemon-agent-connection.d.ts.map +1 -1
  133. package/dist/modes/agent-connection/daemon-agent-connection.js +13 -2
  134. package/dist/modes/agent-connection/daemon-agent-connection.js.map +1 -1
  135. package/dist/modes/agent-connection/in-process-agent-connection.d.ts +2 -0
  136. package/dist/modes/agent-connection/in-process-agent-connection.d.ts.map +1 -1
  137. package/dist/modes/agent-connection/in-process-agent-connection.js +6 -0
  138. package/dist/modes/agent-connection/in-process-agent-connection.js.map +1 -1
  139. package/dist/modes/agent-connection/types.d.ts +3 -0
  140. package/dist/modes/agent-connection/types.d.ts.map +1 -1
  141. package/dist/modes/agent-connection/types.js.map +1 -1
  142. package/dist/modes/agents-view/agents-view-mode.d.ts.map +1 -1
  143. package/dist/modes/agents-view/agents-view-mode.js +2 -19
  144. package/dist/modes/agents-view/agents-view-mode.js.map +1 -1
  145. package/dist/modes/daemon/daemon-mode.d.ts +5 -0
  146. package/dist/modes/daemon/daemon-mode.d.ts.map +1 -1
  147. package/dist/modes/daemon/daemon-mode.js +107 -12
  148. package/dist/modes/daemon/daemon-mode.js.map +1 -1
  149. package/dist/modes/daemon/daemon-protocol.d.ts +194 -165
  150. package/dist/modes/daemon/daemon-protocol.d.ts.map +1 -1
  151. package/dist/modes/daemon/daemon-protocol.js +16 -11
  152. package/dist/modes/daemon/daemon-protocol.js.map +1 -1
  153. package/dist/modes/daemon/daemon-rlm-capacity-coordinator.d.ts +19 -0
  154. package/dist/modes/daemon/daemon-rlm-capacity-coordinator.d.ts.map +1 -0
  155. package/dist/modes/daemon/daemon-rlm-capacity-coordinator.js +74 -0
  156. package/dist/modes/daemon/daemon-rlm-capacity-coordinator.js.map +1 -0
  157. package/dist/modes/daemon/daemon-rlm-capacity.d.ts +19 -0
  158. package/dist/modes/daemon/daemon-rlm-capacity.d.ts.map +1 -0
  159. package/dist/modes/daemon/daemon-rlm-capacity.js +85 -0
  160. package/dist/modes/daemon/daemon-rlm-capacity.js.map +1 -0
  161. package/dist/modes/daemon/daemon-session-summarizer.d.ts +2 -3
  162. package/dist/modes/daemon/daemon-session-summarizer.d.ts.map +1 -1
  163. package/dist/modes/daemon/daemon-session-summarizer.js +32 -23
  164. package/dist/modes/daemon/daemon-session-summarizer.js.map +1 -1
  165. package/dist/modes/daemon/daemon-state-root.d.ts +15 -0
  166. package/dist/modes/daemon/daemon-state-root.d.ts.map +1 -0
  167. package/dist/modes/daemon/daemon-state-root.js +40 -0
  168. package/dist/modes/daemon/daemon-state-root.js.map +1 -0
  169. package/dist/modes/daemon/daemon-supervisor-ownership.d.ts +2 -0
  170. package/dist/modes/daemon/daemon-supervisor-ownership.d.ts.map +1 -1
  171. package/dist/modes/daemon/daemon-supervisor-ownership.js +27 -0
  172. package/dist/modes/daemon/daemon-supervisor-ownership.js.map +1 -1
  173. package/dist/modes/daemon/daemon-supervisor.d.ts +10 -1
  174. package/dist/modes/daemon/daemon-supervisor.d.ts.map +1 -1
  175. package/dist/modes/daemon/daemon-supervisor.js +213 -20
  176. package/dist/modes/daemon/daemon-supervisor.js.map +1 -1
  177. package/dist/modes/daemon/daemon-worker-protocol.d.ts +28 -1
  178. package/dist/modes/daemon/daemon-worker-protocol.d.ts.map +1 -1
  179. package/dist/modes/daemon/daemon-worker-protocol.js +16 -2
  180. package/dist/modes/daemon/daemon-worker-protocol.js.map +1 -1
  181. package/dist/modes/daemon/saved-session-catalog.d.ts.map +1 -1
  182. package/dist/modes/daemon/saved-session-catalog.js +2 -0
  183. package/dist/modes/daemon/saved-session-catalog.js.map +1 -1
  184. package/dist/modes/interactive/auth-flows.d.ts +0 -6
  185. package/dist/modes/interactive/auth-flows.d.ts.map +1 -1
  186. package/dist/modes/interactive/auth-flows.js +6 -126
  187. package/dist/modes/interactive/auth-flows.js.map +1 -1
  188. package/dist/modes/interactive/components/configuration-menu.d.ts +3 -0
  189. package/dist/modes/interactive/components/configuration-menu.d.ts.map +1 -1
  190. package/dist/modes/interactive/components/configuration-menu.js +13 -2
  191. package/dist/modes/interactive/components/configuration-menu.js.map +1 -1
  192. package/dist/modes/interactive/components/footer.d.ts +1 -1
  193. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  194. package/dist/modes/interactive/components/footer.js +2 -2
  195. package/dist/modes/interactive/components/footer.js.map +1 -1
  196. package/dist/modes/interactive/components/index.d.ts +0 -1
  197. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  198. package/dist/modes/interactive/components/index.js +0 -1
  199. package/dist/modes/interactive/components/index.js.map +1 -1
  200. package/dist/modes/interactive/components/login-dialog.d.ts +0 -1
  201. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  202. package/dist/modes/interactive/components/login-dialog.js +3 -40
  203. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  204. package/dist/modes/interactive/components/model-selector.d.ts +2 -0
  205. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  206. package/dist/modes/interactive/components/model-selector.js +13 -2
  207. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  208. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  209. package/dist/modes/interactive/components/oauth-selector.js +2 -11
  210. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  211. package/dist/modes/interactive/feature-hints.d.ts.map +1 -1
  212. package/dist/modes/interactive/feature-hints.js +0 -4
  213. package/dist/modes/interactive/feature-hints.js.map +1 -1
  214. package/dist/modes/interactive/interactive-mode.d.ts +3 -12
  215. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  216. package/dist/modes/interactive/interactive-mode.js +81 -507
  217. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  218. package/dist/modes/interactive/onboarding.d.ts +0 -3
  219. package/dist/modes/interactive/onboarding.d.ts.map +1 -1
  220. package/dist/modes/interactive/onboarding.js +0 -17
  221. package/dist/modes/interactive/onboarding.js.map +1 -1
  222. package/dist/modes/rpc/rpc-client.d.ts +4 -1
  223. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  224. package/dist/modes/rpc/rpc-client.js +82 -42
  225. package/dist/modes/rpc/rpc-client.js.map +1 -1
  226. package/dist/node/amazon-bedrock.d.ts +2 -0
  227. package/dist/node/amazon-bedrock.d.ts.map +1 -0
  228. package/dist/node/amazon-bedrock.js +6 -0
  229. package/dist/node/amazon-bedrock.js.map +1 -0
  230. package/dist/product-identity.d.ts +0 -1
  231. package/dist/product-identity.d.ts.map +1 -1
  232. package/dist/product-identity.js +0 -1
  233. package/dist/product-identity.js.map +1 -1
  234. package/docs/development.md +1 -1
  235. package/docs/fork-philosophy.md +4 -8
  236. package/docs/installation.md +83 -62
  237. package/docs/providers.md +23 -25
  238. package/docs/quickstart.md +19 -10
  239. package/docs/rlm-runtime.md +13 -5
  240. package/docs/rpc.md +4 -4
  241. package/docs/sdk.md +20 -11
  242. package/docs/sessions.md +0 -1
  243. package/docs/settings.md +9 -42
  244. package/docs/skills.md +0 -1
  245. package/docs/upstream-0.9.5.md +171 -0
  246. package/docs/usage.md +14 -10
  247. package/package.json +4 -4
  248. package/dist/core/agent-traces.d.ts +0 -149
  249. package/dist/core/agent-traces.d.ts.map +0 -1
  250. package/dist/core/agent-traces.js +0 -904
  251. package/dist/core/agent-traces.js.map +0 -1
  252. package/dist/core/prime-inference-auth.d.ts +0 -70
  253. package/dist/core/prime-inference-auth.d.ts.map +0 -1
  254. package/dist/core/prime-inference-auth.js +0 -352
  255. package/dist/core/prime-inference-auth.js.map +0 -1
  256. package/dist/core/prime-inference-model-selection.d.ts +0 -16
  257. package/dist/core/prime-inference-model-selection.d.ts.map +0 -1
  258. package/dist/core/prime-inference-model-selection.js +0 -16
  259. package/dist/core/prime-inference-model-selection.js.map +0 -1
  260. package/dist/core/prime-inference-models.d.ts +0 -6
  261. package/dist/core/prime-inference-models.d.ts.map +0 -1
  262. package/dist/core/prime-inference-models.js +0 -62
  263. package/dist/core/prime-inference-models.js.map +0 -1
  264. package/dist/core/telemetry.d.ts +0 -95
  265. package/dist/core/telemetry.d.ts.map +0 -1
  266. package/dist/core/telemetry.js +0 -637
  267. package/dist/core/telemetry.js.map +0 -1
  268. package/dist/modes/interactive/components/prime-onboarding-splash.d.ts +0 -39
  269. package/dist/modes/interactive/components/prime-onboarding-splash.d.ts.map +0 -1
  270. package/dist/modes/interactive/components/prime-onboarding-splash.js +0 -286
  271. package/dist/modes/interactive/components/prime-onboarding-splash.js.map +0 -1
  272. package/dist/modes/interactive/components/prime-team-selector.d.ts +0 -30
  273. package/dist/modes/interactive/components/prime-team-selector.d.ts.map +0 -1
  274. package/dist/modes/interactive/components/prime-team-selector.js +0 -166
  275. package/dist/modes/interactive/components/prime-team-selector.js.map +0 -1
  276. package/dist/skills/prime-intellect/SKILL.md +0 -87
  277. package/dist/skills/prime-intellect/references/compute.md +0 -45
  278. package/dist/skills/prime-intellect/references/environments.md +0 -73
  279. package/dist/skills/prime-intellect/references/inference.md +0 -47
  280. package/dist/skills/prime-intellect/references/sandboxes.md +0 -75
  281. package/skills/prime-intellect/SKILL.md +0 -87
  282. package/skills/prime-intellect/references/compute.md +0 -45
  283. package/skills/prime-intellect/references/environments.md +0 -73
  284. package/skills/prime-intellect/references/inference.md +0 -47
  285. package/skills/prime-intellect/references/sandboxes.md +0 -75
@@ -5,12 +5,11 @@ import * as path from "node:path";
5
5
  import { supportsFastMode, } from "@ponythewhite/base-context-ai";
6
6
  import { BUILTIN_MCP_CATALOG } from "@ponythewhite/base-context-ai/mcp";
7
7
  import { CombinedAutocompleteProvider, Container, Loader, Markdown, matchesKey, ProcessTerminal, Spacer, setKeybindings, Text, TruncatedText, TUI, truncateToWidth, visibleWidth, } from "@ponythewhite/base-context-tui";
8
- import { spawn, spawnSync } from "child_process";
8
+ import { spawnSync } from "child_process";
9
9
  import { buildDaemonUpdateRestartReport, launchDaemonUpdateRestartCoordinator, resolveDaemonUpdateRestartSocketPath, selectedUpdateInstallation, } from "../../cli/daemon-update-restart.js";
10
10
  import { createCliSubprocessLaunchSpec } from "../../cli/subprocess-launch.js";
11
- import { APP_NAME, APP_TITLE, getAgentDir, getAgentTracesLogPath, getDebugLogPath, getLogsDir, getPhysicalPackageDir, getShareViewerUrl, SELF_UPDATE_INTERACTIVE_CHILD_ENV, SELF_UPDATE_NOT_ATTEMPTED_EXIT_CODE, VERSION, } from "../../config.js";
11
+ import { APP_NAME, APP_TITLE, getAgentDir, getDebugLogPath, getLogsDir, getPhysicalPackageDir, SELF_UPDATE_INTERACTIVE_CHILD_ENV, SELF_UPDATE_NOT_ATTEMPTED_EXIT_CODE, VERSION, } from "../../config.js";
12
12
  import { AGENT_MESSAGE_RECEIVED_PREVIEW_LABEL, isAgentSessionMessage, startsAgentRun, } from "../../core/agent-messages.js";
13
- import { getPrimeAgentTraceCredential, previewAgentTraceFile, uploadAgentTraceFile, uploadAllAgentTraces, } from "../../core/agent-traces.js";
14
13
  import { isNoModelsAvailableMessage } from "../../core/auth-guidance.js";
15
14
  import { DEFAULT_HEARTBEAT_DELIVERY_MODE, parseHeartbeatCommand, } from "../../core/cron-jobs.js";
16
15
  import { FooterDataProvider } from "../../core/footer-data-provider.js";
@@ -20,15 +19,12 @@ import { runMcpManagementCommand } from "../../core/mcp/mcp-command.js";
20
19
  import { bashOutputToText, COMPACTION_OUTCOME_CUSTOM_TYPE, createHeartbeatPromptMessage, HEARTBEAT_PROMPT_PREVIEW_LABEL, isCompactionOutcomeMessage, isRefinementOutcomeMessage, isSessionSlashCommandMessage, isSessionSlashCommandResultMessage, REFINEMENT_OUTCOME_CUSTOM_TYPE, SESSION_SLASH_COMMAND_CUSTOM_TYPE, SESSION_SLASH_COMMAND_RESULT_CUSTOM_TYPE, } from "../../core/messages.js";
21
20
  import { findExactModelReferenceMatch, resolveModelScopeFromModels } from "../../core/model-resolver.js";
22
21
  import { parseNewSessionCommand } from "../../core/new-session-command.js";
23
- import { resolvePrimeAgentTracesBaseUrl } from "../../core/prime-inference-auth.js";
24
- import { resolvePrimeInferencePostLoginModelAction } from "../../core/prime-inference-model-selection.js";
25
22
  import { parseCommandArgs } from "../../core/prompt-templates.js";
26
23
  import { formatMissingSessionCwdPrompt, MissingSessionCwdError } from "../../core/session-cwd.js";
27
24
  import { SessionImportFileNotFoundError } from "../../core/session-import-errors.js";
28
25
  import { resolveSessionPath, SessionSelectorError, SessionSelectorNotFoundError } from "../../core/session-resolver.js";
29
26
  import { parseSkillBlock } from "../../core/skill-blocks.js";
30
27
  import { BUILTIN_SLASH_COMMANDS, builtinSlashCommandTakesArgument, isBuiltinSlashCommandName, parseSlashCommand, resolveBuiltinSlashCommandName, } from "../../core/slash-commands.js";
31
- import { captureAgentCommandUsed, captureOnboardingCompleted, } from "../../core/telemetry.js";
32
28
  import { truncateTail } from "../../core/tools/truncate.js";
33
29
  import { getOwnedInstallation } from "../../owned-install-layout.js";
34
30
  import { assertProductStatePath } from "../../runtime-paths.js";
@@ -51,7 +47,6 @@ import { AgentMessageComponent } from "./components/agent-message.js";
51
47
  import { ArminComponent } from "./components/armin.js";
52
48
  import { AssistantMessageComponent } from "./components/assistant-message.js";
53
49
  import { BashExecutionComponent } from "./components/bash-execution.js";
54
- import { BorderedLoader } from "./components/bordered-loader.js";
55
50
  import { BranchSummaryMessageComponent } from "./components/branch-summary-message.js";
56
51
  import { showFullPaneOverlay } from "./components/centered-overlay.js";
57
52
  import { CompactionOutcomeMessageComponent, MalformedCompactionOutcomeMessageComponent, } from "./components/compaction-outcome-message.js";
@@ -75,7 +70,6 @@ import { HeartbeatManagerComponent } from "./components/heartbeat-manager.js";
75
70
  import { InjectedPromptMessageComponent, isInjectedPromptMessage } from "./components/injected-prompt-message.js";
76
71
  import { formatKeyText, keyHint, keyText, rawKeyHint } from "./components/keybinding-hints.js";
77
72
  import { createMermaidMarkdownTransform } from "./components/mermaid.js";
78
- import { PrimeOnboardingSplashComponent } from "./components/prime-onboarding-splash.js";
79
73
  import { MalformedRefinementOutcomeMessageComponent, RefinementOutcomeMessageComponent, } from "./components/refinement-outcome-message.js";
80
74
  import { ScopedModelsSelectorComponent } from "./components/scoped-models-selector.js";
81
75
  import { SettingsSelectorComponent } from "./components/settings-selector.js";
@@ -92,7 +86,7 @@ import { UserMessageSelectorComponent } from "./components/user-message-selector
92
86
  import { FeatureHintDeck } from "./feature-hints.js";
93
87
  import { scopeHeartbeatsToSession } from "./heartbeat-scope.js";
94
88
  import { collectMarkedImages, evictImagesToBudget, formatImageMarker, imageMarkerIds, remapImageMarkers, } from "./image-markers.js";
95
- import { isOnboardingModelReady, shouldRunOnboarding, shouldRunPrimeCliOnboardingSplash, } from "./onboarding.js";
89
+ import { isOnboardingModelReady, shouldRunOnboarding } from "./onboarding.js";
96
90
  import { QueueSelection } from "./queue-selection.js";
97
91
  import { formatResumeHint } from "./resume-hint.js";
98
92
  import { getAvailableThemes, getAvailableThemesWithPaths, getEditorTheme, getMarkdownTheme, getThemeByName, initTheme, onThemeChange, setRegisteredThemes, setTheme, setThemeInstance, stopThemeWatcher, Theme, theme, } from "./theme/theme.js";
@@ -558,6 +552,7 @@ export class InteractiveMode {
558
552
  version;
559
553
  startHint = getRandomStartHint();
560
554
  isInitialized = false;
555
+ initializationPromise;
561
556
  onInputCallback;
562
557
  submittedInputBehavior = "steer";
563
558
  latestEditorPromptStash;
@@ -568,6 +563,7 @@ export class InteractiveMode {
568
563
  retainedSubmissionGenerations = new WeakMap();
569
564
  admitPendingStartupPrompts;
570
565
  agentsViewRequest;
566
+ isReturningToAgentsView = false;
571
567
  loadingAnimation = undefined;
572
568
  workingMessage = undefined;
573
569
  workingVisible = true;
@@ -679,7 +675,6 @@ export class InteractiveMode {
679
675
  refineLoader = undefined;
680
676
  retryLoader = undefined;
681
677
  retryCountdown = undefined;
682
- traceUploadAllAbortController = undefined;
683
678
  queueSelection = new QueueSelection();
684
679
  isApplyingQueueSelectionText = false;
685
680
  queueMutationChain = Promise.resolve();
@@ -1069,7 +1064,8 @@ export class InteractiveMode {
1069
1064
  }
1070
1065
  }
1071
1066
  async run() {
1072
- await this.init();
1067
+ this.initializationPromise = this.init();
1068
+ await this.initializationPromise;
1073
1069
  this.restorePromptStashOnOpen();
1074
1070
  // Global, environment-scoped notices (app update, extension updates, tmux setup)
1075
1071
  // belong on the agents view, not in a conversation. When the agents view already
@@ -1227,11 +1223,13 @@ export class InteractiveMode {
1227
1223
  this.showWarning(modelFallbackMessage);
1228
1224
  }
1229
1225
  };
1230
- await this.runStartupOnboarding();
1231
- showDeferredStartupNotifications();
1232
- showModelFallbackWarning();
1233
- void this.maybeWarnAboutAnthropicSubscriptionAuth();
1234
- void deliverStartupPrompts().then(() => settleStartupPrompts("admitted"), () => settleStartupPrompts("admitted"));
1226
+ if (!this.isShuttingDown && !this.isReturningToAgentsView) {
1227
+ await this.runStartupOnboarding();
1228
+ showDeferredStartupNotifications();
1229
+ showModelFallbackWarning();
1230
+ void this.maybeWarnAboutAnthropicSubscriptionAuth();
1231
+ void deliverStartupPrompts().then(() => settleStartupPrompts("admitted"), () => settleStartupPrompts("admitted"));
1232
+ }
1235
1233
  // Enter/Alt+Enter submit directly through AgentConnection. Wait for the
1236
1234
  // lifecycle signal exactly once; a returned editor value has already been
1237
1235
  // admitted and must never be submitted again here.
@@ -1277,9 +1275,6 @@ export class InteractiveMode {
1277
1275
  shouldRunOnboarding() {
1278
1276
  return shouldRunOnboarding(this.getOnboardingState());
1279
1277
  }
1280
- shouldRunPrimeCliOnboardingSplash() {
1281
- return shouldRunPrimeCliOnboardingSplash(this.getOnboardingState());
1282
- }
1283
1278
  markOnboardingShown() {
1284
1279
  if (!this.settingsManager.getOnboardingShown()) {
1285
1280
  this.settingsManager.setOnboardingShown(true);
@@ -1289,71 +1284,21 @@ export class InteractiveMode {
1289
1284
  if (!this.shouldRunOnboarding()) {
1290
1285
  return false;
1291
1286
  }
1292
- const startedAt = Date.now();
1293
- const showPrimeCliSplash = this.shouldRunPrimeCliOnboardingSplash();
1294
- let outcome = "aborted";
1295
- try {
1287
+ const setupCompleted = await this.runOnboardingFlow();
1288
+ if (setupCompleted && isOnboardingModelReady(this.getOnboardingState())) {
1296
1289
  this.markOnboardingShown();
1297
1290
  await this.settingsManager.flush();
1298
- await this.runOnboardingFlow(showPrimeCliSplash);
1299
- outcome = isOnboardingModelReady(this.getOnboardingState()) ? "success" : "aborted";
1300
- return true;
1301
- }
1302
- catch (error) {
1303
- outcome = "error";
1304
- throw error;
1305
- }
1306
- finally {
1307
- const model = this.getCurrentModel();
1308
- const authStatus = model ? this.modelRegistry.getProviderAuthStatus(model.provider) : undefined;
1309
- const storedCredential = model ? this.modelRegistry.authStorage.get(model.provider) : undefined;
1310
- void captureOnboardingCompleted({
1311
- agentDir: getAgentDir(),
1312
- settingsManager: this.settingsManager,
1313
- durationMs: Date.now() - startedAt,
1314
- outcome,
1315
- provider: model?.provider,
1316
- authSource: authStatus?.source,
1317
- storedCredentialType: storedCredential?.type,
1318
- }).catch(() => { });
1319
- }
1320
- }
1321
- async showOnboardingModelSelection(splash) {
1322
- try {
1323
- await this.showConfigurationMenu("models");
1324
- }
1325
- finally {
1326
- splash.dismiss();
1327
1291
  }
1292
+ return true;
1328
1293
  }
1329
- async runOnboardingFlow(showPrimeCliSplash = this.shouldRunPrimeCliOnboardingSplash()) {
1294
+ async runOnboardingFlow() {
1330
1295
  this.modelRegistry.refresh();
1331
- if (showPrimeCliSplash) {
1332
- const splash = await this.showOnboardingSplash("choose a model");
1333
- if (!splash) {
1334
- return;
1335
- }
1336
- await this.showOnboardingModelSelection(splash);
1337
- return;
1338
- }
1339
- const availableModels = await this.getModelCandidates();
1340
- if (availableModels.length > 0) {
1341
- await this.showConfigurationMenu("models");
1342
- return;
1343
- }
1344
- const splash = await this.showOnboardingSplash();
1345
- if (!splash) {
1346
- return;
1347
- }
1348
- splash.showProgress("Signing in to Prime Intellect...");
1349
- const authResult = await this.createAuthFlows().runPrimeInferenceLogin();
1350
- if (authResult.status !== "success") {
1351
- splash.dismiss();
1352
- return;
1296
+ const model = this.getCurrentModel();
1297
+ if (model) {
1298
+ const authFlows = this.createAuthFlows();
1299
+ return this.ensureModelProviderConfigured(model, authFlows, authFlows.getLoginProviderOptions());
1353
1300
  }
1354
- splash.showProgress("Preparing models...");
1355
- await this.prepareForModelSelectionAfterLogin(authResult);
1356
- await this.showOnboardingModelSelection(splash);
1301
+ return this.showConfigurationMenu("providers", undefined, true);
1357
1302
  }
1358
1303
  getMarkdownThemeWithSettings() {
1359
1304
  return {
@@ -1923,7 +1868,7 @@ export class InteractiveMode {
1923
1868
  do {
1924
1869
  this.heartbeatRefreshRequested = false;
1925
1870
  const heartbeats = await connection.listHeartbeats();
1926
- if (this.agentConnection !== connection)
1871
+ if (this.isShuttingDown || this.isReturningToAgentsView || this.agentConnection !== connection)
1927
1872
  return;
1928
1873
  this.applyHeartbeatCatalog(heartbeats);
1929
1874
  } while (this.heartbeatRefreshRequested);
@@ -2107,7 +2052,6 @@ export class InteractiveMode {
2107
2052
  this.isBashRunning() ||
2108
2053
  this.getRetryAttempt() > 0 ||
2109
2054
  this.connectionState?.sessionActions.active !== undefined ||
2110
- this.traceUploadAllAbortController !== undefined ||
2111
2055
  this.sideQuestionEvent?.status === "running");
2112
2056
  }
2113
2057
  getRetryAttempt() {
@@ -2168,7 +2112,8 @@ export class InteractiveMode {
2168
2112
  this.patchConnectionState({ sessionActions: (await this.agentConnection.getState()).sessionActions });
2169
2113
  this.refreshQueueSelectionFromState();
2170
2114
  this.updatePendingMessagesDisplay();
2171
- await this.refreshHeartbeatCatalog().catch(() => undefined);
2115
+ // Optional tray metadata must not delay opening or leaving a chat.
2116
+ void this.refreshHeartbeatCatalog().catch(() => undefined);
2172
2117
  await this.updateAvailableProviderCount();
2173
2118
  this.updateEditorBorderColor();
2174
2119
  this.updateTerminalTitle();
@@ -3780,13 +3725,6 @@ export class InteractiveMode {
3780
3725
  this.ui.requestRender();
3781
3726
  return;
3782
3727
  }
3783
- if (commandName) {
3784
- void captureAgentCommandUsed({
3785
- agentDir: getAgentDir(),
3786
- settingsManager: this.settingsManager,
3787
- commandName,
3788
- }).catch(() => { });
3789
- }
3790
3728
  if (commandName === "btw") {
3791
3729
  this.editor.setText("");
3792
3730
  await this.handleSideQuestion(commandArgs);
@@ -3833,11 +3771,6 @@ export class InteractiveMode {
3833
3771
  this.editor.setText("");
3834
3772
  return;
3835
3773
  }
3836
- if (commandName === "share" && !commandArgs) {
3837
- await this.handleShareCommand();
3838
- this.editor.setText("");
3839
- return;
3840
- }
3841
3774
  if (commandName === "copy" && !commandArgs) {
3842
3775
  await this.handleCopyCommand();
3843
3776
  this.editor.setText("");
@@ -3848,6 +3781,11 @@ export class InteractiveMode {
3848
3781
  this.editor.setText("");
3849
3782
  return;
3850
3783
  }
3784
+ if (commandName === "agents") {
3785
+ this.editor.setText("");
3786
+ await this.handleAgentsCommand(commandArgs);
3787
+ return;
3788
+ }
3851
3789
  if (commandName === "rlm-max-depth") {
3852
3790
  this.editor.setText("");
3853
3791
  await this.handleRlmMaxDepthCommand(commandArgs);
@@ -3865,11 +3803,6 @@ export class InteractiveMode {
3865
3803
  this.editor.setText("");
3866
3804
  return;
3867
3805
  }
3868
- if (commandName === "traces") {
3869
- await this.handleTracesCommand(canonicalCommandText);
3870
- this.editor.setText("");
3871
- return;
3872
- }
3873
3806
  if (commandName === "context" && !commandArgs) {
3874
3807
  this.echoLocalCommand(text);
3875
3808
  await this.handleContextCommand();
@@ -4130,6 +4063,7 @@ export class InteractiveMode {
4130
4063
  // by teardown must neither prompt nor mutate the editor/durable stash.
4131
4064
  if (submissionOutcome === "lifecycle-cancelled" ||
4132
4065
  this.isShuttingDown ||
4066
+ this.isReturningToAgentsView ||
4133
4067
  this.agentsViewRequest ||
4134
4068
  this.promptStashSessionId !== submissionSessionId) {
4135
4069
  // The editor is already torn down, but its shared session stash outlives
@@ -4151,6 +4085,7 @@ export class InteractiveMode {
4151
4085
  // rejection must be retained rather than overwrite newer input or vanish.
4152
4086
  const rejectedDraft = submittedDraft ?? { text };
4153
4087
  const canRestore = !this.isShuttingDown &&
4088
+ !this.isReturningToAgentsView &&
4154
4089
  !this.agentsViewRequest &&
4155
4090
  submissionGeneration === this.inputSubmissionGeneration &&
4156
4091
  this.editor.getText().length === 0;
@@ -4174,7 +4109,7 @@ export class InteractiveMode {
4174
4109
  this.ui.requestRender();
4175
4110
  }
4176
4111
  finally {
4177
- if (this.isShuttingDown || this.agentsViewRequest) {
4112
+ if (this.isShuttingDown || this.isReturningToAgentsView || this.agentsViewRequest) {
4178
4113
  submissionOutcome = "lifecycle-cancelled";
4179
4114
  }
4180
4115
  if (submissionOutcome === "admitted" &&
@@ -5653,7 +5588,6 @@ export class InteractiveMode {
5653
5588
  this.showCtrlCExitHint();
5654
5589
  }
5655
5590
  interruptOrClearInput() {
5656
- this.traceUploadAllAbortController?.abort(new Error("Trace upload cancelled"));
5657
5591
  if (this.sideQuestionEvent?.status === "running") {
5658
5592
  this.abortSideQuestion(this.sideQuestionEvent.id, true);
5659
5593
  }
@@ -5773,11 +5707,15 @@ export class InteractiveMode {
5773
5707
  await this.returnToAgentsView();
5774
5708
  }
5775
5709
  async returnToAgentsView(request = "agents_view") {
5776
- if (this.isShuttingDown || this.agentsViewRequest)
5710
+ if (this.isShuttingDown || this.isReturningToAgentsView)
5711
+ return;
5712
+ this.isReturningToAgentsView = true;
5713
+ // Keep startup's connection alive without blocking an explicit shutdown.
5714
+ await this.initializationPromise?.catch(() => undefined);
5715
+ if (this.isShuttingDown)
5777
5716
  return;
5778
- this.stashDraftForAgentsView();
5779
- this.agentsViewRequest = request;
5780
5717
  this.isShuttingDown = true;
5718
+ this.stashDraftForAgentsView();
5781
5719
  this.unregisterSignalHandlers();
5782
5720
  await this.teardownSessionUi({ preserveAltScreen: true });
5783
5721
  let handoffComplete = false;
@@ -5787,6 +5725,7 @@ export class InteractiveMode {
5787
5725
  }
5788
5726
  finally {
5789
5727
  await this.options.onShutdown?.();
5728
+ this.agentsViewRequest = request;
5790
5729
  this.onInputCallback?.(undefined);
5791
5730
  handoffComplete = true;
5792
5731
  }
@@ -6867,7 +6806,7 @@ export class InteractiveMode {
6867
6806
  showModelSelector(initialSearchInput) {
6868
6807
  void this.showConfigurationMenu("models", initialSearchInput);
6869
6808
  }
6870
- showConfigurationMenu(initialTab, initialModelSearch) {
6809
+ showConfigurationMenu(initialTab, initialModelSearch, providerFirst = this.getCurrentModel() === undefined) {
6871
6810
  const modelCatalog = this.getCachedModelCandidates();
6872
6811
  const authFlows = this.createAuthFlows();
6873
6812
  const providerOptions = authFlows.getLoginProviderOptions();
@@ -6900,12 +6839,12 @@ export class InteractiveMode {
6900
6839
  handle?.focus();
6901
6840
  this.ui.requestRender();
6902
6841
  };
6903
- const finish = () => {
6842
+ const finish = (modelSelected = false) => {
6904
6843
  if (settled)
6905
6844
  return;
6906
6845
  settled = true;
6907
6846
  hide();
6908
- resolve();
6847
+ resolve(modelSelected);
6909
6848
  };
6910
6849
  const refreshModels = (force) => {
6911
6850
  const refreshPromise = this.getModelSelectorRefreshPromise({ force });
@@ -6921,9 +6860,24 @@ export class InteractiveMode {
6921
6860
  this.showError(error instanceof Error ? error.message : String(error));
6922
6861
  });
6923
6862
  };
6863
+ const showProviderModels = (providerId) => {
6864
+ menu.updateModels(this.getCurrentModel(), this.getCachedModelCandidates(), this.connectionConfiguredProviders);
6865
+ if (providerFirst)
6866
+ menu.showProviderModels(providerId);
6867
+ else
6868
+ menu.setActiveTab("models");
6869
+ refreshModels(true);
6870
+ };
6924
6871
  const authenticate = (provider, tab) => {
6925
6872
  if (settled)
6926
6873
  return;
6874
+ if (providerFirst &&
6875
+ tab === "providers" &&
6876
+ (this.connectionConfiguredProviders.has(provider.id) ||
6877
+ this.modelRegistry.getProviderAuthStatus(provider.id).configured)) {
6878
+ showProviderModels(provider.id);
6879
+ return;
6880
+ }
6927
6881
  void authFlows
6928
6882
  .loginProvider(provider)
6929
6883
  .then(async (authResult) => {
@@ -6944,10 +6898,7 @@ export class InteractiveMode {
6944
6898
  await this.handleReloadCommand();
6945
6899
  return;
6946
6900
  }
6947
- await this.prepareForModelSelectionAfterLogin(authResult);
6948
- menu.updateModels(this.getCurrentModel(), this.getCachedModelCandidates(), this.connectionConfiguredProviders);
6949
- menu.setActiveTab("models");
6950
- refreshModels(true);
6901
+ showProviderModels(authResult.providerId);
6951
6902
  })
6952
6903
  .catch((error) => {
6953
6904
  handle?.focus();
@@ -6956,6 +6907,7 @@ export class InteractiveMode {
6956
6907
  };
6957
6908
  menu = new ConfigurationMenuComponent({
6958
6909
  initialTab,
6910
+ providerFirst,
6959
6911
  tui: this.ui,
6960
6912
  authStorage: this.modelRegistry.authStorage,
6961
6913
  providerOptions,
@@ -6990,7 +6942,7 @@ export class InteractiveMode {
6990
6942
  }
6991
6943
  finally {
6992
6944
  if (completed)
6993
- finish();
6945
+ finish(true);
6994
6946
  }
6995
6947
  })();
6996
6948
  },
@@ -7295,50 +7247,6 @@ export class InteractiveMode {
7295
7247
  return this.handleFatalRuntimeError("Failed to resume session", error);
7296
7248
  }
7297
7249
  }
7298
- showOnboardingSplash(continueActionLabel) {
7299
- return new Promise((resolve) => {
7300
- let settled = false;
7301
- let dismissed = false;
7302
- let handle;
7303
- let selector;
7304
- const settle = (result) => {
7305
- if (settled) {
7306
- return;
7307
- }
7308
- settled = true;
7309
- resolve(result);
7310
- };
7311
- const dismiss = () => {
7312
- if (dismissed) {
7313
- return;
7314
- }
7315
- dismissed = true;
7316
- selector?.dispose();
7317
- handle?.hide();
7318
- this.ui.requestRender();
7319
- };
7320
- selector = new PrimeOnboardingSplashComponent(() => {
7321
- selector?.dispose();
7322
- settle({
7323
- showProgress: (message) => selector?.showProgress(message),
7324
- dismiss,
7325
- });
7326
- }, () => {
7327
- dismiss();
7328
- settle(undefined);
7329
- }, {
7330
- getRows: () => this.ui.terminal.rows,
7331
- requestRender: () => this.ui.requestRender(),
7332
- ...(continueActionLabel ? { continueActionLabel } : {}),
7333
- });
7334
- handle = this.ui.showOverlay(selector, {
7335
- width: "100%",
7336
- maxHeight: "100%",
7337
- row: 0,
7338
- col: 0,
7339
- });
7340
- });
7341
- }
7342
7250
  createAuthFlows() {
7343
7251
  return new ProviderAuthFlows({
7344
7252
  ui: this.ui,
@@ -7357,40 +7265,6 @@ export class InteractiveMode {
7357
7265
  },
7358
7266
  });
7359
7267
  }
7360
- async prepareForModelSelectionAfterLogin(authResult) {
7361
- const currentModel = this.getCurrentModel();
7362
- // The agent core uses unknown/unknown as its no-model sentinel.
7363
- const selectedModel = currentModel?.provider === "unknown" && currentModel.id === "unknown" ? undefined : currentModel;
7364
- let action = resolvePrimeInferencePostLoginModelAction(authResult, selectedModel, this.modelRegistry);
7365
- if (!action.openModelPicker) {
7366
- return false;
7367
- }
7368
- if (!selectedModel) {
7369
- try {
7370
- const availableModels = await this.getConnectionAvailableModels();
7371
- action = resolvePrimeInferencePostLoginModelAction(authResult, selectedModel, {
7372
- find: (provider, modelId) => availableModels.find((model) => model.provider === provider && model.id === modelId) ??
7373
- this.modelRegistry.find(provider, modelId),
7374
- });
7375
- }
7376
- catch {
7377
- // Preserve the registry fallback so selection can still report a specific failure below.
7378
- }
7379
- }
7380
- if (action.fallbackModel) {
7381
- try {
7382
- await this.applySelectedModel(action.fallbackModel);
7383
- await this.settingsManager.flush();
7384
- }
7385
- catch (error) {
7386
- this.showError(`Prime Inference login succeeded, but the default model could not be selected: ${error instanceof Error ? error.message : String(error)}`);
7387
- }
7388
- }
7389
- else if (!selectedModel) {
7390
- this.showError("Prime Inference login succeeded, but the default GLM 5.2 model is unavailable.");
7391
- }
7392
- return true;
7393
- }
7394
7268
  async handleMcpCommand(args) {
7395
7269
  const argv = parseCommandArgs((args ?? "").trim());
7396
7270
  const [sub, server] = argv;
@@ -7431,7 +7305,7 @@ export class InteractiveMode {
7431
7305
  const successMessage = verb === "removed"
7432
7306
  ? `Removed MCP server "${name}" (${transport}). It is no longer available through mcp.`
7433
7307
  : usesOAuth
7434
- ? `${verb === "replaced" ? "Replaced" : "Added"} MCP server "${name}" (${transport}). OAuth is unavailable until the Base Context provider contract is validated. Use explicit bearer-token or API-key configuration instead.`
7308
+ ? `${verb === "replaced" ? "Replaced" : "Added"} MCP server "${name}" (${transport}). Run /mcp login ${name} to connect its OAuth account.`
7435
7309
  : `${verb === "replaced" ? "Replaced" : "Added"} MCP server "${name}" (${transport}). Available next turn through mcp.`;
7436
7310
  await this.reloadAfterMcpChange(usesOAuth ? successMessage : result.message, successMessage);
7437
7311
  }
@@ -7760,93 +7634,6 @@ export class InteractiveMode {
7760
7634
  await this.handleFatalRuntimeError("Failed to import session", error);
7761
7635
  }
7762
7636
  }
7763
- async handleShareCommand() {
7764
- // Check if gh is available and logged in
7765
- try {
7766
- const authResult = spawnSync("gh", ["auth", "status"], { encoding: "utf-8" });
7767
- if (authResult.status !== 0) {
7768
- this.showError("GitHub CLI is not logged in. Run 'gh auth login' first.");
7769
- return;
7770
- }
7771
- }
7772
- catch {
7773
- this.showError("GitHub CLI (gh) is not installed. Install it from https://cli.github.com/");
7774
- return;
7775
- }
7776
- // Export to a temp file
7777
- const tmpFile = path.join(os.tmpdir(), "session.html");
7778
- try {
7779
- await this.agentConnection.exportToHtml(tmpFile);
7780
- }
7781
- catch (error) {
7782
- this.showError(`Failed to export session: ${error instanceof Error ? error.message : "Unknown error"}`);
7783
- return;
7784
- }
7785
- // Show cancellable loader, replacing the editor
7786
- const loader = new BorderedLoader(this.ui, theme, "Creating gist...");
7787
- this.editorContainer.clear();
7788
- this.editorContainer.addChild(loader);
7789
- this.ui.setFocus(loader);
7790
- this.ui.requestRender();
7791
- const restoreEditor = () => {
7792
- loader.dispose();
7793
- this.editorContainer.clear();
7794
- this.editorContainer.addChild(this.editor);
7795
- this.ui.setFocus(this.editor);
7796
- try {
7797
- fs.unlinkSync(tmpFile);
7798
- }
7799
- catch {
7800
- // Ignore cleanup errors
7801
- }
7802
- };
7803
- // Create a secret gist asynchronously
7804
- let proc = null;
7805
- loader.onAbort = () => {
7806
- proc?.kill();
7807
- restoreEditor();
7808
- this.showStatus("Share cancelled");
7809
- };
7810
- try {
7811
- const result = await new Promise((resolve) => {
7812
- proc = spawn("gh", ["gist", "create", "--public=false", tmpFile]);
7813
- let stdout = "";
7814
- let stderr = "";
7815
- proc.stdout?.on("data", (data) => {
7816
- stdout += data.toString();
7817
- });
7818
- proc.stderr?.on("data", (data) => {
7819
- stderr += data.toString();
7820
- });
7821
- proc.on("close", (code) => resolve({ stdout, stderr, code }));
7822
- });
7823
- if (loader.signal.aborted)
7824
- return;
7825
- restoreEditor();
7826
- if (result.code !== 0) {
7827
- const errorMsg = result.stderr?.trim() || "Unknown error";
7828
- this.showError(`Failed to create gist: ${errorMsg}`);
7829
- return;
7830
- }
7831
- // Extract gist ID from the URL returned by gh
7832
- // gh returns something like: https://gist.github.com/username/GIST_ID
7833
- const gistUrl = result.stdout?.trim();
7834
- const gistId = gistUrl?.split("/").pop();
7835
- if (!gistId) {
7836
- this.showError("Failed to parse gist ID from gh output");
7837
- return;
7838
- }
7839
- // Create the preview URL
7840
- const previewUrl = getShareViewerUrl(gistId);
7841
- this.showStatus(`Share URL: ${previewUrl}\nGist: ${gistUrl}`);
7842
- }
7843
- catch (error) {
7844
- if (!loader.signal.aborted) {
7845
- restoreEditor();
7846
- this.showError(`Failed to create gist: ${error instanceof Error ? error.message : "Unknown error"}`);
7847
- }
7848
- }
7849
- }
7850
7637
  async handleCopyCommand() {
7851
7638
  const text = await this.agentConnection.getLastAssistantText();
7852
7639
  if (!text) {
@@ -7880,6 +7667,23 @@ export class InteractiveMode {
7880
7667
  this.chatContainer.addChild(new Text(theme.fg("dim", `Session name set: ${name}`), 1, 0));
7881
7668
  this.ui.requestRender();
7882
7669
  }
7670
+ async handleAgentsCommand(args) {
7671
+ const value = args.trim();
7672
+ const maxSubagents = Number(value);
7673
+ if (value && (!/^\d+$/.test(value) || !Number.isSafeInteger(maxSubagents))) {
7674
+ this.showWarning("Usage: /agents [N]. N must be a non-negative safe integer; 0 disables new subagent spawns.");
7675
+ return;
7676
+ }
7677
+ try {
7678
+ const status = value
7679
+ ? await this.agentConnection.setRlmMaxSubagents(maxSubagents)
7680
+ : await this.agentConnection.getRlmMaxSubagentsStatus();
7681
+ this.showStatus(`The current maximum number of concurrent subagents is ${status.maxSubagents}.`);
7682
+ }
7683
+ catch (error) {
7684
+ this.showError(error instanceof Error ? error.message : String(error));
7685
+ }
7686
+ }
7883
7687
  async handleRlmMaxDepthCommand(args) {
7884
7688
  const tokens = args ? args.split(/\s+/) : [];
7885
7689
  if (tokens.length === 0) {
@@ -7979,236 +7783,6 @@ export class InteractiveMode {
7979
7783
  this.chatContainer.addChild(new Text(prompt, 1, 0));
7980
7784
  this.ui.requestRender();
7981
7785
  }
7982
- formatTraceUploadResult(result) {
7983
- switch (result.status) {
7984
- case "uploaded":
7985
- return `Trace uploaded (${result.bytesStored.toLocaleString()} bytes).`;
7986
- case "disabled":
7987
- return "Trace sharing is disabled.";
7988
- case "unchanged":
7989
- return "Trace is already uploaded; no new content since the last upload.";
7990
- case "missing_credentials":
7991
- return "Trace sharing needs a Prime API key. Run /traces login.";
7992
- case "no_session_file":
7993
- return "Current session has no persisted trace yet.";
7994
- case "empty_session":
7995
- return "Current session trace is empty.";
7996
- case "invalid_session":
7997
- return `Trace upload skipped: ${result.message}.`;
7998
- case "too_large":
7999
- return `Trace upload skipped: session file is ${result.size.toLocaleString()} bytes; limit is ${result.maxBytes.toLocaleString()} bytes.`;
8000
- case "failed":
8001
- if (result.statusCode === 404) {
8002
- return "Trace upload endpoint was not found. The platform API may not be deployed yet, or BASE_CONTEXT_TRACES_BASE_URL points at the wrong API.";
8003
- }
8004
- return `Trace upload failed: ${result.statusCode ? `HTTP ${result.statusCode}: ` : ""}${result.message}. See ${getAgentTracesLogPath()} for details.`;
8005
- }
8006
- }
8007
- async uploadCurrentTraceOnce() {
8008
- const state = await this.agentConnection.getState();
8009
- return uploadAgentTraceFile({
8010
- sessionFile: state.sessionFile,
8011
- authStorage: this.modelRegistry.authStorage,
8012
- settingsManager: this.settingsManager,
8013
- requireEnabled: false,
8014
- reloadConfig: false,
8015
- });
8016
- }
8017
- async previewCurrentTrace() {
8018
- const state = await this.agentConnection.getState();
8019
- const result = await previewAgentTraceFile({ sessionFile: state.sessionFile });
8020
- let info;
8021
- switch (result.status) {
8022
- case "no_session_file":
8023
- info = "Trace preview is unavailable until the current session has a persisted assistant response.";
8024
- break;
8025
- case "empty_session":
8026
- info = "The current trace is empty.";
8027
- break;
8028
- case "invalid_session":
8029
- case "failed":
8030
- info = `Trace preview failed: ${result.message}.`;
8031
- break;
8032
- case "ready":
8033
- info = this.formatTracePreview(result);
8034
- break;
8035
- }
8036
- this.chatContainer.addChild(new Spacer(1));
8037
- this.chatContainer.addChild(new Text(info, 1, 0));
8038
- this.ui.requestRender();
8039
- }
8040
- formatTracePreview(result) {
8041
- const lines = [
8042
- theme.bold("Trace Preview"),
8043
- theme.fg("dim", "Nothing has been uploaded by this command."),
8044
- "",
8045
- `${theme.fg("dim", "File:")} ${result.sessionFile}`,
8046
- `${theme.fg("dim", "Size:")} ${result.size.toLocaleString()} bytes`,
8047
- `${theme.fg("dim", "Uploadable:")} ${result.uploadable ? "Yes" : `No (limit ${result.maxBytes.toLocaleString()} bytes)`}`,
8048
- `${theme.fg("dim", "Endpoint:")} ${result.endpoint}`,
8049
- `${theme.fg("dim", "Session ID:")} ${result.sessionId}`,
8050
- `${theme.fg("dim", "Trace ID:")} ${result.traceId}`,
8051
- ];
8052
- if (result.parentSessionId) {
8053
- lines.push(`${theme.fg("dim", "Parent session:")} ${result.parentSessionId}`);
8054
- }
8055
- if (result.gitRepo) {
8056
- lines.push(`${theme.fg("dim", "Git repository:")} ${result.gitRepo}`);
8057
- }
8058
- if (result.gitCommit) {
8059
- lines.push(`${theme.fg("dim", "Git commit:")} ${result.gitCommit}`);
8060
- }
8061
- lines.push("", theme.bold("Raw JSONL payload preview"));
8062
- if (result.contentPreview) {
8063
- lines.push(result.contentPreview);
8064
- if (result.truncated) {
8065
- lines.push("", theme.fg("dim", "Preview truncated; upload sends the complete file."));
8066
- }
8067
- }
8068
- else {
8069
- lines.push(theme.fg("dim", "Payload omitted because the trace exceeds the upload limit."));
8070
- }
8071
- return lines.join("\n");
8072
- }
8073
- async uploadAllTraces(sessionDir, signal) {
8074
- return uploadAllAgentTraces({
8075
- authStorage: this.modelRegistry.authStorage,
8076
- settingsManager: this.settingsManager,
8077
- sessionDir,
8078
- requireEnabled: false,
8079
- reloadConfig: false,
8080
- signal,
8081
- onProgress: ({ completed, total }) => {
8082
- if (total > 0 && (completed === 0 || completed === total || completed % 10 === 0)) {
8083
- this.showStatus(`Uploading traces: ${completed.toLocaleString()}/${total.toLocaleString()} (${keyText("app.clear")} to cancel)`);
8084
- }
8085
- },
8086
- });
8087
- }
8088
- async handleTracesCommand(text) {
8089
- const command = text
8090
- .replace(/^\/traces\b/, "")
8091
- .trim()
8092
- .toLowerCase() || "status";
8093
- if (command === "status") {
8094
- await this.settingsManager.reload().catch(() => undefined);
8095
- const credential = await getPrimeAgentTraceCredential(this.modelRegistry.authStorage);
8096
- const state = await this.agentConnection.getState();
8097
- const info = [
8098
- theme.bold("Trace Sharing"),
8099
- "",
8100
- `${theme.fg("dim", "Automatic uploads:")} ${this.settingsManager.getAgentTracesEnabled() ? "Enabled" : "Disabled"}`,
8101
- `${theme.fg("dim", "Credential:")} ${credential?.label ?? "Not configured"}`,
8102
- `${theme.fg("dim", "Endpoint:")} ${resolvePrimeAgentTracesBaseUrl()}`,
8103
- `${theme.fg("dim", "Session file:")} ${state.sessionFile ?? "In-memory"}`,
8104
- "",
8105
- theme.fg("dim", "Commands: /traces on, /traces off, /traces preview, /traces upload-current, /traces upload-all, /traces login"),
8106
- ].join("\n");
8107
- this.chatContainer.addChild(new Spacer(1));
8108
- this.chatContainer.addChild(new Text(info, 1, 0));
8109
- this.ui.requestRender();
8110
- return;
8111
- }
8112
- if (command === "off" || command === "disable") {
8113
- this.settingsManager.setAgentTracesEnabled(false);
8114
- await this.settingsManager.flush();
8115
- this.showStatus("Trace sharing disabled.");
8116
- return;
8117
- }
8118
- if (command === "login") {
8119
- await this.createAuthFlows().runPrimeAgentTracesLogin();
8120
- return;
8121
- }
8122
- if (command === "preview") {
8123
- await this.previewCurrentTrace();
8124
- return;
8125
- }
8126
- if (command === "on" || command === "enable") {
8127
- let credential = await getPrimeAgentTraceCredential(this.modelRegistry.authStorage);
8128
- if (!credential) {
8129
- const authResult = await this.createAuthFlows().runPrimeAgentTracesLogin();
8130
- if (authResult.status !== "success") {
8131
- return;
8132
- }
8133
- credential = await getPrimeAgentTraceCredential(this.modelRegistry.authStorage);
8134
- }
8135
- if (!credential) {
8136
- this.showError("Trace sharing needs a Prime API key.");
8137
- return;
8138
- }
8139
- this.settingsManager.setAgentTracesEnabled(true);
8140
- await this.settingsManager.flush();
8141
- const uploadResult = await this.uploadCurrentTraceOnce();
8142
- const uploadMessage = uploadResult.status === "no_session_file" || uploadResult.status === "empty_session"
8143
- ? "Current session will upload after the first assistant response."
8144
- : this.formatTraceUploadResult(uploadResult);
8145
- this.showStatus(`Trace sharing enabled. ${uploadMessage}`);
8146
- return;
8147
- }
8148
- if (command === "upload" || command === "upload-current") {
8149
- const credential = await getPrimeAgentTraceCredential(this.modelRegistry.authStorage);
8150
- if (!credential) {
8151
- this.showError("Trace sharing needs a Prime API key. Run /traces login.");
8152
- return;
8153
- }
8154
- const uploadResult = await this.uploadCurrentTraceOnce();
8155
- const message = this.formatTraceUploadResult(uploadResult);
8156
- if (uploadResult.status === "failed") {
8157
- this.showError(message);
8158
- }
8159
- else {
8160
- this.showStatus(message);
8161
- }
8162
- return;
8163
- }
8164
- if (command === "upload-all") {
8165
- const credential = await getPrimeAgentTraceCredential(this.modelRegistry.authStorage);
8166
- if (!credential) {
8167
- this.showError("Trace sharing needs a Prime API key. Run /traces login.");
8168
- return;
8169
- }
8170
- if (this.traceUploadAllAbortController) {
8171
- this.showWarning("A trace upload is already running. Cancel it before starting another.");
8172
- return;
8173
- }
8174
- const state = await this.agentConnection.getState();
8175
- const abortController = new AbortController();
8176
- this.traceUploadAllAbortController = abortController;
8177
- let result;
8178
- try {
8179
- result = await this.uploadAllTraces(state.sessionDir, abortController.signal);
8180
- }
8181
- finally {
8182
- if (this.traceUploadAllAbortController === abortController) {
8183
- this.traceUploadAllAbortController = undefined;
8184
- }
8185
- }
8186
- if (abortController.signal.aborted) {
8187
- this.showStatus("Trace upload cancelled.");
8188
- return;
8189
- }
8190
- if (result.total === 0) {
8191
- this.showStatus("No persisted traces were found.");
8192
- return;
8193
- }
8194
- const summary = [
8195
- `Uploaded ${result.uploaded.toLocaleString()} of ${result.total.toLocaleString()} traces`,
8196
- result.skipped > 0 ? `${result.skipped.toLocaleString()} skipped` : undefined,
8197
- result.failed > 0 ? `${result.failed.toLocaleString()} failed` : undefined,
8198
- `${result.bytesStored.toLocaleString()} bytes stored`,
8199
- ]
8200
- .filter((part) => part !== undefined)
8201
- .join("; ");
8202
- if (result.failed > 0) {
8203
- this.showWarning(`${summary}. See ${getAgentTracesLogPath()} for details.`);
8204
- }
8205
- else {
8206
- this.showStatus(`${summary}.`);
8207
- }
8208
- return;
8209
- }
8210
- this.showWarning("Usage: /traces [status|on|off|preview|upload|upload-current|upload-all|login]");
8211
- }
8212
7786
  async handleContextCommand() {
8213
7787
  let info;
8214
7788
  try {