eve 0.25.3 → 0.26.1

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 (221) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/src/chunks/{use-eve-agent-Cy73lgA6.js → use-eve-agent-BkztZA0v.js} +76 -55
  3. package/dist/src/chunks/{use-eve-agent-CQIeqmKc.js → use-eve-agent-CruinZmd.js} +76 -55
  4. package/dist/src/cli/banner.d.ts +5 -0
  5. package/dist/src/cli/banner.js +1 -1
  6. package/dist/src/cli/commands/logs-events.d.ts +36 -0
  7. package/dist/src/cli/commands/logs-events.js +2 -0
  8. package/dist/src/cli/commands/logs.d.ts +64 -0
  9. package/dist/src/cli/commands/logs.js +4 -0
  10. package/dist/src/cli/dev/diagnostic-dump.d.ts +60 -0
  11. package/dist/src/cli/dev/diagnostic-dump.js +1 -0
  12. package/dist/src/cli/dev/diagnostic-sink.d.ts +37 -0
  13. package/dist/src/cli/dev/diagnostic-sink.js +1 -0
  14. package/dist/src/cli/dev/diagnostics.d.ts +42 -0
  15. package/dist/src/cli/dev/diagnostics.js +1 -0
  16. package/dist/src/cli/dev/tui/blocks.d.ts +60 -8
  17. package/dist/src/cli/dev/tui/blocks.js +8 -8
  18. package/dist/src/cli/dev/tui/command-typeahead.js +1 -1
  19. package/dist/src/cli/dev/tui/diagnostic-presentation.d.ts +16 -0
  20. package/dist/src/cli/dev/tui/diagnostic-presentation.js +3 -0
  21. package/dist/src/cli/dev/tui/errors.d.ts +21 -16
  22. package/dist/src/cli/dev/tui/errors.js +1 -1
  23. package/dist/src/cli/dev/tui/file-content-cache.d.ts +35 -0
  24. package/dist/src/cli/dev/tui/file-content-cache.js +3 -0
  25. package/dist/src/cli/dev/tui/line-diff.d.ts +24 -0
  26. package/dist/src/cli/dev/tui/line-diff.js +1 -0
  27. package/dist/src/cli/dev/tui/line-editor.js +1 -1
  28. package/dist/src/cli/dev/tui/markdown.d.ts +2 -1
  29. package/dist/src/cli/dev/tui/markdown.js +7 -3
  30. package/dist/src/cli/dev/tui/model-editor.d.ts +103 -0
  31. package/dist/src/cli/dev/tui/model-editor.js +1 -0
  32. package/dist/src/cli/dev/tui/prompt-command-handler.d.ts +1 -1
  33. package/dist/src/cli/dev/tui/prompt-command-handler.js +1 -1
  34. package/dist/src/cli/dev/tui/prompt-placeholder.d.ts +12 -0
  35. package/dist/src/cli/dev/tui/prompt-placeholder.js +1 -0
  36. package/dist/src/cli/dev/tui/question-panel.d.ts +24 -0
  37. package/dist/src/cli/dev/tui/question-panel.js +1 -0
  38. package/dist/src/cli/dev/tui/rail.d.ts +15 -0
  39. package/dist/src/cli/dev/tui/rail.js +1 -0
  40. package/dist/src/cli/dev/tui/remote-auth-command.js +1 -1
  41. package/dist/src/cli/dev/tui/runner.d.ts +27 -65
  42. package/dist/src/cli/dev/tui/runner.js +1 -1
  43. package/dist/src/cli/dev/tui/setup-commands.d.ts +1 -1
  44. package/dist/src/cli/dev/tui/setup-commands.js +2 -2
  45. package/dist/src/cli/dev/tui/setup-flow.d.ts +3 -0
  46. package/dist/src/cli/dev/tui/setup-issues.js +1 -1
  47. package/dist/src/cli/dev/tui/setup-panel.d.ts +33 -0
  48. package/dist/src/cli/dev/tui/setup-panel.js +4 -4
  49. package/dist/src/cli/dev/tui/status-line.d.ts +8 -6
  50. package/dist/src/cli/dev/tui/status-line.js +1 -1
  51. package/dist/src/cli/dev/tui/stream-format.d.ts +16 -3
  52. package/dist/src/cli/dev/tui/stream-format.js +1 -1
  53. package/dist/src/cli/dev/tui/subagent-pump.d.ts +127 -0
  54. package/dist/src/cli/dev/tui/subagent-pump.js +1 -0
  55. package/dist/src/cli/dev/tui/terminal-renderer.d.ts +37 -1
  56. package/dist/src/cli/dev/tui/terminal-renderer.js +12 -10
  57. package/dist/src/cli/dev/tui/test/fake-setup-flow-renderer.js +1 -1
  58. package/dist/src/cli/dev/tui/test/mock-terminal.d.ts +7 -0
  59. package/dist/src/cli/dev/tui/test/mock-terminal.js +1 -1
  60. package/dist/src/cli/dev/tui/theme.d.ts +30 -2
  61. package/dist/src/cli/dev/tui/theme.js +1 -1
  62. package/dist/src/cli/dev/tui/todo-panel.d.ts +44 -0
  63. package/dist/src/cli/dev/tui/todo-panel.js +1 -0
  64. package/dist/src/cli/dev/tui/tool-block-groups.d.ts +40 -0
  65. package/dist/src/cli/dev/tui/tool-block-groups.js +1 -0
  66. package/dist/src/cli/dev/tui/tool-format.js +1 -1
  67. package/dist/src/cli/dev/tui/tool-presentation.d.ts +67 -0
  68. package/dist/src/cli/dev/tui/tool-presentation.js +1 -0
  69. package/dist/src/cli/dev/tui/tool-rows.d.ts +15 -0
  70. package/dist/src/cli/dev/tui/tool-rows.js +2 -0
  71. package/dist/src/cli/dev/tui/tui.js +1 -1
  72. package/dist/src/cli/dev/tui/turn-clock.d.ts +36 -0
  73. package/dist/src/cli/dev/tui/turn-clock.js +1 -0
  74. package/dist/src/cli/dev/tui/types.d.ts +2 -2
  75. package/dist/src/cli/dev/ui-options.js +1 -1
  76. package/dist/src/cli/run.js +2 -2
  77. package/dist/src/cli/ui/live-row.js +1 -1
  78. package/dist/src/client/agent-info-schema.d.ts +9 -0
  79. package/dist/src/client/agent-info-schema.js +1 -1
  80. package/dist/src/client/client.js +1 -1
  81. package/dist/src/client/eve-agent-store.d.ts +1 -2
  82. package/dist/src/client/eve-agent-store.js +1 -1
  83. package/dist/src/client/index.js +1 -1
  84. package/dist/src/client/open-stream.d.ts +14 -10
  85. package/dist/src/client/open-stream.js +1 -1
  86. package/dist/src/client/session-utils.d.ts +2 -1
  87. package/dist/src/client/session-utils.js +1 -1
  88. package/dist/src/client/session.d.ts +3 -5
  89. package/dist/src/client/session.js +1 -1
  90. package/dist/src/client/types.d.ts +0 -6
  91. package/dist/src/compiled/.vendor-stamp.json +2 -1
  92. package/dist/src/compiled/marked/LICENSE.md +44 -0
  93. package/dist/src/compiled/marked/index.d.ts +24 -0
  94. package/dist/src/compiled/marked/index.js +59 -0
  95. package/dist/src/compiler/extension-compatibility.d.ts +2 -2
  96. package/dist/src/compiler/extension-compatibility.js +1 -1
  97. package/dist/src/context/build-dynamic-tools.js +1 -1
  98. package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
  99. package/dist/src/evals/session.js +1 -1
  100. package/dist/src/execution/node-step.js +1 -1
  101. package/dist/src/execution/sandbox/bindings/docker-cli.d.ts +4 -0
  102. package/dist/src/execution/sandbox/bindings/docker-cli.js +1 -1
  103. package/dist/src/execution/sandbox/bindings/microsandbox-create.js +1 -1
  104. package/dist/src/execution/terminal-session-failure-step.js +1 -1
  105. package/dist/src/harness/emission.js +1 -1
  106. package/dist/src/harness/model-call-error.d.ts +11 -30
  107. package/dist/src/harness/model-call-error.js +1 -1
  108. package/dist/src/harness/semantic-errors/index.d.ts +9 -0
  109. package/dist/src/harness/semantic-errors/index.js +1 -0
  110. package/dist/src/harness/semantic-errors/rule.d.ts +76 -0
  111. package/dist/src/harness/semantic-errors/rule.js +1 -0
  112. package/dist/src/harness/semantic-errors/rules/gateway.d.ts +11 -0
  113. package/dist/src/harness/semantic-errors/rules/gateway.js +1 -0
  114. package/dist/src/harness/semantic-errors/rules/model-provider.d.ts +11 -0
  115. package/dist/src/harness/semantic-errors/rules/model-provider.js +1 -0
  116. package/dist/src/harness/semantic-errors/rules/sandbox.d.ts +16 -0
  117. package/dist/src/harness/semantic-errors/rules/sandbox.js +1 -0
  118. package/dist/src/harness/semantic-errors/rules/system.d.ts +2 -0
  119. package/dist/src/harness/semantic-errors/rules/system.js +1 -0
  120. package/dist/src/harness/semantic-errors/rules/workflow.d.ts +9 -0
  121. package/dist/src/harness/semantic-errors/rules/workflow.js +1 -0
  122. package/dist/src/harness/semantic-errors/signals.d.ts +28 -0
  123. package/dist/src/harness/semantic-errors/signals.js +1 -0
  124. package/dist/src/harness/tool-loop.js +2 -2
  125. package/dist/src/harness/workflow-sandbox.d.ts +6 -0
  126. package/dist/src/harness/workflow-sandbox.js +2 -2
  127. package/dist/src/internal/application/output-publication-lock.js +1 -1
  128. package/dist/src/internal/application/package.js +1 -1
  129. package/dist/src/internal/logging.d.ts +33 -1
  130. package/dist/src/internal/logging.js +1 -1
  131. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response-from-manifest.js +1 -1
  132. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.d.ts +3 -1
  133. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.js +1 -1
  134. package/dist/src/internal/nitro/routes/info.js +1 -1
  135. package/dist/src/internal/resolve-model-endpoint-status.d.ts +46 -3
  136. package/dist/src/internal/resolve-model-endpoint-status.js +1 -1
  137. package/dist/src/internal/workflow/development-world-client.js +1 -1
  138. package/dist/src/internal/workflow/development-world-server.js +1 -1
  139. package/dist/src/packages/eve-catalog/src/index.js +1 -1
  140. package/dist/src/public/models/openai/chatgpt/model.js +3 -1
  141. package/dist/src/react/use-eve-agent.d.ts +0 -1
  142. package/dist/src/react/use-eve-agent.js +1 -1
  143. package/dist/src/setup/boxes/add-channels.js +1 -1
  144. package/dist/src/setup/boxes/deploy-project.js +1 -1
  145. package/dist/src/setup/boxes/model-capabilities.d.ts +24 -0
  146. package/dist/src/setup/boxes/model-capabilities.js +1 -0
  147. package/dist/src/setup/boxes/resolve-provisioning.js +1 -1
  148. package/dist/src/setup/boxes/select-model.d.ts +30 -8
  149. package/dist/src/setup/boxes/select-model.js +1 -1
  150. package/dist/src/setup/cli/option-row.js +1 -1
  151. package/dist/src/setup/cli/prompt-ui.d.ts +2 -0
  152. package/dist/src/setup/cli/prompt-ui.js +2 -2
  153. package/dist/src/setup/cli/rail-log.d.ts +4 -6
  154. package/dist/src/setup/cli/rail-log.js +3 -2
  155. package/dist/src/setup/connection-connector.js +2 -2
  156. package/dist/src/setup/flows/link.d.ts +13 -3
  157. package/dist/src/setup/flows/link.js +1 -1
  158. package/dist/src/setup/flows/login.js +1 -1
  159. package/dist/src/setup/flows/model-source-change.d.ts +38 -0
  160. package/dist/src/setup/flows/model-source-change.js +1 -0
  161. package/dist/src/setup/flows/model.d.ts +69 -65
  162. package/dist/src/setup/flows/model.js +1 -1
  163. package/dist/src/setup/flows/provider.d.ts +22 -0
  164. package/dist/src/setup/flows/provider.js +3 -3
  165. package/dist/src/setup/prompter.d.ts +2 -0
  166. package/dist/src/setup/scaffold/create/project.js +1 -1
  167. package/dist/src/setup/slack-connect-lifecycle.js +1 -1
  168. package/dist/src/setup/slackbot.js +1 -1
  169. package/dist/src/setup/vercel-project.d.ts +6 -0
  170. package/dist/src/setup/vercel-project.js +0 -0
  171. package/dist/src/shared/dynamic-tool-definition.d.ts +1 -8
  172. package/dist/src/shared/errors.d.ts +5 -0
  173. package/dist/src/shared/errors.js +1 -1
  174. package/dist/src/shared/gateway-service-tier.d.ts +19 -0
  175. package/dist/src/shared/gateway-service-tier.js +1 -0
  176. package/dist/src/shared/model-summary.d.ts +12 -0
  177. package/dist/src/shared/model-summary.js +1 -0
  178. package/dist/src/shared/workflow-sandbox.d.ts +2 -0
  179. package/dist/src/shared/workflow-sandbox.js +1 -1
  180. package/dist/src/source-change/agent-config-ast.d.ts +54 -0
  181. package/dist/src/source-change/agent-config-ast.js +2 -0
  182. package/dist/src/source-change/agent-config-string-path.d.ts +18 -0
  183. package/dist/src/source-change/agent-config-string-path.js +2 -0
  184. package/dist/src/source-change/apply-agent-model-settings.d.ts +26 -0
  185. package/dist/src/source-change/apply-agent-model-settings.js +1 -0
  186. package/dist/src/source-change/apply-model-name.js +1 -2
  187. package/dist/src/source-change/static-source-change.d.ts +14 -0
  188. package/dist/src/source-change/static-source-change.js +1 -1
  189. package/dist/src/svelte/index.js +1 -1
  190. package/dist/src/svelte/use-eve-agent.d.ts +0 -6
  191. package/dist/src/svelte/use-eve-agent.js +1 -1
  192. package/dist/src/vue/index.js +1 -1
  193. package/dist/src/vue/use-eve-agent.d.ts +0 -2
  194. package/dist/src/vue/use-eve-agent.js +1 -1
  195. package/docs/concepts/execution-model-and-durability.md +1 -1
  196. package/docs/concepts/sessions-runs-and-streaming.md +1 -1
  197. package/docs/getting-started.mdx +1 -1
  198. package/docs/guides/auth-and-route-protection.md +1 -1
  199. package/docs/guides/client/overview.mdx +1 -1
  200. package/docs/guides/client/streaming.mdx +1 -10
  201. package/docs/guides/deployment/meta.json +4 -0
  202. package/docs/guides/deployment/overview.md +61 -0
  203. package/docs/guides/deployment/self-hosting.md +88 -0
  204. package/docs/guides/deployment/vercel.mdx +90 -0
  205. package/docs/guides/dev-tui.md +8 -4
  206. package/docs/guides/dynamic-capabilities.md +2 -0
  207. package/docs/guides/frontend/nextjs.mdx +1 -1
  208. package/docs/guides/frontend/nuxt.mdx +1 -1
  209. package/docs/guides/frontend/overview.mdx +2 -5
  210. package/docs/guides/frontend/sveltekit.mdx +1 -1
  211. package/docs/guides/frontend/use-eve-agent-svelte.mdx +1 -4
  212. package/docs/guides/frontend/use-eve-agent-vue.mdx +1 -4
  213. package/docs/guides/instrumentation.md +1 -1
  214. package/docs/reference/cli.md +24 -2
  215. package/docs/tutorial/ship-it.mdx +1 -1
  216. package/package.json +2 -1
  217. package/docs/guides/deployment.md +0 -210
  218. /package/dist/src/cli/{dev/tui → ui}/live-region.d.ts +0 -0
  219. /package/dist/src/cli/{dev/tui → ui}/live-region.js +0 -0
  220. /package/dist/src/cli/{dev/tui → ui}/terminal-text.d.ts +0 -0
  221. /package/dist/src/cli/{dev/tui → ui}/terminal-text.js +0 -0
@@ -0,0 +1,103 @@
1
+ import { type ReasoningLevel } from "#setup/boxes/model-capabilities.js";
2
+ import type { GatewayModelCapabilities } from "#setup/boxes/model-capabilities.js";
3
+ import { type SelectState } from "#setup/cli/select-state.js";
4
+ import type { ModelSettingsRequest, ModelSettingsResult } from "#setup/flows/model.js";
5
+ import type { SelectOption } from "#setup/prompter.js";
6
+ /** The Change-model menu's rows, in visual order. */
7
+ export type ModelEditorRowId = "model" | "reasoning" | "tier" | "done";
8
+ /**
9
+ * The screen stack, depth two: the value menu, or the model list it opens.
10
+ * Reasoning and tier adjust inline on their menu rows — only the catalog pick
11
+ * warrants its own screen. The list carries scratch select state seeded when
12
+ * opened; Esc drops it, so "returns unchanged" is structural.
13
+ */
14
+ export type ModelEditorScreen = {
15
+ kind: "menu";
16
+ cursor: ModelEditorRowId;
17
+ } | {
18
+ kind: "model";
19
+ select: SelectState;
20
+ };
21
+ /** The in-progress values; nothing lands in source until the menu's Done. */
22
+ export interface ModelEditorDraft {
23
+ modelId: string | null;
24
+ reasoning: "default" | ReasoningLevel;
25
+ tier: "standard" | "priority";
26
+ }
27
+ /** One Change-model interaction, advanced by {@link transitionModelEditor}. */
28
+ export interface ModelEditorState {
29
+ screen: ModelEditorScreen;
30
+ draft: ModelEditorDraft;
31
+ /** Catalog capabilities for `draft.modelId`; recomputed on every pick. */
32
+ capabilities: GatewayModelCapabilities | undefined;
33
+ }
34
+ /** Semantic input after terminal-key decoding. */
35
+ export type ModelEditorEvent = {
36
+ type: "move";
37
+ direction: "up" | "down";
38
+ } | {
39
+ type: "adjust";
40
+ direction: "left" | "right";
41
+ } | {
42
+ type: "char";
43
+ char: string;
44
+ } | {
45
+ type: "backspace";
46
+ } | {
47
+ type: "cancel";
48
+ } | {
49
+ type: "submit";
50
+ };
51
+ export type ModelEditorTransition = {
52
+ kind: "ignore";
53
+ state: ModelEditorState;
54
+ } | {
55
+ kind: "render";
56
+ state: ModelEditorState;
57
+ } | {
58
+ kind: "cancel";
59
+ } | {
60
+ kind: "settle";
61
+ result: ModelSettingsResult;
62
+ };
63
+ /**
64
+ * How a value row presents: an adjustable control, a dim explanatory line the
65
+ * cursor skips, or nothing at all — a control that cannot apply to the
66
+ * drafted model (no priority tier) is noise, while an authored-but-unowned
67
+ * state (custom tier, external provider) still explains itself.
68
+ */
69
+ export type ModelEditorSectionView = {
70
+ kind: "interactive";
71
+ } | {
72
+ kind: "static";
73
+ text: string;
74
+ } | {
75
+ kind: "hidden";
76
+ };
77
+ /**
78
+ * The reasoning row stays interactive while a level is drafted even when the
79
+ * catalog disowns reasoning, so the authored value at least stays visible.
80
+ */
81
+ export declare function reasoningSectionView(request: ModelSettingsRequest, draft: ModelEditorDraft, capabilities: GatewayModelCapabilities | undefined): ModelEditorSectionView;
82
+ /** The tier row's presentation; static or hidden for every state it cannot own. */
83
+ export declare function tierSectionView(request: ModelSettingsRequest, capabilities: GatewayModelCapabilities | undefined): ModelEditorSectionView;
84
+ /**
85
+ * The track's notch positions: the levels the catalog supports (every level
86
+ * when capabilities are unknown). The provider default is not a notch — an
87
+ * unset draft renders an empty track and the first right-adjust enters the
88
+ * scale at the lowest level. A drafted level the catalog does not list is
89
+ * inserted in canonical level order, so the track never hides the value it
90
+ * is about to replace.
91
+ */
92
+ export declare function reasoningPositions(capabilities: GatewayModelCapabilities | undefined, drafted: "default" | ReasoningLevel): readonly ReasoningLevel[];
93
+ /**
94
+ * The value menu's rows, derived fresh from the draft on every transition and
95
+ * paint: interactive sections are pickable rows, static sections are disabled
96
+ * rows carrying their explanation, and a hidden tier is omitted entirely.
97
+ * Value hints are the painter's job — it styles them with theme glyphs.
98
+ */
99
+ export declare function modelEditorMenuRows(request: ModelSettingsRequest, draft: ModelEditorDraft, capabilities: GatewayModelCapabilities | undefined): SelectOption<ModelEditorRowId>[];
100
+ /** Creates the screen's state; the cursor opens on the first pickable row. */
101
+ export declare function initialModelEditorState(request: ModelSettingsRequest): ModelEditorState;
102
+ /** Applies one keypress worth of semantics; terminal resources stay in the renderer. */
103
+ export declare function transitionModelEditor(state: ModelEditorState, event: ModelEditorEvent, request: ModelSettingsRequest): ModelEditorTransition;
@@ -0,0 +1 @@
1
+ import{ALL_REASONING_LEVELS}from"#setup/boxes/model-capabilities.js";import{filterOptions,initialSelectState,reduceSelect,selectValueAtCursor}from"#setup/cli/select-state.js";const NOT_EDITABLE_TEXT=`No editable agent.ts config object is available`;function reasoningSectionView(e,t,n){return e.settingsEditable?n?.reasoning===!1&&t.reasoning==="default"?{kind:`static`,text:`Not supported by the selected model`}:{kind:`interactive`}:{kind:`static`,text:NOT_EDITABLE_TEXT}}function tierSectionView(e,t){return e.settingsEditable?e.externalRouting?{kind:`static`,text:`Disabled for a direct external provider`}:e.serviceTier.kind===`custom`?{kind:`static`,text:`Custom (${e.serviceTier.value}) — authored in agent.ts`}:t!==void 0&&!t.fastMode?{kind:`hidden`}:{kind:`interactive`}:{kind:`static`,text:NOT_EDITABLE_TEXT}}function reasoningPositions(t,n){let r=[...t===void 0?ALL_REASONING_LEVELS:t.reasoningLevels];if(n!=="default"&&!r.includes(n)){let t=ALL_REASONING_LEVELS.indexOf(n),i=r.findIndex(n=>ALL_REASONING_LEVELS.indexOf(n)>t);i===-1?r.push(n):r.splice(i,0,n)}return r}function snapReasoningToCapabilities(t,n){if(t==="default"||n===void 0)return t;let r=n.reasoningLevels;if(!n.reasoning||r.length===0)return`default`;if(r.includes(t))return t;let i=ALL_REASONING_LEVELS.indexOf(t),a=r[0];for(let t of r)Math.abs(ALL_REASONING_LEVELS.indexOf(t)-i)<Math.abs(ALL_REASONING_LEVELS.indexOf(a)-i)&&(a=t);return a}function modelEditorMenuRows(e,t,n){let r=[];e.model.kind===`pick`?r.push({value:`model`,label:`Model`}):r.push({value:`model`,label:`Model`,disabled:!0,description:e.model.reason});let i=reasoningSectionView(e,t,n);i.kind===`static`?r.push({value:`reasoning`,label:`Reasoning effort`,disabled:!0,description:i.text}):r.push({value:`reasoning`,label:`Reasoning effort`});let a=tierSectionView(e,n);return a.kind===`interactive`?r.push({value:`tier`,label:`Service tier`}):a.kind===`static`&&r.push({value:`tier`,label:`Service tier`,disabled:!0,description:a.text}),r.push({value:`done`,label:`Done`}),r}function initialModelEditorState(e){let t={modelId:e.model.current,reasoning:e.reasoning??`default`,tier:e.serviceTier.kind===`priority`?`priority`:`standard`},n=e.capabilitiesFor(t.modelId);return{screen:{kind:`menu`,cursor:modelEditorMenuRows(e,t,n).find(e=>e.disabled!==!0)?.value??`done`},draft:t,capabilities:n}}function expandedModelSelect(e,t){let r={options:e.model.kind===`pick`?e.model.options:[]};return t!==null&&(r.defaultValue=t),initialSelectState(r)}function ignore(e){return{kind:`ignore`,state:e}}function toMenu(e,t){return{kind:`render`,state:{...e,screen:{kind:`menu`,cursor:t}}}}function settleResult(e,t){let n={};if(e.model.kind===`pick`&&t.modelId!==null&&t.modelId!==e.model.current&&(n.model=t.modelId),!e.settingsEditable)return n;t.reasoning!==(e.reasoning??`default`)&&(n.reasoning=t.reasoning);let r=!e.externalRouting&&e.serviceTier.kind!==`custom`,i=e.serviceTier.kind===`priority`?`priority`:`standard`;return r&&t.tier!==i&&(n.serviceTier=t.tier),n}function adjustMenuValue(e,t,n,r){let i=r===`left`?-1:1;if(n===`reasoning`){if(reasoningSectionView(t,e.draft,e.capabilities).kind!==`interactive`)return ignore(e);let n=reasoningPositions(e.capabilities,e.draft.reasoning);if(n.length===0)return ignore(e);let r=e.draft.reasoning==="default"?-1:n.indexOf(e.draft.reasoning),a=r===-1?n[i===1?0:n.length-1]:n[(r+i+n.length)%n.length];return a===e.draft.reasoning?ignore(e):{kind:`render`,state:{...e,draft:{...e.draft,reasoning:a}}}}if(n===`tier`){if(tierSectionView(t,e.capabilities).kind!==`interactive`)return ignore(e);let n=e.draft.tier===`priority`?`standard`:`priority`;return{kind:`render`,state:{...e,draft:{...e.draft,tier:n}}}}return ignore(e)}function transitionMenu(e,t,n,i){let a=modelEditorMenuRows(n,e.draft,e.capabilities);switch(t.type){case`cancel`:return{kind:`cancel`};case`move`:{let n=a[reduceSelect({filter:``,cursor:Math.max(0,a.findIndex(e=>e.value===i)),selected:new Set},{type:t.direction},{options:a}).cursor]?.value;return n===void 0||n===i?ignore(e):toMenu(e,n)}case`adjust`:return adjustMenuValue(e,n,i,t.direction);case`submit`:{let t=a.find(e=>e.value===i);return t===void 0||t.disabled===!0?ignore(e):i===`model`?{kind:`render`,state:{...e,screen:{kind:`model`,select:expandedModelSelect(n,e.draft.modelId)}}}:i===`done`?{kind:`settle`,result:settleResult(n,e.draft)}:transitionMenu(e,{type:`move`,direction:`down`},n,i)}case`char`:case`backspace`:return ignore(e)}}function transitionModelScreen(e,n,a,o){let s=a.model.kind===`pick`?a.model.options:[],renderSelect=t=>t===o?ignore(e):{kind:`render`,state:{...e,screen:{kind:`model`,select:t}}};switch(n.type){case`cancel`:return o.filter.length>0?renderSelect(reduceSelect(o,{type:`clear`},{options:s})):toMenu(e,`model`);case`move`:return renderSelect(reduceSelect(o,{type:n.direction},{options:s}));case`char`:return renderSelect(reduceSelect(o,{type:`char`,char:n.char},{options:s}));case`backspace`:return renderSelect(reduceSelect(o,{type:`backspace`},{options:s}));case`submit`:{let n=selectValueAtCursor(filterOptions(s,o.filter),o.cursor);if(n===void 0)return ignore(e);let r=a.capabilitiesFor(n);return{kind:`render`,state:{screen:{kind:`menu`,cursor:`model`},draft:{...e.draft,modelId:n,reasoning:snapReasoningToCapabilities(e.draft.reasoning,r),tier:r!==void 0&&!r.fastMode?`standard`:e.draft.tier},capabilities:r}}}case`adjust`:return ignore(e)}}function transitionModelEditor(e,t,n){switch(e.screen.kind){case`menu`:return transitionMenu(e,t,n,e.screen.cursor);case`model`:return transitionModelScreen(e,t,n,e.screen.select)}}export{initialModelEditorState,modelEditorMenuRows,reasoningPositions,reasoningSectionView,tierSectionView,transitionModelEditor};
@@ -1,4 +1,4 @@
1
- import type { ApplyModelOutcome } from "#setup/flows/model.js";
1
+ import type { ApplyModelOutcome } from "#setup/flows/model-source-change.js";
2
2
  import type { PromptCommandHandler } from "./runner.js";
3
3
  import type { RemoteAuthFlow } from "./remote-auth.js";
4
4
  import type { TuiSetupFlows } from "./setup-commands.js";
@@ -1 +1 @@
1
- import{isPromptCommandAvailableFor}from"./prompt-commands.js";import{toErrorMessage}from"#shared/errors.js";function createPromptCommandHandler(n){return{async handle(r,i){let{target:a}=n;if(a.kind===`remote`&&!isPromptCommandAvailableFor(r.name,`remote`))return{message:`/${r.name} needs eve dev running the local server (it is not available with --url).`};if(r.name===`model`&&r.argument.length>0){if(a.kind!==`local`)return{message:`/model needs eve dev running the local server (it is not available with --url).`};let e=a.workspaceRoot;try{let{changeAgentModel:t,formatApplyModelOutcome:i,modelChangeRefusalForUneditableModel:a}=await import(`#setup/flows/model.js`),o=await(n.modelChangeRefusal??a)(e);return o===null?{message:i(await(n.applyModel??t)({appRoot:e,slug:r.argument}))}:{message:o}}catch(e){return{message:`Couldn't change the model: ${toErrorMessage(e)}`}}}let o=i.renderer.setupFlow;if(o===void 0)return{message:`/${r.name} is not supported by this renderer.`};if(r.name===`vc:login`&&a.kind===`remote`){if(i.remoteConnection===void 0)return{message:`/vc:login is not available in this session.`};let e;try{({runRemoteAuthCommand:e}=await import(`./remote-auth-command.js`))}catch(e){return{message:`/vc:login failed: ${toErrorMessage(e)}`}}return{message:await e({connection:i.remoteConnection,flow:n.remoteAuthFlow,renderer:o})}}let s;try{s=await import(`./setup-commands.js`)}catch(e){return{message:`/${r.name} failed: ${toErrorMessage(e)}`}}let{runTuiSetupCommand:c,SETUP_FLOW_CONFIG:l}=s,u=l[r.name];o.begin(u.title,u.indicator);let d=!0;try{let e={command:r.name,appRoot:a.workspaceRoot,renderer:o,disabledConnectionReasons:i.disabledConnectionReasons};i.initialModelStep!==void 0&&(e.initialModelStep=i.initialModelStep),n.flows!==void 0&&(e.flows=n.flows);let t=await c(e);d=t.preserveFlowDiagnostics;let s={message:t.message};return t.effect!==void 0&&(s.effect=t.effect),s}finally{i.keepSetupFlowOpen!==!0&&o.end({preserveDiagnostics:d})}}}}export{createPromptCommandHandler};
1
+ import{isPromptCommandAvailableFor}from"./prompt-commands.js";import{toErrorMessage}from"#shared/errors.js";function createPromptCommandHandler(n){return{async handle(r,i){let{target:a}=n;if(a.kind===`remote`&&!isPromptCommandAvailableFor(r.name,`remote`))return{message:`/${r.name} needs eve dev running the local server (it is not available with --url).`};if(r.name===`model`&&r.argument.length>0){if(a.kind!==`local`)return{message:`/model needs eve dev running the local server (it is not available with --url).`};let e=a.workspaceRoot;try{let{modelChangeRefusalForUneditableModel:t}=await import(`#setup/flows/model.js`),{changeAgentModel:i,formatApplyModelOutcome:a}=await import(`#setup/flows/model-source-change.js`),o=await(n.modelChangeRefusal??t)(e);return o===null?{message:a(await(n.applyModel??i)({appRoot:e,slug:r.argument}))}:{message:o}}catch(e){return{message:`Couldn't change the model: ${toErrorMessage(e)}`}}}let o=i.renderer.setupFlow;if(o===void 0)return{message:`/${r.name} is not supported by this renderer.`};if(r.name===`vc:login`&&a.kind===`remote`){if(i.remoteConnection===void 0)return{message:`/vc:login is not available in this session.`};let e;try{({runRemoteAuthCommand:e}=await import(`./remote-auth-command.js`))}catch(e){return{message:`/vc:login failed: ${toErrorMessage(e)}`}}return{message:await e({connection:i.remoteConnection,flow:n.remoteAuthFlow,renderer:o})}}let s;try{s=await import(`./setup-commands.js`)}catch(e){return{message:`/${r.name} failed: ${toErrorMessage(e)}`}}let{runTuiSetupCommand:c,SETUP_FLOW_CONFIG:l}=s,u=l[r.name];o.begin(u.title,u.indicator);let d=!0;try{let e={command:r.name,appRoot:a.workspaceRoot,renderer:o,disabledConnectionReasons:i.disabledConnectionReasons};i.initialModelStep!==void 0&&(e.initialModelStep=i.initialModelStep),n.flows!==void 0&&(e.flows=n.flows);let t=await c(e);d=t.preserveFlowDiagnostics;let s={message:t.message};return t.effect!==void 0&&(s.effect=t.effect),s}finally{i.keepSetupFlowOpen!==!0&&o.end({preserveDiagnostics:d})}}}}export{createPromptCommandHandler};
@@ -0,0 +1,12 @@
1
+ /**
2
+ * The empty prompt's rotating invitation, written in the agent's own voice
3
+ * ("my capabilities") since the prompt is a message to it. Messages point at
4
+ * things an eve agent can actually do out of the box, so an idle prompt
5
+ * doubles as a hint surface. The caret-blink repaint keeps the rotation
6
+ * moving without its own timer.
7
+ */
8
+ export declare const PROMPT_PLACEHOLDER_MESSAGES: readonly string[];
9
+ /** How long each message holds before the rotation advances. */
10
+ export declare const promptPlaceholderCycleMs = 6000;
11
+ /** Picks the message for the given time since the renderer started. */
12
+ export declare function promptPlaceholder(elapsedMs: number): string;
@@ -0,0 +1 @@
1
+ const PROMPT_PLACEHOLDER_MESSAGES=[`Ask about my capabilities`,`Have me explore the workspace`,`Refine my instructions`],promptPlaceholderCycleMs=6e3;function promptPlaceholder(e){return PROMPT_PLACEHOLDER_MESSAGES[Math.floor(Math.max(0,e)/promptPlaceholderCycleMs)%PROMPT_PLACEHOLDER_MESSAGES.length]}export{PROMPT_PLACEHOLDER_MESSAGES,promptPlaceholder,promptPlaceholderCycleMs};
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Pure rendering for the HITL question panel — the overlay the agent's
3
+ * `ask_question` tool opens above the input area. A full-width rule separates
4
+ * it from the transcript, options render as numbered rows with their
5
+ * descriptions always visible, and the trailing "Type your own answer" row
6
+ * carries an inline elbow editor that receives focus the moment the cursor
7
+ * rests on it (the provider-key grammar from the setup panel). The renderer
8
+ * hosts lifecycle and keys; this module only paints rows.
9
+ */
10
+ import type { AgentTUIInputOption } from "./runner.js";
11
+ import { type LineState } from "./line-editor.js";
12
+ import type { Theme } from "./theme.js";
13
+ export interface QuestionPanelState {
14
+ readonly prompt: string;
15
+ readonly options: readonly AgentTUIInputOption[];
16
+ /** Row index under the cursor; `options.length` is the freeform row. */
17
+ readonly cursor: number;
18
+ /** Whether the trailing freeform row exists. */
19
+ readonly allowFreeform: boolean;
20
+ /** The freeform row's inline editor; focused while the cursor rests on it. */
21
+ readonly editor: LineState;
22
+ readonly caretVisible: boolean;
23
+ }
24
+ export declare function renderQuestionPanel(state: QuestionPanelState, theme: Theme, width: number): string[];
@@ -0,0 +1 @@
1
+ import{visibleLine}from"./line-editor.js";import{clipVisible,renderInputWithBlockCursor,wrapVisibleLine}from"#cli/ui/terminal-text.js";function selectedRow(e,t){let n=t.colors;return`${n.inverse(n.blue(` ${t.glyph.selectedPointer} ${e} `))} ${n.dim(`↵`)}`}function renderQuestionPanel(e,n,i){let a=n.colors,o=n.glyph,s=[a.dim(o.hrule.repeat(Math.max(1,i)))];for(let t of e.prompt.split(/\r?\n/u))for(let e of wrapVisibleLine(t,Math.max(8,i-2)))s.push(` ${a.bold(e)}`);s.push(``);for(let[t,r]of e.options.entries())s.push(...optionRows(r.label,r.description,t,e,n));if(e.allowFreeform){let t=e.options.length,r=e.cursor===t;s.push(...optionRows(`Type your own answer`,void 0,t,e,n)),(r||e.editor.text.length>0)&&s.push(` ${a.dim(o.elbow)} ${freeformEditorBody(e,r,n,i)}`)}return s.push(``,` ${a.dim(`Esc to dismiss`)}`),s.map(e=>clipVisible(e,i))}function optionRows(e,t,n,r,i){let a=i.colors,o=`${n+1}. ${e}`,s=[r.cursor===n?` ${selectedRow(o,i)}`:` ${a.dim(`${n+1}.`)} ${e}`];return t!==void 0&&t.length>0&&s.push(` ${a.dim(t)}`),s}function freeformEditorBody(t,r,i,a){let o=i.colors,s=Math.max(4,a-12);if(!r){let n=visibleLine(t.editor,s,i.glyph.ellipsis);return o.dim(`${n.before}${n.under}${n.after}`)}return renderInputWithBlockCursor({...visibleLine(t.editor,s,i.glyph.ellipsis),visible:t.caretVisible,inverse:o.inverse})}export{renderQuestionPanel};
@@ -0,0 +1,15 @@
1
+ /**
2
+ * The shared atoms of the transcript's rail grammar. Persistent sections
3
+ * (tool rows, subagent sections, the todo panel) all hang their marks at the
4
+ * same two-cell tool column and elide overflow with the same counted row —
5
+ * one definition keeps the alignment a checked fact instead of a set of
6
+ * parallel comments.
7
+ */
8
+ import type { Theme } from "./theme.js";
9
+ /**
10
+ * The two-cell indent that puts a section's mark at the prose text column
11
+ * (the character after the `│`/`▲` gutter marks).
12
+ */
13
+ export declare const TOOL_COLUMN_LEAD = " ";
14
+ /** The dim `… (N more)` elision label used by every capped region. */
15
+ export declare function elisionText(hidden: number, theme: Theme): string;
@@ -0,0 +1 @@
1
+ const TOOL_COLUMN_LEAD=` `;function elisionText(e,t){return t.colors.dim(`${t.glyph.ellipsis} (${e} more)`)}export{TOOL_COLUMN_LEAD,elisionText};
@@ -1,3 +1,3 @@
1
1
  import{createTuiPrompter}from"./tui-prompter.js";import{describeRemoteAuthCompletedMutations}from"./remote-auth-result.js";import{runRemoteAuthFlow}from"./remote-auth.js";import{remoteHost}from"./target.js";import{WizardCancelledError}from"#setup/step.js";function shouldConfigureTrustedSources(e){switch(e.state){case`auth-required`:case`auth-failed`:return e.challenge.kind===`vercel-deployment-protection`;case`unavailable`:return e.failure.code===`TRUSTED_SOURCES_ENVIRONMENT_MISMATCH`;case`checking`:case`authenticating`:case`ready`:return!1}}function unavailableAfterAuthentication(e,t){let[n=t,...r]=t.split(/\n\s*\n/u);return[`Authentication was refreshed, but ${e} is unavailable: ${/[.!?]$/u.test(n.trim())?n.trim():`${n.trim()}.`}`,...r.map(e=>e.trim()).filter(e=>e.length>0)].join(`
2
2
 
3
- `)}function mutedRenderer(e,t){return{readSelect:n=>t()?Promise.resolve(void 0):e.readSelect(n),readEditableSelect:n=>t()?Promise.resolve(void 0):e.readEditableSelect(n),readText:n=>t()?Promise.resolve(void 0):e.readText(n),readAcknowledge:n=>t()?Promise.resolve():e.readAcknowledge(n),readChoice:n=>t()?{choice:Promise.resolve(void 0),close:()=>{}}:e.readChoice(n),setStatus:n=>{t()||e.setStatus(n)},renderLine:(n,r)=>{(!t()||r===`warning`||r===`error`)&&e.renderLine(n,r)},renderOutput:n=>{t()||e.renderOutput(n)}}}async function runRemoteAuthCommand(i){i.renderer.begin(`Authenticate via Vercel OIDC`,`pulse`);let a=!0,o=!1,s=new AbortController,c=i.renderer.waitForInterrupt(),l=i.connection.current().target;try{let u=i.flow??runRemoteAuthFlow,d=shouldConfigureTrustedSources(i.connection.current().connection),f=createTuiPrompter(mutedRenderer(i.renderer,()=>o)),p=i.connection.authenticate(async e=>{let t=await u({workspaceRoot:l.workspaceRoot,serverUrl:l.serverUrl,configureTrustedSources:d,prompter:f,signal:e});return a=t.kind===`failed`,t},s.signal),m=await Promise.race([p.then(e=>({kind:`completed`,outcome:e})),c.promise.then(()=>({kind:`interrupted`}))]);m.kind===`interrupted`&&(o=!0,a=!0,s.abort(new WizardCancelledError));let h=m.kind===`completed`?m.outcome:await p;switch(h.kind){case`authenticated`:return`Authenticated ${remoteHost(l)} via Vercel OIDC.`;case`cancelled`:if(o){let e=describeRemoteAuthCompletedMutations(h.completedMutations);return e.length===0?`/vc:login interrupted.`:`/vc:login interrupted. Completed before interruption: ${e.join(`, `)}.`}return h.completedMutations.some(e=>e.kind===`vercel-login`)?`/vc:login cancelled after logging in to Vercel.`:`/vc:login cancelled.`;case`failed`:return h.message;case`unavailable`:return unavailableAfterAuthentication(remoteHost(l),h.failure.message)}}finally{c.dispose(),i.renderer.setStatus(void 0),i.renderer.end({preserveDiagnostics:a})}}export{runRemoteAuthCommand};
3
+ `)}function mutedRenderer(e,t){return{readSelect:n=>t()?Promise.resolve(void 0):e.readSelect(n),readEditableSelect:n=>t()?Promise.resolve(void 0):e.readEditableSelect(n),readText:n=>t()?Promise.resolve(void 0):e.readText(n),readAcknowledge:n=>t()?Promise.resolve():e.readAcknowledge(n),readChoice:n=>t()?{choice:Promise.resolve(void 0),close:()=>{}}:e.readChoice(n),setStatus:n=>{t()||e.setStatus(n)},renderLine:(n,r)=>{(!t()||r===`warning`||r===`error`)&&e.renderLine(n,r)},renderOutput:n=>{t()||e.renderOutput(n)}}}async function runRemoteAuthCommand(i){i.renderer.begin(`Authenticate via Vercel OIDC`,`pulse`);let a=!0,o=!1,s=new AbortController,c=i.renderer.waitForInterrupt(),l=i.connection.current().target;try{let u=i.flow??runRemoteAuthFlow,d=shouldConfigureTrustedSources(i.connection.current().connection),f=createTuiPrompter(mutedRenderer(i.renderer,()=>o)),p=i.connection.authenticate(async e=>{let t=await u({workspaceRoot:l.workspaceRoot,serverUrl:l.serverUrl,configureTrustedSources:d,prompter:f,signal:e});return a=t.kind===`failed`,t},s.signal),m=await Promise.race([p.then(e=>({kind:`completed`,outcome:e})),c.promise.then(()=>({kind:`interrupted`}))]);m.kind===`interrupted`&&(o=!0,a=!0,s.abort(new WizardCancelledError));let h=m.kind===`completed`?m.outcome:await p;switch(h.kind){case`authenticated`:return`Authenticated ${remoteHost(l)} via Vercel OIDC.`;case`cancelled`:if(o){let e=describeRemoteAuthCompletedMutations(h.completedMutations);return e.length===0?`/vc:login interrupted.`:`/vc:login interrupted. Completed before interruption: ${e.join(`, `)}.`}return h.completedMutations.some(e=>e.kind===`vercel-login`)?`/vc:login dismissed after logging in to Vercel.`:`/vc:login dismissed.`;case`failed`:return h.message;case`unavailable`:return unavailableAfterAuthentication(remoteHost(l),h.failure.message)}}finally{c.dispose(),i.renderer.setStatus(void 0),i.renderer.end({preserveDiagnostics:a})}}export{runRemoteAuthCommand};
@@ -1,4 +1,6 @@
1
1
  import { type AgentInfoResult, type ConnectionAuthorizationOutcome, type InputRequest, Client, ClientSession } from "#client/index.js";
2
+ import { type SubagentView } from "./subagent-pump.js";
3
+ export type { SubagentRun, SubagentStepUpdate, SubagentToolUpdate, SubagentView, } from "./subagent-pump.js";
2
4
  import { type DevBootProgressReporter } from "#internal/dev-boot-progress.js";
3
5
  import { type PromptCommand, type PromptCommandSpec } from "./prompt-commands.js";
4
6
  import { type RemoteConnectionController, type RemoteConnectionControllerOptions, type RemoteConnectionSnapshot } from "./remote-connection.js";
@@ -12,6 +14,7 @@ import { type VercelStatusEffect, type VercelStatusSnapshot } from "./vercel-sta
12
14
  import { type McpConnectionProbe } from "./mcp-connection-status.js";
13
15
  import type { detectProjectIdentity } from "#setup/project-resolution.js";
14
16
  import { getVercelAuthStatus } from "#setup/vercel-project.js";
17
+ import type { DevDiagnostics } from "../diagnostics.js";
15
18
  export { parsePromptCommand, type PromptCommand } from "./prompt-commands.js";
16
19
  export type AgentTUIStreamResult = {
17
20
  events: AsyncIterable<AgentTUIStreamEvent> | ReadableStream<AgentTUIStreamEvent>;
@@ -42,6 +45,10 @@ export type AgentTUIStreamEvent = {
42
45
  } | {
43
46
  type: "reasoning-complete";
44
47
  id: string;
48
+ } | {
49
+ type: "tool-call-preparing";
50
+ toolCallId: string;
51
+ toolName: string;
45
52
  } | {
46
53
  type: "tool-call";
47
54
  toolCallId: string;
@@ -59,15 +66,21 @@ export type AgentTUIStreamEvent = {
59
66
  type: "tool-error";
60
67
  toolCallId: string;
61
68
  errorText: string;
69
+ } | {
70
+ type: "tool-rejected";
71
+ toolCallId: string;
72
+ reason: string;
62
73
  } | {
63
74
  type: "error";
64
75
  errorText: string;
76
+ hint?: string;
65
77
  detail?: string;
66
78
  } | {
67
79
  type: "finish";
68
80
  usage?: AgentTUIStreamUsage;
69
81
  };
70
82
  export type AgentTUITurnState = {
83
+ aborted?: boolean;
71
84
  boundaryEvent?: "session.completed" | "session.failed" | "session.waiting";
72
85
  pendingApprovals: AgentTUIToolApprovalRequest[];
73
86
  pendingQuestions: InputRequest[];
@@ -137,6 +150,12 @@ export type AgentTUIRenderer = {
137
150
  * recovery and slash-command results. Optional.
138
151
  */
139
152
  renderNotice?(text: string): void;
153
+ /**
154
+ * Commits the session boundary (`┌── Session restarted, clear context.`)
155
+ * when a dead session is replaced mid-conversation. Optional; renderers
156
+ * without it get the plain notice.
157
+ */
158
+ renderSessionBoundary?(): void;
140
159
  /**
141
160
  * Commits one development sandbox lifecycle line to the transcript.
142
161
  * Optional so non-terminal renderers can ignore local prewarm progress.
@@ -154,22 +173,13 @@ export type AgentTUIRenderer = {
154
173
  readInputQuestion?(question: AgentTUIInputQuestion, options?: AgentTUISessionOptions): Promise<AgentTUIInputQuestionResponse | undefined>;
155
174
  renderStream(result: AgentTUIStreamResult, options?: AgentTUISessionOptions): Promise<void>;
156
175
  /**
157
- * Out-of-band update for one child step (reasoning + message text) of a
158
- * subagent dispatch. Called by the runner as child-session stream events
159
- * arrive. The renderer renders this as a body section colored by the
160
- * subagent palette.
176
+ * The renderer's whole subagent surface sections, nested steps and
177
+ * tools, ghost sweeps, completion. One optional capability with required
178
+ * members: a renderer either has a subagent view or it doesn't, and a
179
+ * type-legal partial implementation (which would ghost placeholders or
180
+ * duplicate parent tool rows) cannot exist.
161
181
  */
162
- upsertSubagentStep?(update: SubagentStepUpdate): void;
163
- /**
164
- * Out-of-band update for one child tool call of a subagent dispatch.
165
- */
166
- upsertSubagentTool?(update: SubagentToolUpdate): void;
167
- /**
168
- * Registers a tool call id as originating from a subagent's child
169
- * session. The renderer must skip or remove parent-level tool blocks for
170
- * these ids — they are surfaced via {@link upsertSubagentTool} instead.
171
- */
172
- markChildToolCallId?(callId: string): void;
182
+ readonly subagents?: SubagentView;
173
183
  /**
174
184
  * Out-of-band update for one MCP connection authorization lifecycle.
175
185
  * Called by the runner as `authorization.*` events arrive.
@@ -311,62 +321,14 @@ export type EveTUIRunnerOptions = TuiDisplayOptions & {
311
321
  getVercelAuthStatus?: typeof getVercelAuthStatus;
312
322
  /** Reports phases from this runner's initial local-dev connection. */
313
323
  onBootProgress?: DevBootProgressReporter;
324
+ /** Parent-owned diagnostics recorder; omitted for remote and test renderers. */
325
+ diagnostics?: DevDiagnostics;
314
326
  };
315
327
  export declare class EveTUIRunner {
316
328
  #private;
317
329
  constructor(options: EveTUIRunnerOptions);
318
330
  run(): Promise<void>;
319
331
  }
320
- type SubagentChildStep = {
321
- reasoning: string;
322
- message: string;
323
- finalized: boolean;
324
- };
325
- type SubagentToolState = {
326
- toolName: string;
327
- input: unknown;
328
- status: "approval-requested" | "executing" | "done" | "failed";
329
- output?: unknown;
330
- errorText?: string;
331
- };
332
- export type SubagentRun = {
333
- name: string;
334
- /**
335
- * One entry per logical "child message" — independent of the child's
336
- * `stepIndex` field, which the harness can reuse across multiple
337
- * assistant messages within a turn (e.g. a message before a tool call
338
- * and another message after the tool result both arrive under
339
- * `stepIndex: 0`). The key is a monotonic counter so each
340
- * `message.completed` opens a new box on the next inbound delta.
341
- */
342
- steps: Map<number, SubagentChildStep>;
343
- /**
344
- * Section currently accepting reasoning/message deltas. `null` means
345
- * the next delta opens a new section.
346
- */
347
- currentSectionKey: number | null;
348
- /** Monotonic counter for new section keys. */
349
- nextSectionKey: number;
350
- tools: Map<string, SubagentToolState>;
351
- };
352
- export type SubagentStepUpdate = {
353
- callId: string;
354
- subagentName: string;
355
- sectionKey: number;
356
- reasoning: string;
357
- message: string;
358
- finalized: boolean;
359
- };
360
- export type SubagentToolUpdate = {
361
- callId: string;
362
- subagentName: string;
363
- childCallId: string;
364
- toolName: string;
365
- input: unknown;
366
- status: "approval-requested" | "executing" | "done" | "failed";
367
- output?: unknown;
368
- errorText?: string;
369
- };
370
332
  export type ConnectionAuthChallenge = {
371
333
  url?: string;
372
334
  userCode?: string;
@@ -1 +1 @@
1
- import{PROMPT_COMMANDS,formatPromptCommandHelp,parsePromptCommand}from"./prompt-commands.js";import{pickAgentHeaderTip}from"./agent-header.js";import{probeAgentInfo}from"./agent-info-probe.js";import{failureKey,formatFailureDetail,formatFailureMessage,formatGatewayAuthFailureNotice,isAbortLikeError,isGatewayAuthFailure,isInterruptedError}from"./errors.js";import{parseLogDisplayMode}from"./log-display-mode.js";import{createMcpConnectionStatusTracker}from"./mcp-connection-status.js";import{createRemoteConnectionController}from"./remote-connection.js";import{BOOT_DETECTIONS,CLI_MISSING_SETUP_ISSUE,LOGIN_SETUP_ISSUE,detectSetupIssues,formatSetupIssuesLine,orderedSetupIssues,resolveModelProviderState}from"./setup-issues.js";import{TerminalRenderer}from"./terminal-renderer.js";import{createVercelStatusTracker}from"./vercel-status.js";import{isCurrentTurnBoundaryEvent}from"#client/index.js";import{toErrorMessage}from"#shared/errors.js";import{getVercelAuthStatus}from"#setup/vercel-project.js";import{loadDevelopmentEnvironmentFiles}from"#cli/dev/environment.js";import{subscribeDevelopmentSandboxPrewarmLogs}from"#execution/sandbox/development-prewarm.js";import{createDevelopmentRuntimeArtifactRefresher}from"#services/dev-client.js";import{devBootPhase}from"#internal/dev-boot-progress.js";function authIssueForStatus(e){if(e===`logged-out`)return LOGIN_SETUP_ISSUE;if(e===`cli-missing`)return CLI_MISSING_SETUP_ISSUE}var EveTUIRunner=class{#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;#u;#d;#f;#p;#m;#h;#g;#_;#v;#y;#b;#x=!1;#S=new AbortController;#C=!1;#w=[];#T;#E;#D;#O=pickAgentHeaderTip();#k;#A=new Map;#j=new Map;#M=new Map;#N=new Map;#P=new Set;#F=!1;#I;constructor(t){if(this.#e=t.session,t.client!==void 0&&(this.#t=t.client),this.#n=createRenderer(t),this.#r=t.name??`eve`,this.#i=t.tools??`full`,this.#a=t.reasoning??`full`,this.#o=t.subagents??`full`,this.#s=t.connectionAuth??`full`,this.#c=t.assistantResponseStats??`tokensPerSecond`,this.#l=t.contextSize,this.#u=t.formatTransportError??toErrorMessage,t.initialInput!==void 0&&(this.#m=t.initialInput),t.appRoot!==void 0){this.#p=t.appRoot;let e={appRoot:t.appRoot,onChange:e=>this.#n.setVercelStatus?.(e)};t.detectProjectIdentity!==void 0&&(e.detectIdentity=t.detectProjectIdentity),this.#E=createVercelStatusTracker(e),t.probeMcpConnection!==void 0&&(this.#D=createMcpConnectionStatusTracker({onChange:()=>{},probe:t.probeMcpConnection}))}if(t.promptCommandHandler!==void 0&&(this.#h=t.promptCommandHandler),this.#g=t.availablePromptCommands??PROMPT_COMMANDS,t.remote!==void 0){if(this.#t===void 0)throw Error(`A remote TUI requires a configured development client.`);this.#_=createRemoteConnectionController({client:this.#t,credentials:t.remote.credentials,target:t.remote.target,onChange:e=>this.#n.setRemoteConnectionStatus?.(e),resolveOidcToken:t.remote.resolveOidcToken,resolveDeployment:t.remote.resolveDeployment})}this.#v=t.bootDetections??BOOT_DETECTIONS,this.#y=t.getVercelAuthStatus??getVercelAuthStatus,t.onBootProgress!==void 0&&(this.#b=t.onBootProgress),t.serverUrl!==void 0&&(this.#f=t.serverUrl),t.serverUrl!==void 0&&t.remote===void 0&&(this.#d=createDevelopmentRuntimeArtifactRefresher({serverUrl:t.serverUrl}))}async#L(){if(this.#f===void 0){this.#z(),await this.#q(void 0);return}let e;if(this.#_!==void 0){let t=await this.#_.check();t.state===`ready`&&(e=t.info)}else{let t=this.#t;if(t!==void 0)try{let n=await devBootPhase(`connecting to agent`,()=>probeAgentInfo({client:t}),this.#b);n.kind===`ready`&&(e=n.info)}catch{e=void 0}}this.#z();let t=this.#R(e);await this.#q(t)}#R(e){let t=this.#p===void 0?e:resolveModelProviderState(e,process.env);this.#k=t;let n=this.#f;if(n===void 0)return t;let r={name:this.#r,serverUrl:n};return t!==void 0&&(r.info=t),this.#p!==void 0&&(r.tip=this.#O),this.#n.renderAgentHeader?.(r),t}#z(){let e=this.#b;this.#b=void 0,e?.({type:`before-first-paint`})}async run(){try{await this.#B()}finally{this.#x=!0,this.#S.abort(),this.#H(),this.#I?.(),this.#I=void 0,this.#n.shutdown?.(),this.#E?.dispose(),this.#D?.dispose(),this.#_?.dispose()}}async#B(){let e=this.#r,r,i,a=!1,o=!1,s=this.#m;await this.#L(),this.#_?.current().connection.state===`auth-required`&&await this.#re({type:`extension`,name:`vc:login`,argument:``},e,{trigger:`startup`}),this.#Z(),this.#E?.refreshIdentity(),this.#D?.refresh();let c=this.#m===void 0?void 0:parsePromptCommand(this.#m);for(c?.type===`extension`&&c.name===`model`&&c.argument===``&&this.#p!==void 0&&this.#h!==void 0&&this.#n.setupFlow!==void 0&&(s=void 0,await this.#ie(e));;){if(!o){if(r==null){if(!this.#n.readPrompt){if(a)return;throw Error(`No prompt was provided and the renderer does not support prompt input.`)}let t={title:e};s!==void 0&&(t.initialDraft=s,s=void 0);try{r=await this.#U(t)}catch(e){if(isInterruptedError(e))return;throw e}if(r==null)return}let c=parsePromptCommand(r);if(c?.type===`exit`)return;if(c?.type===`new`){this.#V(),i=void 0,o=!1,r=void 0,this.#n.reset?.();continue}if(c?.type===`help`){this.#Q(formatPromptCommandHelp(this.#g)),i=void 0,o=!1,r=void 0;continue}if(c?.type===`loglevel`){this.#Q(this.#oe(c.argument)),i=void 0,o=!1,r=void 0;continue}if(c?.type===`extension`){try{await this.#re(c,e,{trigger:`command`})}catch(e){if(isInterruptedError(e))return;throw e}i=void 0,r=void 0,o=!1;continue}a=!0}let c=await this.#W({prompt:o?void 0:r,inputResponses:i}),l=r,u=!1;try{for(;;){await this.#n.renderStream(c,{title:e,submittedPrompt:l,continueSession:!!this.#n.readPrompt,tools:this.#i,reasoning:this.#a,subagents:this.#o,connectionAuth:this.#s,assistantResponseStats:this.#c,contextSize:this.#l});let t=c.turnState?.pendingApprovals??[],n=c.turnState?.pendingQuestions??[];if(t.length>0||n.length>0){let a=[];if(t.length>0){if(!this.#n.readToolApproval)throw Error(`Tool approval was requested, but the renderer does not support tool approval input.`);for(let n of t){let t=await this.#n.readToolApproval(n,{title:e});a.push({requestId:n.approvalId,optionId:t.approved?`approve`:`deny`}),this.#A.delete(n.approvalId)}}if(n.length>0){if(!this.#n.readInputQuestion)throw Error(`An interactive question was requested, but the renderer does not support input questions.`);for(let t of n){let n=toAgentTUIInputQuestion(t),r=await this.#n.readInputQuestion(n,{title:e});if(r===void 0)continue;let i={requestId:t.requestId};r.optionId!==void 0&&(i.optionId=r.optionId),r.text!==void 0&&(i.text=r.text),a.push(i),this.#A.delete(t.requestId)}}o=!0,i=a,r=void 0,u=!0;break}if(this.#de(c)){c=this.#G(),l=void 0;continue}c.turnState&&c.turnState.boundaryEvent===void 0&&(this.#F=!0);break}}catch(e){if(isInterruptedError(e))return;throw e}u||(o=!1,i=void 0,r=void 0,this.#F&&(this.#F=!1,this.#V(),this.#n.renderNotice?.(`Session ended — started a new session. Earlier context was cleared.`)))}}#V(){this.#H(),this.#j.clear(),this.#A.clear(),this.#N.clear(),this.#P.clear(),this.#n.setConnectionAuthPendingCount?.(0),this.#t&&(this.#e=this.#t.session()),this.#d?.clear()}#H(){for(let e of this.#M.values())e.abort();this.#M.clear()}async#U(e){if(!this.#n.readPrompt)return;let t=this.#n.readPrompt(e),n=this.#d;if(n===void 0)return await t;let r=!1,i=!1,a,refresh=async()=>{if(!(r||i)){i=!0;try{await n.refreshIdle({onRuntimeArtifactsChanged:()=>this.#le()})}finally{i=!1}}},startRefresh=()=>{if(r||i)return;let e=refresh().finally(()=>{a===e&&(a=void 0)});a=e};startRefresh();let o=setInterval(()=>{startRefresh()},500);o.unref?.();try{return await t}finally{r=!0,clearInterval(o),await a}}async#W(e){let t=new AbortController,n={signal:t.signal};e.prompt!==void 0&&(n.message=e.prompt),e.inputResponses!==void 0&&e.inputResponses.length>0&&(n.inputResponses=e.inputResponses);let r;try{this.#d!==void 0&&await this.#d.refresh({inputResponses:n.inputResponses,message:n.message,onRuntimeArtifactsChanged:()=>this.#le()}),n.message!==void 0&&(n.inputResponses?.length??0)===0&&this.#n.flushDelayedDevBuildErrors?.(),r=await this.#e.send(n)}catch(e){if(isInterruptedError(e))throw e;return this.#_?.reportFailure(e),this.#F=!0,{events:errorOnlyTUIStream({errorText:this.#u(e)}),turnState:createTurnState()}}return this.#K(r,()=>t.abort())}#G(){let e=new AbortController;return this.#K(this.#e.stream({signal:e.signal}),()=>e.abort())}#K(e,t){let n=createTurnState();return{abort:t,events:eveEventsToTUIStream({events:e,pendingInputRequests:this.#A,subagentRuns:this.#j,turnState:n,onSubagentCalled:e=>this.#me(e),onSubagentCompleted:e=>this.#ge(e),onConnectionAuthRequired:e=>this.#ue(e),onConnectionAuthCompleted:e=>this.#fe(e),onTerminalFailure:()=>{this.#F=!0},failureOverride:this.#p===void 0?void 0:e=>isGatewayAuthFailure(e)?formatGatewayAuthFailureNotice(e):void 0}),turnState:n}}async#q(e){if(this.#p===void 0)return;let t={appRoot:this.#p,env:process.env};e!==void 0&&(t.info=e),this.#w=await detectSetupIssues(t,this.#v),this.#n.renderSetupWarning!==void 0&&(this.#J(),this.#Y())}#J(){let e=orderedSetupIssues(this.#w,this.#T);e.length>0?this.#n.renderSetupWarning?.(formatSetupIssuesLine(e)):this.#n.clearSetupWarning?.()}async#Y(){let e=this.#p;if(e===void 0)return;let t;try{t=await this.#y(e,{signal:this.#S.signal})}catch{return}this.#x||this.#C||(this.#T=authIssueForStatus(t),this.#J())}async#X(e){let t=this.#p;if(t===void 0||this.#n.renderSetupWarning===void 0)return;let n={appRoot:t,env:process.env};e!==void 0&&(n.info=e);try{this.#w=await detectSetupIssues(n,this.#v);let e=await this.#y(t,{signal:this.#S.signal});this.#T=authIssueForStatus(e)}catch{return}this.#x||this.#J()}#Z(){this.#p===void 0||this.#n.renderSandboxLog===void 0||this.#I===void 0&&(this.#I=subscribeDevelopmentSandboxPrewarmLogs({appRoot:this.#p,log:e=>this.#n.renderSandboxLog?.(e)}))}#Q(e){if(e!==void 0){if(this.#n.renderCommandResult!==void 0){this.#n.renderCommandResult(e);return}this.#n.renderNotice?.(e)}}async#$(e,t){let n=this.#h;if(n===void 0)return{message:`/${e.name} is not available in this session.`};let r={renderer:this.#n,title:t.title,initialModelStep:t.initialModelStep,remoteConnection:this.#_},i=this.#D?.current(),a=i!==void 0&&Object.keys(i).length>0?{...r,disabledConnectionReasons:i}:r;return t.keepSetupFlowOpen===!0?await n.handle(e,{...a,keepSetupFlowOpen:!0}):await n.handle(e,a)}#ee(e,t){if(t!==`startup`)return;let n=this.#_?.current().connection.state,r=n===`auth-failed`||n===`unavailable`?`failed`:void 0,i=e.argument.length===0?``:` ${e.argument}`;this.#n.renderCommandInvocation?.(`/${e.name}${i}`,r)}async#te(e){if(e?.kind===`connection-added`){this.#E?.applyEffect({kind:`refresh-identity`}),this.#C=!0,await this.#ne(),await this.#se();return}if(e?.kind===`model-access-changed`){this.#E?.applyEffect({kind:`refresh-identity`}),this.#C=!0,await this.#se();return}e!==void 0&&(this.#E?.applyEffect(e),this.#C=!0,this.#X(this.#k))}async#ne(){let e=this.#d;e!==void 0&&await e.refreshAfterSourceChange({onRuntimeArtifactsChanged:()=>this.#le()})}async#re(e,t,n){let r=await this.#$(e,{initialModelStep:n.initialModelStep,keepSetupFlowOpen:n.keepSetupFlowOpen,title:t});this.#ee(e,n.trigger),this.#Q(r?.message),await this.#te(r?.effect),this.#ae()}async#ie(e){let t=this.#p;if(t===void 0)return;let authStatus=async()=>{try{return await this.#y(t,{signal:this.#S.signal})}catch{return}},n=await authStatus();if(n===`cli-missing`&&(await this.#re({type:`extension`,name:`vc:install`,argument:``},e,{trigger:`startup`,keepSetupFlowOpen:!0}),n=await authStatus(),n===`cli-missing`)){this.#n.setupFlow?.end();return}if(n===`logged-out`&&(await this.#re({type:`extension`,name:`vc:login`,argument:``},e,{trigger:`startup`,keepSetupFlowOpen:!0}),n=await authStatus(),n===`cli-missing`||n===`logged-out`)){this.#n.setupFlow?.end();return}await this.#re({type:`extension`,name:`model`,argument:``},e,{trigger:`startup`,initialModelStep:`provider`})}#ae(){let e=this.#_?.current().connection;e?.state!==`ready`||e.info===this.#k||(this.#k=e.info,this.#f!==void 0&&this.#n.renderAgentHeader?.({info:e.info,name:this.#r,serverUrl:this.#f}))}#oe(e){let t=this.#n;if(t.logDisplayMode===void 0||t.setLogDisplayMode===void 0)return`/loglevel is not available in this session.`;if(e===``)return`Logs: ${t.logDisplayMode()}. Use /loglevel all|stderr|sandbox|none — logs stay buffered, so switching also hides or restores past lines.`;let n=parseLogDisplayMode(e);if(n===void 0)return`Unknown log level "${e}". Use all, stderr, sandbox, or none.`;if(n===t.logDisplayMode())return`Logs already set to ${n}.`;switch(t.setLogDisplayMode(n),n){case`none`:return`Logs hidden. Output stays buffered — /loglevel all restores it.`;case`stderr`:return`Showing stderr logs only.`;case`sandbox`:return`Showing sandbox logs only.`;case`all`:return`Showing all logs.`}}async#se(){let e=this.#p;if(e===void 0)return;loadDevelopmentEnvironmentFiles(e);let t=this.#R(await this.#ce());this.#X(t)}async#ce(){let e=this.#t;if(e===void 0)return;let t=await probeAgentInfo({client:e});return t.kind===`ready`?t.info:void 0}async#le(){let e=this.#k,t=await this.#ce();t!==void 0&&this.#R(t),(!this.#n.renderAgentHeader||t===void 0)&&this.#n.renderNotice?.(formatAgentUpdateNotice(e,t))}#ue(e){let t={name:e.data.name,description:e.data.description,state:`required`};e.data.authorization!==void 0&&(t.challenge=e.data.authorization),e.data.webhookUrl!==void 0&&(t.webhookUrl=e.data.webhookUrl),this.#N.set(e.data.name,t),this.#pe(t)}#de(e){if(e.turnState?.boundaryEvent!==`session.waiting`)return!1;let t=!1;for(let e of this.#N.values())e.state!==`required`||e.webhookUrl===void 0||(e.state=`pending`,this.#P.add(e.name),this.#pe(e),t=!0);return t&&this.#n.setConnectionAuthPendingCount?.(this.#P.size),this.#P.size>0}#fe(e){let t=this.#N.get(e.data.name)??{name:e.data.name,description:``,state:e.data.outcome};t.state=e.data.outcome,e.data.reason!==void 0&&(t.reason=e.data.reason),this.#N.set(e.data.name,t),this.#P.delete(e.data.name),this.#pe(t),this.#n.setConnectionAuthPendingCount?.(this.#P.size)}#pe(e){let t={name:e.name,description:e.description,state:e.state};e.challenge!==void 0&&(t.challenge=e.challenge),e.reason!==void 0&&(t.reason=e.reason),this.#n.upsertConnectionAuth?.(t)}#me(e){let t=e.data.callId;if(this.#M.has(t))return;let n=this.#t;if(!n)return;let r=new AbortController;this.#M.set(t,r),(async()=>{try{let i=n.session({sessionId:e.data.childSessionId,streamIndex:0}).stream({signal:r.signal});for await(let e of i)if(r.signal.aborted||(this.#_e(t,e),isCurrentTurnBoundaryEvent(e)))break}catch(e){if(!isAbortLikeError(e)){let n=toErrorMessage(e),r=this.#j.get(t);if(r){let{key:e,step:i}=openCurrentSubagentSection(r);i.message=i.message?`${i.message}\n\nstream error: ${n}`:`stream error: ${n}`,i.finalized=!0,r.currentSectionKey=null,this.#n.upsertSubagentStep?.({callId:t,subagentName:r.name,sectionKey:e,reasoning:i.reasoning,message:i.message,finalized:!0})}}}finally{this.#M.delete(t)}})()}#he(e,t,n){let r=t.tools.get(n.childCallId),i=r??{toolName:n.toolName,input:n.input,status:n.status};if(r){let e={"approval-requested":0,executing:1,done:2,failed:2};e[n.status]>e[r.status]&&(r.status=n.status),r.input=n.input}else t.tools.set(n.childCallId,i);this.#n.markChildToolCallId?.(n.childCallId),this.#n.upsertSubagentTool?.({callId:e,subagentName:t.name,childCallId:n.childCallId,toolName:i.toolName,input:i.input,status:i.status})}#ge(e){let t=this.#j.get(e);if(t){for(let[n,r]of t.steps)r.finalized||(r.finalized=!0,this.#n.upsertSubagentStep?.({callId:e,subagentName:t.name,sectionKey:n,reasoning:r.reasoning,message:r.message,finalized:!0}));t.currentSectionKey=null}}#_e(e,t){let n=this.#j.get(e);if(!n)return;let r=this.#n,emit=(t,i)=>{r.upsertSubagentStep?.({callId:e,subagentName:n.name,sectionKey:t,reasoning:i.reasoning,message:i.message,finalized:i.finalized})},finalizeCurrent=()=>{if(n.currentSectionKey===null)return;let e=n.steps.get(n.currentSectionKey);e&&(e.finalized=!0,emit(n.currentSectionKey,e)),n.currentSectionKey=null};switch(t.type){case`reasoning.appended`:{let{key:e,step:r}=openCurrentSubagentSection(n);r.reasoning+=t.data.reasoningDelta,emit(e,r);break}case`reasoning.completed`:break;case`message.appended`:{let{key:e,step:r}=openCurrentSubagentSection(n);r.message+=t.data.messageDelta,emit(e,r);break}case`message.completed`:{let{key:e,step:r}=openCurrentSubagentSection(n);t.data.message!==null&&r.message.length===0&&(r.message=t.data.message),r.finalized=!0,emit(e,r),n.currentSectionKey=null;break}case`step.completed`:finalizeCurrent();break;case`actions.requested`:finalizeCurrent();for(let r of t.data.actions)r.kind===`tool-call`&&this.#he(e,n,{childCallId:r.callId,toolName:r.toolName,input:r.input,status:`executing`});break;case`input.requested`:finalizeCurrent();for(let r of t.data.requests)r.action.kind===`tool-call`&&this.#he(e,n,{childCallId:r.action.callId,toolName:r.action.toolName,input:r.action.input,status:`approval-requested`});break;case`action.result`:{let i=t.data.result;if(i.kind!==`tool-result`)break;let a=n.tools.get(i.callId);if(!a)break;t.data.status===`failed`?(a.status=`failed`,a.errorText=formatActionResultError(t)):(a.status=`done`,a.output=i.output);let o={callId:e,subagentName:n.name,childCallId:i.callId,toolName:a.toolName,input:a.input,status:a.status};a.output!==void 0&&(o.output=a.output),a.errorText!==void 0&&(o.errorText=a.errorText),r.upsertSubagentTool?.(o);break}default:break}}};function createRenderer(e){return e.renderer?e.renderer:new TerminalRenderer({tools:e.tools,reasoning:e.reasoning,subagents:e.subagents,connectionAuth:e.connectionAuth,assistantResponseStats:e.assistantResponseStats,contextSize:e.contextSize,logs:e.logs,availablePromptCommands:e.availablePromptCommands,input:e.userInput,output:e.screen})}function formatAgentUpdateNotice(e,t){let n=e?.agent.model.id,r=t?.agent.model.id;return n!==void 0&&r!==void 0&&n!==r?`Agent updated: Model ${n} -> ${r}`:`Agent updated.`}async function*eveEventsToTUIStream(e){let{events:t,pendingInputRequests:n,subagentRuns:r,turnState:i,onSubagentCalled:a,onSubagentCompleted:o,onConnectionAuthRequired:s,onConnectionAuthCompleted:c,onTerminalFailure:l,failureOverride:u}=e,d=new Map,f=new Map,p=0,m=new Set,h=new Set,g=new Set,_=!1,v=!1,y;for await(let e of t)if(!(v&&isPostTurnVisibleEvent(e)))switch(e.type){case`session.started`:case`turn.started`:case`message.received`:break;case`step.started`:p+=1,yield{type:`step-start`};break;case`step.completed`:{let t=e;y=t.data.usage,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`step-finish`,usage:t.data.usage};break}case`message.appended`:{let t=e,n=textPartId(t.data.turnId,t.data.stepIndex),r=partStateFor(d,n),i=t.data.messageSoFar;if(r.completed){if(r.text.startsWith(i)||p<=r.completedEpoch)break;r.generation+=1,r.text=``,r.completed=!1}if(!i.startsWith(r.text)||i.length<=r.text.length)break;let a=i.slice(r.text.length);r.text=i,yield{type:`assistant-delta`,id:partGenerationId(n,r.generation),delta:a};break}case`message.completed`:{let t=textPartId(e.data.turnId,e.data.stepIndex),n=partStateFor(d,t),r=e.data.message;if(n.completed){if(r===null||r===n.text||p<=n.completedEpoch)break;n.generation+=1,n.text=r,n.completedEpoch=p,yield{type:`assistant-complete`,id:partGenerationId(t,n.generation),text:r};break}let i=partGenerationId(t,n.generation);if(r!==null){if(n.text.length===0)n.text=r,n.completed=!0,n.completedEpoch=p,yield{type:`assistant-complete`,id:i,text:r};else if(r.startsWith(n.text)){let e=r.slice(n.text.length);e.length>0&&(yield{type:`assistant-delta`,id:i,delta:e}),n.text=r,n.completed=!0,n.completedEpoch=p,yield{type:`assistant-complete`,id:i}}}else n.text.length>0&&(n.completed=!0,n.completedEpoch=p,yield{type:`assistant-complete`,id:i});break}case`reasoning.appended`:{let t=e,n=reasoningPartId(t.data.turnId,t.data.stepIndex),r=partStateFor(f,n),i=t.data.reasoningSoFar;if(r.completed){if(r.text.startsWith(i)||p<=r.completedEpoch)break;r.generation+=1,r.text=``,r.completed=!1}if(!i.startsWith(r.text)||i.length<=r.text.length)break;let a=i.slice(r.text.length);r.text=i,yield{type:`reasoning-delta`,id:partGenerationId(n,r.generation),delta:a};break}case`reasoning.completed`:{let t=reasoningPartId(e.data.turnId,e.data.stepIndex),n=partStateFor(f,t),r=e.data.reasoning;if(n.completed){if(r.length===0||r===n.text||n.text.startsWith(r)||p<=n.completedEpoch)break;n.generation+=1,n.text=r,n.completedEpoch=p;let e=partGenerationId(t,n.generation);yield{type:`reasoning-delta`,id:e,delta:r},yield{type:`reasoning-complete`,id:e};break}let i=partGenerationId(t,n.generation);if(n.text.length===0&&r.length>0)n.text=r,yield{type:`reasoning-delta`,id:i,delta:r};else if(r.length>0&&!r.startsWith(n.text))break;n.completed=!0,n.completedEpoch=p,yield{type:`reasoning-complete`,id:i};break}case`actions.requested`:{let t=e.data.actions.filter(e=>e.kind===`tool-call`);if(t.length===0)break;for(let e of t)m.has(e.callId)||(m.add(e.callId),yield{type:`tool-call`,toolCallId:e.callId,toolName:e.toolName,input:e.input});break}case`input.requested`:{let t=e.data.requests.filter(e=>e.action.kind===`tool-call`);if(t.length===0)break;for(let e of t){let t=e.action.callId;if(m.has(t)||(m.add(t),yield{type:`tool-call`,toolCallId:t,toolName:e.action.toolName,input:e.action.input}),!h.has(e.requestId)){if(h.add(e.requestId),n.set(e.requestId,e),isQuestionRequest(e)){upsertPendingQuestion(i,e);continue}upsertPendingApproval(i,e),yield{type:`tool-approval-request`,approvalId:e.requestId,toolCallId:t}}}break}case`action.result`:{let t=e;if(t.data.result.kind!==`tool-result`)break;let n=t.data.result.callId;if(!m.has(n))break;t.data.status===`failed`?yield{type:`tool-error`,toolCallId:n,errorText:formatActionResultError(t)}:yield{type:`tool-result`,toolCallId:n,output:t.data.result.output};break}case`step.failed`:case`turn.failed`:{let t=toFailureEvent(e,g,u);t&&(yield t);break}case`session.failed`:{i.sawSessionFailure=!0,l?.(e);let t=toFailureEvent(e,g,u);t&&(yield t),i.boundaryEvent=e.type,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`finish`,usage:y},_=!0;return}case`session.waiting`:case`session.completed`:i.boundaryEvent=e.type,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`finish`,usage:y},_=!0;return;case`turn.completed`:v=!0,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p);break;case`subagent.called`:{let t=e;if(!r.has(t.data.callId))r.set(t.data.callId,{name:t.data.name,steps:new Map,currentSectionKey:null,nextSectionKey:0,tools:new Map});else{let e=r.get(t.data.callId);e&&(e.name=t.data.name)}a?.(t);break}case`subagent.started`:case`subagent.event`:break;case`subagent.completed`:o?.(e.data.callId);break;case`authorization.required`:s?.(e);break;case`authorization.completed`:c?.(e);break;default:break}_||(yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`finish`,usage:y})}async function*errorOnlyTUIStream(e){yield{type:`error`,errorText:e.errorText},yield{type:`finish`}}function createTurnState(){return{pendingApprovals:[],pendingQuestions:[],sawSessionFailure:!1}}function upsertPendingApproval(e,t){let n=toAgentTUIToolApprovalRequest(t),r=e.pendingApprovals.findIndex(e=>e.approvalId===n.approvalId);r===-1?e.pendingApprovals.push(n):e.pendingApprovals[r]=n}function toAgentTUIToolApprovalRequest(e){return{approvalId:e.requestId,toolCallId:e.action.callId,toolName:e.action.toolName,input:e.action.input}}function upsertPendingQuestion(e,t){let n=e.pendingQuestions.findIndex(e=>e.requestId===t.requestId);n===-1?e.pendingQuestions.push(t):e.pendingQuestions[n]=t}function textPartId(e,t){return`text:${e}:${t}`}function reasoningPartId(e,t){return`reasoning:${e}:${t}`}function partStateFor(e,t){let n=e.get(t);return n===void 0&&(n={generation:0,text:``,completed:!1,completedEpoch:0},e.set(t,n)),n}function partGenerationId(e,t){return t===0?e:`${e}#${t}`}function*closeOpenParts(e,t,n){for(let[r,i]of e)i.completed||i.text.length===0||(i.completed=!0,i.completedEpoch=n,yield{type:t,id:partGenerationId(r,i.generation)})}function isPostTurnVisibleEvent(e){switch(e.type){case`actions.requested`:case`authorization.completed`:case`authorization.required`:case`input.requested`:case`message.appended`:case`message.completed`:case`reasoning.appended`:case`reasoning.completed`:case`result.completed`:case`step.completed`:case`step.failed`:case`step.started`:case`subagent.called`:case`subagent.completed`:case`subagent.event`:case`subagent.started`:case`turn.completed`:case`turn.failed`:return!0;default:return!1}}function formatActionResultError(e){if(e.data.error?.message)return e.data.error.message;let t=e.data.result.output;if(typeof t==`string`)return t;try{return JSON.stringify(t)}catch{return`Tool execution failed.`}}function toFailureEvent(e,t,n){let r=failureKey(e);if(t.has(r))return;t.add(r);let i=n?.(e),c={type:`error`,errorText:i??formatFailureMessage(e)};if(i!==void 0)return c;let l=formatFailureDetail(e);return l!==void 0&&(c.detail=l),c}function isQuestionRequest(e){return e.display===`select`||e.display===`text`?!0:e.display===`confirmation`?!1:e.options!==void 0&&e.options.length>0}function toAgentTUIInputQuestion(e){let t=e.display===`text`?`text`:e.display===`select`||e.options!==void 0&&e.options.length>0?`select`:`text`,n={requestId:e.requestId,prompt:e.prompt,display:t};return e.options!==void 0&&(n.options=e.options.map(e=>{let t={id:e.id,label:e.label};return e.description!==void 0&&(t.description=e.description),e.style!==void 0&&(t.style=e.style),t})),e.allowFreeform!==void 0&&(n.allowFreeform=e.allowFreeform),n}function openCurrentSubagentSection(e){e.currentSectionKey===null&&(e.currentSectionKey=e.nextSectionKey++,e.steps.set(e.currentSectionKey,{reasoning:``,message:``,finalized:!1}));let t=e.steps.get(e.currentSectionKey);if(!t)throw Error(`invariant: subagent section state missing for current key`);return{key:e.currentSectionKey,step:t}}export{EveTUIRunner,parsePromptCommand};
1
+ import{PROMPT_COMMANDS,formatPromptCommandHelp,parsePromptCommand}from"./prompt-commands.js";import{pickAgentHeaderTip}from"./agent-header.js";import{probeAgentInfo}from"./agent-info-probe.js";import{failureKey,formatFailureDetail,formatFailureHint,formatFailureMessage,isInterruptedError,localFailureHint}from"./errors.js";import{parseLogDisplayMode}from"./log-display-mode.js";import{createMcpConnectionStatusTracker}from"./mcp-connection-status.js";import{createRemoteConnectionController}from"./remote-connection.js";import{SubagentPump}from"./subagent-pump.js";import{BOOT_DETECTIONS,CLI_MISSING_SETUP_ISSUE,LOGIN_SETUP_ISSUE,detectSetupIssues,formatSetupIssuesLine,orderedSetupIssues,resolveModelProviderState}from"./setup-issues.js";import{TerminalRenderer}from"./terminal-renderer.js";import{createVercelStatusTracker}from"./vercel-status.js";import"#client/index.js";import{toErrorMessage}from"#shared/errors.js";import{getVercelAuthStatus}from"#setup/vercel-project.js";import{loadDevelopmentEnvironmentFiles}from"#cli/dev/environment.js";import{subscribeDevelopmentSandboxPrewarmLogs}from"#execution/sandbox/development-prewarm.js";import{createDevelopmentRuntimeArtifactRefresher}from"#services/dev-client.js";import{devBootPhase}from"#internal/dev-boot-progress.js";function authIssueForStatus(e){if(e===`logged-out`)return LOGIN_SETUP_ISSUE;if(e===`cli-missing`)return CLI_MISSING_SETUP_ISSUE}var EveTUIRunner=class{#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;#u;#d;#f;#p;#m;#h;#g;#_;#v;#y;#b;#x=!1;#S=new AbortController;#C=!1;#w=[];#T;#E;#D;#O=pickAgentHeaderTip();#k;#A=new Map;#j;#M=new Map;#N=new Set;#P=!1;#F;constructor(t){this.#e=t.session,t.client!==void 0&&(this.#t=t.client),this.#n=createRenderer(t);let n={formatActionResultError};if(this.#t!==void 0&&(n.client=this.#t),this.#n.subagents!==void 0&&(n.view=this.#n.subagents),this.#j=new SubagentPump(n),this.#r=t.name??`eve`,this.#i=t.tools??`full`,this.#a=t.reasoning??`full`,this.#o=t.subagents??`full`,this.#s=t.connectionAuth??`full`,this.#c=t.assistantResponseStats??`tokensPerSecond`,this.#l=t.contextSize,this.#u=t.formatTransportError??toErrorMessage,t.initialInput!==void 0&&(this.#m=t.initialInput),t.appRoot!==void 0){this.#p=t.appRoot;let e={appRoot:t.appRoot,onChange:e=>this.#n.setVercelStatus?.(e)};t.detectProjectIdentity!==void 0&&(e.detectIdentity=t.detectProjectIdentity),this.#E=createVercelStatusTracker(e),t.probeMcpConnection!==void 0&&(this.#D=createMcpConnectionStatusTracker({onChange:()=>{},probe:t.probeMcpConnection}))}if(t.promptCommandHandler!==void 0&&(this.#h=t.promptCommandHandler),this.#g=t.availablePromptCommands??PROMPT_COMMANDS,t.remote!==void 0){if(this.#t===void 0)throw Error(`A remote TUI requires a configured development client.`);this.#_=createRemoteConnectionController({client:this.#t,credentials:t.remote.credentials,target:t.remote.target,onChange:e=>this.#n.setRemoteConnectionStatus?.(e),resolveOidcToken:t.remote.resolveOidcToken,resolveDeployment:t.remote.resolveDeployment})}this.#v=t.bootDetections??BOOT_DETECTIONS,this.#y=t.getVercelAuthStatus??getVercelAuthStatus,t.onBootProgress!==void 0&&(this.#b=t.onBootProgress),t.serverUrl!==void 0&&(this.#f=t.serverUrl),t.serverUrl!==void 0&&t.remote===void 0&&(this.#d=createDevelopmentRuntimeArtifactRefresher({serverUrl:t.serverUrl}))}async#I(){if(this.#f===void 0){this.#R(),await this.#G(void 0);return}let e;if(this.#_!==void 0){let t=await this.#_.check();t.state===`ready`&&(e=t.info)}else{let t=this.#t;if(t!==void 0)try{let n=await devBootPhase(`connecting to agent`,()=>probeAgentInfo({client:t}),this.#b);n.kind===`ready`&&(e=n.info)}catch{e=void 0}}this.#R();let t=this.#L(e);await this.#G(t)}#L(e){let t=this.#p===void 0?e:resolveModelProviderState(e,process.env);this.#k=t;let n=this.#f;if(n===void 0)return t;let r={name:this.#r,serverUrl:n};return t!==void 0&&(r.info=t),this.#p!==void 0&&(r.tip=this.#O),this.#n.renderAgentHeader?.(r),t}#R(){let e=this.#b;this.#b=void 0,e?.({type:`before-first-paint`})}async run(){try{await this.#z()}finally{this.#x=!0,this.#S.abort(),this.#j.abortAll(),this.#F?.(),this.#F=void 0,this.#n.shutdown?.(),this.#E?.dispose(),this.#D?.dispose(),this.#_?.dispose()}}async#z(){let e=this.#r,r,i,a=!1,o=!1,s=this.#m;await this.#I(),this.#_?.current().connection.state===`auth-required`&&await this.#te({type:`extension`,name:`vc:login`,argument:``},e,{trigger:`startup`}),this.#Y(),this.#E?.refreshIdentity(),this.#D?.refresh();let c=this.#m===void 0?void 0:parsePromptCommand(this.#m);for(c?.type===`extension`&&c.name===`model`&&c.argument===``&&this.#p!==void 0&&this.#h!==void 0&&this.#n.setupFlow!==void 0&&(s=void 0,await this.#ne(e));;){if(!o){if(r==null){if(!this.#n.readPrompt){if(a)return;throw Error(`No prompt was provided and the renderer does not support prompt input.`)}let t={title:e};s!==void 0&&(t.initialDraft=s,s=void 0);try{r=await this.#V(t)}catch(e){if(isInterruptedError(e))return;throw e}if(r==null)return}let c=parsePromptCommand(r);if(c?.type===`exit`)return;if(c?.type===`new`){this.#B(),i=void 0,o=!1,r=void 0,this.#n.reset?.();continue}if(c?.type===`help`){this.#X(formatPromptCommandHelp(this.#g)),i=void 0,o=!1,r=void 0;continue}if(c?.type===`loglevel`){this.#X(this.#ie(c.argument)),i=void 0,o=!1,r=void 0;continue}if(c?.type===`extension`){try{await this.#te(c,e,{trigger:`command`})}catch(e){if(isInterruptedError(e))return;throw e}i=void 0,r=void 0,o=!1;continue}a=!0}let c=await this.#H({prompt:o?void 0:r,inputResponses:i}),u=r,d=!1;try{for(;;){await this.#n.renderStream(c,{title:e,submittedPrompt:u,continueSession:!!this.#n.readPrompt,tools:this.#i,reasoning:this.#a,subagents:this.#o,connectionAuth:this.#s,assistantResponseStats:this.#c,contextSize:this.#l});let t=c.turnState?.pendingApprovals??[],n=c.turnState?.pendingQuestions??[];if(t.length>0||n.length>0){let a=[];if(t.length>0){if(!this.#n.readToolApproval)throw Error(`Tool approval was requested, but the renderer does not support tool approval input.`);for(let n of t){let t=await this.#n.readToolApproval(n,{title:e});a.push({requestId:n.approvalId,optionId:t.approved?`approve`:`deny`}),this.#A.delete(n.approvalId)}}if(n.length>0){if(!this.#n.readInputQuestion)throw Error(`An interactive question was requested, but the renderer does not support input questions.`);for(let t of n){let n=toAgentTUIInputQuestion(t),r=await this.#n.readInputQuestion(n,{title:e});if(r===void 0)continue;let i={requestId:t.requestId};r.optionId!==void 0&&(i.optionId=r.optionId),r.text!==void 0&&(i.text=r.text),a.push(i),this.#A.delete(t.requestId)}}if(a.length===0)break;o=!0,i=a,r=void 0,d=!0;break}if(this.#le(c)){c=this.#U(),u=void 0;continue}if(c.turnState&&c.turnState.boundaryEvent===void 0)if(c.turnState.aborted)this.#P=!0;else{let e=this.#e.state.sessionId;this.#n.renderNotice?.(e?`Lost the event stream — the turn may still be running on the server (session ${e}). Your next message resumes this session; use /cancel to stop the turn.`:`Lost the connection to the running turn.`)}break}}catch(e){if(isInterruptedError(e))return;throw e}d||(o=!1,i=void 0,r=void 0,this.#P&&(this.#P=!1,this.#B(),c.turnState?.aborted?this.#n.renderNotice?.(`Stopped following the turn and started a new session. Earlier context was cleared; the interrupted turn may still be running on the server.`):this.#n.renderSessionBoundary===void 0?this.#n.renderNotice?.(`Session ended — started a new session. Earlier context was cleared.`):this.#n.renderSessionBoundary()))}}#B(){this.#j.abortAll(),this.#A.clear(),this.#M.clear(),this.#N.clear(),this.#n.setConnectionAuthPendingCount?.(0),this.#t&&(this.#e=this.#t.session()),this.#d?.clear()}async#V(e){if(!this.#n.readPrompt)return;let t=this.#n.readPrompt(e),n=this.#d;if(n===void 0)return await t;let r=!1,i=!1,a,refresh=async()=>{if(!(r||i)){i=!0;try{await n.refreshIdle({onRuntimeArtifactsChanged:()=>this.#se()})}finally{i=!1}}},startRefresh=()=>{if(r||i)return;let e=refresh().finally(()=>{a===e&&(a=void 0)});a=e};startRefresh();let o=setInterval(()=>{startRefresh()},500);o.unref?.();try{return await t}finally{r=!0,clearInterval(o),await a}}async#H(e){let t=new AbortController,n={signal:t.signal};e.prompt!==void 0&&(n.message=e.prompt),e.inputResponses!==void 0&&e.inputResponses.length>0&&(n.inputResponses=e.inputResponses);let r;try{this.#d!==void 0&&await this.#d.refresh({inputResponses:n.inputResponses,message:n.message,onRuntimeArtifactsChanged:()=>this.#se()}),n.message!==void 0&&(n.inputResponses?.length??0)===0&&this.#n.flushDelayedDevBuildErrors?.(),r=await this.#e.send(n)}catch(e){if(isInterruptedError(e))throw e;return this.#_?.reportFailure(e),this.#P=!0,{events:errorOnlyTUIStream({errorText:this.#u(e)}),turnState:createTurnState()}}return this.#W(r,()=>t.abort())}#U(){let e=new AbortController;return this.#W(this.#e.stream({signal:e.signal}),()=>e.abort())}#W(e,t){let n=createTurnState();return{abort:()=>{n.aborted=!0,t()},events:eveEventsToTUIStream({events:e,pendingInputRequests:this.#A,turnState:n,onSubagentCalled:e=>this.#j.begin(e),onSubagentCompleted:e=>this.#j.settle(e),onConnectionAuthRequired:e=>this.#ce(e),onConnectionAuthCompleted:e=>this.#ue(e),onTerminalFailure:()=>{this.#P=!0},failureHintOverride:this.#p===void 0?void 0:localFailureHint}),turnState:n}}async#G(e){if(this.#p===void 0)return;let t={appRoot:this.#p,env:process.env};e!==void 0&&(t.info=e),this.#w=await detectSetupIssues(t,this.#v),this.#n.renderSetupWarning!==void 0&&(this.#K(),this.#q())}#K(){let e=orderedSetupIssues(this.#w,this.#T);e.length>0?this.#n.renderSetupWarning?.(formatSetupIssuesLine(e)):this.#n.clearSetupWarning?.()}async#q(){let e=this.#p;if(e===void 0)return;let t;try{t=await this.#y(e,{signal:this.#S.signal})}catch{return}this.#x||this.#C||(this.#T=authIssueForStatus(t),this.#K())}async#J(e){let t=this.#p;if(t===void 0||this.#n.renderSetupWarning===void 0)return;let n={appRoot:t,env:process.env};e!==void 0&&(n.info=e);try{this.#w=await detectSetupIssues(n,this.#v);let e=await this.#y(t,{signal:this.#S.signal});this.#T=authIssueForStatus(e)}catch{return}this.#x||this.#K()}#Y(){this.#p===void 0||this.#n.renderSandboxLog===void 0||this.#F===void 0&&(this.#F=subscribeDevelopmentSandboxPrewarmLogs({appRoot:this.#p,log:e=>this.#n.renderSandboxLog?.(e)}))}#X(e){if(e!==void 0){if(this.#n.renderCommandResult!==void 0){this.#n.renderCommandResult(e);return}this.#n.renderNotice?.(e)}}async#Z(e,t){let n=this.#h;if(n===void 0)return{message:`/${e.name} is not available in this session.`};let r={renderer:this.#n,title:t.title,initialModelStep:t.initialModelStep,remoteConnection:this.#_},i=this.#D?.current(),a=i!==void 0&&Object.keys(i).length>0?{...r,disabledConnectionReasons:i}:r;return t.keepSetupFlowOpen===!0?await n.handle(e,{...a,keepSetupFlowOpen:!0}):await n.handle(e,a)}#Q(e,t){if(t!==`startup`)return;let n=this.#_?.current().connection.state,r=n===`auth-failed`||n===`unavailable`?`failed`:void 0,i=e.argument.length===0?``:` ${e.argument}`;this.#n.renderCommandInvocation?.(`/${e.name}${i}`,r)}async#$(e){if(e?.kind===`connection-added`){this.#E?.applyEffect({kind:`refresh-identity`}),this.#C=!0,await this.#ee(),await this.#ae();return}if(e?.kind===`model-access-changed`){this.#E?.applyEffect({kind:`refresh-identity`}),this.#C=!0,await this.#ae();return}e!==void 0&&(this.#E?.applyEffect(e),this.#C=!0,this.#J(this.#k))}async#ee(){let e=this.#d;e!==void 0&&await e.refreshAfterSourceChange({onRuntimeArtifactsChanged:()=>this.#se()})}async#te(e,t,n){let r=await this.#Z(e,{initialModelStep:n.initialModelStep,keepSetupFlowOpen:n.keepSetupFlowOpen,title:t});this.#Q(e,n.trigger),this.#X(r?.message),await this.#$(r?.effect),this.#re()}async#ne(e){let t=this.#p;if(t===void 0)return;let authStatus=async()=>{try{return await this.#y(t,{signal:this.#S.signal})}catch{return}},n=await authStatus();if(n===`cli-missing`&&(await this.#te({type:`extension`,name:`vc:install`,argument:``},e,{trigger:`startup`,keepSetupFlowOpen:!0}),n=await authStatus(),n===`cli-missing`)){this.#n.setupFlow?.end();return}if(n===`logged-out`&&(await this.#te({type:`extension`,name:`vc:login`,argument:``},e,{trigger:`startup`,keepSetupFlowOpen:!0}),n=await authStatus(),n===`cli-missing`||n===`logged-out`)){this.#n.setupFlow?.end();return}await this.#te({type:`extension`,name:`model`,argument:``},e,{trigger:`startup`,initialModelStep:`provider`})}#re(){let e=this.#_?.current().connection;e?.state!==`ready`||e.info===this.#k||(this.#k=e.info,this.#f!==void 0&&this.#n.renderAgentHeader?.({info:e.info,name:this.#r,serverUrl:this.#f}))}#ie(e){let t=this.#n;if(t.logDisplayMode===void 0||t.setLogDisplayMode===void 0)return`/loglevel is not available in this session.`;if(e===``)return`Logs: ${t.logDisplayMode()}. Use /loglevel all|stderr|sandbox|none — logs stay buffered, so switching also hides or restores past lines.`;let n=parseLogDisplayMode(e);if(n===void 0)return`Unknown log level "${e}". Use all, stderr, sandbox, or none.`;if(n===t.logDisplayMode())return`Logs already set to ${n}.`;switch(t.setLogDisplayMode(n),n){case`none`:return`Logs hidden. Output stays buffered — /loglevel all restores it.`;case`stderr`:return`Showing stderr logs only.`;case`sandbox`:return`Showing sandbox logs only.`;case`all`:return`Showing all logs.`}}async#ae(){let e=this.#p;if(e===void 0)return;loadDevelopmentEnvironmentFiles(e);let t=this.#L(await this.#oe());this.#J(t)}async#oe(){let e=this.#t;if(e===void 0)return;let t=await probeAgentInfo({client:e});return t.kind===`ready`?t.info:void 0}async#se(){let e=this.#k,t=await this.#oe();t!==void 0&&this.#L(t),(!this.#n.renderAgentHeader||t===void 0)&&this.#n.renderNotice?.(formatAgentUpdateNotice(e,t))}#ce(e){let t={name:e.data.name,description:e.data.description,state:`required`};e.data.authorization!==void 0&&(t.challenge=e.data.authorization),e.data.webhookUrl!==void 0&&(t.webhookUrl=e.data.webhookUrl),this.#M.set(e.data.name,t),this.#de(t)}#le(e){if(e.turnState?.boundaryEvent!==`session.waiting`)return!1;let t=!1;for(let e of this.#M.values())e.state!==`required`||e.webhookUrl===void 0||(e.state=`pending`,this.#N.add(e.name),this.#de(e),t=!0);return t&&this.#n.setConnectionAuthPendingCount?.(this.#N.size),this.#N.size>0}#ue(e){let t=this.#M.get(e.data.name)??{name:e.data.name,description:``,state:e.data.outcome};t.state=e.data.outcome,e.data.reason!==void 0&&(t.reason=e.data.reason),this.#M.set(e.data.name,t),this.#N.delete(e.data.name),this.#de(t),this.#n.setConnectionAuthPendingCount?.(this.#N.size)}#de(e){let t={name:e.name,description:e.description,state:e.state};e.challenge!==void 0&&(t.challenge=e.challenge),e.reason!==void 0&&(t.reason=e.reason),this.#n.upsertConnectionAuth?.(t)}};function createRenderer(e){return e.renderer?e.renderer:new TerminalRenderer({tools:e.tools,reasoning:e.reasoning,subagents:e.subagents,connectionAuth:e.connectionAuth,assistantResponseStats:e.assistantResponseStats,contextSize:e.contextSize,logs:e.logs,availablePromptCommands:e.availablePromptCommands,input:e.userInput,output:e.screen,diagnostics:e.diagnostics})}function formatAgentUpdateNotice(e,t){let n=e?.agent.model.id,r=t?.agent.model.id;return n!==void 0&&r!==void 0&&n!==r?`Agent updated: Model ${n} -> ${r}`:`Agent updated.`}async function*eveEventsToTUIStream(e){let{events:t,pendingInputRequests:n,turnState:r,onSubagentCalled:i,onSubagentCompleted:a,onConnectionAuthRequired:o,onConnectionAuthCompleted:s,onTerminalFailure:c,failureHintOverride:l}=e,u=new Map,d=new Map,f=0,p=new Set,m=new Set,h=new Set,g=!1,_=!1,v;for await(let e of t)if(!(_&&isPostTurnVisibleEvent(e)))switch(e.type){case`session.started`:case`turn.started`:case`message.received`:break;case`step.started`:f+=1,yield{type:`step-start`};break;case`step.completed`:{let t=e;v=t.data.usage,yield*closeOpenParts(u,`assistant-complete`,f),yield*closeOpenParts(d,`reasoning-complete`,f),yield{type:`step-finish`,usage:t.data.usage};break}case`message.appended`:{let t=e,n=textPartId(t.data.turnId,t.data.stepIndex),r=partStateFor(u,n),i=t.data.messageSoFar;if(r.completed){if(r.text.startsWith(i)||f<=r.completedEpoch)break;r.generation+=1,r.text=``,r.completed=!1}if(!i.startsWith(r.text)||i.length<=r.text.length)break;let a=i.slice(r.text.length);r.text=i,yield{type:`assistant-delta`,id:partGenerationId(n,r.generation),delta:a};break}case`message.completed`:{let t=textPartId(e.data.turnId,e.data.stepIndex),n=partStateFor(u,t),r=e.data.message;if(n.completed){if(r===null||r===n.text||f<=n.completedEpoch)break;n.generation+=1,n.text=r,n.completedEpoch=f,yield{type:`assistant-complete`,id:partGenerationId(t,n.generation),text:r};break}let i=partGenerationId(t,n.generation);if(r!==null){if(n.text.length===0)n.text=r,n.completed=!0,n.completedEpoch=f,yield{type:`assistant-complete`,id:i,text:r};else if(r.startsWith(n.text)){let e=r.slice(n.text.length);e.length>0&&(yield{type:`assistant-delta`,id:i,delta:e}),n.text=r,n.completed=!0,n.completedEpoch=f,yield{type:`assistant-complete`,id:i}}}else n.text.length>0&&(n.completed=!0,n.completedEpoch=f,yield{type:`assistant-complete`,id:i});break}case`reasoning.appended`:{let t=e,n=reasoningPartId(t.data.turnId,t.data.stepIndex),r=partStateFor(d,n),i=t.data.reasoningSoFar;if(r.completed){if(r.text.startsWith(i)||f<=r.completedEpoch)break;r.generation+=1,r.text=``,r.completed=!1}if(!i.startsWith(r.text)||i.length<=r.text.length)break;let a=i.slice(r.text.length);r.text=i,yield{type:`reasoning-delta`,id:partGenerationId(n,r.generation),delta:a};break}case`reasoning.completed`:{let t=reasoningPartId(e.data.turnId,e.data.stepIndex),n=partStateFor(d,t),r=e.data.reasoning;if(n.completed){if(r.length===0||r===n.text||n.text.startsWith(r)||f<=n.completedEpoch)break;n.generation+=1,n.text=r,n.completedEpoch=f;let e=partGenerationId(t,n.generation);yield{type:`reasoning-delta`,id:e,delta:r},yield{type:`reasoning-complete`,id:e};break}let i=partGenerationId(t,n.generation);if(n.text.length===0&&r.length>0)n.text=r,yield{type:`reasoning-delta`,id:i,delta:r};else if(r.length>0&&!r.startsWith(n.text))break;n.completed=!0,n.completedEpoch=f,yield{type:`reasoning-complete`,id:i};break}case`actions.requested`:{let t=e.data.actions.filter(e=>e.kind===`tool-call`);if(t.length===0)break;for(let e of t)p.has(e.callId)||(p.add(e.callId),yield{type:`tool-call`,toolCallId:e.callId,toolName:e.toolName,input:e.input});break}case`input.requested`:{let t=e.data.requests.filter(e=>e.action.kind===`tool-call`);if(t.length===0)break;for(let e of t){let t=e.action.callId;if(p.has(t)||(p.add(t),yield{type:`tool-call`,toolCallId:t,toolName:e.action.toolName,input:e.action.input}),!m.has(e.requestId)){if(m.add(e.requestId),n.set(e.requestId,e),isQuestionRequest(e)){upsertPendingQuestion(r,e);continue}upsertPendingApproval(r,e),yield{type:`tool-approval-request`,approvalId:e.requestId,toolCallId:t}}}break}case`action.result`:{let t=e;if(t.data.result.kind!==`tool-result`)break;let n=t.data.result.callId;if(!p.has(n))break;switch(t.data.status){case`completed`:yield{type:`tool-result`,toolCallId:n,output:t.data.result.output};break;case`failed`:yield{type:`tool-error`,toolCallId:n,errorText:formatActionResultError(t)};break;case`rejected`:yield{type:`tool-rejected`,toolCallId:n,reason:formatActionResultError(t)};break}break}case`step.failed`:case`turn.failed`:{let t=toFailureEvent(e,h,l);t&&(yield t);break}case`session.failed`:{r.sawSessionFailure=!0,c?.(e);let t=toFailureEvent(e,h,l);t&&(yield t),r.boundaryEvent=e.type,yield*closeOpenParts(u,`assistant-complete`,f),yield*closeOpenParts(d,`reasoning-complete`,f),yield{type:`finish`,usage:v},g=!0;return}case`session.waiting`:case`session.completed`:r.boundaryEvent=e.type,yield*closeOpenParts(u,`assistant-complete`,f),yield*closeOpenParts(d,`reasoning-complete`,f),yield{type:`finish`,usage:v},g=!0;return;case`turn.completed`:_=!0,yield*closeOpenParts(u,`assistant-complete`,f),yield*closeOpenParts(d,`reasoning-complete`,f);break;case`subagent.called`:i?.(e);break;case`subagent.started`:case`subagent.event`:break;case`subagent.completed`:a?.(e.data.callId);break;case`authorization.required`:o?.(e);break;case`authorization.completed`:s?.(e);break;default:break}g||(yield*closeOpenParts(u,`assistant-complete`,f),yield*closeOpenParts(d,`reasoning-complete`,f),yield{type:`finish`,usage:v})}async function*errorOnlyTUIStream(e){yield{type:`error`,errorText:e.errorText},yield{type:`finish`}}function createTurnState(){return{aborted:!1,pendingApprovals:[],pendingQuestions:[],sawSessionFailure:!1}}function upsertPendingApproval(e,t){let n=toAgentTUIToolApprovalRequest(t),r=e.pendingApprovals.findIndex(e=>e.approvalId===n.approvalId);r===-1?e.pendingApprovals.push(n):e.pendingApprovals[r]=n}function toAgentTUIToolApprovalRequest(e){return{approvalId:e.requestId,toolCallId:e.action.callId,toolName:e.action.toolName,input:e.action.input}}function upsertPendingQuestion(e,t){let n=e.pendingQuestions.findIndex(e=>e.requestId===t.requestId);n===-1?e.pendingQuestions.push(t):e.pendingQuestions[n]=t}function textPartId(e,t){return`text:${e}:${t}`}function reasoningPartId(e,t){return`reasoning:${e}:${t}`}function partStateFor(e,t){let n=e.get(t);return n===void 0&&(n={generation:0,text:``,completed:!1,completedEpoch:0},e.set(t,n)),n}function partGenerationId(e,t){return t===0?e:`${e}#${t}`}function*closeOpenParts(e,t,n){for(let[r,i]of e)i.completed||i.text.length===0||(i.completed=!0,i.completedEpoch=n,yield{type:t,id:partGenerationId(r,i.generation)})}function isPostTurnVisibleEvent(e){switch(e.type){case`actions.requested`:case`authorization.completed`:case`authorization.required`:case`input.requested`:case`message.appended`:case`message.completed`:case`reasoning.appended`:case`reasoning.completed`:case`result.completed`:case`step.completed`:case`step.failed`:case`step.started`:case`subagent.called`:case`subagent.completed`:case`subagent.event`:case`subagent.started`:case`turn.completed`:case`turn.failed`:return!0;default:return!1}}function formatActionResultError(e){if(e.data.error?.message)return e.data.error.message;let t=e.data.result.output;if(typeof t==`string`)return t;try{return JSON.stringify(t)}catch{return`Tool execution failed.`}}function toFailureEvent(e,t,n){let r=failureKey(e);if(t.has(r))return;t.add(r);let i={type:`error`,errorText:formatFailureMessage(e)},l=n?.(e)??formatFailureHint(e);l!==void 0&&(i.hint=l);let u=formatFailureDetail(e);return u!==void 0&&(i.detail=u),i}function isQuestionRequest(e){return e.display===`select`||e.display===`text`?!0:e.display===`confirmation`?!1:e.options!==void 0&&e.options.length>0}function toAgentTUIInputQuestion(e){let t=e.display===`text`?`text`:e.display===`select`||e.options!==void 0&&e.options.length>0?`select`:`text`,n={requestId:e.requestId,prompt:e.prompt,display:t};return e.options!==void 0&&(n.options=e.options.map(e=>{let t={id:e.id,label:e.label};return e.description!==void 0&&(t.description=e.description),e.style!==void 0&&(t.style=e.style),t})),e.allowFreeform!==void 0&&(n.allowFreeform=e.allowFreeform),n}export{EveTUIRunner,parsePromptCommand};
@@ -42,7 +42,7 @@ export declare const SETUP_FLOW_CONFIG: {
42
42
  };
43
43
  };
44
44
  /** The prompter surface plus the working-state interrupt trap a command races against. */
45
- export type TuiSetupCommandRenderer = TuiPrompterRenderer & Pick<SetupFlowRenderer, "readProviderPicker" | "waitForInterrupt">;
45
+ export type TuiSetupCommandRenderer = TuiPrompterRenderer & Pick<SetupFlowRenderer, "readProviderPicker" | "readModelEditor" | "waitForInterrupt">;
46
46
  export interface TuiSetupCommandInput {
47
47
  command: TuiSetupCommand;
48
48
  /** The local project the in-process dev server is running. */
@@ -1,2 +1,2 @@
1
- import{createTuiPrompter}from"./tui-prompter.js";import{runDeployFlow}from"#setup/flows/deploy.js";import{WizardCancelledError}from"#setup/step.js";import{runLoginFlow}from"#setup/flows/login.js";import{HumanActionRequiredError}from"#setup/human-action.js";import{runChannelsFlow}from"#setup/flows/channels.js";import{runConnectionsFlow}from"#setup/flows/connections.js";import{runInstallVercelCliFlow}from"#setup/flows/install-vercel-cli.js";import{runModelFlow}from"#setup/flows/model.js";import{runProviderFlow}from"#setup/flows/provider.js";import{openUrl}from"#setup/primitives/open-url.js";import{slackMessageDeepLink}from"#setup/slack-connect.js";const SETUP_FLOW_CONFIG={"vc:install":{title:`Install the Vercel CLI`,indicator:`pulse`},"vc:login":{title:`Log in to Vercel`,indicator:`pulse`},model:{title:`Configure the agent model`,indicator:`pulse`},channels:{title:`Agent channels`,indicator:`pulse`},connect:{title:`Agent connections`,indicator:`pulse`},deploy:{title:`Deploy to Vercel`,indicator:`spinner`}};function muteableRenderer(e,t){return{readSelect:n=>t()?Promise.resolve(void 0):e.readSelect(n),readEditableSelect:n=>t()?Promise.resolve(void 0):e.readEditableSelect(n),readProviderPicker:n=>t()?Promise.resolve(void 0):e.readProviderPicker(n),readText:n=>t()?Promise.resolve(void 0):e.readText(n),readAcknowledge:n=>t()?Promise.resolve():e.readAcknowledge(n),readChoice:n=>t()?{choice:Promise.resolve(void 0),close:()=>{}}:e.readChoice(n),setStatus:n=>{t()||e.setStatus(n)},renderLine:(n,r)=>{(!t()||r===`warning`||r===`error`)&&e.renderLine(n,r)},renderOutput:n=>{t()||e.renderOutput(n)}}}async function runTuiSetupCommand(t){let{command:r}=t,i=!1,a=new AbortController,o=muteableRenderer(t.renderer,()=>i),s=(t.createPrompter??createTuiPrompter)(o),c=t.renderer.waitForInterrupt(),l=Symbol(`interrupted`),u=executeSetupCommand(t,s,o,a.signal);try{let e=await Promise.race([u,c.promise.then(()=>l)]);return e===l?(i=!0,a.abort(new WizardCancelledError),{...await u,message:`/${r} interrupted.`,preserveFlowDiagnostics:!0}):e}finally{c.dispose(),t.renderer.setStatus(void 0)}}async function executeSetupCommand(e,i,u,d){let{command:f,appRoot:p}=e,m={runInstallVercelCliFlow,runLoginFlow,runModelFlow,runChannelsFlow,runConnectionsFlow,runDeployFlow,...e.flows};try{switch(f){case`vc:install`:return installVercelCliResultMessage(await m.runInstallVercelCliFlow({appRoot:p,prompter:i,signal:d}));case`vc:login`:return loginResultMessage(await m.runLoginFlow({appRoot:p,prompter:i,signal:d}));case`model`:{let pickProvider=e=>u.readProviderPicker(e),t={appRoot:p,prompter:i,signal:d,deps:{runProviderFlow:e=>runProviderFlow({...e,picker:pickProvider})}};e.initialModelStep!==void 0&&(t.initialStep=e.initialModelStep);let n=await m.runModelFlow(t);if(n.kind===`cancelled`)return{message:`/model cancelled.`,preserveFlowDiagnostics:!1};let r=[];n.modelMessage!==void 0&&r.push(n.modelMessage),n.providerOutcome!==void 0&&r.push(providerOutcomeMessage(n.providerOutcome));let a={message:r.join(`
2
- `),preserveFlowDiagnostics:!1};return n.providerOutcome!==void 0&&(a.effect={kind:`model-access-changed`}),a}case`channels`:{let e=await m.runChannelsFlow({appRoot:p,prompter:i,signal:d});switch(e.kind){case`failed`:return pendingChannelsResult(`Channel files changed, but /channels failed: ${e.message}`);case`cancelled`:return{message:`/channels cancelled.`,preserveFlowDiagnostics:!0};case`deploy-and-chat`:return await runDeployAndChat(m,{appRoot:p,prompter:i,signal:d},e.chat);case`done`:return e.addedChannels.length===0?{message:`No channels added.`,preserveFlowDiagnostics:!0}:{message:`Channels added: ${e.addedChannels.join(`, `)} — run /deploy to ship them.`,preserveFlowDiagnostics:!0,effect:{kind:`channels-added`}}}}case`connect`:{let t=await m.runConnectionsFlow({appRoot:p,prompter:i,signal:d,disabledConnectionReasons:e.disabledConnectionReasons});switch(t.kind){case`cancelled`:return{message:`/connect cancelled.`,preserveFlowDiagnostics:!0,effect:{kind:`model-access-changed`}};case`failed`:return{message:t.addedConnections.length===0?`/connect failed: ${t.message}`:`Connection files changed, but /connect failed: ${t.message}`,preserveFlowDiagnostics:!0,effect:t.addedConnections.length===0?{kind:`model-access-changed`}:{kind:`connection-added`}};case`done`:return{message:t.addedConnections.length===0?`No connections added.`:`Connections added: ${t.addedConnections.join(`, `)}.`,preserveFlowDiagnostics:!0,effect:t.addedConnections.length===0?{kind:`model-access-changed`}:{kind:`connection-added`}}}}case`deploy`:{let e=await m.runDeployFlow({appRoot:p,prompter:i,interactive:!0,signal:d});return e.kind===`cancelled`?{message:`/deploy cancelled.`,preserveFlowDiagnostics:!0}:e.kind===`needs-link`?{message:`Not linked to a Vercel project — run /model to connect one first.`,preserveFlowDiagnostics:!0}:{message:e.productionUrl===void 0?`Deployed.`:`Deployed: ${e.productionUrl}`,preserveFlowDiagnostics:!0,effect:{kind:`deployed`}}}}}catch(e){if(e instanceof WizardCancelledError)return{message:`/${f} cancelled.`,preserveFlowDiagnostics:f!==`model`};let t=vercelActionOutcome(e,f);return t===void 0?{message:`/${f} failed: ${e instanceof Error?e.message:String(e)}`,preserveFlowDiagnostics:!0}:t}}function vercelActionOutcome(e,t){if(!(e instanceof HumanActionRequiredError))return;let n=vercelActionMessage(e.action.kind,t);return n===void 0?void 0:{message:n,preserveFlowDiagnostics:!0}}function vercelActionMessage(e,t){switch(e){case`vercel-login`:return`You're not logged in to Vercel — run /vc:login, then retry /${t}.`;case`vercel-forbidden`:return`Vercel denied access to that team — run /vc:login to re-authenticate (for example to complete SSO), or pick a team you can access, then retry /${t}.`;case`vercel-cli-missing`:return`The Vercel CLI isn't installed — run /vc:install to install it, then retry /${t}.`;default:return}}async function runDeployAndChat(e,t,r){let i;try{i=await e.runDeployFlow({...t,interactive:!0})}catch(e){if(e instanceof WizardCancelledError)return pendingChannelsResult(`Channels added, but /deploy was cancelled. Run /deploy to ship them.`);let t=vercelActionOutcome(e,`deploy`);return pendingChannelsResult(t===void 0?`Channels added, but /deploy failed: ${e instanceof Error?e.message:String(e)}`:`Channels added. ${t.message}`)}if(i.kind===`cancelled`)return pendingChannelsResult(`Channels added, but /deploy was cancelled. Run /deploy to ship them.`);if(i.kind===`needs-link`)return pendingChannelsResult(`Channels added, but this directory is not linked to Vercel. Run /model, then /deploy.`);let a=i.productionUrl===void 0?`Deployed.`:`Deployed: ${i.productionUrl}`,o;if(r.chatUrl===void 0)o=`Message your agent in Slack to see it live.`;else{let e=slackMessageDeepLink(r.chatUrl);openUrl(e),o=`Chat with your agent in Slack: ${e}`}return{message:`${a}\n${o}`,preserveFlowDiagnostics:!0,effect:{kind:`deployed`}}}function installVercelCliResultMessage(e){switch(e.kind){case`cancelled`:return{message:`/vc:install cancelled.`,preserveFlowDiagnostics:!1};case`already`:return{message:`The Vercel CLI is already installed.`,preserveFlowDiagnostics:!1};case`failed`:return{message:"Couldn't install the Vercel CLI — install it manually with `npm i -g vercel@latest`.",preserveFlowDiagnostics:!0};case`installed`:return{message:`Installed the Vercel CLI. Run /vc:login next.`,preserveFlowDiagnostics:!1,effect:{kind:`refresh-identity`}}}}function loginResultMessage(e){switch(e.kind){case`cancelled`:return{message:`/vc:login cancelled.`,preserveFlowDiagnostics:!1};case`already`:return{message:`You're already logged in to Vercel.`,preserveFlowDiagnostics:!1};case`cli-missing`:return{message:`The Vercel CLI isn't installed — run /vc:install to install it, then retry /vc:login.`,preserveFlowDiagnostics:!0};case`failed`:return{message:`Vercel login didn't complete — run /vc:login to try again.`,preserveFlowDiagnostics:!0};case`logged-in`:return{message:`Logged in to Vercel.`,preserveFlowDiagnostics:!1,effect:{kind:`refresh-identity`}};case`unavailable`:return{message:`Couldn't reach Vercel — check your connection, then retry /vc:login.`,preserveFlowDiagnostics:!0}}}function pendingChannelsResult(e){return{message:e,preserveFlowDiagnostics:!0,effect:{kind:`channels-added`}}}function providerOutcomeMessage(e){let{credential:t,status:n}=e;return n.kind===`gateway-project`?t===void 0?`Project linked. No model credential found; set AI_GATEWAY_API_KEY in .env.local.`:`Project linked. Connected to AI Gateway via ${t}.`:n.kind===`gateway-key`?`Connected to AI Gateway via ${n.envKey} in ${n.envFile}.`:`Provider updated — no gateway credential detected; set AI_GATEWAY_API_KEY in .env.local.`}export{SETUP_FLOW_CONFIG,runTuiSetupCommand};
1
+ import{createTuiPrompter}from"./tui-prompter.js";import{runDeployFlow}from"#setup/flows/deploy.js";import{WizardCancelledError}from"#setup/step.js";import{runLoginFlow}from"#setup/flows/login.js";import{HumanActionRequiredError}from"#setup/human-action.js";import{runChannelsFlow}from"#setup/flows/channels.js";import{runConnectionsFlow}from"#setup/flows/connections.js";import{runInstallVercelCliFlow}from"#setup/flows/install-vercel-cli.js";import{runModelFlow}from"#setup/flows/model.js";import{runProviderFlow}from"#setup/flows/provider.js";import{openUrl}from"#setup/primitives/open-url.js";import{slackMessageDeepLink}from"#setup/slack-connect.js";const SETUP_FLOW_CONFIG={"vc:install":{title:`Install the Vercel CLI`,indicator:`pulse`},"vc:login":{title:`Log in to Vercel`,indicator:`pulse`},model:{title:`Configure the agent model`,indicator:`pulse`},channels:{title:`Agent channels`,indicator:`pulse`},connect:{title:`Agent connections`,indicator:`pulse`},deploy:{title:`Deploy to Vercel`,indicator:`spinner`}};function muteableRenderer(e,t){return{readSelect:n=>t()?Promise.resolve(void 0):e.readSelect(n),readEditableSelect:n=>t()?Promise.resolve(void 0):e.readEditableSelect(n),readProviderPicker:n=>t()?Promise.resolve(void 0):e.readProviderPicker(n),readModelEditor:n=>t()?Promise.resolve(void 0):e.readModelEditor(n),readText:n=>t()?Promise.resolve(void 0):e.readText(n),readAcknowledge:n=>t()?Promise.resolve():e.readAcknowledge(n),readChoice:n=>t()?{choice:Promise.resolve(void 0),close:()=>{}}:e.readChoice(n),setStatus:n=>{t()||e.setStatus(n)},renderLine:(n,r)=>{(!t()||r===`warning`||r===`error`)&&e.renderLine(n,r)},renderOutput:n=>{t()||e.renderOutput(n)}}}async function runTuiSetupCommand(t){let{command:r}=t,i=!1,a=new AbortController,o=muteableRenderer(t.renderer,()=>i),s=(t.createPrompter??createTuiPrompter)(o),c=t.renderer.waitForInterrupt(),l=Symbol(`interrupted`),u=executeSetupCommand(t,s,o,a.signal);try{let e=await Promise.race([u,c.promise.then(()=>l)]);return e===l?(i=!0,a.abort(new WizardCancelledError),{...await u,message:`/${r} interrupted.`,preserveFlowDiagnostics:!0}):e}finally{c.dispose(),t.renderer.setStatus(void 0)}}async function executeSetupCommand(e,i,u,d){let{command:f,appRoot:p}=e,m={runInstallVercelCliFlow,runLoginFlow,runModelFlow,runChannelsFlow,runConnectionsFlow,runDeployFlow,...e.flows};try{switch(f){case`vc:install`:return installVercelCliResultMessage(await m.runInstallVercelCliFlow({appRoot:p,prompter:i,signal:d}));case`vc:login`:return loginResultMessage(await m.runLoginFlow({appRoot:p,prompter:i,signal:d}));case`model`:{let pickProvider=e=>u.readProviderPicker(e),t={appRoot:p,prompter:i,signal:d,deps:{pickModelSettings:e=>u.readModelEditor(e),runProviderFlow:e=>runProviderFlow({...e,picker:pickProvider})}};e.initialModelStep!==void 0&&(t.initialStep=e.initialModelStep);let n=await m.runModelFlow(t);if(n.kind===`cancelled`)return{message:n.discardedDraft===!0?`/model dismissed. Drafted changes were discarded; Done commits them.`:`/model dismissed.`,preserveFlowDiagnostics:!1};let r=[];n.modelMessage!==void 0&&r.push(n.modelMessage),n.providerOutcome!==void 0&&r.push(providerOutcomeMessage(n.providerOutcome));let a={message:r.join(`
2
+ `),preserveFlowDiagnostics:!1};return n.providerOutcome!==void 0&&(a.effect={kind:`model-access-changed`}),a}case`channels`:{let e=await m.runChannelsFlow({appRoot:p,prompter:i,signal:d});switch(e.kind){case`failed`:return pendingChannelsResult(`Channel files changed, but /channels failed: ${e.message}`);case`cancelled`:return{message:`/channels dismissed.`,preserveFlowDiagnostics:!0};case`deploy-and-chat`:return await runDeployAndChat(m,{appRoot:p,prompter:i,signal:d},e.chat);case`done`:return e.addedChannels.length===0?{message:`No channels added.`,preserveFlowDiagnostics:!0}:{message:`Channels added: ${e.addedChannels.join(`, `)} — run /deploy to ship them.`,preserveFlowDiagnostics:!0,effect:{kind:`channels-added`}}}}case`connect`:{let t=await m.runConnectionsFlow({appRoot:p,prompter:i,signal:d,disabledConnectionReasons:e.disabledConnectionReasons});switch(t.kind){case`cancelled`:return{message:`/connect dismissed.`,preserveFlowDiagnostics:!0,effect:{kind:`model-access-changed`}};case`failed`:return{message:t.addedConnections.length===0?`/connect failed: ${t.message}`:`Connection files changed, but /connect failed: ${t.message}`,preserveFlowDiagnostics:!0,effect:t.addedConnections.length===0?{kind:`model-access-changed`}:{kind:`connection-added`}};case`done`:return{message:t.addedConnections.length===0?`No connections added.`:`Connections added: ${t.addedConnections.join(`, `)}.`,preserveFlowDiagnostics:!0,effect:t.addedConnections.length===0?{kind:`model-access-changed`}:{kind:`connection-added`}}}}case`deploy`:{let e=await m.runDeployFlow({appRoot:p,prompter:i,interactive:!0,signal:d});return e.kind===`cancelled`?{message:`/deploy dismissed.`,preserveFlowDiagnostics:!0}:e.kind===`needs-link`?{message:`Not linked to a Vercel project — run /model to connect one first.`,preserveFlowDiagnostics:!0}:{message:e.productionUrl===void 0?`Deployed.`:`Deployed: ${e.productionUrl}`,preserveFlowDiagnostics:!0,effect:{kind:`deployed`}}}}}catch(e){if(e instanceof WizardCancelledError)return{message:`/${f} dismissed.`,preserveFlowDiagnostics:f!==`model`};let t=vercelActionOutcome(e,f);return t===void 0?{message:`/${f} failed: ${e instanceof Error?e.message:String(e)}`,preserveFlowDiagnostics:!0}:t}}function vercelActionOutcome(e,t){if(!(e instanceof HumanActionRequiredError))return;let n=vercelActionMessage(e.action.kind,t);return n===void 0?void 0:{message:n,preserveFlowDiagnostics:!0}}function vercelActionMessage(e,t){switch(e){case`vercel-login`:return`You're not logged in to Vercel — run /vc:login, then retry /${t}.`;case`vercel-forbidden`:return`Vercel denied access to that team — run /vc:login to re-authenticate (for example to complete SSO), or pick a team you can access, then retry /${t}.`;case`vercel-cli-missing`:return`The Vercel CLI isn't installed — run /vc:install to install it, then retry /${t}.`;default:return}}async function runDeployAndChat(e,t,r){let i;try{i=await e.runDeployFlow({...t,interactive:!0})}catch(e){if(e instanceof WizardCancelledError)return pendingChannelsResult(`Channels added, but /deploy was dismissed. Run /deploy to ship them.`);let t=vercelActionOutcome(e,`deploy`);return pendingChannelsResult(t===void 0?`Channels added, but /deploy failed: ${e instanceof Error?e.message:String(e)}`:`Channels added. ${t.message}`)}if(i.kind===`cancelled`)return pendingChannelsResult(`Channels added, but /deploy was dismissed. Run /deploy to ship them.`);if(i.kind===`needs-link`)return pendingChannelsResult(`Channels added, but this directory is not linked to Vercel. Run /model, then /deploy.`);let a=i.productionUrl===void 0?`Deployed.`:`Deployed: ${i.productionUrl}`,o;if(r.chatUrl===void 0)o=`Message your agent in Slack to see it live.`;else{let e=slackMessageDeepLink(r.chatUrl);openUrl(e),o=`Chat with your agent in Slack: ${e}`}return{message:`${a}\n${o}`,preserveFlowDiagnostics:!0,effect:{kind:`deployed`}}}function installVercelCliResultMessage(e){switch(e.kind){case`cancelled`:return{message:`/vc:install dismissed.`,preserveFlowDiagnostics:!1};case`already`:return{message:`The Vercel CLI is already installed.`,preserveFlowDiagnostics:!1};case`failed`:return{message:"Couldn't install the Vercel CLI — install it manually with `npm i -g vercel@latest`.",preserveFlowDiagnostics:!0};case`installed`:return{message:`Installed the Vercel CLI. Run /vc:login next.`,preserveFlowDiagnostics:!1,effect:{kind:`refresh-identity`}}}}function loginResultMessage(e){switch(e.kind){case`cancelled`:return{message:`/vc:login dismissed.`,preserveFlowDiagnostics:!1};case`already`:return{message:`You're already logged in to Vercel.`,preserveFlowDiagnostics:!1};case`cli-missing`:return{message:`The Vercel CLI isn't installed — run /vc:install to install it, then retry /vc:login.`,preserveFlowDiagnostics:!0};case`failed`:return{message:`Vercel login didn't complete — run /vc:login to try again.`,preserveFlowDiagnostics:!0};case`logged-in`:return{message:`Logged in to Vercel.`,preserveFlowDiagnostics:!1,effect:{kind:`refresh-identity`}};case`unavailable`:return{message:`Couldn't reach Vercel — check your connection, then retry /vc:login.`,preserveFlowDiagnostics:!0}}}function pendingChannelsResult(e){return{message:e,preserveFlowDiagnostics:!0,effect:{kind:`channels-added`}}}function providerOutcomeMessage(e){let{resolution:t,status:n}=e;if(n.kind===`gateway-project`)return t===void 0?`Project linked. No model credential found; set AI_GATEWAY_API_KEY in .env.local.`:t.credential===`oidc`?`Project linked. Connected to AI Gateway via VERCEL_OIDC_TOKEN.`:t.shadowedOidc===void 0?`Project linked. Connected to AI Gateway via AI_GATEWAY_API_KEY.`:`Project linked. AI_GATEWAY_API_KEY (${t.source.kind===`shell`?`shell`:t.source.path}) outranks the project's VERCEL_OIDC_TOKEN and stays the active credential — ${t.source.kind===`shell`?`unset it in your shell`:`remove it from ${t.source.path}`} to run on the project.`;if(n.kind===`gateway-key`){let e=n.source.kind===`shell`?`your shell`:n.source.path;return`Connected to AI Gateway via ${n.envKey} in ${e}.`}return`Provider updated — no gateway credential detected; set AI_GATEWAY_API_KEY in .env.local.`}export{SETUP_FLOW_CONFIG,runTuiSetupCommand};
@@ -1,5 +1,6 @@
1
1
  import type { ChannelSetupChoice, ChannelSetupChoiceOptions } from "#setup/cli/index.js";
2
2
  import type { SearchActionOption } from "#setup/cli/select-state.js";
3
+ import type { ModelSettingsRequest, ModelSettingsResult } from "#setup/flows/model.js";
3
4
  import type { ProviderPickerChoice, ProviderPickerRequest } from "#setup/flows/provider.js";
4
5
  import type { SelectNotice } from "#setup/prompter.js";
5
6
  import type { SetupPanelOption } from "./setup-panel.js";
@@ -74,6 +75,8 @@ export interface SetupFlowRenderer {
74
75
  }): Promise<SetupEditableSelectResult | undefined>;
75
76
  /** Provider-only picker with masked async validation. Not part of Prompter. */
76
77
  readProviderPicker(options: ProviderPickerRequest): Promise<ProviderPickerChoice | undefined>;
78
+ /** Composite Change-model screen: catalog list, reasoning slider, tier toggle. Not part of Prompter. */
79
+ readModelEditor(options: ModelSettingsRequest): Promise<ModelSettingsResult | undefined>;
77
80
  readText(options: {
78
81
  message: string;
79
82
  placeholder?: string;
@@ -1 +1 @@
1
- import{join}from"node:path";import{pathExists}from"#setup/path-exists.js";function hasEnvValue(e,t){let n=e[t];return n!==void 0&&n.trim().length>0}function resolveModelProviderState(e,t){let n=modelProviderAccess({env:t,info:e});if(e===void 0||n.kind!==`gateway`||n.runtime.status!==`connected`)return e;let{credential:r}=n.runtime,i=e.agent.model,a=i.endpoint;return a?.kind===`gateway`&&a.connected&&a.credential===r?e:{...e,agent:{...e.agent,model:{...i,endpoint:{kind:`gateway`,connected:!0,credential:r}}}}}function modelProviderAccess(e){let t=e.info?.agent.model;if(t?.routing?.kind===`external`)return{kind:`external`};if(t?.routing?.kind!==`gateway`)return{kind:`unknown`};if(hasEnvValue(e.env,`AI_GATEWAY_API_KEY`))return{kind:`gateway`,runtime:{status:`connected`,credential:`api-key`}};let n=t.endpoint;return n?.kind===`gateway`&&n.connected?{kind:`gateway`,runtime:{status:`connected`,credential:n.credential}}:hasEnvValue(e.env,`VERCEL_OIDC_TOKEN`)?{kind:`gateway`,runtime:{status:`connected`,credential:`oidc`}}:n?.kind===`gateway`?{kind:`gateway`,runtime:{status:`disconnected`}}:{kind:`gateway`,runtime:{status:`unknown`}}}const BOOT_DETECTIONS=[{id:`model-provider`,async detect({appRoot:n,env:r,info:i}){let a=modelProviderAccess({env:r,info:i});if(a.kind===`external`)return[];if(a.kind===`gateway`){if(a.runtime.status===`connected`)return[];if(a.runtime.status===`disconnected`)return[{kind:`attention`,label:await pathExists(join(n,`.vercel`,`project.json`))?`AI Gateway credentials missing`:`model provider not linked`,command:`/model`}]}return await pathExists(join(n,`.vercel`,`project.json`))?[{kind:`attention`,label:`AI Gateway credentials missing`,command:`/model`}]:[{kind:`attention`,label:`model provider not linked`,command:`/model`}]}}],LOGIN_SETUP_ISSUE={kind:`attention`,label:`not logged in`,command:`/vc:login`},CLI_MISSING_SETUP_ISSUE={kind:`attention`,label:`Vercel CLI not found`,command:`/vc:install`};async function detectSetupIssues(e,t=BOOT_DETECTIONS){return(await Promise.all(t.map(async t=>{try{return await t.detect(e)}catch{return[]}}))).flat()}function orderedSetupIssues(e,t){return t===void 0?[...e]:[t,...e]}function formatSetupIssuesLine(e){let t=e.length===1?`setup issue`:`setup issues`,n=e.map(e=>`${e.label} · ${e.command}`).join(`, `);return`${e.length} ${t}: ${n}`}export{BOOT_DETECTIONS,CLI_MISSING_SETUP_ISSUE,LOGIN_SETUP_ISSUE,detectSetupIssues,formatSetupIssuesLine,orderedSetupIssues,resolveModelProviderState};
1
+ import{join}from"node:path";import{pathExists}from"#setup/path-exists.js";import{hasEnvValue,resolveGatewayCredential}from"#internal/resolve-model-endpoint-status.js";function resolveModelProviderState(e,t){let n=modelProviderAccess({env:t,info:e});if(e===void 0||n.kind!==`gateway`||n.runtime.status!==`connected`)return e;let{credential:r}=n.runtime,i=e.agent.model,a=i.endpoint;return a?.kind===`gateway`&&a.connected&&a.credential===r?e:{...e,agent:{...e.agent,model:{...i,endpoint:{kind:`gateway`,connected:!0,credential:r}}}}}function modelProviderAccess(e){let t=e.info?.agent.model;if(t?.routing?.kind===`external`)return{kind:`external`};if(t?.routing?.kind!==`gateway`)return{kind:`unknown`};let i=resolveGatewayCredential({apiKeyInEnv:hasEnvValue(e.env.AI_GATEWAY_API_KEY),oidcAvailable:hasEnvValue(e.env.VERCEL_OIDC_TOKEN)});if(i?.credential===`api-key`)return{kind:`gateway`,runtime:{status:`connected`,credential:`api-key`}};let a=t.endpoint;return a?.kind===`gateway`&&a.connected?{kind:`gateway`,runtime:{status:`connected`,credential:a.credential}}:i===void 0?a?.kind===`gateway`?{kind:`gateway`,runtime:{status:`disconnected`}}:{kind:`gateway`,runtime:{status:`unknown`}}:{kind:`gateway`,runtime:{status:`connected`,credential:i.credential}}}const BOOT_DETECTIONS=[{id:`model-provider`,async detect({appRoot:n,env:r,info:i}){let a=modelProviderAccess({env:r,info:i});if(a.kind===`external`)return[];if(a.kind===`gateway`){if(a.runtime.status===`connected`)return[];if(a.runtime.status===`disconnected`)return[{kind:`attention`,label:await pathExists(join(n,`.vercel`,`project.json`))?`AI Gateway credentials missing`:`model provider not linked`,command:`/model`}]}return await pathExists(join(n,`.vercel`,`project.json`))?[{kind:`attention`,label:`AI Gateway credentials missing`,command:`/model`}]:[{kind:`attention`,label:`model provider not linked`,command:`/model`}]}}],LOGIN_SETUP_ISSUE={kind:`attention`,label:`not logged in`,command:`/vc:login`},CLI_MISSING_SETUP_ISSUE={kind:`attention`,label:`Vercel CLI not found`,command:`/vc:install`};async function detectSetupIssues(e,t=BOOT_DETECTIONS){return(await Promise.all(t.map(async t=>{try{return await t.detect(e)}catch{return[]}}))).flat()}function orderedSetupIssues(e,t){return t===void 0?[...e]:[t,...e]}function formatSetupIssuesLine(e){let t=e.length===1?`setup issue`:`setup issues`,n=e.map(e=>`${e.label} · ${e.command}`).join(`, `);return`${e.length} ${t}: ${n}`}export{BOOT_DETECTIONS,CLI_MISSING_SETUP_ISSUE,LOGIN_SETUP_ISSUE,detectSetupIssues,formatSetupIssuesLine,orderedSetupIssues,resolveModelProviderState};