eve 0.6.0-beta.18 → 0.6.0-beta.19

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 (36) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/docs/public/advanced/dev-tui.md +2 -2
  3. package/dist/src/cli/commands/link.d.ts +1 -1
  4. package/dist/src/cli/dev/tui/agent-header.d.ts +1 -1
  5. package/dist/src/cli/dev/tui/agent-header.js +1 -1
  6. package/dist/src/cli/dev/tui/errors.d.ts +1 -1
  7. package/dist/src/cli/dev/tui/errors.js +1 -1
  8. package/dist/src/cli/dev/tui/prompt-command-handler.d.ts +2 -1
  9. package/dist/src/cli/dev/tui/prompt-command-handler.js +1 -1
  10. package/dist/src/cli/dev/tui/prompt-commands.d.ts +1 -1
  11. package/dist/src/cli/dev/tui/prompt-commands.js +1 -1
  12. package/dist/src/cli/dev/tui/setup-commands.d.ts +2 -4
  13. package/dist/src/cli/dev/tui/setup-commands.js +2 -1
  14. package/dist/src/cli/dev/tui/setup-flow.d.ts +3 -0
  15. package/dist/src/cli/dev/tui/setup-issues.d.ts +1 -1
  16. package/dist/src/cli/dev/tui/setup-issues.js +1 -1
  17. package/dist/src/cli/dev/tui/setup-panel.d.ts +6 -1
  18. package/dist/src/cli/dev/tui/setup-panel.js +1 -1
  19. package/dist/src/cli/dev/tui/terminal-renderer.d.ts +1 -1
  20. package/dist/src/cli/dev/tui/terminal-renderer.js +1 -1
  21. package/dist/src/cli/dev/tui/tui-prompter.js +1 -1
  22. package/dist/src/harness/model-call-error.d.ts +1 -1
  23. package/dist/src/internal/application/package.js +1 -1
  24. package/dist/src/setup/flows/channels.d.ts +1 -1
  25. package/dist/src/setup/flows/link.d.ts +2 -2
  26. package/dist/src/setup/flows/model.d.ts +81 -12
  27. package/dist/src/setup/flows/model.js +1 -1
  28. package/dist/src/setup/flows/vercel.d.ts +7 -6
  29. package/dist/src/setup/flows/vercel.js +1 -1
  30. package/dist/src/setup/project-resolution.js +1 -1
  31. package/dist/src/setup/prompter.d.ts +18 -0
  32. package/dist/src/setup/prompter.js +1 -1
  33. package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
  34. package/dist/src/setup/scaffold/create/project.js +2 -2
  35. package/dist/src/setup/scaffold/update/channels.js +1 -1
  36. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # eve
2
2
 
3
+ ## 0.6.0-beta.19
4
+
5
+ ### Minor Changes
6
+
7
+ - 9061941: The dev TUI's `/model` now opens a configure menu uniting the model and provider setup, and the separate `/vercel` command is removed: "Change model" runs the searchable AI Gateway catalog picker, and "Configure provider" (bold yellow with "Required to enable the agent" until a Vercel link or gateway credential is detected) runs the provider questions `/vercel` used to ask. Each action returns to the menu, which shows each row's current value on its own line — e.g. "AI Gateway (Linked to my-project)" — and keeps the latest outcome visible beneath the options ("✓ Model changed to …"); Esc leaves. Error messages and the startup attention line now point at `/model`, and `/model <provider/model-id>` still applies a model directly.
8
+
3
9
  ## 0.6.0-beta.18
4
10
 
5
11
  ### Minor Changes
@@ -19,12 +19,12 @@ On startup the TUI prints a header for the connected agent — the model, instru
19
19
  · Subagents researcher
20
20
  · Server http://localhost:3000
21
21
 
22
- Type to chat · ↑ history · /new reset session · /model /vercel /channels /deploy · /exit quit · Ctrl+C interrupt
22
+ Type to chat · ↑ history · /new reset session · /model /channels /deploy · /exit quit · Ctrl+C interrupt
23
23
  ```
24
24
 
25
25
  From there the conversation streams straight into your terminal's normal scrollback — your prompts, the agent's replies, reasoning, tool calls, nested subagents, connection-authorization prompts, and any captured `stdout`/`stderr` — so you keep native scrolling, copy/paste, and a transcript that persists after you exit. Each turn is rendered without boxes: a colored gutter glyph marks who's speaking, tool calls collapse to a one-line summary (`✓ get_weather city="SF" → 73°F`), and a subagent's work is indented beneath its `◆` header. A sticky line at the bottom shows the input prompt or the live status (spinner, token usage). Press `Enter` to send; `Ctrl+C` interrupts a running turn or quits at the prompt. Slash commands: `/new` starts a fresh session and `/exit` quits.
26
26
 
27
- When `eve dev` runs the server locally, three more slash commands manage the project without leaving the session. `/vercel` opens with two questions which model provider to use (picking something other than AI Gateway shows wiring instructions for your own provider and stops there) and how to connect to AI Gateway (paste your own `AI_GATEWAY_API_KEY`, saved straight to `.env.local`, or connect via a project) and the project path then walks the same Vercel team/project pickers as setup (picking again re-links) and pulls the project's environment so an AI Gateway credential lands in `.env.local` the dev server reloads env files automatically, no restart needed. `/channels` shows the agent's channel list — already-registered channels render as locked rows — and adds the one you pick, including the Slack Connect provisioning, then installs the dependencies the scaffold added so the dev server can load the new channels right away; after each addition the list repaints with the new channel locked, until Done (or Esc) leaves the flow. `/deploy` ships the agent to Vercel production, linking first when the directory is unlinked. Each command echoes as an invocation line, asks through a bordered panel that takes the input area's place — one question at a time, clearly separate from the chat transcript — and finishes with a one-line `⎿` result; loading states stay on the ephemeral status line instead of piling into the transcript. These commands are not available when connected to a remote server with `--url`, and when a turn fails because AI Gateway authentication is missing or stale, the error points you at `/vercel` directly. The TUI also checks at startup: a missing model-provider setup surfaces as an attention line — `⚠ 1 setup issue: model provider not linked · /vercel` — so the fix is visible before the first message fails, and each command's outcome hangs under it with the `⎿` connector. Local sessions also get `/model`: bare `/model` opens the same searchable model picker setup uses (the AI Gateway catalog, pre-selected on the model the runtime is serving), `/model <provider/model-id>` applies one directly, and the change is written into your agent's authored source — the command reports success only after the reloaded runtime confirms the new id.
27
+ When `eve dev` runs the server locally, three more slash commands manage the project without leaving the session. Bare `/model` opens a two-row configure menu that loops until Esc. "Change model" runs the same searchable model picker setup uses (the AI Gateway catalog, pre-selected on the model the runtime is serving); a model change is written into your agent's authored source, and the command reports success only after Eve confirms the new id (`/model <provider/model-id>` applies one directly, skipping the menu). The provider row opens the provider questions: which model provider to use (picking something other than AI Gateway shows wiring instructions for your own provider and stops there, leaving any existing setup untouched) and how to connect to AI Gateway paste your own `AI_GATEWAY_API_KEY`, saved straight to `.env.local`, or connect via a project, which walks the same Vercel team/project pickers as setup (picking again re-links) and pulls the project's environment so an AI Gateway credential lands in `.env.local`; the dev server reloads env files automatically, no restart needed. The row demands attention (a bold yellow "Configure provider" with "Required to enable the agent") until a link or gateway credential is detected, then names the connection (e.g. "AI Gateway (Linked to my-project in my-team)") after, and each action's latest outcome stays visible beneath the menu (e.g. "✓ Model changed to openai/gpt-5.5"). `/channels` shows the agent's channel list — already-registered channels render as locked rows — and adds the one you pick, including the Slack Connect provisioning, then installs the dependencies the scaffold added so the dev server can load the new channels right away; after each addition the list repaints with the new channel locked, until Done (or Esc) leaves the flow. `/deploy` ships the agent to Vercel production, linking first when the directory is unlinked. Each command echoes as an invocation line, asks through a bordered panel that takes the input area's place — one question at a time, clearly separate from the chat transcript — and finishes with a one-line `⎿` result; loading states stay on the ephemeral status line instead of piling into the transcript. These commands are not available when connected to a remote server with `--url`, and when a turn fails because AI Gateway authentication is missing or stale, the error points you at `/model` directly. The TUI also checks at startup: a missing model-provider setup surfaces as an attention line — `⚠ 1 setup issue: model provider not linked · /model` — so the fix is visible before the first message fails, and each command's outcome hangs under it with the `⎿` connector.
28
28
 
29
29
  The prompt input behaves like a shell line editor: `↑`/`↓` cycle through the messages you've sent this session, `←`/`→`, Home/End, and `Ctrl+A`/`Ctrl+E` move the caret, and `Ctrl+U`/`Ctrl+K`/`Ctrl+W` kill the line, the rest of the line, or the previous word. If a turn fails terminally — the server session dies or the connection drops — the TUI starts a fresh session and notes it inline so you can keep going (server-side context resets with the old session). Errors render compactly, with docs links highlighted, and a code bug escaping your agent's own code shows its stack trace dim beneath the error headline. Captured server `stdout`/`stderr` renders as dim, indented log runs behind a `│` rule — consecutive lines from the same source share one label, and nothing is ever hidden.
30
30
 
@@ -15,7 +15,7 @@ export interface LinkCommandDependencies {
15
15
  * `eve link`: pick a Vercel team and project (re-linking when one is already
16
16
  * linked), run `vercel link`, then pull env so the AI Gateway credential lands
17
17
  * in `.env.local`. The flow itself is {@link runLinkFlow}, shared with the dev
18
- * TUI's `/vercel`. Interactive only: the pickers are the point of the command,
18
+ * TUI `/model` menu's provider row. Interactive only: the pickers are the point of the command,
19
19
  * so a non-TTY run refuses with guidance instead of guessing a project.
20
20
  */
21
21
  export declare function runLinkCommand(logger: LinkCliLogger, appRoot: string, dependencies?: LinkCommandDependencies): Promise<void>;
@@ -18,7 +18,7 @@ export interface AgentHeaderInput {
18
18
  theme: Theme;
19
19
  /** Available terminal width. */
20
20
  width: number;
21
- /** Mention /model, /vercel, /channels, /deploy in the key hints (local sessions only). */
21
+ /** Mention the setup slash commands in the key hints (local sessions only). */
22
22
  setupCommands?: boolean;
23
23
  }
24
24
  /**
@@ -1 +1 @@
1
- import{truncate}from"./tool-format.js";function buildAgentHeader(t){let{theme:n,info:r,name:i,serverUrl:a,width:o}=t,s=n.colors,c=[];if(r){c.push({label:`Model`,value:r.agent.model.id}),r.instructions.static&&c.push({label:`Instructions`,value:r.instructions.static.logicalPath});let e=[...r.tools.authored,...r.tools.dynamic.filter(e=>e.origin===`authored`).map(e=>({name:e.slug}))];e.length>0&&c.push({label:`Tools`,value:joinNames(e)});let t=[...r.skills.static,...r.skills.dynamic.filter(e=>e.origin===`authored`).map(e=>({name:e.slug}))];t.length>0&&c.push({label:`Skills`,value:joinNames(t)}),r.subagents.local.length>0&&c.push({label:`Subagents`,value:joinNames(r.subagents.local)}),r.schedules.length>0&&c.push({label:`Schedules`,value:joinNames(r.schedules)}),r.sandbox&&c.push({label:`Sandbox`,value:r.sandbox.logicalPath})}c.push({label:`Server`,value:a,link:!0});let l=c.reduce((e,t)=>Math.max(e,t.label.length),0),u=Math.max(8,o-l-6),d=[];if(d.push(` ${s.bold(`${n.glyph.brand} ${i}`)}`),r&&(r.diagnostics.discoveryErrors>0||r.diagnostics.discoveryWarnings>0)){let e=[];r.diagnostics.discoveryErrors>0&&e.push(s.red(`${r.diagnostics.discoveryErrors} error${plural(r.diagnostics.discoveryErrors)}`)),r.diagnostics.discoveryWarnings>0&&e.push(s.yellow(`${r.diagnostics.discoveryWarnings} warning${plural(r.diagnostics.discoveryWarnings)}`)),d.push(` ${s.dim(n.glyph.warning)} ${e.join(s.dim(` · `))}`)}for(let t of c){let r=s.dim(n.glyph.dot)+` `+s.gray(t.label.padEnd(l)),i=truncate(t.value,u);d.push(` ${r} ${t.link?s.cyan(i):i}`)}d.push(``);let f=t.setupCommands?` ${n.glyph.dot} /model /vercel /channels /deploy`:``;return d.push(` ${s.dim(`Type to chat ${n.glyph.dot} ↑ history ${n.glyph.dot} /new reset session${f} ${n.glyph.dot} /exit quit ${n.glyph.dot} Ctrl+C interrupt`)}`),d}function joinNames(e){return e.map(e=>e.name).join(`, `)}function plural(e){return e===1?``:`s`}export{buildAgentHeader};
1
+ import{truncate}from"./tool-format.js";function buildAgentHeader(t){let{theme:n,info:r,name:i,serverUrl:a,width:o}=t,s=n.colors,c=[];if(r){c.push({label:`Model`,value:r.agent.model.id}),r.instructions.static&&c.push({label:`Instructions`,value:r.instructions.static.logicalPath});let e=[...r.tools.authored,...r.tools.dynamic.filter(e=>e.origin===`authored`).map(e=>({name:e.slug}))];e.length>0&&c.push({label:`Tools`,value:joinNames(e)});let t=[...r.skills.static,...r.skills.dynamic.filter(e=>e.origin===`authored`).map(e=>({name:e.slug}))];t.length>0&&c.push({label:`Skills`,value:joinNames(t)}),r.subagents.local.length>0&&c.push({label:`Subagents`,value:joinNames(r.subagents.local)}),r.schedules.length>0&&c.push({label:`Schedules`,value:joinNames(r.schedules)}),r.sandbox&&c.push({label:`Sandbox`,value:r.sandbox.logicalPath})}c.push({label:`Server`,value:a,link:!0});let l=c.reduce((e,t)=>Math.max(e,t.label.length),0),u=Math.max(8,o-l-6),d=[];if(d.push(` ${s.bold(`${n.glyph.brand} ${i}`)}`),r&&(r.diagnostics.discoveryErrors>0||r.diagnostics.discoveryWarnings>0)){let e=[];r.diagnostics.discoveryErrors>0&&e.push(s.red(`${r.diagnostics.discoveryErrors} error${plural(r.diagnostics.discoveryErrors)}`)),r.diagnostics.discoveryWarnings>0&&e.push(s.yellow(`${r.diagnostics.discoveryWarnings} warning${plural(r.diagnostics.discoveryWarnings)}`)),d.push(` ${s.dim(n.glyph.warning)} ${e.join(s.dim(` · `))}`)}for(let t of c){let r=s.dim(n.glyph.dot)+` `+s.gray(t.label.padEnd(l)),i=truncate(t.value,u);d.push(` ${r} ${t.link?s.cyan(i):i}`)}d.push(``);let f=t.setupCommands?` ${n.glyph.dot} /model /channels /deploy`:``;return d.push(` ${s.dim(`Type to chat ${n.glyph.dot} ↑ history ${n.glyph.dot} /new reset session${f} ${n.glyph.dot} /exit quit ${n.glyph.dot} Ctrl+C interrupt`)}`),d}function joinNames(e){return e.map(e=>e.name).join(`, `)}function plural(e){return e===1?``:`s`}export{buildAgentHeader};
@@ -51,7 +51,7 @@ export declare function formatFailureMessage(event: FailureStreamEvent): string;
51
51
  */
52
52
  export declare function formatFailureDetail(event: FailureStreamEvent): string | undefined;
53
53
  /**
54
- * Minimal TUI rendering for a gateway-auth failure when `/vercel` is available
54
+ * Minimal TUI rendering for a gateway-auth failure when `/model` is available
55
55
  * locally. Replaces the harness's full summary — whose remediation names CLI
56
56
  * commands and dashboard URLs — with one actionable line; the caller drops
57
57
  * the diagnostic detail along with it. The variant is picked off the summary
@@ -1 +1 @@
1
- import{GATEWAY_AUTHENTICATION_ERROR_NAME,GATEWAY_AUTH_FAILURE_SUMMARY_NAME}from"#harness/model-call-error.js";var InterruptedError=class extends Error{constructor(){super(`Interrupted`),this.name=`InterruptedError`}};function interruptedError(){return new InterruptedError}function isInterruptedError(e){return e instanceof InterruptedError}function isAbortLikeError(e){return e instanceof Error?e.name===`AbortError`||/\babort(?:ed)?\b/iu.test(e.message):!1}function failureKey(e){return`${e.data.code}:${e.data.message}`}function formatFailureMessage(e){let{code:t,message:n}=e.data;return!t||n===t||n.startsWith(`${t}:`)||n.startsWith(`${t} `)?n:`${t}: ${n}`}function formatFailureDetail(e){let t=e.data.details;if(typeof t!=`object`||!t)return;let n=t.detail;if(typeof n!=`string`)return;let r=n.trim();if(!(r.length===0||r===e.data.message.trim()))return r}function formatGatewayAuthFailureNotice(e){let t=e.data.message;return/rejected the provided API key|Invalid API key/i.test(t)?`AI Gateway rejected your AI_GATEWAY_API_KEY. Run /vercel to refresh credentials, or update it in .env.local (a stale shell export can shadow it).`:/rejected the OIDC token|Invalid OIDC token/i.test(t)?`Your AI Gateway OIDC token is invalid or expired. Run /vercel to refresh it, or set AI_GATEWAY_API_KEY in .env.local.`:`There is no AI_GATEWAY_API_KEY set. Run /vercel to connect this to a project and refresh AI Gateway credentials, or set it manually in .env.local.`}function isGatewayAuthFailure(n){let r=n.data.details;if(typeof r!=`object`||!r)return!1;let i=r;return i.gatewayName===GATEWAY_AUTHENTICATION_ERROR_NAME||i.name===GATEWAY_AUTH_FAILURE_SUMMARY_NAME}export{InterruptedError,failureKey,formatFailureDetail,formatFailureMessage,formatGatewayAuthFailureNotice,interruptedError,isAbortLikeError,isGatewayAuthFailure,isInterruptedError};
1
+ import{GATEWAY_AUTHENTICATION_ERROR_NAME,GATEWAY_AUTH_FAILURE_SUMMARY_NAME}from"#harness/model-call-error.js";var InterruptedError=class extends Error{constructor(){super(`Interrupted`),this.name=`InterruptedError`}};function interruptedError(){return new InterruptedError}function isInterruptedError(e){return e instanceof InterruptedError}function isAbortLikeError(e){return e instanceof Error?e.name===`AbortError`||/\babort(?:ed)?\b/iu.test(e.message):!1}function failureKey(e){return`${e.data.code}:${e.data.message}`}function formatFailureMessage(e){let{code:t,message:n}=e.data;return!t||n===t||n.startsWith(`${t}:`)||n.startsWith(`${t} `)?n:`${t}: ${n}`}function formatFailureDetail(e){let t=e.data.details;if(typeof t!=`object`||!t)return;let n=t.detail;if(typeof n!=`string`)return;let r=n.trim();if(!(r.length===0||r===e.data.message.trim()))return r}function formatGatewayAuthFailureNotice(e){let t=e.data.message;return/rejected the provided API key|Invalid API key/i.test(t)?`AI Gateway rejected your AI_GATEWAY_API_KEY. Run /model to refresh credentials, or update it in .env.local (a stale shell export can shadow it).`:/rejected the OIDC token|Invalid OIDC token/i.test(t)?`Your AI Gateway OIDC token is invalid or expired. Run /model to refresh it, or set AI_GATEWAY_API_KEY in .env.local.`:`There is no AI_GATEWAY_API_KEY set. Run /model to connect this to a project and refresh AI Gateway credentials, or set it manually in .env.local.`}function isGatewayAuthFailure(n){let r=n.data.details;if(typeof r!=`object`||!r)return!1;let i=r;return i.gatewayName===GATEWAY_AUTHENTICATION_ERROR_NAME||i.name===GATEWAY_AUTH_FAILURE_SUMMARY_NAME}export{InterruptedError,failureKey,formatFailureDetail,formatFailureMessage,formatGatewayAuthFailureNotice,interruptedError,isAbortLikeError,isGatewayAuthFailure,isInterruptedError};
@@ -1,3 +1,4 @@
1
+ import type { ApplyModelOutcome } from "#setup/flows/model.js";
1
2
  import type { PromptCommandHandler } from "./runner.js";
2
3
  export interface PromptCommandHandlerOptions {
3
4
  readonly appRoot?: string;
@@ -5,6 +6,6 @@ export interface PromptCommandHandlerOptions {
5
6
  readonly applyModel?: (input: {
6
7
  appRoot: string;
7
8
  slug: string;
8
- }) => Promise<string>;
9
+ }) => Promise<ApplyModelOutcome>;
9
10
  }
10
11
  export declare function createPromptCommandHandler(options: PromptCommandHandlerOptions): PromptCommandHandler;
@@ -1 +1 @@
1
- function createPromptCommandHandler(e){return{async handle(t,n){let r=e.appRoot;if(r===void 0)return`/${t.name} needs eve dev running the local server (it is not available with --url).`;if(t.name===`model`&&t.argument.length>0){let n=e.applyModel??(await import(`#setup/flows/model.js`)).changeAgentModel;try{return await n({appRoot:r,slug:t.argument})}catch(e){return`Couldn't change the model: ${e instanceof Error?e.message:String(e)}`}}let i=n.renderer.setupFlow;if(i===void 0)return`/${t.name} is not supported by this renderer.`;let{runTuiSetupCommand:a,SETUP_FLOW_TITLES:o}=await import(`./setup-commands.js`);i.begin(o[t.name]);let s=!0;try{let e=await a({command:t.name,appRoot:r,renderer:i});return s=e.preserveFlowDiagnostics,e.message}finally{i.end({preserveDiagnostics:s})}}}}export{createPromptCommandHandler};
1
+ function createPromptCommandHandler(e){return{async handle(t,n){let r=e.appRoot;if(r===void 0)return`/${t.name} needs eve dev running the local server (it is not available with --url).`;if(t.name===`model`&&t.argument.length>0){let{changeAgentModel:n,formatApplyModelOutcome:i}=await import(`#setup/flows/model.js`),a=e.applyModel??n;try{return i(await a({appRoot:r,slug:t.argument}))}catch(e){return`Couldn't change the model: ${e instanceof Error?e.message:String(e)}`}}let i=n.renderer.setupFlow;if(i===void 0)return`/${t.name} is not supported by this renderer.`;let{runTuiSetupCommand:a,SETUP_FLOW_TITLES:o}=await import(`./setup-commands.js`);i.begin(o[t.name]);let s=!0;try{let e=await a({command:t.name,appRoot:r,renderer:i});return s=e.preserveFlowDiagnostics,e.message}finally{i.end({preserveDiagnostics:s})}}}}export{createPromptCommandHandler};
@@ -1,4 +1,4 @@
1
- export type PromptCommandExtensionName = "model" | "vercel" | "channels" | "deploy";
1
+ export type PromptCommandExtensionName = "model" | "channels" | "deploy";
2
2
  /** The slash commands the prompt accepts. */
3
3
  export type PromptCommand = {
4
4
  type: "new";
@@ -1,2 +1,2 @@
1
- const PROMPT_COMMANDS=[{name:`help`,aliases:[],description:`Show available commands`,takesArgument:!1,build:()=>({type:`help`})},{name:`new`,aliases:[],description:`Start a fresh session`,takesArgument:!1,build:()=>({type:`new`})},{name:`model`,aliases:[],description:`Pick or set the agent's model`,argumentHint:`[provider/model]`,takesArgument:!0,build:e=>({type:`extension`,name:`model`,argument:e})},{name:`vercel`,aliases:[],description:`Link the project to Vercel`,takesArgument:!1,build:()=>({type:`extension`,name:`vercel`,argument:``})},{name:`channels`,aliases:[],description:`Add chat channels to the agent`,takesArgument:!1,build:()=>({type:`extension`,name:`channels`,argument:``})},{name:`deploy`,aliases:[],description:`Deploy the agent to Vercel`,takesArgument:!1,build:()=>({type:`extension`,name:`deploy`,argument:``})},{name:`exit`,aliases:[`quit`],description:`Quit the TUI`,takesArgument:!1,build:()=>({type:`exit`})}];function parsePromptCommand(t){let n=t.trim();if(!n.startsWith(`/`))return null;for(let t of PROMPT_COMMANDS)for(let e of[t.name,...t.aliases]){let r=`/${e}`;if(n===r)return t.build(``);if(t.takesArgument&&n.startsWith(`${r} `))return t.build(n.slice(r.length).trim())}return null}function isPromptControlCommand(e){return parsePromptCommand(e)!==null}function formatPromptCommandHelp(){let t=PROMPT_COMMANDS.map(e=>{let t=e.argumentHint===void 0?``:` ${e.argumentHint}`,n=e.aliases.map(e=>` (/${e})`).join(``);return{invocation:`/${e.name}${t}${n}`,description:e.description}}),n=Math.max(...t.map(e=>e.invocation.length))+2;return t.map(e=>e.invocation.padEnd(n)+e.description).join(`
1
+ const PROMPT_COMMANDS=[{name:`help`,aliases:[],description:`Show available commands`,takesArgument:!1,build:()=>({type:`help`})},{name:`new`,aliases:[],description:`Start a fresh session`,takesArgument:!1,build:()=>({type:`new`})},{name:`model`,aliases:[],description:`Configure the agent's model and provider`,argumentHint:`[provider/model]`,takesArgument:!0,build:e=>({type:`extension`,name:`model`,argument:e})},{name:`channels`,aliases:[],description:`Add chat channels to the agent`,takesArgument:!1,build:()=>({type:`extension`,name:`channels`,argument:``})},{name:`deploy`,aliases:[],description:`Deploy the agent to Vercel`,takesArgument:!1,build:()=>({type:`extension`,name:`deploy`,argument:``})},{name:`exit`,aliases:[`quit`],description:`Quit the TUI`,takesArgument:!1,build:()=>({type:`exit`})}];function parsePromptCommand(t){let n=t.trim();if(!n.startsWith(`/`))return null;for(let t of PROMPT_COMMANDS)for(let e of[t.name,...t.aliases]){let r=`/${e}`;if(n===r)return t.build(``);if(t.takesArgument&&n.startsWith(`${r} `))return t.build(n.slice(r.length).trim())}return null}function isPromptControlCommand(e){return parsePromptCommand(e)!==null}function formatPromptCommandHelp(){let t=PROMPT_COMMANDS.map(e=>{let t=e.argumentHint===void 0?``:` ${e.argumentHint}`,n=e.aliases.map(e=>` (/${e})`).join(``);return{invocation:`/${e.name}${t}${n}`,description:e.description}}),n=Math.max(...t.map(e=>e.invocation.length))+2;return t.map(e=>e.invocation.padEnd(n)+e.description).join(`
2
2
  `)}export{PROMPT_COMMANDS,formatPromptCommandHelp,isPromptControlCommand,parsePromptCommand};
@@ -1,6 +1,5 @@
1
1
  import { runChannelsFlow } from "#setup/flows/channels.js";
2
2
  import { runDeployFlow } from "#setup/flows/deploy.js";
3
- import { runVercelFlow } from "#setup/flows/vercel.js";
4
3
  import { runModelFlow } from "#setup/flows/model.js";
5
4
  import type { Prompter } from "#setup/prompter.js";
6
5
  import { type TuiPrompterRenderer } from "./tui-prompter.js";
@@ -10,7 +9,7 @@ export type TuiSetupCommand = PromptCommandExtensionName;
10
9
  * Human panel titles per command. The bordered panel never repeats the echoed
11
10
  * command (the transcript already shows it); /channels and /model carry no
12
11
  * title at all because their opening questions ("Where will you chat with
13
- * your agent?", "Which model should your agent use?") are the panel's header.
12
+ * your agent?", "Configure the agent's model") are the panel's header.
14
13
  */
15
14
  export declare const SETUP_FLOW_TITLES: Record<TuiSetupCommand, string>;
16
15
  export interface TuiSetupCommandInput {
@@ -27,7 +26,6 @@ export interface TuiSetupCommandInput {
27
26
  /** The flow entry points the commands dispatch to, injectable for tests. */
28
27
  export interface TuiSetupFlows {
29
28
  runModelFlow: typeof runModelFlow;
30
- runVercelFlow: typeof runVercelFlow;
31
29
  runChannelsFlow: typeof runChannelsFlow;
32
30
  runDeployFlow: typeof runDeployFlow;
33
31
  }
@@ -37,7 +35,7 @@ export interface TuiSetupCommandResult {
37
35
  preserveFlowDiagnostics: boolean;
38
36
  }
39
37
  /**
40
- * Runs one TUI setup command (/model, /vercel, /channels, /deploy) over the
38
+ * Runs one TUI setup command (/model, /channels, /deploy) over the
41
39
  * shared setup flows, asking through the TUI's own bordered panel. Never throws:
42
40
  * every outcome — done, cancelled, failed — folds into the returned command
43
41
  * result. Known limitation: a flow cannot be cancelled mid-subprocess (keys
@@ -1 +1,2 @@
1
- import{createTuiPrompter}from"./tui-prompter.js";import{runDeployFlow}from"#setup/flows/deploy.js";import{runChannelsFlow}from"#setup/flows/channels.js";import{runVercelFlow}from"#setup/flows/vercel.js";import{runModelFlow}from"#setup/flows/model.js";import{WizardCancelledError}from"#setup/step.js";const SETUP_FLOW_TITLES={model:``,vercel:`Connect to Vercel`,channels:``,deploy:`Deploy to Vercel`};async function runTuiSetupCommand(t){let{command:n,appRoot:r}=t,i={runModelFlow,runVercelFlow,runChannelsFlow,runDeployFlow,...t.flows},a=(t.createPrompter??createTuiPrompter)(t.renderer);try{switch(n){case`model`:{let e=await i.runModelFlow({appRoot:r,prompter:a});return e.kind===`cancelled`?{message:`/model cancelled.`,preserveFlowDiagnostics:!1}:{message:e.message,preserveFlowDiagnostics:!1}}case`vercel`:{let e=await i.runVercelFlow({appRoot:r,prompter:a});return e.kind===`cancelled`?{message:`/vercel cancelled.`,preserveFlowDiagnostics:!1}:`outcome`in e?{message:`Using your own model provider — set its API key in .env.local.`,preserveFlowDiagnostics:!1}:{message:e.credential===void 0?`Project linked — no model credential found; set AI_GATEWAY_API_KEY in .env.local.`:`Project linked — connected to AI Gateway via ${e.credential}.`,preserveFlowDiagnostics:!1}}case`channels`:{let e=await i.runChannelsFlow({appRoot:r,prompter:a});return e.kind===`cancelled`?{message:`/channels cancelled.`,preserveFlowDiagnostics:!0}:{message:e.addedChannels.length===0?`No channels added.`:`Channels added: ${e.addedChannels.join(`, `)} — run /deploy to ship them.`,preserveFlowDiagnostics:!0}}case`deploy`:{let e=await i.runDeployFlow({appRoot:r,prompter:a,interactive:!0});return e.kind===`cancelled`?{message:`/deploy cancelled.`,preserveFlowDiagnostics:!0}:e.kind===`needs-link`?{message:`Not linked to a Vercel project — run /vercel first.`,preserveFlowDiagnostics:!0}:{message:e.productionUrl===void 0?`Deployed.`:`Deployed: ${e.productionUrl}`,preserveFlowDiagnostics:!0}}}}catch(e){return e instanceof WizardCancelledError?{message:`/${n} cancelled.`,preserveFlowDiagnostics:n!==`vercel`}:{message:`/${n} failed: ${e instanceof Error?e.message:String(e)}`,preserveFlowDiagnostics:!0}}finally{t.renderer.setStatus(void 0)}}export{SETUP_FLOW_TITLES,runTuiSetupCommand};
1
+ import{createTuiPrompter}from"./tui-prompter.js";import{runDeployFlow}from"#setup/flows/deploy.js";import{runChannelsFlow}from"#setup/flows/channels.js";import{runModelFlow}from"#setup/flows/model.js";import{WizardCancelledError}from"#setup/step.js";const SETUP_FLOW_TITLES={model:``,channels:``,deploy:`Deploy to Vercel`};async function runTuiSetupCommand(r){let{command:i,appRoot:a}=r,o={runModelFlow,runChannelsFlow,runDeployFlow,...r.flows},s=(r.createPrompter??createTuiPrompter)(r.renderer);try{switch(i){case`model`:{let e=await o.runModelFlow({appRoot:a,prompter:s});if(e.kind===`cancelled`)return{message:`/model cancelled.`,preserveFlowDiagnostics:!1};let t=[];return e.modelMessage!==void 0&&t.push(e.modelMessage),e.providerOutcome!==void 0&&t.push(providerOutcomeMessage(e.providerOutcome)),{message:t.join(`
2
+ `),preserveFlowDiagnostics:!1}}case`channels`:{let e=await o.runChannelsFlow({appRoot:a,prompter:s});return e.kind===`cancelled`?{message:`/channels cancelled.`,preserveFlowDiagnostics:!0}:{message:e.addedChannels.length===0?`No channels added.`:`Channels added: ${e.addedChannels.join(`, `)} — run /deploy to ship them.`,preserveFlowDiagnostics:!0}}case`deploy`:{let e=await o.runDeployFlow({appRoot:a,prompter:s,interactive:!0});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}}}}catch(e){return e instanceof WizardCancelledError?{message:`/${i} cancelled.`,preserveFlowDiagnostics:i!==`model`}:{message:`/${i} failed: ${e instanceof Error?e.message:String(e)}`,preserveFlowDiagnostics:!0}}finally{r.renderer.setStatus(void 0)}}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_TITLES,runTuiSetupCommand};
@@ -1,3 +1,4 @@
1
+ import type { SelectNotice } from "#setup/prompter.js";
1
2
  import type { SetupPanelOption } from "./setup-panel.js";
2
3
  export interface SetupFlowRenderer {
3
4
  begin(title: string): void;
@@ -13,6 +14,8 @@ export interface SetupFlowRenderer {
13
14
  initialValue?: string;
14
15
  initialValues?: readonly string[];
15
16
  placeholder?: string;
17
+ layout?: "stacked";
18
+ notices?: readonly SelectNotice[];
16
19
  }): Promise<readonly string[] | undefined>;
17
20
  readText(options: {
18
21
  message: string;
@@ -3,7 +3,7 @@ import type { AgentInfoResult } from "#client/index.js";
3
3
  export interface SetupIssue {
4
4
  /** Short category label, e.g. "AI Gateway credentials". */
5
5
  label: string;
6
- /** The slash command that fixes it, e.g. "/vercel". */
6
+ /** The slash command that fixes it, e.g. "/model". */
7
7
  command: string;
8
8
  }
9
9
  /** What a boot detection may inspect. */
@@ -1 +1 @@
1
- import{join}from"node:path";import{pathExists}from"#setup/path-exists.js";const BOOT_DETECTIONS=[{id:`model-provider`,async detect({appRoot:n,env:r}){return r.AI_GATEWAY_API_KEY||r.VERCEL_OIDC_TOKEN?[]:await pathExists(join(n,`.vercel`,`project.json`))?[{label:`AI Gateway credentials missing`,command:`/vercel`}]:[{label:`model provider not linked`,command:`/vercel`}]}}];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 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,detectSetupIssues,formatSetupIssuesLine};
1
+ import{join}from"node:path";import{pathExists}from"#setup/path-exists.js";const BOOT_DETECTIONS=[{id:`model-provider`,async detect({appRoot:n,env:r}){return r.AI_GATEWAY_API_KEY||r.VERCEL_OIDC_TOKEN?[]:await pathExists(join(n,`.vercel`,`project.json`))?[{label:`AI Gateway credentials missing`,command:`/model`}]:[{label:`model provider not linked`,command:`/model`}]}}];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 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,detectSetupIssues,formatSetupIssuesLine};
@@ -14,6 +14,7 @@
14
14
  */
15
15
  import type { PromptOption } from "#setup/cli/index.js";
16
16
  import { type SelectState } from "#setup/cli/select-state.js";
17
+ import type { SelectNotice } from "#setup/prompter.js";
17
18
  import { type LineState } from "./line-editor.js";
18
19
  import type { Theme } from "./theme.js";
19
20
  /** One row of a setup select panel; the shared prompt-option shape. */
@@ -26,6 +27,10 @@ export interface SetupSelectPanelState {
26
27
  placeholder?: string;
27
28
  select: SelectState;
28
29
  error?: string;
30
+ /** "stacked" puts each hint on its own line with blank rows between options. */
31
+ layout?: "stacked";
32
+ /** Outcome lines from earlier menu laps, shown beneath the options. */
33
+ notices?: readonly SelectNotice[];
29
34
  }
30
35
  export interface SetupTextPanelState {
31
36
  message: string;
@@ -45,7 +50,7 @@ export interface FlowPanelLine {
45
50
  }
46
51
  /** The whole bordered section: title, recent progress, question or status. */
47
52
  export interface FlowPanelState {
48
- /** The invoked command, e.g. "/vercel". Empty renders no title row. */
53
+ /** The invoked command, e.g. "/deploy". Empty renders no title row. */
49
54
  title: string;
50
55
  lines: readonly FlowPanelLine[];
51
56
  /** Ephemeral status shown when no question is active. */
@@ -1 +1 @@
1
- import{sliceVisible,visibleLength}from"./terminal-text.js";import{visibleLine}from"./line-editor.js";import{filterOptions,submitRowIndex}from"#setup/cli/select-state.js";function clip(n,r){return visibleLength(n)>r?sliceVisible(n,r):n}function questionFooter(e,t){let n=t.colors;return[``,` ${n.dim(n.italic(e.join(` ${t.glyph.dot} `)))}`]}function toneGlyph(e,t){let n=t.colors;switch(e){case`success`:return n.green(t.glyph.success);case`warning`:return n.yellow(t.glyph.warning);case`error`:return n.red(t.glyph.error);case`info`:return n.dim(t.glyph.dot)}}function renderFlowPanel(e,t,n){let r=t.colors,i=[r.dim(t.glyph.hrule.repeat(Math.max(1,n)))];e.title.length>0&&i.push(` ${r.blue(r.bold(e.title))}`),i.push(``);let a=e.lines.slice(-6);for(let e of a){let n=e.tone===`info`?r.dim(e.text):e.text;i.push(`${toneGlyph(e.tone,t)} ${n}`)}return a.length>0&&i.push(``),e.question===void 0?e.status===void 0?e.preview===void 0?i.push(`${r.yellow(e.frame??``)} ${r.dim(`Working…`)}`):i.push(`${r.yellow(e.frame??``)} ${r.dim(e.preview)}`):(i.push(`${r.yellow(e.status.frame)} ${r.dim(e.status.text)}`),e.preview!==void 0&&i.push(` ${r.dim(e.preview)}`)):i.push(...e.question),i.map(e=>clip(e,n))}function optionRow(e){let{option:t,theme:n}=e,r=n.colors,i=e.isCursor?r.cyan(n.glyph.prompt):` `,a=e.number===void 0?``:`${e.number}. `,o=e.checkbox?`${t.locked?r.dim(`◼`):e.isChecked?r.green(`◼`):r.dim(`◻`)} `:``,s=t.label;t.disabled?s=r.dim(`${s}${t.disabledReason?` (${t.disabledReason})`:``}`):t.locked?s=r.dim(`${s}${t.lockedReason?` (${t.lockedReason})`:``}`):e.isCursor&&(s=r.blue(s));let c=t.hint?r.dim(` ${n.glyph.dot} ${t.hint}`):``;return`${i} ${a}${o}${s}${c}`}function renderSelectQuestion(e,t,n){let a=t.colors,o=e.search?filterOptions(e.options,e.select.filter):e.options,s=e.multiple?submitRowIndex(o):-1,c=e.select.cursor,l=[` ${a.bold(e.message)}`,``],u=numbersSelectRows(e);if(e.search){let n=e.select.filter.length>0?e.select.filter+a.dim(t.glyph.caret):e.placeholder===void 0?a.dim(t.glyph.caret):a.dim(e.placeholder);l.push(` ${n}`,``)}let d=0;for(;o[d]?.featured;)d+=1;let f=e.search&&e.select.filter===``&&d>0?Math.min(d,8):e.search?8:o.length,p=Math.max(0,Math.min(c-Math.floor(f/2),Math.max(0,o.length-f))),m=Math.min(p+f,o.length);o.length===0&&l.push(` ${a.dim(`(no matches)`)}`);for(let n=p;n<m;n+=1){let r=o[n],i=n===c,s={option:r,isCursor:i,isChecked:e.multiple&&e.select.selected.has(r.value),checkbox:e.multiple,theme:t};u&&(s.number=n+1),l.push(optionRow(s)),i&&r.description&&!r.disabled&&l.push(` ${a.dim(r.description)}`)}if(e.multiple&&s>=0){let e=c===s,n=e?a.cyan(t.glyph.prompt):` `,r=e?a.blue(a.bold(`Submit`)):`Submit`;l.push(``,`${n} ${r}`)}o.length>m-p&&l.push(` ${a.dim(`↑↓ ${o.length} options, showing ${p+1}–${m}`)}`),e.error!==void 0&&l.push(``,` ${a.red(e.error)}`);let h=[];return e.search&&h.push(`type to filter`),h.push(`↑/↓ move`),h.push(e.multiple?`space to toggle`:`enter to select`),e.multiple&&h.push(`enter on Submit to confirm`),h.push(`esc to cancel`),l.push(...questionFooter(h,t)),l.map(e=>clip(e,n))}function numbersSelectRows(e){return!e.multiple&&!e.search&&e.options.length>1}function renderTextQuestion(e,t,r,i){let a=t.colors,o=[` ${a.bold(e.message)}`,``],s=Math.max(4,r-4),{before:c,after:l}=visibleLine(e.mask?{text:`•`.repeat(e.editor.text.length),cursor:e.editor.cursor}:{text:e.editor.text,cursor:e.editor.cursor},s,t.glyph.ellipsis),u=i?a.cyan(t.glyph.caret):` `,d=e.editor.text.length===0&&e.placeholder!==void 0?`${u}${a.dim(e.placeholder)}`:`${c}${u}${l}`;return o.push(` ${d}`),e.error!==void 0&&o.push(``,` ${a.red(e.error)}`),o.push(...questionFooter([`enter to submit`,`esc to cancel`],t)),o.map(e=>clip(e,r))}function renderAcknowledgeQuestion(e,t,n){let r=t.colors,i=[` ${r.bold(e.message)}`];if(e.lines.length>0){i.push(``);for(let t of e.lines)i.push(` ${r.dim(t)}`)}return i.push(...questionFooter([`enter to continue`],t)),i.map(e=>clip(e,n))}export{numbersSelectRows,renderAcknowledgeQuestion,renderFlowPanel,renderSelectQuestion,renderTextQuestion};
1
+ import{sliceVisible,visibleLength}from"./terminal-text.js";import{visibleLine}from"./line-editor.js";import{filterOptions,submitRowIndex}from"#setup/cli/select-state.js";function clip(n,r){return visibleLength(n)>r?sliceVisible(n,r):n}function questionFooter(e,t){let n=t.colors;return[``,` ${n.dim(n.italic(e.join(` ${t.glyph.dot} `)))}`]}const BOLD_OR_DIM_CLOSE=`\x1B[22m`;function dimWithEmphasis(e,t){return t.colors.dim(e.replaceAll(BOLD_OR_DIM_CLOSE,`${BOLD_OR_DIM_CLOSE}`))}function toneGlyph(e,t){let n=t.colors;switch(e){case`success`:return n.green(t.glyph.success);case`warning`:return n.yellow(t.glyph.warning);case`error`:return n.red(t.glyph.error);case`info`:return n.dim(t.glyph.dot)}}function renderFlowPanel(e,t,n){let r=t.colors,i=[r.dim(t.glyph.hrule.repeat(Math.max(1,n)))];e.title.length>0&&i.push(` ${r.blue(r.bold(e.title))}`),i.push(``);let a=e.lines.slice(-6);for(let e of a){let n=e.tone===`info`?r.dim(e.text):e.text;i.push(`${toneGlyph(e.tone,t)} ${n}`)}return a.length>0&&i.push(``),e.question===void 0?e.status===void 0?e.preview===void 0?i.push(`${r.yellow(e.frame??``)} ${r.dim(`Working…`)}`):i.push(`${r.yellow(e.frame??``)} ${r.dim(e.preview)}`):(i.push(`${r.yellow(e.status.frame)} ${r.dim(e.status.text)}`),e.preview!==void 0&&i.push(` ${r.dim(e.preview)}`)):i.push(...e.question),i.map(e=>clip(e,n))}function optionRow(e){let{option:t,theme:n}=e,r=n.colors,i=e.isCursor?r.cyan(n.glyph.prompt):` `,a=e.number===void 0?``:`${e.number}. `,o=e.checkbox?`${t.locked?r.dim(`◼`):e.isChecked?r.green(`◼`):r.dim(`◻`)} `:``,s=t.label;t.disabled?s=r.dim(`${s}${t.disabledReason?` (${t.disabledReason})`:``}`):t.locked?s=r.dim(`${s}${t.lockedReason?` (${t.lockedReason})`:``}`):e.isCursor&&(s=r.blue(s));let c=t.hint?r.dim(` ${n.glyph.dot} ${t.hint}`):``;return`${i} ${a}${o}${s}${c}`}function renderSelectQuestion(e,t,n){let a=t.colors,o=e.search?filterOptions(e.options,e.select.filter):e.options,s=e.multiple?submitRowIndex(o):-1,c=e.select.cursor,l=[` ${a.bold(e.message)}`,``],u=numbersSelectRows(e);if(e.search){let n=e.select.filter.length>0?e.select.filter+a.dim(t.glyph.caret):e.placeholder===void 0?a.dim(t.glyph.caret):a.dim(e.placeholder);l.push(` ${n}`,``)}let d=0;for(;o[d]?.featured;)d+=1;let f=e.search&&e.select.filter===``&&d>0?Math.min(d,8):e.search?8:o.length,p=Math.max(0,Math.min(c-Math.floor(f/2),Math.max(0,o.length-f))),m=Math.min(p+f,o.length);o.length===0&&l.push(` ${a.dim(`(no matches)`)}`);for(let n=p;n<m;n+=1){let r=o[n],i=n===c,s=e.layout===`stacked`,d=r;if(s&&r.hint!==void 0){let{hint:e,...t}=r;d=t}let f={option:d,isCursor:i,isChecked:e.multiple&&e.select.selected.has(r.value),checkbox:e.multiple,theme:t};if(u&&(f.number=n+1),l.push(optionRow(f)),s&&r.hint!==void 0){let e=` `.repeat(2+(u?`${n+1}. `.length:0));l.push(`${e}${dimWithEmphasis(r.hint,t)}`)}i&&r.description&&!r.disabled&&l.push(` ${a.dim(r.description)}`),s&&n<m-1&&l.push(``)}if(e.multiple&&s>=0){let e=c===s,n=e?a.cyan(t.glyph.prompt):` `,r=e?a.blue(a.bold(`Submit`)):`Submit`;l.push(``,`${n} ${r}`)}if(o.length>m-p&&l.push(` ${a.dim(`↑↓ ${o.length} options, showing ${p+1}–${m}`)}`),e.notices!==void 0&&e.notices.length>0){l.push(``);for(let n of e.notices){let e=n.tone===`info`?a.dim(n.text):n.text;l.push(` ${toneGlyph(n.tone,t)} ${e}`)}}e.error!==void 0&&l.push(``,` ${a.red(e.error)}`);let h=[];return e.search&&h.push(`type to filter`),h.push(`↑/↓ move`),h.push(e.multiple?`space to toggle`:`enter to select`),e.multiple&&h.push(`enter on Submit to confirm`),h.push(`esc to cancel`),l.push(...questionFooter(h,t)),l.map(e=>clip(e,n))}function numbersSelectRows(e){return!e.multiple&&!e.search&&e.options.length>1}function renderTextQuestion(e,t,r,i){let a=t.colors,o=[` ${a.bold(e.message)}`,``],s=Math.max(4,r-4),{before:c,after:l}=visibleLine(e.mask?{text:`•`.repeat(e.editor.text.length),cursor:e.editor.cursor}:{text:e.editor.text,cursor:e.editor.cursor},s,t.glyph.ellipsis),u=i?a.cyan(t.glyph.caret):` `,d=e.editor.text.length===0&&e.placeholder!==void 0?`${u}${a.dim(e.placeholder)}`:`${c}${u}${l}`;return o.push(` ${d}`),e.error!==void 0&&o.push(``,` ${a.red(e.error)}`),o.push(...questionFooter([`enter to submit`,`esc to cancel`],t)),o.map(e=>clip(e,r))}function renderAcknowledgeQuestion(e,t,n){let r=t.colors,i=[` ${r.bold(e.message)}`];if(e.lines.length>0){i.push(``);for(let t of e.lines)i.push(` ${r.dim(t)}`)}return i.push(...questionFooter([`enter to continue`],t)),i.map(e=>clip(e,n))}export{numbersSelectRows,renderAcknowledgeQuestion,renderFlowPanel,renderSelectQuestion,renderTextQuestion};
@@ -73,7 +73,7 @@ export declare class TerminalRenderer implements AgentTUIRenderer {
73
73
  renderSetupWarning(text: string): void;
74
74
  /**
75
75
  * Commits one command's outcome under its invocation with the elbow
76
- * connector (` ⎿ /vercel cancelled.`), Claude Code's sub-result grammar.
76
+ * connector (` ⎿ /model cancelled.`), Claude Code's sub-result grammar.
77
77
  */
78
78
  renderCommandResult(text: string): void;
79
79
  shutdown(): void;
@@ -1,5 +1,5 @@
1
1
  import{summarizeToolArgs,summarizeToolResult}from"./tool-format.js";import{buildAgentHeader}from"./agent-header.js";import{sliceVisible,stripAnsi,visibleLength}from"./terminal-text.js";import{PROMPT_COMMANDS,isPromptControlCommand,parsePromptCommand}from"./prompt-commands.js";import{renderBlockLines}from"./blocks.js";import{dismissTypeahead,isTypeaheadOpen,moveTypeaheadSelection,renderCommandSuggestions,selectedTypeaheadCommand,typeaheadCompletion,typeaheadFor}from"./command-typeahead.js";import{interruptedError}from"./errors.js";import{EMPTY_LINE,PromptHistory,backspace,deleteForward,deleteWord,insert,killToEnd,killToStart,lineOf,moveEnd,moveHome,moveLeft,moveRight,visibleLine}from"./line-editor.js";import{LiveRegion}from"./live-region.js";import{numbersSelectRows,renderAcknowledgeQuestion,renderFlowPanel,renderSelectQuestion,renderTextQuestion}from"./setup-panel.js";import{createTheme,detectUnicode}from"./theme.js";import{formatAssistantResponseStats,formatTokenCount,nextKey,takeUntil}from"./stream-format.js";import{toErrorMessage}from"#shared/errors.js";import{filterOptions,initialSelectState,orderedSelection,reduceSelect,selectValueAtCursor,submitRowIndex}from"#setup/cli/select-state.js";const STATUS={processing:`Working…`,toolResults:`Reading results…`,streaming:`Responding…`,executingTools:`Running tools…`,connectionAuth:`Waiting for connection authorization…`};var TerminalRenderer=class{#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;#u;#d;#f=[];#p=new Map;#m=new Set;#h=new Set;#g=new Map;#_=new Set;#v;#y=!1;#b;#x=0;#S=``;#C=0;#w=new PromptHistory;#T=!1;#E;#D=!1;#O=STATUS.processing;#k=`Eve`;#A=!1;#j=!1;#M=!0;#N=0;#P;#F;#I;#L=``;#R;#z;#B;#V=!1;#H=!1;#U;#W;#G;#K;#q;#J;#Y=``;#X=``;#Z;#Q;setupFlow={begin:e=>this.#te(e),end:e=>this.#ne(e?.preserveDiagnostics??!0),readSelect:e=>this.#re(e),readText:e=>this.#ie(e),readAcknowledge:e=>this.#ae(e),setStatus:e=>this.#ce(e),renderLine:(e,t)=>this.#le(e,t),renderOutput:e=>this.#ue(e)};constructor(e){this.#e=e?.input??process.stdin,this.#t=e?.output??process.stdout,this.#n=new LiveRegion(this.#t),this.#r=createTheme({color:e?.color??!0,unicode:e?.unicode??detectUnicode()}),this.#i=e?.tools??`auto-collapsed`,this.#a=e?.reasoning??`full`,this.#o=e?.subagents??`auto-collapsed`,this.#s=e?.connectionAuth??`full`,this.#c=e?.assistantResponseStats??`tokensPerSecond`,this.#l=e?.contextSize,this.#W=e?.contextSize,this.#u=e?.captureForeignOutput??this.#t===process.stdout,this.#d=e?.logs??`all`}renderAgentHeader(e){if(this.#k=e.name,this.#v=e,this.#de(),this.#y){this.#we({kind:`agent-header`,body:this.#Be().join(`
2
- `),live:!1}),this.#Re();return}this.#y=!0,this.#n.flush(this.#Be(),[])}async readPrompt(e){this.#de(e),this.#T=!0,this.#D=!1,this.#O=``;let t=lineOf(``);return this.#w.begin(t.text),this.#$(t),this.#E=typeaheadFor(PROMPT_COMMANDS,t.text),this.#ye(),this.#Re(),await new Promise((e,n)=>{let apply=e=>{t=e,this.#xe(),this.#$(t),this.#E=typeaheadFor(PROMPT_COMMANDS,e.text,this.#E),this.#Re()},recall=e=>{e!==void 0&&apply(lineOf(e))},interrupt=()=>{this.#E=void 0,this.#be(),this.#fe(),n(interruptedError())},suggestions=()=>this.#E!==void 0&&isTypeaheadOpen(this.#E)?this.#E:void 0,highlighted=()=>{let e=suggestions();return e===void 0?void 0:selectedTypeaheadCommand(e)};this.#I=n=>{switch(n.type){case`character`:apply(insert(t,n.value));break;case`backspace`:apply(backspace(t));break;case`delete`:apply(deleteForward(t));break;case`left`:apply(moveLeft(t));break;case`right`:apply(moveRight(t));break;case`home`:case`ctrl-a`:apply(moveHome(t));break;case`end`:case`ctrl-e`:apply(moveEnd(t));break;case`ctrl-k`:apply(killToEnd(t));break;case`ctrl-u`:apply(killToStart(t));break;case`ctrl-w`:apply(deleteWord(t));break;case`up`:{let e=suggestions();e===void 0?recall(this.#w.previous(t.text)):(this.#E=moveTypeaheadSelection(e,-1),this.#Re());break}case`down`:{let e=suggestions();e===void 0?recall(this.#w.next()):(this.#E=moveTypeaheadSelection(e,1),this.#Re());break}case`tab`:{let e=highlighted();e!==void 0&&apply(lineOf(typeaheadCompletion(e)));break}case`escape`:{let e=suggestions();e!==void 0&&(this.#E=dismissTypeahead(e),this.#Re());break}case`enter`:{let n=highlighted(),r=n!==void 0&&parsePromptCommand(t.text)===null?typeaheadCompletion(n).trimEnd():t.text;this.#E=void 0,this.#w.add(r),this.#T=!1,this.#be(),this.#O=STATUS.processing,isPromptControlCommand(r)?this.#we({kind:`command`,body:r.trim(),live:!1}):(this.#Te(r),this.#Z=r),this.#$(EMPTY_LINE),this.#Re(),this.#me(),e(r);break}case`ctrl-d`:t.text.length===0?interrupt():apply(deleteForward(t));break;case`ctrl-l`:case`ctrl-r`:this.#Re();break;case`ctrl-c`:interrupt();break;default:break}},this.#pe()})}#$(e){this.#S=e.text,this.#C=e.cursor}async renderStream(e,t){this.#de(t),this.#m.clear(),this.#T=!1,this.#D=!0,this.#O=STATUS.processing,this.#Ee(t?.submittedPrompt),this.#j=!1,this.#U=void 0,this.#G=void 0,this.#K=void 0,this.#q=Date.now();let n={tools:t?.tools??this.#i,reasoning:t?.reasoning??this.#a,assistantResponseStats:t?.assistantResponseStats??this.#c};this.#Se(),this.#Re();let r=new Promise(e=>{this.#B=e});this.#I=e=>this.#ve(e),this.#pe();let i={text:new Map,reasoning:new Map,tools:new Map,hasPendingToolResults:!1};try{for await(let t of takeUntil(iterateTUIStream(e.events),r)){if(this.#j)break;this.#Me(t,n,i)}}catch(e){this.#De(`Error`,toErrorMessage(e))}finally{this.#B=void 0,this.#j&&e.abort?.(),this.#me(),this.#Ce(),this.#D=!1,this.#O=this.#j?`Interrupted`:t?.continueSession?`Ready`:`Done`,this.#je(),this.#Re(),(this.#j||!t?.continueSession)&&this.#fe()}if(this.#j)throw interruptedError()}async readToolApproval(e,t){return this.#de(t),this.#T=!1,this.#D=!1,this.#O=`Approve ${formatToolApprovalTitle(e)}? (y/n)`,this.#j=!1,this.#Re(),await new Promise((t,n)=>{this.#I=r=>{switch(r.type){case`character`:{let n=r.value.toLowerCase();n===`y`?(this.#O=STATUS.processing,this.#me(),this.#Re(),t({approved:!0})):n===`n`&&(this.#O=STATUS.processing,this.#ee(e.toolCallId),this.#me(),this.#Re(),t({approved:!1,reason:`Denied by user.`}));break}case`ctrl-r`:this.#Re();break;case`ctrl-c`:this.#j=!0,this.#fe(),n(interruptedError());break;default:break}},this.#pe()})}async readInputQuestion(e,t){this.#de(t),this.#T=!1,this.#D=!1,this.#j=!1;let n=e.options??[],r=n.length>0,i=(e.allowFreeform===!0||!r)&&r,a=n.length+ +!!i,o=questionSectionId(e.requestId),s=r?`select`:`text`,c=0,l=``,isOnFreeformRow=()=>i&&c===n.length,renderSection=()=>{this.#ke({id:o,kind:`question`,title:e.prompt,body:formatQuestionContent(e,c,this.#r),preformatted:!0,live:!0})},repaintStatus=()=>{if(s===`select`){let e=isOnFreeformRow()?`type`:`select`;this.#O=`↑/↓ move · enter ${e} · Ctrl+C quit`,this.#T=!1}else this.#T=!0,this.#$(lineOf(l)),this.#O=``;this.#Re()};renderSection(),s===`text`&&this.#ye(),repaintStatus();let finalize=t=>{this.#ke({id:o,kind:`question`,title:e.prompt,body:` ${this.#r.colors.green(this.#r.glyph.success)} ${t.label}`,preformatted:!0,live:!1}),this.#T=!1,this.#O=STATUS.processing,this.#be(),this.#me(),this.#Re();let n={};return t.optionId!==void 0&&(n.optionId=t.optionId),t.text!==void 0&&(n.text=t.text),n};return await new Promise((t,i)=>{this.#I=o=>{if(o.type===`ctrl-c`){this.#j=!0,this.#be(),this.#fe(),i(interruptedError());return}if(o.type===`ctrl-r`){this.#Re();return}if(s===`select`){switch(o.type){case`up`:a>0&&(c=(c-1+a)%a,renderSection(),repaintStatus());break;case`down`:a>0&&(c=(c+1)%a,renderSection(),repaintStatus());break;case`enter`:{if(isOnFreeformRow()){s=`text`,l=``,this.#ye(),repaintStatus();break}let e=n[c];e&&t(finalize({optionId:e.id,label:e.label}));break}default:break}return}switch(o.type){case`character`:l+=o.value,this.#xe(),repaintStatus();break;case`backspace`:l=l.slice(0,-1),this.#xe(),repaintStatus();break;case`enter`:{let n=resolveQuestionText(l,e);if(n===void 0)break;t(finalize(n));break}case`escape`:if(r){if(l.length>0){l=``,this.#xe(),repaintStatus();break}s=`select`,l=``,this.#T=!1,this.#be(),repaintStatus();break}l=``,this.#xe(),repaintStatus();break;default:break}},this.#pe()})}upsertSubagentStep(e){if(this.#o===`hidden`)return;let t=e.reasoning?.trim()??``,n=e.message?.trim()??``;if(!(t.length===0&&n.length===0)){if(this.#Oe(e.callId,e.subagentName),this.#o===`collapsed`){this.#Re();return}this.#ke({id:subagentStepSectionId(e.callId,e.sectionKey),kind:`subagent-step`,depth:1,reasoning:t,body:n,live:!e.finalized}),this.#Re()}}upsertSubagentTool(n){if(this.#o===`hidden`)return;if(this.#Oe(n.callId,n.subagentName),this.#o===`collapsed`){this.#Re();return}let r=subagentToolStatus(n.status),i={id:subagentToolSectionId(n.callId,n.childCallId),kind:`subagent-tool`,depth:1,title:n.toolName,subtitle:summarizeToolArgs(n.input),status:r,live:r===`running`||r===`approval`,expanded:this.#o===`full`,toolInput:n.input};n.output===void 0?n.errorText!==void 0&&(i.result=n.errorText):(i.result=summarizeToolResult(n.output),i.toolOutput=n.output),this.#ke(i),this.#Re()}markChildToolCallId(e){this.#h.add(e);let t=this.#g.get(e);t!==void 0&&(this.#Ae(t),this.#g.delete(e),this.#Re())}#ee(e){let t=this.#p.get(toolSectionId(e));t!==void 0&&(t.status=`denied`,t.live=!1)}upsertConnectionAuth(e){if(this.#s===`hidden`)return;let t=e.state===`authorized`||e.state===`declined`||e.state===`failed`||e.state===`timed-out`;this.#ke({id:connectionAuthSectionId(e.name),kind:`connection-auth`,title:`${e.name} · authorization · ${e.state}`,body:formatConnectionAuthContent(e),preformatted:!0,live:!t}),this.#Re()}setConnectionAuthPendingCount(e){let t=Math.max(0,e);if(t===this.#x)return;let n=this.#x>0;this.#x=t,t>0?(this.#O=STATUS.connectionAuth,this.#Re()):n&&(this.#O=STATUS.processing,this.#Re())}reset(){this.#f=[],this.#p.clear(),this.#m.clear(),this.#b=void 0,this.#v=void 0,this.#y=!1,this.#h.clear(),this.#g.clear(),this.#_.clear(),this.#Z=void 0,this.#x=0,this.#U=void 0,this.#G=void 0,this.#K=void 0,this.#q=void 0,this.#A&&(this.#n.clearAll(),this.#Re())}renderNotice(e){e.trim().length!==0&&(this.#de(),this.#we({kind:`notice`,body:e,live:!1}),this.#Re())}renderSetupWarning(e){e.trim().length!==0&&(this.#de(),this.#we({kind:`warning`,body:e,live:!1}),this.#Re())}renderCommandResult(e){e.trim().length!==0&&(this.#de(),this.#we({kind:`result`,body:e,live:!1}),this.#Re())}#te(e){this.#de(),this.#T=!1,this.#D=!1,this.#O=``,this.#Q={title:e,lines:[],outputBuffer:[]},this.#Se(),this.#Re()}#ne(e){let t=this.#Q;if(t!==void 0){if(this.#Q=void 0,this.#Ce(),e)for(let e of t.lines)(e.tone===`warning`||e.tone===`error`)&&this.#we({kind:`flow`,title:e.tone,body:e.text,live:!1});this.#Re()}}async#re(e){this.#de(),this.#T=!1,this.#D=!1,this.#O=``;let t={options:e.options,submitRow:e.multiple},n={options:e.options,submitRow:e.multiple};e.initialValue!==void 0&&(n.defaultValue=e.initialValue),e.initialValues!==void 0&&(n.initialValues=e.initialValues);let r=initialSelectState(n),i,a=this.#oe(),panelState=()=>{let t={message:e.message,options:e.options,multiple:e.multiple,search:e.search,select:r};return e.placeholder!==void 0&&(t.placeholder=e.placeholder),i!==void 0&&(t.error=i),t};return a.question=e=>renderSelectQuestion(panelState(),this.#r,e),this.#Re(),await new Promise(n=>{let settle=e=>{this.#se(),n(e)},apply=e=>{r=reduceSelect(r,e,t),i=void 0,this.#Re()};this.#I=n=>{switch(n.type){case`ctrl-c`:case`escape`:settle(void 0);return;case`ctrl-r`:this.#Re();return;case`up`:apply({type:`up`});return;case`down`:apply({type:`down`});return;case`backspace`:e.search&&apply({type:`backspace`});return;case`character`:if(e.multiple&&n.value===` `){apply({type:`toggle`});return}if(numbersSelectRows(e)&&/^[1-9]$/.test(n.value)){let t=Number(n.value)-1,a=e.options[t];a!==void 0&&!a.disabled&&!a.locked&&(r={...r,cursor:t},i=void 0,this.#Re());return}if(e.search){for(let e of n.value)e>=` `&&e!==``&&(r=reduceSelect(r,{type:`char`,char:e},t));i=void 0,this.#Re()}return;case`enter`:{let t=e.search?filterOptions(e.options,r.filter):[...e.options];if(e.multiple){if(r.cursor===submitRowIndex(t)){if(e.required&&r.selected.size===0){i=`Select at least one option, then submit.`,this.#Re();return}settle(orderedSelection(e.options,r.selected));return}apply({type:`toggle`});return}let n=selectValueAtCursor(t,r.cursor);if(n===void 0){i=`Type to match an option, then press enter.`,this.#Re();return}settle([n]);return}default:return}},this.#pe()})}async#ie(e){this.#de(),this.#T=!1,this.#D=!1,this.#O=``;let t=lineOf(``),n,r=this.#oe();return r.question=r=>{let i={message:e.message,editor:t,mask:e.mask===!0};return e.placeholder!==void 0&&(i.placeholder=e.placeholder),n!==void 0&&(i.error=n),renderTextQuestion(i,this.#r,r,this.#M)},this.#ye(),this.#Re(),await new Promise(r=>{let settle=e=>{this.#be(),this.#se(),r(e)},apply=e=>{t=e,n=void 0,this.#xe(),this.#Re()};this.#I=r=>{switch(r.type){case`ctrl-c`:case`escape`:settle(void 0);return;case`ctrl-r`:this.#Re();return;case`character`:apply(insert(t,r.value));return;case`backspace`:apply(backspace(t));return;case`delete`:apply(deleteForward(t));return;case`left`:apply(moveLeft(t));return;case`right`:apply(moveRight(t));return;case`home`:case`ctrl-a`:apply(moveHome(t));return;case`end`:case`ctrl-e`:apply(moveEnd(t));return;case`ctrl-k`:apply(killToEnd(t));return;case`ctrl-u`:apply(killToStart(t));return;case`ctrl-w`:apply(deleteWord(t));return;case`enter`:{let r=t.text.length>0?t.text:e.defaultValue??``,i=e.validate?.(r);if(i!==void 0){n=i,this.#Re();return}settle(r);return}default:return}},this.#pe()})}async#ae(e){this.#de(),this.#T=!1,this.#D=!1,this.#O=``;let t=this.#oe();return t.question=t=>renderAcknowledgeQuestion({message:e.message,lines:e.lines},this.#r,t),this.#Re(),await new Promise(e=>{this.#I=t=>{switch(t.type){case`enter`:case`escape`:case`ctrl-c`:this.#se(),e();return;case`ctrl-r`:this.#Re();return;default:return}},this.#pe()})}#oe(){return this.#Q===void 0&&(this.#Q={title:``,lines:[],outputBuffer:[]}),this.#Q}#se(){this.#Q!==void 0&&(this.#Q.question=void 0),this.#I=void 0,this.#me(),this.#Re()}#ce(e){if(this.#Q!==void 0){this.#Q.status=e,e===void 0&&(this.#Q.preview=void 0),this.#Re();return}if(e===void 0){this.#D=!1,this.#O=``,this.#Ce(),this.#Re();return}this.#de(),this.#D=!0,this.#O=e,this.#Se(),this.#Re()}#le(e,t){if(e.trim().length===0)return;let n=this.#Q;if(n!==void 0){if(n.preview=void 0,t===`warning`||t===`error`)for(let e of n.outputBuffer)n.lines.push({text:e,tone:`info`});n.outputBuffer=[],n.lines.push({text:e,tone:t}),this.#Re();return}this.#de(),this.#we({kind:`flow`,title:t,body:e,live:!1}),this.#Re()}#ue(e){if(e.trim().length===0)return;let t=this.#Q;if(t===void 0){this.#le(e,`info`);return}t.preview=e,t.outputBuffer.push(e),t.outputBuffer.length>8&&t.outputBuffer.shift(),this.#Re()}shutdown(){this.#fe()}#de(e){this.#k=e?.title??this.#k,this.#W=e?.contextSize??this.#l,!this.#A&&(this.#A=!0,this.#n.reset(),this.#n.hideCursor(),this.#qe(),this.#e.isTTY&&(this.#e.setRawMode?.(!0),this.#e.resume()),this.#z=()=>this.#Re(),this.#t.on(`resize`,this.#z))}#fe(){this.#me(),this.#be(),this.#Ce(),this.#A&&=(this.#Re(),this.#n.clear(),this.#n.showCursor(),this.#Je(),this.#n.newline(),this.#e.isTTY&&(this.#e.setRawMode?.(!1),this.#e.pause()),this.#z&&=(this.#t.off(`resize`,this.#z),void 0),!1)}#pe(){this.#e.on(`data`,this.#he)}#me(){this.#e.off(`data`,this.#he),this.#_e(),this.#L=``,this.#I=void 0}#he=e=>{this.#_e(),this.#L+=e.toString(`utf8`),this.#ge(),this.#L===`\x1B`&&(this.#R=setTimeout(()=>{this.#L===`\x1B`&&(this.#L=``,this.#I?.({type:`escape`}))},30),this.#R.unref?.())};#ge(){for(;this.#L.length>0;){let e=nextKey(this.#L);if(e.incomplete)return;this.#L=this.#L.slice(e.consumed),e.key&&e.key.type!==`ignore`&&this.#I?.(e.key)}}#_e(){this.#R&&=(clearTimeout(this.#R),void 0)}#ve(e){switch(e.type){case`ctrl-l`:case`ctrl-r`:this.#Re();break;case`ctrl-c`:this.#j=!0,this.#B?.();break;default:break}}#ye(){this.#be(),this.#xe(),this.#P=setInterval(()=>{this.#M=!this.#M,this.#Re()},500),this.#P.unref?.()}#be(){this.#P&&=(clearInterval(this.#P),void 0),this.#M=!0}#xe(){this.#M=!0}#Se(){this.#Ce(),this.#F=setInterval(()=>{this.#N+=1,this.#Re()},90),this.#F.unref?.()}#Ce(){this.#F&&=(clearInterval(this.#F),void 0)}#we(e){this.#f.push(e),e.id&&this.#p.set(e.id,e)}#Te(e){this.#we({kind:`user`,body:e,live:!1}),this.#Re()}#Ee(e){if(e!=null){if(this.#Z===e){this.#Z=void 0;return}this.#we({kind:`user`,body:e,live:!1})}}#De(e,t,n){let r={kind:`error`,title:e,body:t,live:!1};n!==void 0&&(r.detail=n),this.#we(r),this.#Re()}#Oe(e,t){this.#_.has(e)||(this.#_.add(e),this.#we({id:subagentHeaderId(e),kind:`subagent`,title:t,live:!1}))}#ke(e){if(e.id&&this.#m.has(e.id))return;let t=e.id?this.#p.get(e.id):void 0;if(t){Object.assign(t,e);return}this.#we(e)}#Ae(e){this.#f=this.#f.filter(t=>t.id!==e),this.#p.delete(e)}#je(){for(let e of this.#f)e.status!==`approval`&&(e.live=!1)}#Me(e,t,n){switch(e.type){case`step-start`:this.#Ne(n.hasPendingToolResults?STATUS.toolResults:STATUS.processing),n.hasPendingToolResults=!1;break;case`step-finish`:this.#Le(e.usage),this.#Re();break;case`assistant-delta`:{this.#Ne(STATUS.streaming);let t=(n.text.get(e.id)??``)+e.delta;n.text.set(e.id,t),this.#Pe(e.id,t,!0);break}case`assistant-complete`:{let t=n.text.get(e.id)??``,r=e.text!==void 0&&t.length===0?e.text??``:t;n.text.set(e.id,r),this.#Pe(e.id,r,!1);break}case`reasoning-delta`:{if(t.reasoning===`hidden`)break;this.#Ne(STATUS.streaming);let r=(n.reasoning.get(e.id)??``)+e.delta;n.reasoning.set(e.id,r),this.#Fe(e.id,r,!0,t);break}case`reasoning-complete`:{if(t.reasoning===`hidden`)break;let r=n.reasoning.get(e.id)??``;this.#Fe(e.id,r,!1,t);break}case`tool-call`:if(t.tools===`hidden`)break;this.#Ne(STATUS.executingTools),this.#Ie({input:e.input,status:`running`,toolCallId:e.toolCallId,toolName:e.toolName},t,n);break;case`tool-approval-request`:{if(t.tools===`hidden`)break;let r=n.tools.get(e.toolCallId);if(r===void 0)break;this.#Ie({...r,status:`approval`},t,n);break}case`tool-result`:{if(t.tools===`hidden`)break;let r=n.tools.get(e.toolCallId);if(r===void 0)break;n.hasPendingToolResults=!0,this.#Ne(STATUS.toolResults),this.#Ie({...r,output:e.output,status:`done`},t,n);break}case`tool-error`:{if(t.tools===`hidden`)break;let r=n.tools.get(e.toolCallId);if(r===void 0)break;n.hasPendingToolResults=!0,this.#Ne(STATUS.toolResults),this.#Ie({...r,errorText:e.errorText,status:`error`},t,n);break}case`error`:this.#De(`Error`,e.errorText,e.detail);break;case`finish`:this.#Le(e.usage),this.#Re();break}}#Ne(e){let t=this.#x>0?STATUS.connectionAuth:e;this.#O!==t&&(this.#O=t,this.#Re())}#Pe(e,t,n){let r=t.trim();r.length!==0&&(this.#ke({id:e,kind:`assistant`,body:r,live:n}),this.#Re())}#Fe(e,t,n,r){let i=t.trim();i.length!==0&&(this.#ke({id:e,kind:`reasoning`,body:i,collapsed:collapseReasoning(r.reasoning,n),live:n}),this.#Re())}#Ie(e,t,n){if(n.tools.set(e.toolCallId,e),this.#h.has(e.toolCallId))return;let r=toolSectionId(e.toolCallId);this.#g.set(e.toolCallId,r),this.#ke(renderNativeToolBlock(e,r,t.tools===`full`)),this.#Re()}#Le(e){if(e===void 0)return;let{inputTokens:t,outputTokens:n}=e;if((t!=null||n!=null)&&(this.#U=(t??0)+(n??0)),this.#G=n??this.#G,this.#G!=null&&this.#q!==void 0){let e=(Date.now()-this.#q)/1e3;e>0&&(this.#K=this.#G/e)}}#Re(){if(this.#A){if(this.#V){this.#H=!0;return}this.#V=!0;try{do this.#H=!1,this.#ze();while(this.#H)}finally{this.#V=!1}}}#ze(){if(!this.#A)return;let e=this.#Ge(),t=this.#Ue(e),n=Math.max(1,this.#Ke()-t.length),r=[],i=this.#b;for(;this.#f.length>0&&this.#f[0].live===!1;){let t=this.#f.shift(),n=this.#Ve(t,e,i);i=previousBlockOf(t),this.#b=i,r.push(...n),t.id&&(this.#m.add(t.id),this.#p.delete(t.id))}let a=[];for(let t of this.#f){let n=this.#Ve(t,e,i);i=previousBlockOf(t);for(let e=0;e<n.length;e+=1)a.push({block:t,row:n[e]})}let o=[...clipLiveRows(a.map(e=>e.row),n,e,this.#r),...t];r.length>0?this.#n.flush(r,o):this.#n.update(o)}#Be(){let e=this.#v;if(e===void 0)return[];let t={name:e.name,serverUrl:e.serverUrl,theme:this.#r,width:this.#Ge()};return e.info!==void 0&&(t.info=e.info),e.setupCommands!==void 0&&(t.setupCommands=e.setupCommands),buildAgentHeader(t)}#Ve(e,t,n){let r={spinner:this.#He()};n!==void 0&&(r.previous=n);let i=renderBlockLines(e,t,this.#r,r);return(e.depth??0)===0&&leadsWithGap(e,n)?[``,...i]:i}#He(){return this.#r.spinner[this.#N%this.#r.spinner.length]??``}#Ue(e){let t=this.#r.colors,n=[``],r=this.#Q;if(r!==void 0){let t={title:r.title,lines:r.lines,frame:this.#He()};return r.question===void 0?(r.status!==void 0&&(t.status={text:r.status,frame:this.#He()}),r.preview!==void 0&&(t.preview=r.preview)):t.question=r.question(e),n.push(...renderFlowPanel(t,this.#r,e)),n}if(this.#T){this.#E!==void 0&&isTypeaheadOpen(this.#E)&&n.push(...renderCommandSuggestions(this.#E,this.#r,e));let r=Math.max(4,e-3),{before:i,after:a}=visibleLine({text:this.#S,cursor:this.#C},r,this.#r.glyph.ellipsis),o=isPromptControlCommand(this.#S),style=e=>o&&e.length>0?t.blue(e):e,c=this.#M?t.cyan(this.#r.glyph.caret):` `;return n.push(`${t.cyan(this.#r.glyph.prompt)} ${style(i)}${c}${style(a)}`),n}let i=this.#D?t.yellow(this.#He()):t.dim(this.#r.glyph.dot),a=this.#O.length>0?this.#O:`Ready`,o=this.#D?t.dim(a):a,c=this.#We(),l=c?`${i} ${o} ${t.dim(this.#r.glyph.dot)} ${c}`:`${i} ${o}`;return n.push(clip(l,e)),n}#We(){let e=this.#r.colors,t=[],n=formatTokenCount(this.#U,this.#W);n&&t.push(n);let r=formatAssistantResponseStats({totalTokens:this.#U,outputTokens:this.#G,tokensPerSecond:this.#K},this.#c);return r&&t.push(r),this.#D&&t.push(`Ctrl+C to interrupt`),t.length>0?e.dim(t.join(` ${this.#r.glyph.dot} `)):``}#Ge(){return Math.max(20,this.#t.columns||80)}#Ke(){return Math.max(8,this.#t.rows||24)}#qe(){if(this.#J!==void 0||!this.#u)return;this.#Y=``,this.#X=``;let capture=(e,t)=>{let n=e.write.bind(e);return e.write=((e,n,r)=>{let i=typeof n==`string`?n:void 0,a=typeof n==`function`?n:r;return this.#Ye(t,chunkToString(e,i)),a?.(),!0}),()=>{e.write=n}},e=capture(process.stdout,`stdout`),t=capture(process.stderr,`stderr`);this.#J=()=>{e(),t()}}#Je(){let e=this.#J;e!==void 0&&(this.#J=void 0,e(),this.#Y.length>0&&(this.#Xe(`stdout`)&&process.stdout.write(`${this.#Y}\n`),this.#Y=``),this.#X.length>0&&(this.#Xe(`stderr`)&&process.stderr.write(`${this.#X}\n`),this.#X=``))}#Ye(e,t){let n=(e===`stdout`?this.#Y:this.#X)+t,r=n.lastIndexOf(`
2
+ `),live:!1}),this.#Re();return}this.#y=!0,this.#n.flush(this.#Be(),[])}async readPrompt(e){this.#de(e),this.#T=!0,this.#D=!1,this.#O=``;let t=lineOf(``);return this.#w.begin(t.text),this.#$(t),this.#E=typeaheadFor(PROMPT_COMMANDS,t.text),this.#ye(),this.#Re(),await new Promise((e,n)=>{let apply=e=>{t=e,this.#xe(),this.#$(t),this.#E=typeaheadFor(PROMPT_COMMANDS,e.text,this.#E),this.#Re()},recall=e=>{e!==void 0&&apply(lineOf(e))},interrupt=()=>{this.#E=void 0,this.#be(),this.#fe(),n(interruptedError())},suggestions=()=>this.#E!==void 0&&isTypeaheadOpen(this.#E)?this.#E:void 0,highlighted=()=>{let e=suggestions();return e===void 0?void 0:selectedTypeaheadCommand(e)};this.#I=n=>{switch(n.type){case`character`:apply(insert(t,n.value));break;case`backspace`:apply(backspace(t));break;case`delete`:apply(deleteForward(t));break;case`left`:apply(moveLeft(t));break;case`right`:apply(moveRight(t));break;case`home`:case`ctrl-a`:apply(moveHome(t));break;case`end`:case`ctrl-e`:apply(moveEnd(t));break;case`ctrl-k`:apply(killToEnd(t));break;case`ctrl-u`:apply(killToStart(t));break;case`ctrl-w`:apply(deleteWord(t));break;case`up`:{let e=suggestions();e===void 0?recall(this.#w.previous(t.text)):(this.#E=moveTypeaheadSelection(e,-1),this.#Re());break}case`down`:{let e=suggestions();e===void 0?recall(this.#w.next()):(this.#E=moveTypeaheadSelection(e,1),this.#Re());break}case`tab`:{let e=highlighted();e!==void 0&&apply(lineOf(typeaheadCompletion(e)));break}case`escape`:{let e=suggestions();e!==void 0&&(this.#E=dismissTypeahead(e),this.#Re());break}case`enter`:{let n=highlighted(),r=n!==void 0&&parsePromptCommand(t.text)===null?typeaheadCompletion(n).trimEnd():t.text;this.#E=void 0,this.#w.add(r),this.#T=!1,this.#be(),this.#O=STATUS.processing,isPromptControlCommand(r)?this.#we({kind:`command`,body:r.trim(),live:!1}):(this.#Te(r),this.#Z=r),this.#$(EMPTY_LINE),this.#Re(),this.#me(),e(r);break}case`ctrl-d`:t.text.length===0?interrupt():apply(deleteForward(t));break;case`ctrl-l`:case`ctrl-r`:this.#Re();break;case`ctrl-c`:interrupt();break;default:break}},this.#pe()})}#$(e){this.#S=e.text,this.#C=e.cursor}async renderStream(e,t){this.#de(t),this.#m.clear(),this.#T=!1,this.#D=!0,this.#O=STATUS.processing,this.#Ee(t?.submittedPrompt),this.#j=!1,this.#U=void 0,this.#G=void 0,this.#K=void 0,this.#q=Date.now();let n={tools:t?.tools??this.#i,reasoning:t?.reasoning??this.#a,assistantResponseStats:t?.assistantResponseStats??this.#c};this.#Se(),this.#Re();let r=new Promise(e=>{this.#B=e});this.#I=e=>this.#ve(e),this.#pe();let i={text:new Map,reasoning:new Map,tools:new Map,hasPendingToolResults:!1};try{for await(let t of takeUntil(iterateTUIStream(e.events),r)){if(this.#j)break;this.#Me(t,n,i)}}catch(e){this.#De(`Error`,toErrorMessage(e))}finally{this.#B=void 0,this.#j&&e.abort?.(),this.#me(),this.#Ce(),this.#D=!1,this.#O=this.#j?`Interrupted`:t?.continueSession?`Ready`:`Done`,this.#je(),this.#Re(),(this.#j||!t?.continueSession)&&this.#fe()}if(this.#j)throw interruptedError()}async readToolApproval(e,t){return this.#de(t),this.#T=!1,this.#D=!1,this.#O=`Approve ${formatToolApprovalTitle(e)}? (y/n)`,this.#j=!1,this.#Re(),await new Promise((t,n)=>{this.#I=r=>{switch(r.type){case`character`:{let n=r.value.toLowerCase();n===`y`?(this.#O=STATUS.processing,this.#me(),this.#Re(),t({approved:!0})):n===`n`&&(this.#O=STATUS.processing,this.#ee(e.toolCallId),this.#me(),this.#Re(),t({approved:!1,reason:`Denied by user.`}));break}case`ctrl-r`:this.#Re();break;case`ctrl-c`:this.#j=!0,this.#fe(),n(interruptedError());break;default:break}},this.#pe()})}async readInputQuestion(e,t){this.#de(t),this.#T=!1,this.#D=!1,this.#j=!1;let n=e.options??[],r=n.length>0,i=(e.allowFreeform===!0||!r)&&r,a=n.length+ +!!i,o=questionSectionId(e.requestId),s=r?`select`:`text`,c=0,l=``,isOnFreeformRow=()=>i&&c===n.length,renderSection=()=>{this.#ke({id:o,kind:`question`,title:e.prompt,body:formatQuestionContent(e,c,this.#r),preformatted:!0,live:!0})},repaintStatus=()=>{if(s===`select`){let e=isOnFreeformRow()?`type`:`select`;this.#O=`↑/↓ move · enter ${e} · Ctrl+C quit`,this.#T=!1}else this.#T=!0,this.#$(lineOf(l)),this.#O=``;this.#Re()};renderSection(),s===`text`&&this.#ye(),repaintStatus();let finalize=t=>{this.#ke({id:o,kind:`question`,title:e.prompt,body:` ${this.#r.colors.green(this.#r.glyph.success)} ${t.label}`,preformatted:!0,live:!1}),this.#T=!1,this.#O=STATUS.processing,this.#be(),this.#me(),this.#Re();let n={};return t.optionId!==void 0&&(n.optionId=t.optionId),t.text!==void 0&&(n.text=t.text),n};return await new Promise((t,i)=>{this.#I=o=>{if(o.type===`ctrl-c`){this.#j=!0,this.#be(),this.#fe(),i(interruptedError());return}if(o.type===`ctrl-r`){this.#Re();return}if(s===`select`){switch(o.type){case`up`:a>0&&(c=(c-1+a)%a,renderSection(),repaintStatus());break;case`down`:a>0&&(c=(c+1)%a,renderSection(),repaintStatus());break;case`enter`:{if(isOnFreeformRow()){s=`text`,l=``,this.#ye(),repaintStatus();break}let e=n[c];e&&t(finalize({optionId:e.id,label:e.label}));break}default:break}return}switch(o.type){case`character`:l+=o.value,this.#xe(),repaintStatus();break;case`backspace`:l=l.slice(0,-1),this.#xe(),repaintStatus();break;case`enter`:{let n=resolveQuestionText(l,e);if(n===void 0)break;t(finalize(n));break}case`escape`:if(r){if(l.length>0){l=``,this.#xe(),repaintStatus();break}s=`select`,l=``,this.#T=!1,this.#be(),repaintStatus();break}l=``,this.#xe(),repaintStatus();break;default:break}},this.#pe()})}upsertSubagentStep(e){if(this.#o===`hidden`)return;let t=e.reasoning?.trim()??``,n=e.message?.trim()??``;if(!(t.length===0&&n.length===0)){if(this.#Oe(e.callId,e.subagentName),this.#o===`collapsed`){this.#Re();return}this.#ke({id:subagentStepSectionId(e.callId,e.sectionKey),kind:`subagent-step`,depth:1,reasoning:t,body:n,live:!e.finalized}),this.#Re()}}upsertSubagentTool(n){if(this.#o===`hidden`)return;if(this.#Oe(n.callId,n.subagentName),this.#o===`collapsed`){this.#Re();return}let r=subagentToolStatus(n.status),i={id:subagentToolSectionId(n.callId,n.childCallId),kind:`subagent-tool`,depth:1,title:n.toolName,subtitle:summarizeToolArgs(n.input),status:r,live:r===`running`||r===`approval`,expanded:this.#o===`full`,toolInput:n.input};n.output===void 0?n.errorText!==void 0&&(i.result=n.errorText):(i.result=summarizeToolResult(n.output),i.toolOutput=n.output),this.#ke(i),this.#Re()}markChildToolCallId(e){this.#h.add(e);let t=this.#g.get(e);t!==void 0&&(this.#Ae(t),this.#g.delete(e),this.#Re())}#ee(e){let t=this.#p.get(toolSectionId(e));t!==void 0&&(t.status=`denied`,t.live=!1)}upsertConnectionAuth(e){if(this.#s===`hidden`)return;let t=e.state===`authorized`||e.state===`declined`||e.state===`failed`||e.state===`timed-out`;this.#ke({id:connectionAuthSectionId(e.name),kind:`connection-auth`,title:`${e.name} · authorization · ${e.state}`,body:formatConnectionAuthContent(e),preformatted:!0,live:!t}),this.#Re()}setConnectionAuthPendingCount(e){let t=Math.max(0,e);if(t===this.#x)return;let n=this.#x>0;this.#x=t,t>0?(this.#O=STATUS.connectionAuth,this.#Re()):n&&(this.#O=STATUS.processing,this.#Re())}reset(){this.#f=[],this.#p.clear(),this.#m.clear(),this.#b=void 0,this.#v=void 0,this.#y=!1,this.#h.clear(),this.#g.clear(),this.#_.clear(),this.#Z=void 0,this.#x=0,this.#U=void 0,this.#G=void 0,this.#K=void 0,this.#q=void 0,this.#A&&(this.#n.clearAll(),this.#Re())}renderNotice(e){e.trim().length!==0&&(this.#de(),this.#we({kind:`notice`,body:e,live:!1}),this.#Re())}renderSetupWarning(e){e.trim().length!==0&&(this.#de(),this.#we({kind:`warning`,body:e,live:!1}),this.#Re())}renderCommandResult(e){e.trim().length!==0&&(this.#de(),this.#we({kind:`result`,body:e,live:!1}),this.#Re())}#te(e){this.#de(),this.#T=!1,this.#D=!1,this.#O=``,this.#Q={title:e,lines:[],outputBuffer:[]},this.#Se(),this.#Re()}#ne(e){let t=this.#Q;if(t!==void 0){if(this.#Q=void 0,this.#Ce(),e)for(let e of t.lines)(e.tone===`warning`||e.tone===`error`)&&this.#we({kind:`flow`,title:e.tone,body:e.text,live:!1});this.#Re()}}async#re(e){this.#de(),this.#T=!1,this.#D=!1,this.#O=``;let t={options:e.options,submitRow:e.multiple},n={options:e.options,submitRow:e.multiple};e.initialValue!==void 0&&(n.defaultValue=e.initialValue),e.initialValues!==void 0&&(n.initialValues=e.initialValues);let r=initialSelectState(n),i,a=this.#oe(),panelState=()=>{let t={message:e.message,options:e.options,multiple:e.multiple,search:e.search,select:r};return e.placeholder!==void 0&&(t.placeholder=e.placeholder),e.layout!==void 0&&(t.layout=e.layout),e.notices!==void 0&&(t.notices=e.notices),i!==void 0&&(t.error=i),t};return a.question=e=>renderSelectQuestion(panelState(),this.#r,e),this.#Re(),await new Promise(n=>{let settle=e=>{this.#se(),n(e)},apply=e=>{r=reduceSelect(r,e,t),i=void 0,this.#Re()};this.#I=n=>{switch(n.type){case`ctrl-c`:case`escape`:settle(void 0);return;case`ctrl-r`:this.#Re();return;case`up`:apply({type:`up`});return;case`down`:apply({type:`down`});return;case`backspace`:e.search&&apply({type:`backspace`});return;case`character`:if(e.multiple&&n.value===` `){apply({type:`toggle`});return}if(numbersSelectRows(e)&&/^[1-9]$/.test(n.value)){let t=Number(n.value)-1,a=e.options[t];a!==void 0&&!a.disabled&&!a.locked&&(r={...r,cursor:t},i=void 0,this.#Re());return}if(e.search){for(let e of n.value)e>=` `&&e!==``&&(r=reduceSelect(r,{type:`char`,char:e},t));i=void 0,this.#Re()}return;case`enter`:{let t=e.search?filterOptions(e.options,r.filter):[...e.options];if(e.multiple){if(r.cursor===submitRowIndex(t)){if(e.required&&r.selected.size===0){i=`Select at least one option, then submit.`,this.#Re();return}settle(orderedSelection(e.options,r.selected));return}apply({type:`toggle`});return}let n=selectValueAtCursor(t,r.cursor);if(n===void 0){i=`Type to match an option, then press enter.`,this.#Re();return}settle([n]);return}default:return}},this.#pe()})}async#ie(e){this.#de(),this.#T=!1,this.#D=!1,this.#O=``;let t=lineOf(``),n,r=this.#oe();return r.question=r=>{let i={message:e.message,editor:t,mask:e.mask===!0};return e.placeholder!==void 0&&(i.placeholder=e.placeholder),n!==void 0&&(i.error=n),renderTextQuestion(i,this.#r,r,this.#M)},this.#ye(),this.#Re(),await new Promise(r=>{let settle=e=>{this.#be(),this.#se(),r(e)},apply=e=>{t=e,n=void 0,this.#xe(),this.#Re()};this.#I=r=>{switch(r.type){case`ctrl-c`:case`escape`:settle(void 0);return;case`ctrl-r`:this.#Re();return;case`character`:apply(insert(t,r.value));return;case`backspace`:apply(backspace(t));return;case`delete`:apply(deleteForward(t));return;case`left`:apply(moveLeft(t));return;case`right`:apply(moveRight(t));return;case`home`:case`ctrl-a`:apply(moveHome(t));return;case`end`:case`ctrl-e`:apply(moveEnd(t));return;case`ctrl-k`:apply(killToEnd(t));return;case`ctrl-u`:apply(killToStart(t));return;case`ctrl-w`:apply(deleteWord(t));return;case`enter`:{let r=t.text.length>0?t.text:e.defaultValue??``,i=e.validate?.(r);if(i!==void 0){n=i,this.#Re();return}settle(r);return}default:return}},this.#pe()})}async#ae(e){this.#de(),this.#T=!1,this.#D=!1,this.#O=``;let t=this.#oe();return t.question=t=>renderAcknowledgeQuestion({message:e.message,lines:e.lines},this.#r,t),this.#Re(),await new Promise(e=>{this.#I=t=>{switch(t.type){case`enter`:case`escape`:case`ctrl-c`:this.#se(),e();return;case`ctrl-r`:this.#Re();return;default:return}},this.#pe()})}#oe(){return this.#Q===void 0&&(this.#Q={title:``,lines:[],outputBuffer:[]}),this.#Q}#se(){this.#Q!==void 0&&(this.#Q.question=void 0),this.#I=void 0,this.#me(),this.#Re()}#ce(e){if(this.#Q!==void 0){this.#Q.status=e,e===void 0&&(this.#Q.preview=void 0),this.#Re();return}if(e===void 0){this.#D=!1,this.#O=``,this.#Ce(),this.#Re();return}this.#de(),this.#D=!0,this.#O=e,this.#Se(),this.#Re()}#le(e,t){if(e.trim().length===0)return;let n=this.#Q;if(n!==void 0){if(n.preview=void 0,t===`warning`||t===`error`)for(let e of n.outputBuffer)n.lines.push({text:e,tone:`info`});n.outputBuffer=[],n.lines.push({text:e,tone:t}),this.#Re();return}this.#de(),this.#we({kind:`flow`,title:t,body:e,live:!1}),this.#Re()}#ue(e){if(e.trim().length===0)return;let t=this.#Q;if(t===void 0){this.#le(e,`info`);return}t.preview=e,t.outputBuffer.push(e),t.outputBuffer.length>8&&t.outputBuffer.shift(),this.#Re()}shutdown(){this.#fe()}#de(e){this.#k=e?.title??this.#k,this.#W=e?.contextSize??this.#l,!this.#A&&(this.#A=!0,this.#n.reset(),this.#n.hideCursor(),this.#qe(),this.#e.isTTY&&(this.#e.setRawMode?.(!0),this.#e.resume()),this.#z=()=>this.#Re(),this.#t.on(`resize`,this.#z))}#fe(){this.#me(),this.#be(),this.#Ce(),this.#A&&=(this.#Re(),this.#n.clear(),this.#n.showCursor(),this.#Je(),this.#n.newline(),this.#e.isTTY&&(this.#e.setRawMode?.(!1),this.#e.pause()),this.#z&&=(this.#t.off(`resize`,this.#z),void 0),!1)}#pe(){this.#e.on(`data`,this.#he)}#me(){this.#e.off(`data`,this.#he),this.#_e(),this.#L=``,this.#I=void 0}#he=e=>{this.#_e(),this.#L+=e.toString(`utf8`),this.#ge(),this.#L===`\x1B`&&(this.#R=setTimeout(()=>{this.#L===`\x1B`&&(this.#L=``,this.#I?.({type:`escape`}))},30),this.#R.unref?.())};#ge(){for(;this.#L.length>0;){let e=nextKey(this.#L);if(e.incomplete)return;this.#L=this.#L.slice(e.consumed),e.key&&e.key.type!==`ignore`&&this.#I?.(e.key)}}#_e(){this.#R&&=(clearTimeout(this.#R),void 0)}#ve(e){switch(e.type){case`ctrl-l`:case`ctrl-r`:this.#Re();break;case`ctrl-c`:this.#j=!0,this.#B?.();break;default:break}}#ye(){this.#be(),this.#xe(),this.#P=setInterval(()=>{this.#M=!this.#M,this.#Re()},500),this.#P.unref?.()}#be(){this.#P&&=(clearInterval(this.#P),void 0),this.#M=!0}#xe(){this.#M=!0}#Se(){this.#Ce(),this.#F=setInterval(()=>{this.#N+=1,this.#Re()},90),this.#F.unref?.()}#Ce(){this.#F&&=(clearInterval(this.#F),void 0)}#we(e){this.#f.push(e),e.id&&this.#p.set(e.id,e)}#Te(e){this.#we({kind:`user`,body:e,live:!1}),this.#Re()}#Ee(e){if(e!=null){if(this.#Z===e){this.#Z=void 0;return}this.#we({kind:`user`,body:e,live:!1})}}#De(e,t,n){let r={kind:`error`,title:e,body:t,live:!1};n!==void 0&&(r.detail=n),this.#we(r),this.#Re()}#Oe(e,t){this.#_.has(e)||(this.#_.add(e),this.#we({id:subagentHeaderId(e),kind:`subagent`,title:t,live:!1}))}#ke(e){if(e.id&&this.#m.has(e.id))return;let t=e.id?this.#p.get(e.id):void 0;if(t){Object.assign(t,e);return}this.#we(e)}#Ae(e){this.#f=this.#f.filter(t=>t.id!==e),this.#p.delete(e)}#je(){for(let e of this.#f)e.status!==`approval`&&(e.live=!1)}#Me(e,t,n){switch(e.type){case`step-start`:this.#Ne(n.hasPendingToolResults?STATUS.toolResults:STATUS.processing),n.hasPendingToolResults=!1;break;case`step-finish`:this.#Le(e.usage),this.#Re();break;case`assistant-delta`:{this.#Ne(STATUS.streaming);let t=(n.text.get(e.id)??``)+e.delta;n.text.set(e.id,t),this.#Pe(e.id,t,!0);break}case`assistant-complete`:{let t=n.text.get(e.id)??``,r=e.text!==void 0&&t.length===0?e.text??``:t;n.text.set(e.id,r),this.#Pe(e.id,r,!1);break}case`reasoning-delta`:{if(t.reasoning===`hidden`)break;this.#Ne(STATUS.streaming);let r=(n.reasoning.get(e.id)??``)+e.delta;n.reasoning.set(e.id,r),this.#Fe(e.id,r,!0,t);break}case`reasoning-complete`:{if(t.reasoning===`hidden`)break;let r=n.reasoning.get(e.id)??``;this.#Fe(e.id,r,!1,t);break}case`tool-call`:if(t.tools===`hidden`)break;this.#Ne(STATUS.executingTools),this.#Ie({input:e.input,status:`running`,toolCallId:e.toolCallId,toolName:e.toolName},t,n);break;case`tool-approval-request`:{if(t.tools===`hidden`)break;let r=n.tools.get(e.toolCallId);if(r===void 0)break;this.#Ie({...r,status:`approval`},t,n);break}case`tool-result`:{if(t.tools===`hidden`)break;let r=n.tools.get(e.toolCallId);if(r===void 0)break;n.hasPendingToolResults=!0,this.#Ne(STATUS.toolResults),this.#Ie({...r,output:e.output,status:`done`},t,n);break}case`tool-error`:{if(t.tools===`hidden`)break;let r=n.tools.get(e.toolCallId);if(r===void 0)break;n.hasPendingToolResults=!0,this.#Ne(STATUS.toolResults),this.#Ie({...r,errorText:e.errorText,status:`error`},t,n);break}case`error`:this.#De(`Error`,e.errorText,e.detail);break;case`finish`:this.#Le(e.usage),this.#Re();break}}#Ne(e){let t=this.#x>0?STATUS.connectionAuth:e;this.#O!==t&&(this.#O=t,this.#Re())}#Pe(e,t,n){let r=t.trim();r.length!==0&&(this.#ke({id:e,kind:`assistant`,body:r,live:n}),this.#Re())}#Fe(e,t,n,r){let i=t.trim();i.length!==0&&(this.#ke({id:e,kind:`reasoning`,body:i,collapsed:collapseReasoning(r.reasoning,n),live:n}),this.#Re())}#Ie(e,t,n){if(n.tools.set(e.toolCallId,e),this.#h.has(e.toolCallId))return;let r=toolSectionId(e.toolCallId);this.#g.set(e.toolCallId,r),this.#ke(renderNativeToolBlock(e,r,t.tools===`full`)),this.#Re()}#Le(e){if(e===void 0)return;let{inputTokens:t,outputTokens:n}=e;if((t!=null||n!=null)&&(this.#U=(t??0)+(n??0)),this.#G=n??this.#G,this.#G!=null&&this.#q!==void 0){let e=(Date.now()-this.#q)/1e3;e>0&&(this.#K=this.#G/e)}}#Re(){if(this.#A){if(this.#V){this.#H=!0;return}this.#V=!0;try{do this.#H=!1,this.#ze();while(this.#H)}finally{this.#V=!1}}}#ze(){if(!this.#A)return;let e=this.#Ge(),t=this.#Ue(e),n=Math.max(1,this.#Ke()-t.length),r=[],i=this.#b;for(;this.#f.length>0&&this.#f[0].live===!1;){let t=this.#f.shift(),n=this.#Ve(t,e,i);i=previousBlockOf(t),this.#b=i,r.push(...n),t.id&&(this.#m.add(t.id),this.#p.delete(t.id))}let a=[];for(let t of this.#f){let n=this.#Ve(t,e,i);i=previousBlockOf(t);for(let e=0;e<n.length;e+=1)a.push({block:t,row:n[e]})}let o=[...clipLiveRows(a.map(e=>e.row),n,e,this.#r),...t];r.length>0?this.#n.flush(r,o):this.#n.update(o)}#Be(){let e=this.#v;if(e===void 0)return[];let t={name:e.name,serverUrl:e.serverUrl,theme:this.#r,width:this.#Ge()};return e.info!==void 0&&(t.info=e.info),e.setupCommands!==void 0&&(t.setupCommands=e.setupCommands),buildAgentHeader(t)}#Ve(e,t,n){let r={spinner:this.#He()};n!==void 0&&(r.previous=n);let i=renderBlockLines(e,t,this.#r,r);return(e.depth??0)===0&&leadsWithGap(e,n)?[``,...i]:i}#He(){return this.#r.spinner[this.#N%this.#r.spinner.length]??``}#Ue(e){let t=this.#r.colors,n=[``],r=this.#Q;if(r!==void 0){let t={title:r.title,lines:r.lines,frame:this.#He()};return r.question===void 0?(r.status!==void 0&&(t.status={text:r.status,frame:this.#He()}),r.preview!==void 0&&(t.preview=r.preview)):t.question=r.question(e),n.push(...renderFlowPanel(t,this.#r,e)),n}if(this.#T){this.#E!==void 0&&isTypeaheadOpen(this.#E)&&n.push(...renderCommandSuggestions(this.#E,this.#r,e));let r=Math.max(4,e-3),{before:i,after:a}=visibleLine({text:this.#S,cursor:this.#C},r,this.#r.glyph.ellipsis),o=isPromptControlCommand(this.#S),style=e=>o&&e.length>0?t.blue(e):e,c=this.#M?t.cyan(this.#r.glyph.caret):` `;return n.push(`${t.cyan(this.#r.glyph.prompt)} ${style(i)}${c}${style(a)}`),n}let i=this.#D?t.yellow(this.#He()):t.dim(this.#r.glyph.dot),a=this.#O.length>0?this.#O:`Ready`,o=this.#D?t.dim(a):a,c=this.#We(),l=c?`${i} ${o} ${t.dim(this.#r.glyph.dot)} ${c}`:`${i} ${o}`;return n.push(clip(l,e)),n}#We(){let e=this.#r.colors,t=[],n=formatTokenCount(this.#U,this.#W);n&&t.push(n);let r=formatAssistantResponseStats({totalTokens:this.#U,outputTokens:this.#G,tokensPerSecond:this.#K},this.#c);return r&&t.push(r),this.#D&&t.push(`Ctrl+C to interrupt`),t.length>0?e.dim(t.join(` ${this.#r.glyph.dot} `)):``}#Ge(){return Math.max(20,this.#t.columns||80)}#Ke(){return Math.max(8,this.#t.rows||24)}#qe(){if(this.#J!==void 0||!this.#u)return;this.#Y=``,this.#X=``;let capture=(e,t)=>{let n=e.write.bind(e);return e.write=((e,n,r)=>{let i=typeof n==`string`?n:void 0,a=typeof n==`function`?n:r;return this.#Ye(t,chunkToString(e,i)),a?.(),!0}),()=>{e.write=n}},e=capture(process.stdout,`stdout`),t=capture(process.stderr,`stderr`);this.#J=()=>{e(),t()}}#Je(){let e=this.#J;e!==void 0&&(this.#J=void 0,e(),this.#Y.length>0&&(this.#Xe(`stdout`)&&process.stdout.write(`${this.#Y}\n`),this.#Y=``),this.#X.length>0&&(this.#Xe(`stderr`)&&process.stderr.write(`${this.#X}\n`),this.#X=``))}#Ye(e,t){let n=(e===`stdout`?this.#Y:this.#X)+t,r=n.lastIndexOf(`
3
3
  `),a=r===-1?n:n.slice(r+1);if(e===`stdout`?this.#Y=a:this.#X=a,r===-1||!this.#Xe(e))return;let o=stripAnsi(n.slice(0,r)).replace(/\s+$/u,``);o.trim().length!==0&&(this.#we({kind:`log`,title:e,body:o,live:!1}),this.#Re())}#Xe(e){switch(this.#d){case`none`:return!1;case`stderr`:return e===`stderr`;case`all`:return!0}}};function chunkToString(e,t){return typeof e==`string`?e:Buffer.from(e).toString(t)}async function*iterateTUIStream(e){if(e instanceof ReadableStream){let t=e.getReader();try{for(;;){let{done:e,value:n}=await t.read();if(e)return;yield n}}finally{t.releaseLock()}return}yield*e}function clip(e,t){return visibleLength(e)>t?sliceVisible(e,t):e}function previousBlockOf(e){let t={kind:e.kind};return e.title!==void 0&&(t.title=e.title),t}function leadsWithGap(e,t){if(e.kind===`log`&&t?.kind===`log`)return t.title!==e.title;if(t?.kind===`log`&&e.kind!==`log`)return!0;switch(e.kind){case`user`:case`assistant`:case`reasoning`:case`subagent`:case`error`:case`notice`:case`question`:case`connection-auth`:case`log`:case`command`:case`warning`:case`flow`:case`agent-header`:return!0;default:return!1}}function clipLiveRows(e,t,n,r){if(e.length<=t)return[...e];if(t<=1)return[clip(hiddenRowsMarker(e.length,r),n)];let i=t-1;return[clip(hiddenRowsMarker(e.length-i,r),n),...e.slice(e.length-i)]}function hiddenRowsMarker(e,t){let n=e.toLocaleString(),r=e===1?`row`:`rows`;return t.colors.dim(`${t.glyph.dot} ${t.glyph.ellipsis} ${n} earlier ${r} hidden while streaming`)}function collapseReasoning(e,t){switch(e){case`collapsed`:return!0;case`auto-collapsed`:return!t;default:return!1}}function renderNativeToolBlock(n,r,i){let a={id:r,kind:`tool`,title:n.toolName,subtitle:summarizeToolArgs(n.input),status:n.status,live:n.status===`running`||n.status===`approval`,expanded:i,toolInput:n.input};return n.output===void 0?n.errorText!==void 0&&(a.result=n.errorText):(a.result=summarizeToolResult(n.output),a.toolOutput=n.output),a}function subagentToolStatus(e){switch(e){case`approval-requested`:return`approval`;case`executing`:return`running`;case`done`:return`done`;case`failed`:return`error`}}function formatToolApprovalTitle(e){return e.title??e.toolName}function toolSectionId(e){return`tool:${e}`}function questionSectionId(e){return`question:${e}`}function subagentHeaderId(e){return`subagent:${e}:header`}function subagentStepSectionId(e,t){return`subagent:${e}:step:${t}`}function subagentToolSectionId(e,t){return`subagent:${e}:tool:${t}`}function connectionAuthSectionId(e){return`connection-auth:${e}`}function formatConnectionAuthContent(e){let t=[];e.description.length>0&&t.push(e.description);let n=e.challenge;return n?.url&&t.push(`URL: ${n.url}`),n?.userCode&&t.push(`Code: ${n.userCode}`),n?.expiresAt&&t.push(`Expires: ${n.expiresAt}`),n?.instructions&&t.push(n.instructions),e.reason!==void 0&&e.reason.length>0&&t.push(`Reason: ${e.reason}`),t.join(`
4
4
  `)}function formatQuestionContent(e,t,n){let r=n.colors,i=[],a=e.options??[];if(a.length>0){for(let[e,o]of a.entries()){let a=o.description?` ${r.dim(`— ${o.description}`)}`:``,s=t===e,c=s?`${r.cyan(n.glyph.pointer)} `:` `,l=s?r.cyan(o.label):o.label;i.push(`${c}${l}${a}`)}if(e.allowFreeform===!0){let e=t===a.length,o=e?`${r.cyan(n.glyph.pointer)} `:` `,s=`Type your own answer`;i.push(`${o}${e?r.cyan(s):r.dim(s)}`)}}else i.push(r.dim(` (type your answer)`));return i.join(`
5
5
  `)}function resolveQuestionText(e,t){let n=e.trim();if(n.length===0)return;let r=n.toLowerCase(),i=t.options??[];if(i.length>0){let e=matchQuestionOption(r,i);if(e!==void 0)return{optionId:e.id,label:e.label}}if(t.allowFreeform===!0||i.length===0)return{text:n,label:n}}function matchQuestionOption(e,t){let n=t.find(t=>t.id.toLowerCase()===e);if(n!==void 0)return n;let r=t.find(t=>t.label.toLowerCase()===e);if(r!==void 0)return r;let i=Number(e);if(Number.isInteger(i)&&i>0&&i<=t.length)return t[i-1]}export{TerminalRenderer};
@@ -1 +1 @@
1
- import{WizardCancelledError}from"#setup/step.js";import{createSelectOptionCodec}from"#setup/cli/select-option-codec.js";function createTuiPrompter(n){function guardCancel(t){if(t===void 0)throw new WizardCancelledError;return t}async function select(e){let r=createSelectOptionCodec(e.options),i=e.multiple===!0,a={message:e.message,options:r.options,multiple:i,search:e.search??!1,required:e.required??!1};e.placeholder!==void 0&&(a.placeholder=e.placeholder),!i&&e.initialValue!==void 0&&(a.initialValue=r.encode(e.initialValue)),i&&e.initialValues!==void 0&&(a.initialValues=e.initialValues.map(e=>r.encode(e)));let o=guardCancel(await n.readSelect(a)).map(e=>r.decode(e));if(i)return o;let s=o[0];if(s===void 0)throw Error(`Single-select returned no option.`);return s}function line(e){return t=>n.renderLine(t,e)}return{async text(e){let t={message:e.message};return e.placeholder!==void 0&&(t.placeholder=e.placeholder),e.defaultValue!==void 0&&(t.defaultValue=e.defaultValue),e.validate!==void 0&&(t.validate=e.validate),guardCancel(await n.readText(t))},async password(e){let t={message:e.message,mask:!0};return e.validate!==void 0&&(t.validate=e.validate),guardCancel(await n.readText(t))},select,async acknowledge(e){await n.readAcknowledge({message:e.message,lines:e.lines??[]})},note(e,t,r){let i=r?.tone===`success`?`success`:`warning`;t&&n.renderLine(t,i),n.renderLine(e,i)},intro(){},outro(){},log:{message:line(`info`),info:line(`info`),success:line(`success`),warning:line(`warning`),error:line(`error`),commandOutput:e=>n.renderOutput(e),section(e,t){n.renderLine(e,`info`);for(let e of t)n.renderLine(` ${e}`,`info`)},spinner(e){n.setStatus(e);let t=!1;return{stop(){t||(t=!0,n.setStatus(void 0))}}}}}}export{createTuiPrompter};
1
+ import{WizardCancelledError}from"#setup/step.js";import{createSelectOptionCodec}from"#setup/cli/select-option-codec.js";function createTuiPrompter(n){function guardCancel(t){if(t===void 0)throw new WizardCancelledError;return t}async function select(e){let r=createSelectOptionCodec(e.options),i=e.multiple===!0,a={message:e.message,options:r.options,multiple:i,search:e.search??!1,required:e.required??!1};e.placeholder!==void 0&&(a.placeholder=e.placeholder),e.layout!==void 0&&(a.layout=e.layout),e.notices!==void 0&&(a.notices=e.notices),!i&&e.initialValue!==void 0&&(a.initialValue=r.encode(e.initialValue)),i&&e.initialValues!==void 0&&(a.initialValues=e.initialValues.map(e=>r.encode(e)));let o=guardCancel(await n.readSelect(a)).map(e=>r.decode(e));if(i)return o;let s=o[0];if(s===void 0)throw Error(`Single-select returned no option.`);return s}function line(e){return t=>n.renderLine(t,e)}return{async text(e){let t={message:e.message};return e.placeholder!==void 0&&(t.placeholder=e.placeholder),e.defaultValue!==void 0&&(t.defaultValue=e.defaultValue),e.validate!==void 0&&(t.validate=e.validate),guardCancel(await n.readText(t))},async password(e){let t={message:e.message,mask:!0};return e.validate!==void 0&&(t.validate=e.validate),guardCancel(await n.readText(t))},select,async acknowledge(e){await n.readAcknowledge({message:e.message,lines:e.lines??[]})},note(e,t,r){let i=r?.tone===`success`?`success`:`warning`;t&&n.renderLine(t,i),n.renderLine(e,i)},intro(){},outro(){},log:{message:line(`info`),info:line(`info`),success:line(`success`),warning:line(`warning`),error:line(`error`),commandOutput:e=>n.renderOutput(e),section(e,t){n.renderLine(e,`info`);for(let e of t)n.renderLine(` ${e}`,`info`)},spinner(e){n.setStatus(e);let t=!1;return{stop(){t||(t=!0,n.setStatus(void 0))}}}}}}export{createTuiPrompter};
@@ -1,7 +1,7 @@
1
1
  import type { JsonObject } from "#shared/json.js";
2
2
  /**
3
3
  * The upstream error name the AI Gateway uses for authentication failures.
4
- * Exported so consumers of `step.failed` details (the dev TUI's `/vercel`
4
+ * Exported so consumers of `step.failed` details (the dev TUI's `/model`
5
5
  * hint) match the same identifier this module classifies on.
6
6
  */
7
7
  export declare const GATEWAY_AUTHENTICATION_ERROR_NAME = "GatewayAuthenticationError";
@@ -1 +1 @@
1
- import{createRequire}from"node:module";import{basename,dirname,join}from"node:path";import{existsSync,readFileSync,realpathSync}from"node:fs";import{EVE_PACKAGE_NAME}from"#internal/package-name.js";import{fileURLToPath}from"node:url";let cachedPackageInfo;const WORKFLOW_MODULE_ALIASES={"workflow/api":`src/compiled/@workflow/core/runtime.js`,"workflow/errors":`src/compiled/@workflow/errors/index.js`,"workflow/internal/private":`src/compiled/@workflow/core/private.js`,"workflow/runtime":`src/compiled/@workflow/core/runtime.js`};function resolveFallbackPackageVersion(){return`0.6.0-beta.18`}const FALLBACK_PACKAGE_INFO={name:EVE_PACKAGE_NAME,version:resolveFallbackPackageVersion()};function resolveCurrentModulePath(){return typeof __filename==`string`?__filename:resolveCurrentModulePathFromStack()}function resolveCurrentModulePathFromStack(){let e=Error.prepareStackTrace;try{Error.prepareStackTrace=(e,t)=>t;let e=Error().stack?.[0]?.getFileName();if(typeof e!=`string`||e.length===0)throw Error(`Failed to resolve the current module path from the stack trace.`);return e.startsWith(`file:`)?fileURLToPath(e):e}finally{Error.prepareStackTrace=e}}const require=createRequire(resolveCurrentModulePath());function isBuildOutputPackageRoot(e){return basename(e)===`dist`&&existsSync(join(dirname(e),`package.json`))}function resolvePackageBuildRoot(){let e=dirname(realpathSync(resolveCurrentModulePath()));for(;;){if(isBuildOutputPackageRoot(e))return e;let t=dirname(e);if(t===e)return null;e=t}}function findNearestPackageRoot(e){let t=e;for(;;){if(existsSync(join(t,`package.json`))&&!isBuildOutputPackageRoot(t))return t;let r=dirname(t);if(r===t)throw Error(`Failed to resolve package root from "${e}".`);t=r}}function resolvePackageRoot(){return findNearestPackageRoot(dirname(realpathSync(resolveCurrentModulePath())))}function tryResolvePackageRoot(){try{return resolvePackageRoot()}catch{return}}function rewriteSourceFilePathForBuild(e){return e.replace(/\.[cm]?tsx?$/,`.js`)}function resolvePackageSourceFilePath(e){let t=resolvePackageBuildRoot();return t===null?join(resolvePackageRoot(),e):join(t,rewriteSourceFilePathForBuild(e))}function resolvePackageSourceDirectoryPath(e){let t=resolvePackageBuildRoot();return join(t===null?resolvePackageRoot():t,e)}function resolvePackageDependencyPath(e){return require.resolve(e)}function resolvePackageCompiledFilePath(e){let t=resolvePackageBuildRoot();return t===null?join(resolvePackageRoot(),`.generated`,`compiled`,e.replace(/^src\/compiled\//,``)):join(t,e)}function normalizeInstalledPackageInfo(e){let t=e;if(!(typeof t.name!=`string`||typeof t.version!=`string`))return{name:t.name,version:t.version}}function tryReadInstalledPackageInfo(e,t){let n=normalizeInstalledPackageInfo(JSON.parse(readFileSync(e,`utf8`)));if(n?.name===t)return n}function resolveInstalledPackageInfo(){if(cachedPackageInfo)return cachedPackageInfo;let e=tryResolvePackageRoot(),t=e===void 0?void 0:tryReadInstalledPackageInfo(join(e,`package.json`),EVE_PACKAGE_NAME);if(t)return cachedPackageInfo=t,cachedPackageInfo;try{let e=tryReadInstalledPackageInfo(require.resolve(`${EVE_PACKAGE_NAME}/package.json`),EVE_PACKAGE_NAME);if(e)return cachedPackageInfo=e,cachedPackageInfo}catch{}return cachedPackageInfo={...FALLBACK_PACKAGE_INFO},cachedPackageInfo}function resolveWorkflowModulePath(e){if(e===`workflow`)return resolvePackageSourceFilePath(`src/internal/workflow/index.ts`);if(e===`workflow/internal/builtins`)return resolvePackageSourceFilePath(`src/internal/workflow/builtins.ts`);let t=WORKFLOW_MODULE_ALIASES[e];return t===void 0?require.resolve(e):resolvePackageCompiledFilePath(t)}export{resolveInstalledPackageInfo,resolvePackageDependencyPath,resolvePackageRoot,resolvePackageSourceDirectoryPath,resolvePackageSourceFilePath,resolveWorkflowModulePath};
1
+ import{createRequire}from"node:module";import{basename,dirname,join}from"node:path";import{existsSync,readFileSync,realpathSync}from"node:fs";import{EVE_PACKAGE_NAME}from"#internal/package-name.js";import{fileURLToPath}from"node:url";let cachedPackageInfo;const WORKFLOW_MODULE_ALIASES={"workflow/api":`src/compiled/@workflow/core/runtime.js`,"workflow/errors":`src/compiled/@workflow/errors/index.js`,"workflow/internal/private":`src/compiled/@workflow/core/private.js`,"workflow/runtime":`src/compiled/@workflow/core/runtime.js`};function resolveFallbackPackageVersion(){return`0.6.0-beta.19`}const FALLBACK_PACKAGE_INFO={name:EVE_PACKAGE_NAME,version:resolveFallbackPackageVersion()};function resolveCurrentModulePath(){return typeof __filename==`string`?__filename:resolveCurrentModulePathFromStack()}function resolveCurrentModulePathFromStack(){let e=Error.prepareStackTrace;try{Error.prepareStackTrace=(e,t)=>t;let e=Error().stack?.[0]?.getFileName();if(typeof e!=`string`||e.length===0)throw Error(`Failed to resolve the current module path from the stack trace.`);return e.startsWith(`file:`)?fileURLToPath(e):e}finally{Error.prepareStackTrace=e}}const require=createRequire(resolveCurrentModulePath());function isBuildOutputPackageRoot(e){return basename(e)===`dist`&&existsSync(join(dirname(e),`package.json`))}function resolvePackageBuildRoot(){let e=dirname(realpathSync(resolveCurrentModulePath()));for(;;){if(isBuildOutputPackageRoot(e))return e;let t=dirname(e);if(t===e)return null;e=t}}function findNearestPackageRoot(e){let t=e;for(;;){if(existsSync(join(t,`package.json`))&&!isBuildOutputPackageRoot(t))return t;let r=dirname(t);if(r===t)throw Error(`Failed to resolve package root from "${e}".`);t=r}}function resolvePackageRoot(){return findNearestPackageRoot(dirname(realpathSync(resolveCurrentModulePath())))}function tryResolvePackageRoot(){try{return resolvePackageRoot()}catch{return}}function rewriteSourceFilePathForBuild(e){return e.replace(/\.[cm]?tsx?$/,`.js`)}function resolvePackageSourceFilePath(e){let t=resolvePackageBuildRoot();return t===null?join(resolvePackageRoot(),e):join(t,rewriteSourceFilePathForBuild(e))}function resolvePackageSourceDirectoryPath(e){let t=resolvePackageBuildRoot();return join(t===null?resolvePackageRoot():t,e)}function resolvePackageDependencyPath(e){return require.resolve(e)}function resolvePackageCompiledFilePath(e){let t=resolvePackageBuildRoot();return t===null?join(resolvePackageRoot(),`.generated`,`compiled`,e.replace(/^src\/compiled\//,``)):join(t,e)}function normalizeInstalledPackageInfo(e){let t=e;if(!(typeof t.name!=`string`||typeof t.version!=`string`))return{name:t.name,version:t.version}}function tryReadInstalledPackageInfo(e,t){let n=normalizeInstalledPackageInfo(JSON.parse(readFileSync(e,`utf8`)));if(n?.name===t)return n}function resolveInstalledPackageInfo(){if(cachedPackageInfo)return cachedPackageInfo;let e=tryResolvePackageRoot(),t=e===void 0?void 0:tryReadInstalledPackageInfo(join(e,`package.json`),EVE_PACKAGE_NAME);if(t)return cachedPackageInfo=t,cachedPackageInfo;try{let e=tryReadInstalledPackageInfo(require.resolve(`${EVE_PACKAGE_NAME}/package.json`),EVE_PACKAGE_NAME);if(e)return cachedPackageInfo=e,cachedPackageInfo}catch{}return cachedPackageInfo={...FALLBACK_PACKAGE_INFO},cachedPackageInfo}function resolveWorkflowModulePath(e){if(e===`workflow`)return resolvePackageSourceFilePath(`src/internal/workflow/index.ts`);if(e===`workflow/internal/builtins`)return resolvePackageSourceFilePath(`src/internal/workflow/builtins.ts`);let t=WORKFLOW_MODULE_ALIASES[e];return t===void 0?require.resolve(e):resolvePackageCompiledFilePath(t)}export{resolveInstalledPackageInfo,resolvePackageDependencyPath,resolvePackageRoot,resolvePackageSourceDirectoryPath,resolvePackageSourceFilePath,resolveWorkflowModulePath};
@@ -32,7 +32,7 @@ export type ChannelsFlowResult = {
32
32
  * name (the Slack connector slug falls back to the package.json name) — with
33
33
  * two TUI-specific differences: no trailing deploy box (the TUI exposes
34
34
  * `/deploy` as its own command), and Slack from an unlinked directory links
35
- * through the same team/project pickers as `/vercel` instead of the bare
35
+ * through the same team/project pickers as `/model`'s provider step instead of the bare
36
36
  * interactive `vercel link` fallback, which cannot own the terminal while the
37
37
  * TUI holds raw mode.
38
38
  */
@@ -20,7 +20,7 @@ export type LinkFlowResult = {
20
20
  kind: "cancelled";
21
21
  };
22
22
  /**
23
- * THE LINK FLOW, shared by `eve link` and the dev TUI's `/vercel` (its
23
+ * THE LINK FLOW, shared by `eve link` and the dev TUI `/model` menu's provider row (its
24
24
  * "Connect via a project" branch): the same
25
25
  * team/project pickers onboarding uses, then the actual `vercel link`, then a
26
26
  * `vercel env pull` so the AI Gateway credential lands in `.env.local`.
@@ -29,7 +29,7 @@ export type LinkFlowResult = {
29
29
  * gate — one "Link to another project" option; Esc keeps the link and folds
30
30
  * to cancelled — and only then runs the pickers. The new choice is
31
31
  * authoritative (the state seeds an unresolved project so no stale link leaks
32
- * into the boxes). Picking `/vercel` IS the "use Vercel" decision, so
32
+ * into the boxes). Reaching this flow IS the "use Vercel" decision, so
33
33
  * resolve-provisioning's deploy gate is pre-answered.
34
34
  *
35
35
  * Ends by verifying a model credential actually landed (`VERCEL_OIDC_TOKEN`
@@ -1,43 +1,112 @@
1
1
  import { type SelectModelDeps } from "../boxes/select-model.js";
2
2
  import type { Prompter } from "../prompter.js";
3
+ import { runVercelFlow } from "./vercel.js";
3
4
  /** Injected for tests; defaults to the real reads, fetches, and source edit. */
4
5
  export interface ModelFlowDeps {
5
6
  /** Reads the model the runtime currently serves; null before first compile. */
6
7
  readCurrentModel: (appRoot: string) => Promise<string | null>;
7
- /** Applies the picked slug to authored source; resolves to the outcome line. */
8
+ /** Applies the picked slug to authored source. */
8
9
  applyModel: (input: {
9
10
  appRoot: string;
10
11
  slug: string;
11
- }) => Promise<string>;
12
+ }) => Promise<ApplyModelOutcome>;
12
13
  /** Catalog fetch behind the shared model picker. */
13
14
  selectModel?: SelectModelDeps;
15
+ /** Reads how the model is backed right now, for the menu's provider row. */
16
+ detectProviderStatus: (appRoot: string) => Promise<ModelProviderStatus>;
17
+ /** The provider sub-flow behind the menu's provider row. */
18
+ runVercelFlow: typeof runVercelFlow;
14
19
  }
15
- export type ModelFlowResult = {
16
- kind: "done";
17
- message: string;
20
+ /**
21
+ * How the agent's model is backed right now, as far as the local directory
22
+ * shows: a linked Vercel project, a gateway credential in an env file, or
23
+ * nothing detectable. An external provider (own ANTHROPIC_API_KEY etc.)
24
+ * leaves no marker Eve owns, so it reads as `unset`.
25
+ */
26
+ export type ModelProviderStatus = {
27
+ kind: "unset";
18
28
  } | {
29
+ kind: "gateway-project";
30
+ projectName: string;
31
+ teamName?: string;
32
+ } | {
33
+ kind: "gateway-key";
34
+ envKey: "AI_GATEWAY_API_KEY" | "VERCEL_OIDC_TOKEN";
35
+ envFile: string;
36
+ };
37
+ /**
38
+ * A provider sub-flow run that actually moved the provider: the credential
39
+ * the link flow verified landed in an env file (when one did), paired with
40
+ * the re-detected {@link ModelProviderStatus} — the same read the menu's
41
+ * provider row shows, so every surface reports one truth. The sub-flow's
42
+ * external-provider branch only shows instructions — nothing changes on
43
+ * disk — so it never surfaces as an outcome.
44
+ */
45
+ export interface ModelProviderOutcome {
46
+ credential?: "VERCEL_OIDC_TOKEN" | "AI_GATEWAY_API_KEY";
47
+ status: ModelProviderStatus;
48
+ }
49
+ export type ModelFlowResult = {
19
50
  kind: "cancelled";
51
+ } | {
52
+ kind: "done";
53
+ /** The last apply line, when the model was changed this session. */
54
+ modelMessage?: string;
55
+ /** The last provider sub-flow outcome, when one ran to completion. */
56
+ providerOutcome?: ModelProviderOutcome;
20
57
  };
58
+ export declare const MODEL_MENU_MESSAGE = "Configure the agent's model";
59
+ /**
60
+ * Reads the provider status the menu shows. Detection order matters: a linked
61
+ * project subsumes any pulled credential (the link is what the user manages),
62
+ * and `AI_GATEWAY_API_KEY` outranks `VERCEL_OIDC_TOKEN` because it is the one
63
+ * the provider sub-flow's own-key branch writes.
64
+ */
65
+ export declare function detectModelProviderStatus(appRoot: string): Promise<ModelProviderStatus>;
21
66
  /**
22
- * THE MODEL FLOW, the dev TUI's `/model`: the same searchable AI Gateway
23
- * catalog picker onboarding uses ({@link selectModel}), pre-selected on the
24
- * model the runtime currently serves, then the static source edit that bakes
25
- * the choice into `agent.ts`. Activation is the dev server's HMR watcher.
67
+ * THE MODEL FLOW for the dev TUI's `/model`: a two-row action menu that
68
+ * loops, uniting the model pick and the provider setup behind one entry
69
+ * point. "Change model" runs the same searchable AI Gateway catalog picker
70
+ * onboarding uses ({@link selectModel}), pre-selected on the model the
71
+ * runtime currently serves, then the static source edit that bakes the
72
+ * choice into `agent.ts` (activation is the dev server's HMR watcher).
73
+ * The provider row runs {@link runVercelFlow} — the provider gate (AI
74
+ * Gateway or your own), then link-or-paste-a-key.
75
+ * Each sub-flow lands back on the repainted menu; Esc leaves. A
76
+ * cancelled sub-flow also returns to the menu. Esc after something completed
77
+ * reports it exactly like the channels flow (the effects already happened);
78
+ * only an empty exit folds to cancelled.
26
79
  */
27
80
  export declare function runModelFlow(input: {
28
81
  appRoot: string;
29
82
  prompter: Prompter;
30
83
  deps?: Partial<ModelFlowDeps>;
31
84
  }): Promise<ModelFlowResult>;
85
+ /** The outcome of applying a model slug to the agent's authored source. */
86
+ export type ApplyModelOutcome = {
87
+ kind: "changed";
88
+ to: string;
89
+ } | {
90
+ kind: "unchanged";
91
+ model: string;
92
+ }
93
+ /** Invalid slug or an uneditable source — `message` says which and why. */
94
+ | {
95
+ kind: "rejected";
96
+ message: string;
97
+ };
98
+ /** The one-line transcript form of an apply outcome (`/model <slug>`'s reply). */
99
+ export declare function formatApplyModelOutcome(outcome: ApplyModelOutcome): string;
32
100
  /**
33
101
  * Applies a `/model <slug>` change to the local agent's authored source.
34
102
  *
35
103
  * This is the caller layer for the static source-change registry: it
36
104
  * validates the slug against the AI Gateway model catalog, then edits
37
- * `agent.ts` via {@link createStaticSourceChange}. Returns a human-readable
38
- * line for the TUI to surface; activation is the dev server's HMR watcher.
105
+ * `agent.ts` via {@link createStaticSourceChange}. Activation is the dev
106
+ * server's HMR watcher; {@link formatApplyModelOutcome} renders the outcome
107
+ * as the TUI's one-line reply.
39
108
  */
40
109
  export declare function changeAgentModel(input: {
41
110
  readonly appRoot: string;
42
111
  readonly slug: string;
43
- }): Promise<string>;
112
+ }): Promise<ApplyModelOutcome>;
@@ -1 +1 @@
1
- import{interactiveAsker}from"../ask.js";import{snapshotSetupState}from"../state.js";import{fetchGatewayCatalog,selectModel}from"../boxes/select-model.js";import{runInteractive}from"../runner.js";import{inProjectSetupState,prompterSink}from"./in-project.js";import{join}from"node:path";import{discoverAgent}from"#discover/discover-agent.js";import{inspectApplication}from"#services/inspect-application.js";import{formatLanguageModelGatewayId}from"#internal/runtime-model.js";import{createCompiledRuntimeModelCatalogLoader}from"#compiler/model-catalog.js";import{createStaticSourceChange}from"#source-change/static-source-change.js";async function runModelFlow(o){let{appRoot:s,prompter:c}=o,l={readCurrentModel:readCurrentAgentModel,applyModel:changeAgentModel,...o.deps},u=await l.readCurrentModel(s),d=l.selectModel?.fetchModels??fetchGatewayCatalog,f={asker:interactiveAsker(c),deps:{fetchModels:async()=>{let e=c.log.spinner?.(`Loading the model catalog...`);try{return await d()}finally{e?.stop()}}}};u!==null&&(f.defaultModel=u);let p=await runInteractive([selectModel(f)],inProjectSetupState(s,{kind:`unresolved`}),prompterSink(c),{snapshot:snapshotSetupState});return p.kind===`cancelled`?{kind:`cancelled`}:{kind:`done`,message:await l.applyModel({appRoot:s,slug:p.state.modelId})}}async function changeAgentModel(e){let{appRoot:t,slug:n}=e,r=await validateModelSlug(t,n);if(r!==null)return r;let{manifest:i}=await discoverAgent({agentRoot:join(t,`agent`),appRoot:t}),a=await createStaticSourceChange(i).updateModelName(n);return a.kind===`bail`?`Couldn't edit ${a.at.logicalPath}: ${a.reason}. Change \`model\` by hand.`:a.from===a.to?`Model is already \`${a.to}\`.`:`Model → \`${a.to}\` · live on your next prompt.`}async function validateModelSlug(e,t){if(!t.includes(`/`))return`\`${t}\` isn't a provider/model id (e.g. anthropic/claude-sonnet-4.6).`;let n=createCompiledRuntimeModelCatalogLoader(e);try{if(await n.getModelLimits(formatLanguageModelGatewayId(t))===null)return`I couldn't confirm \`${t}\` in the AI Gateway model catalog, so I didn't change agent.ts.`}catch{return null}return null}async function readCurrentAgentModel(e){try{let{compiledState:t}=await inspectApplication(e);return t?.manifest.config.model.id??null}catch{return null}}export{changeAgentModel,runModelFlow};
1
+ import{__toESM}from"../../_virtual/_rolldown/runtime.js";import{require_picocolors}from"../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js";import{interactiveAsker}from"../ask.js";import{detectProjectIdentity}from"../project-resolution.js";import{snapshotSetupState}from"../state.js";import{findEnvFileWithKey}from"../boxes/detect-ai-gateway.js";import{fetchGatewayCatalog,selectModel}from"../boxes/select-model.js";import{WizardCancelledError}from"../step.js";import{runInteractive}from"../runner.js";import{inProjectSetupState,prompterSink}from"./in-project.js";import{runVercelFlow}from"./vercel.js";import{join}from"node:path";import{discoverAgent}from"#discover/discover-agent.js";import{inspectApplication}from"#services/inspect-application.js";import{formatLanguageModelGatewayId}from"#internal/runtime-model.js";import{createCompiledRuntimeModelCatalogLoader}from"#compiler/model-catalog.js";import{createStaticSourceChange}from"#source-change/static-source-change.js";var import_picocolors=__toESM(require_picocolors(),1);const MODEL_MENU_MESSAGE=`Configure the agent's model`;function providerStatusHint(e,t=e=>e){return e.kind===`gateway-project`?`AI Gateway (Linked to ${e.teamName===void 0?t(e.projectName):`${t(e.projectName)} in ${t(e.teamName)}`})`:`AI Gateway (${e.envKey} in ${e.envFile})`}function modelMenuRows(e,t){let n={value:`model`,label:`Change model`};return e!==null&&(n.hint=e),[n,t.kind===`unset`?{value:`provider`,label:import_picocolors.default.bold(import_picocolors.default.yellow(`Configure provider`)),hint:`Required to enable the agent`}:{value:`provider`,label:`Change provider`,hint:providerStatusHint(t,import_picocolors.default.bold)}]}function applyModelNotice(e){switch(e.kind){case`changed`:return{tone:`success`,text:`Model changed to ${e.to}`};case`unchanged`:return{tone:`info`,text:`Model is already ${e.model}`};case`rejected`:return{tone:`warning`,text:e.message}}}function providerNotice(e){return e.kind===`unset`?{tone:`warning`,text:`Provider updated — no gateway credential detected yet.`}:{tone:`success`,text:`Provider changed to ${providerStatusHint(e)}`}}async function detectModelProviderStatus(e){let[t,n,i]=await Promise.all([detectProjectIdentity(e),findEnvFileWithKey(e,`AI_GATEWAY_API_KEY`),findEnvFileWithKey(e,`VERCEL_OIDC_TOKEN`)]);if(t!==void 0){let e={kind:`gateway-project`,projectName:t.projectName};return t.teamName!==void 0&&(e.teamName=t.teamName),e}return n===void 0?i===void 0?{kind:`unset`}:{kind:`gateway-key`,envKey:`VERCEL_OIDC_TOKEN`,envFile:i}:{kind:`gateway-key`,envKey:`AI_GATEWAY_API_KEY`,envFile:n}}async function runModelFlow(e){let{appRoot:t,prompter:n}=e,r={readCurrentModel:readCurrentAgentModel,applyModel:changeAgentModel,detectProviderStatus:detectModelProviderStatus,runVercelFlow,...e.deps};async function checkProject(e){let t=n.log.spinner?.(`Checking the project…`);try{return await e()}finally{t?.stop()}}let[i,a]=await checkProject(()=>Promise.all([r.readCurrentModel(t),r.detectProviderStatus(t)])),o,s,l,u;for(;;){let e;try{e=await n.select({message:MODEL_MENU_MESSAGE,options:modelMenuRows(i,a),layout:`stacked`,notices:[l,u].filter(e=>e!==void 0)})}catch(e){if(!(e instanceof WizardCancelledError))throw e;break}if(e===`model`){let e=await pickModelFromCatalog({appRoot:t,prompter:n,current:i,deps:r.selectModel});e!==void 0&&(o=await r.applyModel({appRoot:t,slug:e}),l=applyModelNotice(o),o.kind===`changed`&&(i=o.to));continue}let d=await r.runVercelFlow({appRoot:t,prompter:n});d.kind===`cancelled`||`outcome`in d||(a=await checkProject(()=>r.detectProviderStatus(t)),s={status:a},d.credential!==void 0&&(s.credential=d.credential),u=providerNotice(a))}if(o===void 0&&s===void 0)return{kind:`cancelled`};let d={kind:`done`};return o!==void 0&&(d.modelMessage=formatApplyModelOutcome(o)),s!==void 0&&(d.providerOutcome=s),d}async function pickModelFromCatalog(e){let{appRoot:t,prompter:r,current:a}=e,c=e.deps?.fetchModels??fetchGatewayCatalog,f={asker:interactiveAsker(r),deps:{fetchModels:async()=>{let e=r.log.spinner?.(`Loading the model catalog...`);try{return await c()}finally{e?.stop()}}}};a!==null&&(f.defaultModel=a);let p=await runInteractive([selectModel(f)],inProjectSetupState(t,{kind:`unresolved`}),prompterSink(r),{snapshot:snapshotSetupState});return p.kind===`cancelled`?void 0:p.state.modelId}function formatApplyModelOutcome(e){switch(e.kind){case`changed`:return`Model → \`${e.to}\` · live on your next prompt.`;case`unchanged`:return`Model is already \`${e.model}\`.`;case`rejected`:return e.message}}async function changeAgentModel(e){let{appRoot:t,slug:n}=e,r=await validateModelSlug(t,n);if(r!==null)return{kind:`rejected`,message:r};let{manifest:i}=await discoverAgent({agentRoot:join(t,`agent`),appRoot:t}),a=await createStaticSourceChange(i).updateModelName(n);return a.kind===`bail`?{kind:`rejected`,message:`Couldn't edit ${a.at.logicalPath}: ${a.reason}. Change \`model\` by hand.`}:a.from===a.to?{kind:`unchanged`,model:a.to}:{kind:`changed`,to:a.to}}async function validateModelSlug(e,t){if(!t.includes(`/`))return`\`${t}\` isn't a provider/model id (e.g. anthropic/claude-sonnet-4.6).`;let n=createCompiledRuntimeModelCatalogLoader(e);try{if(await n.getModelLimits(formatLanguageModelGatewayId(t))===null)return`I couldn't confirm \`${t}\` in the AI Gateway model catalog, so I didn't change agent.ts.`}catch{return null}return null}async function readCurrentAgentModel(e){try{let{compiledState:t}=await inspectApplication(e);return t?.manifest.config.model.id??null}catch{return null}}export{MODEL_MENU_MESSAGE,changeAgentModel,detectModelProviderStatus,formatApplyModelOutcome,runModelFlow};
@@ -16,12 +16,13 @@ export type VercelFlowResult = LinkFlowResult | {
16
16
  outcome: "external-provider";
17
17
  };
18
18
  /**
19
- * THE `/vercel` FLOW (dev TUI only — `eve link` keeps {@link runLinkFlow}'s
20
- * shape). Two entry questions make the provider choice explicit before any
21
- * link machinery runs: a provider gate (AI Gateway, or instructions for
22
- * everything else) and a connection gate (link a project, or paste an
23
- * `AI_GATEWAY_API_KEY` that lands in `.env.local`). The "Connect via a
24
- * project" branch is exactly the link flow, link detection and all.
19
+ * THE PROVIDER FLOW behind the dev TUI `/model` menu's provider row
20
+ * (`eve link` keeps {@link runLinkFlow}'s shape). Two entry questions make
21
+ * the provider choice explicit before any link machinery runs: a provider
22
+ * gate (AI Gateway, or instructions for everything else) and a connection
23
+ * gate (link a project, or paste an `AI_GATEWAY_API_KEY` that lands in
24
+ * `.env.local`). The "Connect via a project" branch is exactly the link
25
+ * flow, link detection and all.
25
26
  */
26
27
  export declare function runVercelFlow(input: {
27
28
  appRoot: string;
@@ -1,2 +1,2 @@
1
- import{appendEnv}from"../append-env.js";import{WizardCancelledError}from"../step.js";import{runLinkFlow}from"./link.js";import{join}from"node:path";const AI_GATEWAY_ENV_KEY=`AI_GATEWAY_API_KEY`,ENV_FILE_NAME=`.env.local`,PROVIDER_QUESTION=`Which model provider do you want to use?`,CONNECTION_QUESTION=`How do you want to connect to AI Gateway?`,EXTERNAL_PROVIDER_INSTRUCTIONS_TITLE=`Using another model provider`,EXTERNAL_PROVIDER_INSTRUCTIONS=[`Set your provider's API key in ${ENV_FILE_NAME} — e.g. ANTHROPIC_API_KEY or OPENAI_API_KEY.`,`Point your agent's model at that provider in your agent source.`,"A running `eve dev` reloads env files automatically — no restart needed."];async function runVercelFlow(t){let{appRoot:n,prompter:r}=t,i={runLinkFlow,appendEnv,...t.deps},a,o;try{a=await r.select({message:PROVIDER_QUESTION,options:[{value:`gateway`,label:`Vercel AI Gateway`,hint:`one key, every model`},{value:`other`,label:`Something else`,hint:`use your own provider credentials`}]}),a===`gateway`&&(o=await r.select({message:CONNECTION_QUESTION,options:[{value:`project`,label:`Connect via a project`,hint:`vercel link + env pull`},{value:`own-key`,label:`Use my own key`,hint:`paste an ${AI_GATEWAY_ENV_KEY}`}]}))}catch(e){if(e instanceof WizardCancelledError)return{kind:`cancelled`};throw e}if(a===`other`)return r.acknowledge?await r.acknowledge({message:EXTERNAL_PROVIDER_INSTRUCTIONS_TITLE,lines:EXTERNAL_PROVIDER_INSTRUCTIONS}):r.note(EXTERNAL_PROVIDER_INSTRUCTIONS.join(`
1
+ import{appendEnv}from"../append-env.js";import{WizardCancelledError}from"../step.js";import{runLinkFlow}from"./link.js";import{join}from"node:path";const AI_GATEWAY_ENV_KEY=`AI_GATEWAY_API_KEY`,ENV_FILE_NAME=`.env.local`,PROVIDER_QUESTION=`Which model provider do you want to use?`,CONNECTION_QUESTION=`How do you want to connect to AI Gateway?`,EXTERNAL_PROVIDER_INSTRUCTIONS_TITLE=`Using another model provider`,EXTERNAL_PROVIDER_INSTRUCTIONS=[`Set your provider's API key in ${ENV_FILE_NAME} — e.g. ANTHROPIC_API_KEY or OPENAI_API_KEY.`,'In agent/agent.ts, set `model` to a provider-authored model e.g. `anthropic("claude-opus-4.8")` from `@ai-sdk/anthropic`.',`See https://beta.eve.dev/docs/agent-config for details.`,"A running `eve dev` reloads env files automatically — no restart needed."];async function runVercelFlow(t){let{appRoot:n,prompter:r}=t,i={runLinkFlow,appendEnv,...t.deps},a,o;try{a=await r.select({message:PROVIDER_QUESTION,options:[{value:`gateway`,label:`Vercel AI Gateway`,hint:`one key, every model`},{value:`other`,label:`Something else`,hint:`use your own provider credentials`}]}),a===`gateway`&&(o=await r.select({message:CONNECTION_QUESTION,options:[{value:`project`,label:`Connect via a project`,hint:`vercel link + env pull`},{value:`own-key`,label:`Use my own key`,hint:`paste an ${AI_GATEWAY_ENV_KEY}`}]}))}catch(e){if(e instanceof WizardCancelledError)return{kind:`cancelled`};throw e}if(a===`other`)return r.acknowledge?await r.acknowledge({message:EXTERNAL_PROVIDER_INSTRUCTIONS_TITLE,lines:EXTERNAL_PROVIDER_INSTRUCTIONS}):r.note(EXTERNAL_PROVIDER_INSTRUCTIONS.join(`
2
2
  `),EXTERNAL_PROVIDER_INSTRUCTIONS_TITLE),{kind:`done`,outcome:`external-provider`};if(o===`own-key`){let e;try{e=await r.password({message:`Enter your ${AI_GATEWAY_ENV_KEY}`,validate:e=>e.trim().length===0?`API key cannot be empty.`:void 0})}catch(e){if(e instanceof WizardCancelledError)return{kind:`cancelled`};throw e}return await i.appendEnv(join(n,ENV_FILE_NAME),{[AI_GATEWAY_ENV_KEY]:e.trim()},{force:!0}),r.log.success(`Saved ${AI_GATEWAY_ENV_KEY} to ${ENV_FILE_NAME}.`),r.log.message("A running `eve dev` reloads env files automatically — no restart needed."),{kind:`done`,credential:AI_GATEWAY_ENV_KEY}}return await i.runLinkFlow({appRoot:n,prompter:r})}export{CONNECTION_QUESTION,EXTERNAL_PROVIDER_INSTRUCTIONS,EXTERNAL_PROVIDER_INSTRUCTIONS_TITLE,PROVIDER_QUESTION,runVercelFlow};
@@ -1 +1 @@
1
- import{captureVercel}from"./primitives/run-vercel.js";import{join}from"node:path";import{readFile}from"node:fs/promises";function pickShortestAlias(e){if(!Array.isArray(e))return;let t;for(let n of e)typeof n!=`string`||n.length===0||(t===void 0||n.length<t.length)&&(t=n);return t}async function fetchProductionAlias(t,n,r){let i=await captureVercel([`api`,`/v9/projects/${t}?teamId=${n}`,`--scope`,n],{cwd:r});if(i.ok)try{let e=pickShortestAlias(JSON.parse(i.stdout).targets?.production?.alias);return e?`https://${e}`:void 0}catch{return}}async function detectDeployment(e){let r;try{r=await readFile(join(e,`.vercel`,`project.json`),`utf8`)}catch{return{state:`unlinked`}}let i;try{i=JSON.parse(r)}catch{return{state:`unlinked`}}let a=typeof i.projectId==`string`?i.projectId:void 0,o=typeof i.orgId==`string`?i.orgId:void 0;if(!a||!o)return{state:`unlinked`};let s=await fetchProductionAlias(a,o,e);return{state:s?`deployed`:`linked`,projectId:a,orgId:o,productionUrl:s}}async function fetchVercelName(t,n,r){let i=await captureVercel([`api`,t,`--scope`,n],{cwd:r});if(i.ok)try{let e=JSON.parse(i.stdout);return typeof e.name==`string`&&e.name.length>0?e.name:typeof e.slug==`string`&&e.slug.length>0?e.slug:void 0}catch{return}}async function detectProjectIdentity(e){let r;try{r=await readFile(join(e,`.vercel`,`project.json`),`utf8`)}catch{return}let i;try{i=JSON.parse(r)}catch{return}let a=typeof i.projectId==`string`?i.projectId:void 0,o=typeof i.orgId==`string`?i.orgId:void 0;return!a||!o?void 0:{projectName:await fetchVercelName(`/v9/projects/${a}?teamId=${o}`,o,e)??a,teamName:o.startsWith(`team_`)?await fetchVercelName(`/v2/teams/${o}`,o,e):void 0}}function projectResolutionFromDeployment(e){return e.state===`unlinked`||e.projectId===void 0?{kind:`unresolved`}:e.state===`deployed`&&e.productionUrl!==void 0?{kind:`deployed`,projectId:e.projectId,productionUrl:e.productionUrl}:{kind:`linked`,projectId:e.projectId}}async function detectProjectResolution(e){return projectResolutionFromDeployment(await detectDeployment(e))}function mergeProjectResolution(e,t){return t.kind===`unresolved`||e.kind===`deployed`&&e.projectId===t.projectId?e:t}function projectResolutionFromDeployResult(e,t){return e.kind===`unresolved`||!t.deployed||t.productionUrl===void 0?e:{kind:`deployed`,projectId:e.projectId,productionUrl:t.productionUrl}}function isProjectResolved(e){return e.kind!==`unresolved`}function projectProductionUrlFromResolution(e){return e.kind===`deployed`?e.productionUrl:void 0}export{detectDeployment,detectProjectIdentity,detectProjectResolution,isProjectResolved,mergeProjectResolution,projectProductionUrlFromResolution,projectResolutionFromDeployResult,projectResolutionFromDeployment};
1
+ import{captureVercel}from"./primitives/run-vercel.js";import{join}from"node:path";import{readFile}from"node:fs/promises";function pickShortestAlias(e){if(!Array.isArray(e))return;let t;for(let n of e)typeof n!=`string`||n.length===0||(t===void 0||n.length<t.length)&&(t=n);return t}async function fetchProductionAlias(t,n,r){let i=await captureVercel([`api`,`/v9/projects/${t}?teamId=${n}`,`--scope`,n],{cwd:r});if(i.ok)try{let e=pickShortestAlias(JSON.parse(i.stdout).targets?.production?.alias);return e?`https://${e}`:void 0}catch{return}}async function detectDeployment(e){let r;try{r=await readFile(join(e,`.vercel`,`project.json`),`utf8`)}catch{return{state:`unlinked`}}let i;try{i=JSON.parse(r)}catch{return{state:`unlinked`}}let a=typeof i.projectId==`string`?i.projectId:void 0,o=typeof i.orgId==`string`?i.orgId:void 0;if(!a||!o)return{state:`unlinked`};let s=await fetchProductionAlias(a,o,e);return{state:s?`deployed`:`linked`,projectId:a,orgId:o,productionUrl:s}}async function fetchVercelName(t,n,r){let i=await captureVercel([`api`,t,`--scope`,n],{cwd:r});if(i.ok)try{let e=JSON.parse(i.stdout);return typeof e.name==`string`&&e.name.length>0?e.name:typeof e.slug==`string`&&e.slug.length>0?e.slug:void 0}catch{return}}async function detectProjectIdentity(e){let r;try{r=await readFile(join(e,`.vercel`,`project.json`),`utf8`)}catch{return}let i;try{i=JSON.parse(r)}catch{return}let a=typeof i.projectId==`string`?i.projectId:void 0,o=typeof i.orgId==`string`?i.orgId:void 0;if(!a||!o)return;let[s,c]=await Promise.all([fetchVercelName(`/v9/projects/${a}?teamId=${o}`,o,e).then(e=>e??a),o.startsWith(`team_`)?fetchVercelName(`/v2/teams/${o}`,o,e):Promise.resolve(void 0)]);return{projectName:s,teamName:c}}function projectResolutionFromDeployment(e){return e.state===`unlinked`||e.projectId===void 0?{kind:`unresolved`}:e.state===`deployed`&&e.productionUrl!==void 0?{kind:`deployed`,projectId:e.projectId,productionUrl:e.productionUrl}:{kind:`linked`,projectId:e.projectId}}async function detectProjectResolution(e){return projectResolutionFromDeployment(await detectDeployment(e))}function mergeProjectResolution(e,t){return t.kind===`unresolved`||e.kind===`deployed`&&e.projectId===t.projectId?e:t}function projectResolutionFromDeployResult(e,t){return e.kind===`unresolved`||!t.deployed||t.productionUrl===void 0?e:{kind:`deployed`,projectId:e.projectId,productionUrl:t.productionUrl}}function isProjectResolved(e){return e.kind!==`unresolved`}function projectProductionUrlFromResolution(e){return e.kind===`deployed`?e.productionUrl:void 0}export{detectDeployment,detectProjectIdentity,detectProjectResolution,isProjectResolved,mergeProjectResolution,projectProductionUrlFromResolution,projectResolutionFromDeployResult,projectResolutionFromDeployment};
@@ -33,6 +33,15 @@ export interface SelectOption<T extends PrompterValue> {
33
33
  */
34
34
  featured?: boolean;
35
35
  }
36
+ /**
37
+ * An outcome line from an earlier lap of a looping menu, shown with the
38
+ * repainted question: the TUI panel renders it beneath the options, the CLI
39
+ * prints it to scrollback before the prompt.
40
+ */
41
+ export interface SelectNotice {
42
+ tone: "success" | "info" | "warning";
43
+ text: string;
44
+ }
36
45
  /** Options common to every {@link Prompter.select} call. */
37
46
  export interface SelectCommonOptions<T extends PrompterValue> {
38
47
  message: string;
@@ -50,6 +59,15 @@ export interface SelectCommonOptions<T extends PrompterValue> {
50
59
  * so it is inherently satisfied.
51
60
  */
52
61
  required?: boolean;
62
+ /**
63
+ * "stacked" renders each option's hint on its own line below the label with
64
+ * a blank line between options — for small action menus whose hints carry
65
+ * current values. A TUI-panel affordance: the CLI prompter keeps its inline
66
+ * hint rendering.
67
+ */
68
+ layout?: "stacked";
69
+ /** Outcome lines from earlier laps of a looping menu. */
70
+ notices?: readonly SelectNotice[];
53
71
  }
54
72
  /** Single-select form: navigate, then enter picks the highlighted option. */
55
73
  export interface SingleSelectOptions<T extends PrompterValue> extends SelectCommonOptions<T> {
@@ -1 +1 @@
1
- import{__toESM}from"../_virtual/_rolldown/runtime.js";import{require_picocolors}from"../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js";import{h,ht,q}from"../node_modules/.pnpm/@clack_core@1.3.1/node_modules/@clack/core/dist/index.js";import{WizardCancelledError}from"./step.js";import{initialQuitGuardState,quitHintNote,reduceQuitGuard}from"./quit-guard.js";import{cornerFor,createRailLog,formatPromptCancellation,formatPromptHeader,formatPromptOpener,formatPromptOutro,formatPromptSubmission,formatRailLine,railFor,runSelectComponent}from"#setup/cli/index.js";var import_picocolors=__toESM(require_picocolors(),1);function guardCancel(e){if(q(e))throw process.stdout.write(formatPromptCancellation(`Setup cancelled.`,import_picocolors.default)),new WizardCancelledError;return e}let escapeCancelDisabled=!1;function disableEscapeCancel(){escapeCancelDisabled||=(h.aliases.delete(`escape`),!0)}function attachQuitGuard(e){let t=initialQuitGuardState;return e.on(`key`,(n,r)=>{let{state:i,action:a}=reduceQuitGuard(t,r?.name===`escape`?{type:`escape`}:{type:`other-key`});t=i,a===`quit`&&(e.state=`cancel`)}),{note:()=>quitHintNote(t,import_picocolors.default)}}function toPromptState(e){return e}function railForState(e){return railFor(toPromptState(e),import_picocolors.default)}function cornerForState(e){return cornerFor(toPromptState(e),import_picocolors.default)}function header(e,t,n){return formatPromptHeader(toPromptState(e),t,{colors:import_picocolors.default,leadingRail:n===0?`white`:`green`})}const REDACTED_DISPLAY=`••••••••`;function textPrompt(e,t){let n,i=new ht({validate:t.validate?e=>t.validate?.(e??``):void 0,placeholder:t.placeholder,defaultValue:t.defaultValue,render(){let r=header(this.state,t.message,e),i=t.placeholder?import_picocolors.default.inverse(t.placeholder[0])+import_picocolors.default.dim(t.placeholder.slice(1)):import_picocolors.default.inverse(import_picocolors.default.hidden(`_`)),a=this.value?`•`.repeat(this.value.length):i,o=t.mask?a:this.value?this.userInputWithCursor:i;switch(this.state){case`error`:return`${r.trim()}\n${railForState(this.state)} ${o}\n${cornerForState(this.state)} ${import_picocolors.default.red(this.error)}\n`;case`submit`:{let n=t.mask?this.value?REDACTED_DISPLAY:t.placeholder||``:this.value||t.placeholder||``;return formatPromptSubmission(this.state,t.message,n,{colors:import_picocolors.default,leadingRail:e===0?`white`:`green`})}case`cancel`:return`${r}${railForState(this.state)} ${import_picocolors.default.strikethrough(import_picocolors.default.dim(t.mask&&this.value?REDACTED_DISPLAY:this.value??``))}${this.value?.trim()?`\n${railForState(this.state)}`:``}`;default:return`${r}${railForState(this.state)} ${o}\n${cornerForState(this.state)}${cornerNote(n?.note())}\n`}}});return n=attachQuitGuard(i),i.prompt()}function cornerNote(e){return e?` ${e}`:``}function createPrompter(){disableEscapeCancel();let e=0,t=createRailLog({colors:import_picocolors.default,output:process.stdout});return{async text(n){t.settle();let r=guardCancel(await textPrompt(e,n));return e+=1,r??``},async password(n){t.settle();let r=guardCancel(await textPrompt(e,{message:n.message,mask:!0,validate:n.validate}));return e+=1,r??``},async select(n){t.settle();let r=guardCancel(await runSelectComponent({message:n.message,options:n.options,multiple:n.multiple===!0,search:n.search??!1,required:n.required??!1,placeholder:n.placeholder,defaultValue:n.multiple===!0?void 0:n.initialValue,initialValues:n.multiple===!0?n.initialValues:void 0,leadingRail:e===0?`white`:`green`,attachGuard:e=>attachQuitGuard(e)}));return e+=1,r},async acknowledge(e){t.settle(),process.stdout.write(formatRailLine(import_picocolors.default.bold(e.message),import_picocolors.default,process.stdout));for(let t of e.lines??[])process.stdout.write(formatRailLine(import_picocolors.default.dim(t),import_picocolors.default,process.stdout))},note(e,n,r){t.settle();let i=r?.tone===`success`?import_picocolors.default.green:import_picocolors.default.red;n&&process.stdout.write(formatRailLine(i(import_picocolors.default.bold(n)),import_picocolors.default,process.stdout)),process.stdout.write(formatRailLine(i(e),import_picocolors.default,process.stdout))},intro(e,n=`Production-grade agent framework.`){t.settle(),process.stdout.write(formatPromptOpener(e,n,import_picocolors.default))},outro(e){t.settle(),process.stdout.write(formatPromptOutro(e,import_picocolors.default))},log:t}}export{createPrompter};
1
+ import{__toESM}from"../_virtual/_rolldown/runtime.js";import{require_picocolors}from"../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js";import{h,ht,q}from"../node_modules/.pnpm/@clack_core@1.3.1/node_modules/@clack/core/dist/index.js";import{WizardCancelledError}from"./step.js";import{initialQuitGuardState,quitHintNote,reduceQuitGuard}from"./quit-guard.js";import{cornerFor,createRailLog,formatPromptCancellation,formatPromptHeader,formatPromptOpener,formatPromptOutro,formatPromptSubmission,formatRailLine,railFor,runSelectComponent}from"#setup/cli/index.js";var import_picocolors=__toESM(require_picocolors(),1);function guardCancel(e){if(q(e))throw process.stdout.write(formatPromptCancellation(`Setup cancelled.`,import_picocolors.default)),new WizardCancelledError;return e}let escapeCancelDisabled=!1;function disableEscapeCancel(){escapeCancelDisabled||=(h.aliases.delete(`escape`),!0)}function attachQuitGuard(e){let t=initialQuitGuardState;return e.on(`key`,(n,r)=>{let{state:i,action:a}=reduceQuitGuard(t,r?.name===`escape`?{type:`escape`}:{type:`other-key`});t=i,a===`quit`&&(e.state=`cancel`)}),{note:()=>quitHintNote(t,import_picocolors.default)}}function toPromptState(e){return e}function railForState(e){return railFor(toPromptState(e),import_picocolors.default)}function cornerForState(e){return cornerFor(toPromptState(e),import_picocolors.default)}function header(e,t,n){return formatPromptHeader(toPromptState(e),t,{colors:import_picocolors.default,leadingRail:n===0?`white`:`green`})}const REDACTED_DISPLAY=`••••••••`;function textPrompt(e,t){let n,i=new ht({validate:t.validate?e=>t.validate?.(e??``):void 0,placeholder:t.placeholder,defaultValue:t.defaultValue,render(){let r=header(this.state,t.message,e),i=t.placeholder?import_picocolors.default.inverse(t.placeholder[0])+import_picocolors.default.dim(t.placeholder.slice(1)):import_picocolors.default.inverse(import_picocolors.default.hidden(`_`)),a=this.value?`•`.repeat(this.value.length):i,o=t.mask?a:this.value?this.userInputWithCursor:i;switch(this.state){case`error`:return`${r.trim()}\n${railForState(this.state)} ${o}\n${cornerForState(this.state)} ${import_picocolors.default.red(this.error)}\n`;case`submit`:{let n=t.mask?this.value?REDACTED_DISPLAY:t.placeholder||``:this.value||t.placeholder||``;return formatPromptSubmission(this.state,t.message,n,{colors:import_picocolors.default,leadingRail:e===0?`white`:`green`})}case`cancel`:return`${r}${railForState(this.state)} ${import_picocolors.default.strikethrough(import_picocolors.default.dim(t.mask&&this.value?REDACTED_DISPLAY:this.value??``))}${this.value?.trim()?`\n${railForState(this.state)}`:``}`;default:return`${r}${railForState(this.state)} ${o}\n${cornerForState(this.state)}${cornerNote(n?.note())}\n`}}});return n=attachQuitGuard(i),i.prompt()}function cornerNote(e){return e?` ${e}`:``}function createPrompter(){disableEscapeCancel();let e=0,t=createRailLog({colors:import_picocolors.default,output:process.stdout});return{async text(n){t.settle();let r=guardCancel(await textPrompt(e,n));return e+=1,r??``},async password(n){t.settle();let r=guardCancel(await textPrompt(e,{message:n.message,mask:!0,validate:n.validate}));return e+=1,r??``},async select(n){t.settle();for(let e of n.notices??[])e.tone===`success`?t.success(e.text):e.tone===`warning`?t.warning(e.text):t.message(e.text);let r=guardCancel(await runSelectComponent({message:n.message,options:n.options,multiple:n.multiple===!0,search:n.search??!1,required:n.required??!1,placeholder:n.placeholder,defaultValue:n.multiple===!0?void 0:n.initialValue,initialValues:n.multiple===!0?n.initialValues:void 0,leadingRail:e===0?`white`:`green`,attachGuard:e=>attachQuitGuard(e)}));return e+=1,r},async acknowledge(e){t.settle(),process.stdout.write(formatRailLine(import_picocolors.default.bold(e.message),import_picocolors.default,process.stdout));for(let t of e.lines??[])process.stdout.write(formatRailLine(import_picocolors.default.dim(t),import_picocolors.default,process.stdout))},note(e,n,r){t.settle();let i=r?.tone===`success`?import_picocolors.default.green:import_picocolors.default.red;n&&process.stdout.write(formatRailLine(i(import_picocolors.default.bold(n)),import_picocolors.default,process.stdout)),process.stdout.write(formatRailLine(i(e),import_picocolors.default,process.stdout))},intro(e,n=`Production-grade agent framework.`){t.settle(),process.stdout.write(formatPromptOpener(e,n,import_picocolors.default))},outro(e){t.settle(),process.stdout.write(formatPromptOutro(e,import_picocolors.default))},log:t}}export{createPrompter};
@@ -1 +1 @@
1
- import{getPackageManagerStrategy}from"../../primitives/pm/index.js";import{pathExists,writeTextFile}from"../files.js";import{patchPackageJson}from"../update/package-json.js";import{resolveVersionToken}from"../version-tokens.js";import{agentTemplateFiles,formatEveDependencySpecifier}from"./project.js";import{join}from"node:path";import{readFile}from"node:fs/promises";const DEPENDENCY_FIELDS=[`dependencies`,`devDependencies`,`optionalDependencies`,`peerDependencies`];function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function hasDeclaredDependency(e,t){if(!isJsonObject(e))return!1;for(let n of DEPENDENCY_FIELDS){let r=e[n];if(isJsonObject(r)&&typeof r[t]==`string`)return!0}return!1}async function addAgentToProject(i){let a=join(i.projectRoot,`package.json`);if(!await pathExists(a))throw Error(`Cannot add an Eve agent to "${i.projectRoot}" because it has no package.json. Run \`eve init <name>\` to create a new project instead.`);let o=agentTemplateFiles(i.model),s=[];for(let e of Object.keys(o))await pathExists(join(i.projectRoot,e))&&s.push(e);if(s.length===0&&await pathExists(join(i.projectRoot,`agent`))&&s.push(`agent/`),s.length>0)throw Error(`Cannot add an Eve agent to "${i.projectRoot}" because it already has: ${s.join(`, `)}. Move them aside first.`);let c=resolveVersionToken(`evePackageVersion`,i.evePackageVersion??`0.6.0-beta.18`),l=resolveVersionToken(`aiPackageVersion`,i.aiPackageVersion??`7.0.0-canary.171`),u=resolveVersionToken(`zodPackageVersion`,i.zodPackageVersion??`4.4.3`),d=[];for(let[e,t]of Object.entries(o)){let r=join(i.projectRoot,e);await writeTextFile(r,t),d.push(r)}let f=JSON.parse(await readFile(a,`utf8`)),p={ai:l,eve:formatEveDependencySpecifier(c),zod:u},m={};for(let[e,t]of Object.entries(p))hasDeclaredDependency(f,e)||(m[e]=t);return Object.keys(m).length>0&&await patchPackageJson(a,{dependencies:m}),await getPackageManagerStrategy(i.packageManager??`pnpm`).applyProjectConfiguration(i.projectRoot),{filesWritten:d,dependenciesAdded:Object.keys(m).sort()}}export{addAgentToProject};
1
+ import{getPackageManagerStrategy}from"../../primitives/pm/index.js";import{pathExists,writeTextFile}from"../files.js";import{patchPackageJson}from"../update/package-json.js";import{resolveVersionToken}from"../version-tokens.js";import{agentTemplateFiles,formatEveDependencySpecifier}from"./project.js";import{join}from"node:path";import{readFile}from"node:fs/promises";const DEPENDENCY_FIELDS=[`dependencies`,`devDependencies`,`optionalDependencies`,`peerDependencies`];function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function hasDeclaredDependency(e,t){if(!isJsonObject(e))return!1;for(let n of DEPENDENCY_FIELDS){let r=e[n];if(isJsonObject(r)&&typeof r[t]==`string`)return!0}return!1}async function addAgentToProject(i){let a=join(i.projectRoot,`package.json`);if(!await pathExists(a))throw Error(`Cannot add an Eve agent to "${i.projectRoot}" because it has no package.json. Run \`eve init <name>\` to create a new project instead.`);let o=agentTemplateFiles(i.model),s=[];for(let e of Object.keys(o))await pathExists(join(i.projectRoot,e))&&s.push(e);if(s.length===0&&await pathExists(join(i.projectRoot,`agent`))&&s.push(`agent/`),s.length>0)throw Error(`Cannot add an Eve agent to "${i.projectRoot}" because it already has: ${s.join(`, `)}. Move them aside first.`);let c=resolveVersionToken(`evePackageVersion`,i.evePackageVersion??`0.6.0-beta.19`),l=resolveVersionToken(`aiPackageVersion`,i.aiPackageVersion??`7.0.0-canary.171`),u=resolveVersionToken(`zodPackageVersion`,i.zodPackageVersion??`4.4.3`),d=[];for(let[e,t]of Object.entries(o)){let r=join(i.projectRoot,e);await writeTextFile(r,t),d.push(r)}let f=JSON.parse(await readFile(a,`utf8`)),p={ai:l,eve:formatEveDependencySpecifier(c),zod:u},m={};for(let[e,t]of Object.entries(p))hasDeclaredDependency(f,e)||(m[e]=t);return Object.keys(m).length>0&&await patchPackageJson(a,{dependencies:m}),await getPackageManagerStrategy(i.packageManager??`pnpm`).applyProjectConfiguration(i.projectRoot),{filesWritten:d,dependenciesAdded:Object.keys(m).sort()}}export{addAgentToProject};
@@ -1,4 +1,4 @@
1
- import{getPackageManagerStrategy}from"../../primitives/pm/index.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{basename,join,resolve}from"node:path";import{mkdir,readdir,stat}from"node:fs/promises";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,ALLOWED_CREATE_IN_PLACE_ENTRIES=new Set([`.DS_Store`,`.git`,`.gitkeep`,`.hg`]),DEFAULT_EVE_PACKAGE_VERSION=`0.6.0-beta.18`,DEFAULT_AI_PACKAGE_VERSION=`7.0.0-canary.171`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`;function modelProviderSlug(e){let t=(e.split(`/`)[0]??``).replaceAll(/[^A-Za-z0-9._-]/gu,``);return t.length>0?t:`anthropic`}function byokProviderEnvVar(e){let t=modelProviderSlug(e).toUpperCase().replaceAll(/[^A-Z0-9]/gu,`_`);return`${/^[0-9]/.test(t)?`_`:``}${t}_API_KEY`}function agentTemplateFiles(e){return{"agent/agent.ts":BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function renderTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_MODEL__`,t.model).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(t.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(t.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(t.evePackageVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,t.aiPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,t.zodPackageVersion).replaceAll(`__EVE_INIT_TSGO_VERSION__`,t.tsgoPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,t.typesNodePackageVersion)}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}const BASE_AGENT_TEMPLATE=`import { defineAgent } from "eve";
1
+ import{getPackageManagerStrategy}from"../../primitives/pm/index.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{basename,join,resolve}from"node:path";import{mkdir,readdir,stat}from"node:fs/promises";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,ALLOWED_CREATE_IN_PLACE_ENTRIES=new Set([`.DS_Store`,`.git`,`.gitkeep`,`.hg`]),DEFAULT_EVE_PACKAGE_VERSION=`0.6.0-beta.19`,DEFAULT_AI_PACKAGE_VERSION=`7.0.0-canary.171`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`;function modelProviderSlug(e){let t=(e.split(`/`)[0]??``).replaceAll(/[^A-Za-z0-9._-]/gu,``);return t.length>0?t:`anthropic`}function byokProviderEnvVar(e){let t=modelProviderSlug(e).toUpperCase().replaceAll(/[^A-Z0-9]/gu,`_`);return`${/^[0-9]/.test(t)?`_`:``}${t}_API_KEY`}function agentTemplateFiles(e){return{"agent/agent.ts":BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function renderTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_MODEL__`,t.model).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(t.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(t.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(t.evePackageVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,t.aiPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,t.zodPackageVersion).replaceAll(`__EVE_INIT_TSGO_VERSION__`,t.tsgoPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,t.typesNodePackageVersion)}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}const BASE_AGENT_TEMPLATE=`import { defineAgent } from "eve";
2
2
 
3
3
  export default defineAgent({
4
4
  model: "__EVE_INIT_MODEL__",
@@ -77,4 +77,4 @@ export default defineAgent({
77
77
  },
78
78
  },
79
79
  });
80
- `:BASE_AGENT_TEMPLATE,...SHARED_TEMPLATE_FILES,"package.json":packageJsonTemplate(t),...getPackageManagerStrategy(n).scaffoldFiles}}async function assertCanCreateInPlace(e,n){if(!await pathExists(e))return;let r=(await readdir(e)).filter(e=>!ALLOWED_CREATE_IN_PLACE_ENTRIES.has(e));if(r.length>0&&!n){let e=r.slice(0,5).join(`, `),t=r.length>5?`, and ${r.length-5} more`:``;throw Error(`Cannot create project in current directory because it is not empty. Found: ${e}${t}. Use an empty directory.`)}}async function scaffoldBaseProject(e){let i=resolve(e.targetDirectory??process.cwd(),e.projectName),a=e.projectName===`.`,s=e.overwriteExisting??!1,u=e.byokProvider??!1,d=e.packageManager??`pnpm`;if(a)await assertCanCreateInPlace(i,s);else if(await pathExists(i))throw Error(`Cannot create project because "${i}" already exists.`);let f=e.typesNodePackageVersion??`25.9.1`,p={appName:basename(i),model:e.model,evePackageVersion:resolveVersionToken(`evePackageVersion`,e.evePackageVersion??`0.6.0-beta.18`),aiPackageVersion:resolveVersionToken(`aiPackageVersion`,e.aiPackageVersion??`7.0.0-canary.171`),zodPackageVersion:resolveVersionToken(`zodPackageVersion`,e.zodPackageVersion??`4.4.3`),tsgoPackageVersion:resolveVersionToken(`tsgoPackageVersion`,e.tsgoPackageVersion??`7.0.0-dev.20260523.1`),typesNodePackageVersion:u?resolveVersionToken(`typesNodePackageVersion`,f):f};await mkdir(i,{recursive:!0});for(let[r,o]of Object.entries(templateFiles(u,d))){let c=`${i}/${r}`,l=await pathExists(c);await writeTextFile(c,renderTemplate(o,p),{force:a&&s}),l&&await e.onOverwriteFile?.(c)}return i}async function isEveProject(e){for(let t of SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS)try{return await stat(join(e,`agent`,`agent${t}`)),!0}catch{}return!1}export{CURRENT_DIRECTORY_PROJECT_NAME,DEFAULT_AI_PACKAGE_VERSION,DEFAULT_EVE_PACKAGE_VERSION,DEFAULT_ZOD_PACKAGE_VERSION,agentTemplateFiles,byokProviderEnvVar,formatEveDependencySpecifier,isEveProject,modelProviderSlug,scaffoldBaseProject};
80
+ `:BASE_AGENT_TEMPLATE,...SHARED_TEMPLATE_FILES,"package.json":packageJsonTemplate(t),...getPackageManagerStrategy(n).scaffoldFiles}}async function assertCanCreateInPlace(e,n){if(!await pathExists(e))return;let r=(await readdir(e)).filter(e=>!ALLOWED_CREATE_IN_PLACE_ENTRIES.has(e));if(r.length>0&&!n){let e=r.slice(0,5).join(`, `),t=r.length>5?`, and ${r.length-5} more`:``;throw Error(`Cannot create project in current directory because it is not empty. Found: ${e}${t}. Use an empty directory.`)}}async function scaffoldBaseProject(e){let i=resolve(e.targetDirectory??process.cwd(),e.projectName),a=e.projectName===`.`,s=e.overwriteExisting??!1,u=e.byokProvider??!1,d=e.packageManager??`pnpm`;if(a)await assertCanCreateInPlace(i,s);else if(await pathExists(i))throw Error(`Cannot create project because "${i}" already exists.`);let f=e.typesNodePackageVersion??`25.9.1`,p={appName:basename(i),model:e.model,evePackageVersion:resolveVersionToken(`evePackageVersion`,e.evePackageVersion??`0.6.0-beta.19`),aiPackageVersion:resolveVersionToken(`aiPackageVersion`,e.aiPackageVersion??`7.0.0-canary.171`),zodPackageVersion:resolveVersionToken(`zodPackageVersion`,e.zodPackageVersion??`4.4.3`),tsgoPackageVersion:resolveVersionToken(`tsgoPackageVersion`,e.tsgoPackageVersion??`7.0.0-dev.20260523.1`),typesNodePackageVersion:u?resolveVersionToken(`typesNodePackageVersion`,f):f};await mkdir(i,{recursive:!0});for(let[r,o]of Object.entries(templateFiles(u,d))){let c=`${i}/${r}`,l=await pathExists(c);await writeTextFile(c,renderTemplate(o,p),{force:a&&s}),l&&await e.onOverwriteFile?.(c)}return i}async function isEveProject(e){for(let t of SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS)try{return await stat(join(e,`agent`,`agent${t}`)),!0}catch{}return!1}export{CURRENT_DIRECTORY_PROJECT_NAME,DEFAULT_AI_PACKAGE_VERSION,DEFAULT_EVE_PACKAGE_VERSION,DEFAULT_ZOD_PACKAGE_VERSION,agentTemplateFiles,byokProviderEnvVar,formatEveDependencySpecifier,isEveProject,modelProviderSlug,scaffoldBaseProject};
@@ -1,4 +1,4 @@
1
- import{getPackageManagerStrategy}from"../../primitives/pm/index.js";import{pathExists,writeTextFile}from"../files.js";import{patchPackageJson}from"./package-json.js";import{resolveVersionToken}from"../version-tokens.js";import{getSupportedModuleBaseName,matchesSupportedModuleBaseName}from"./module-files.js";import{WEB_APP_TEMPLATE_FILES,WEB_APP_TEMPLATE_PACKAGE_JSON}from"../create/web-template.js";import"../create/project.js";import{basename,join,resolve}from"node:path";import{readFile,readdir,writeFile}from"node:fs/promises";const SLACK_CHANNEL_DEFAULT_ROUTE=`/eve/v1/slack`,DEFAULT_SLACK_CONNECTOR_SLUG=`my-agent`,PACKAGE_DEPENDENCY_FIELDS=[`dependencies`,`devDependencies`,`peerDependencies`,`optionalDependencies`],WEB_NEXT_CONFIG_PATH=`next.config.ts`,WEB_VERCEL_JSON_PATH=`vercel.json`,WEB_VERCEL_JSON_SCHEMA=`https://openapi.vercel.sh/vercel.json`,WEB_COMPETING_NEXT_CONFIG_PATHS=[`next.config.js`,`next.config.mjs`,WEB_NEXT_CONFIG_PATH,`next.config.mts`].filter(e=>e!==WEB_NEXT_CONFIG_PATH),WEB_DEFAULT_VERCEL_SERVICES={web:{entrypoint:`.`,framework:`nextjs`,routePrefix:`/`},eve:{buildCommand:`eve build`,entrypoint:`.`,framework:`eve`,routePrefix:`/_eve_internal/eve`}};function toSlackConnectorSlug(e){return e}function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function readDependencyVersion(e,t){let n=JSON.parse(await readFile(e,`utf8`));if(!isJsonObject(n)||!isJsonObject(n.dependencies))return;let r=n.dependencies[t];return typeof r==`string`?r:void 0}function packageJsonHasDependency(e,t){for(let n of PACKAGE_DEPENDENCY_FIELDS){let r=e[n];if(isJsonObject(r)&&typeof r[t]==`string`)return!0}return!1}async function hasPackageDependency(e,n){if(!await pathExists(e))return!1;let r=JSON.parse(await readFile(e,`utf8`));return isJsonObject(r)&&packageJsonHasDependency(r,n)}async function isNextJsProject(e){return hasPackageDependency(join(e,`package.json`),`next`)}async function ensurePackageDependency(e,n,i){return!await pathExists(e)||await readDependencyVersion(e,n)===i?[]:(await patchPackageJson(e,{dependencies:{[n]:i}}),[{path:e,dependencies:[n],devDependencies:[],scripts:[]}])}function resolveWebPackageVersions(e){return{evePackageVersion:e?.evePackageVersion??`0.6.0-beta.18`,aiPackageVersion:e?.aiPackageVersion??`7.0.0-canary.171`,nextPackageVersion:e?.nextPackageVersion??`16.2.6`,reactPackageVersion:e?.reactPackageVersion??`19.2.6`,reactDomPackageVersion:e?.reactDomPackageVersion??`19.2.6`,streamdownPackageVersion:e?.streamdownPackageVersion??`2.5.0`,zodPackageVersion:e?.zodPackageVersion??`4.4.3`,tsgoPackageVersion:e?.tsgoPackageVersion??`7.0.0-dev.20260523.1`,typesNodePackageVersion:e?.typesNodePackageVersion??`25.9.1`,typesReactPackageVersion:e?.typesReactPackageVersion??`19.2.15`,typesReactDomPackageVersion:e?.typesReactDomPackageVersion??`19.2.3`}}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}async function patchWebPackageJson(e,n){if(!await pathExists(e))return[];let a={...WEB_APP_TEMPLATE_PACKAGE_JSON.dependencies,ai:resolveVersionToken(`aiPackageVersion`,n.aiPackageVersion),eve:formatEveDependencySpecifier(resolveVersionToken(`evePackageVersion`,n.evePackageVersion)),next:resolveVersionToken(`nextPackageVersion`,n.nextPackageVersion),react:resolveVersionToken(`reactPackageVersion`,n.reactPackageVersion),"react-dom":resolveVersionToken(`reactDomPackageVersion`,n.reactDomPackageVersion),streamdown:resolveVersionToken(`streamdownPackageVersion`,n.streamdownPackageVersion),zod:resolveVersionToken(`zodPackageVersion`,n.zodPackageVersion)},o={...WEB_APP_TEMPLATE_PACKAGE_JSON.devDependencies,"@types/node":resolveVersionToken(`typesNodePackageVersion`,n.typesNodePackageVersion),"@types/react":resolveVersionToken(`typesReactPackageVersion`,n.typesReactPackageVersion),"@types/react-dom":resolveVersionToken(`typesReactDomPackageVersion`,n.typesReactDomPackageVersion),"@typescript/native-preview":resolveVersionToken(`tsgoPackageVersion`,n.tsgoPackageVersion)},s=WEB_APP_TEMPLATE_PACKAGE_JSON.scripts;return await patchPackageJson(e,{dependencies:a,devDependencies:o,scripts:s}),[{path:e,dependencies:Object.keys(a),devDependencies:Object.keys(o),scripts:Object.keys(s)}]}function normalizeSlackConnectorSlug(e){return toSlackConnectorSlug((e.trim().replace(/^@/,``).split(`/`).at(-1)??``).toLowerCase().replace(/[^a-z0-9_-]+/g,`-`).replace(/^[^a-z0-9]+/,``).replace(/[^a-z0-9]+$/,``).slice(0,100).replace(/[^a-z0-9]+$/,``)||`my-agent`)}async function deriveSlackConnectorSlug(e,t){if(t!==void 0&&t.length>0&&t!==`.`)return normalizeSlackConnectorSlug(t);try{let t=await readFile(join(e,`package.json`),`utf8`),n=JSON.parse(t);if(typeof n.name==`string`&&n.name.length>0)return normalizeSlackConnectorSlug(n.name)}catch{}return normalizeSlackConnectorSlug(basename(resolve(e))||`my-agent`)}function buildSlackTemplate(e){return`import { connectSlackCredentials } from "@vercel/connect/eve";
1
+ import{getPackageManagerStrategy}from"../../primitives/pm/index.js";import{pathExists,writeTextFile}from"../files.js";import{patchPackageJson}from"./package-json.js";import{resolveVersionToken}from"../version-tokens.js";import{getSupportedModuleBaseName,matchesSupportedModuleBaseName}from"./module-files.js";import{WEB_APP_TEMPLATE_FILES,WEB_APP_TEMPLATE_PACKAGE_JSON}from"../create/web-template.js";import"../create/project.js";import{basename,join,resolve}from"node:path";import{readFile,readdir,writeFile}from"node:fs/promises";const SLACK_CHANNEL_DEFAULT_ROUTE=`/eve/v1/slack`,DEFAULT_SLACK_CONNECTOR_SLUG=`my-agent`,PACKAGE_DEPENDENCY_FIELDS=[`dependencies`,`devDependencies`,`peerDependencies`,`optionalDependencies`],WEB_NEXT_CONFIG_PATH=`next.config.ts`,WEB_VERCEL_JSON_PATH=`vercel.json`,WEB_VERCEL_JSON_SCHEMA=`https://openapi.vercel.sh/vercel.json`,WEB_COMPETING_NEXT_CONFIG_PATHS=[`next.config.js`,`next.config.mjs`,WEB_NEXT_CONFIG_PATH,`next.config.mts`].filter(e=>e!==WEB_NEXT_CONFIG_PATH),WEB_DEFAULT_VERCEL_SERVICES={web:{entrypoint:`.`,framework:`nextjs`,routePrefix:`/`},eve:{buildCommand:`eve build`,entrypoint:`.`,framework:`eve`,routePrefix:`/_eve_internal/eve`}};function toSlackConnectorSlug(e){return e}function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function readDependencyVersion(e,t){let n=JSON.parse(await readFile(e,`utf8`));if(!isJsonObject(n)||!isJsonObject(n.dependencies))return;let r=n.dependencies[t];return typeof r==`string`?r:void 0}function packageJsonHasDependency(e,t){for(let n of PACKAGE_DEPENDENCY_FIELDS){let r=e[n];if(isJsonObject(r)&&typeof r[t]==`string`)return!0}return!1}async function hasPackageDependency(e,n){if(!await pathExists(e))return!1;let r=JSON.parse(await readFile(e,`utf8`));return isJsonObject(r)&&packageJsonHasDependency(r,n)}async function isNextJsProject(e){return hasPackageDependency(join(e,`package.json`),`next`)}async function ensurePackageDependency(e,n,i){return!await pathExists(e)||await readDependencyVersion(e,n)===i?[]:(await patchPackageJson(e,{dependencies:{[n]:i}}),[{path:e,dependencies:[n],devDependencies:[],scripts:[]}])}function resolveWebPackageVersions(e){return{evePackageVersion:e?.evePackageVersion??`0.6.0-beta.19`,aiPackageVersion:e?.aiPackageVersion??`7.0.0-canary.171`,nextPackageVersion:e?.nextPackageVersion??`16.2.6`,reactPackageVersion:e?.reactPackageVersion??`19.2.6`,reactDomPackageVersion:e?.reactDomPackageVersion??`19.2.6`,streamdownPackageVersion:e?.streamdownPackageVersion??`2.5.0`,zodPackageVersion:e?.zodPackageVersion??`4.4.3`,tsgoPackageVersion:e?.tsgoPackageVersion??`7.0.0-dev.20260523.1`,typesNodePackageVersion:e?.typesNodePackageVersion??`25.9.1`,typesReactPackageVersion:e?.typesReactPackageVersion??`19.2.15`,typesReactDomPackageVersion:e?.typesReactDomPackageVersion??`19.2.3`}}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}async function patchWebPackageJson(e,n){if(!await pathExists(e))return[];let a={...WEB_APP_TEMPLATE_PACKAGE_JSON.dependencies,ai:resolveVersionToken(`aiPackageVersion`,n.aiPackageVersion),eve:formatEveDependencySpecifier(resolveVersionToken(`evePackageVersion`,n.evePackageVersion)),next:resolveVersionToken(`nextPackageVersion`,n.nextPackageVersion),react:resolveVersionToken(`reactPackageVersion`,n.reactPackageVersion),"react-dom":resolveVersionToken(`reactDomPackageVersion`,n.reactDomPackageVersion),streamdown:resolveVersionToken(`streamdownPackageVersion`,n.streamdownPackageVersion),zod:resolveVersionToken(`zodPackageVersion`,n.zodPackageVersion)},o={...WEB_APP_TEMPLATE_PACKAGE_JSON.devDependencies,"@types/node":resolveVersionToken(`typesNodePackageVersion`,n.typesNodePackageVersion),"@types/react":resolveVersionToken(`typesReactPackageVersion`,n.typesReactPackageVersion),"@types/react-dom":resolveVersionToken(`typesReactDomPackageVersion`,n.typesReactDomPackageVersion),"@typescript/native-preview":resolveVersionToken(`tsgoPackageVersion`,n.tsgoPackageVersion)},s=WEB_APP_TEMPLATE_PACKAGE_JSON.scripts;return await patchPackageJson(e,{dependencies:a,devDependencies:o,scripts:s}),[{path:e,dependencies:Object.keys(a),devDependencies:Object.keys(o),scripts:Object.keys(s)}]}function normalizeSlackConnectorSlug(e){return toSlackConnectorSlug((e.trim().replace(/^@/,``).split(`/`).at(-1)??``).toLowerCase().replace(/[^a-z0-9_-]+/g,`-`).replace(/^[^a-z0-9]+/,``).replace(/[^a-z0-9]+$/,``).slice(0,100).replace(/[^a-z0-9]+$/,``)||`my-agent`)}async function deriveSlackConnectorSlug(e,t){if(t!==void 0&&t.length>0&&t!==`.`)return normalizeSlackConnectorSlug(t);try{let t=await readFile(join(e,`package.json`),`utf8`),n=JSON.parse(t);if(typeof n.name==`string`&&n.name.length>0)return normalizeSlackConnectorSlug(n.name)}catch{}return normalizeSlackConnectorSlug(basename(resolve(e))||`my-agent`)}function buildSlackTemplate(e){return`import { connectSlackCredentials } from "@vercel/connect/eve";
2
2
  import { slackChannel } from "eve/channels/slack";
3
3
 
4
4
  export default slackChannel({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eve",
3
- "version": "0.6.0-beta.18",
3
+ "version": "0.6.0-beta.19",
4
4
  "private": false,
5
5
  "description": "Filesystem-first framework for durable backend AI agents that run anywhere.",
6
6
  "keywords": [