eve 0.15.5 → 0.16.0
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.
- package/CHANGELOG.md +11 -0
- package/dist/src/cli/commands/init.js +1 -1
- package/dist/src/cli/dev/tui/agent-header.js +1 -1
- package/dist/src/cli/dev/tui/blocks.js +8 -8
- package/dist/src/cli/dev/tui/prompt-command-handler.js +1 -1
- package/dist/src/cli/dev/tui/prompt-commands.d.ts +1 -1
- package/dist/src/cli/dev/tui/prompt-commands.js +1 -1
- package/dist/src/cli/dev/tui/runner.d.ts +10 -3
- package/dist/src/cli/dev/tui/runner.js +1 -1
- package/dist/src/cli/dev/tui/setup-commands.d.ts +9 -1
- package/dist/src/cli/dev/tui/setup-commands.js +2 -2
- package/dist/src/cli/dev/tui/setup-flow.d.ts +8 -1
- package/dist/src/cli/dev/tui/setup-issues.d.ts +2 -14
- package/dist/src/cli/dev/tui/setup-issues.js +1 -1
- package/dist/src/cli/dev/tui/setup-panel.d.ts +14 -8
- package/dist/src/cli/dev/tui/setup-panel.js +3 -3
- package/dist/src/cli/dev/tui/terminal-renderer.js +6 -6
- package/dist/src/cli/dev/tui/tui-prompter.js +1 -1
- package/dist/src/cli/dev/tui/tui.d.ts +2 -3
- package/dist/src/cli/dev/tui/tui.js +1 -1
- package/dist/src/cli/dev/ui-options.d.ts +21 -0
- package/dist/src/cli/dev/ui-options.js +1 -0
- package/dist/src/cli/run.d.ts +6 -42
- package/dist/src/cli/run.js +2 -2
- package/dist/src/compiled/.vendor-stamp.json +1 -1
- package/dist/src/compiled/@ai-sdk/mcp/index.d.ts +71 -1
- package/dist/src/compiled/@ai-sdk/mcp/index.js +1 -1
- package/dist/src/harness/emission.d.ts +3 -3
- package/dist/src/harness/emission.js +1 -1
- package/dist/src/harness/stream-actions.d.ts +17 -0
- package/dist/src/harness/stream-actions.js +1 -0
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/nitro/host/configure-nitro-routes.js +2 -2
- package/dist/src/internal/nitro/host/dev-authored-source-watcher.d.ts +1 -0
- package/dist/src/internal/nitro/host/dev-authored-source-watcher.js +1 -1
- package/dist/src/internal/nitro/host/start-development-server.d.ts +8 -0
- package/dist/src/internal/nitro/host/start-development-server.js +2 -2
- package/dist/src/internal/nitro/host.d.ts +1 -1
- package/dist/src/internal/nitro/host.js +1 -1
- package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
- package/dist/src/internal/nitro/routes/dev-runtime-artifacts.d.ts +0 -3
- package/dist/src/internal/nitro/routes/dev-runtime-artifacts.js +1 -1
- package/dist/src/internal/nitro/routes/info.js +1 -1
- package/dist/src/internal/vercel/project-link.d.ts +10 -0
- package/dist/src/internal/vercel/project-link.js +1 -0
- package/dist/src/public/channels/auth.d.ts +26 -13
- package/dist/src/public/channels/auth.js +1 -1
- package/dist/src/runtime/agent/mock-model-adapter.d.ts +3 -2
- package/dist/src/runtime/agent/mock-model-adapter.js +1 -1
- package/dist/src/runtime/connections/principal.d.ts +2 -0
- package/dist/src/runtime/connections/principal.js +1 -1
- package/dist/src/runtime/connections/types.d.ts +4 -1
- package/dist/src/runtime/framework-channels/index.d.ts +1 -6
- package/dist/src/runtime/framework-channels/index.js +1 -1
- package/dist/src/runtime/governance/auth/oidc.js +1 -1
- package/dist/src/runtime/governance/auth/types.d.ts +14 -10
- package/dist/src/runtime/governance/auth/vercel-oidc-project.d.ts +12 -0
- package/dist/src/runtime/governance/auth/vercel-oidc-project.js +1 -0
- package/dist/src/services/dev-client/client-options.d.ts +5 -0
- package/dist/src/services/dev-client/client-options.js +1 -1
- package/dist/src/services/dev-client/request-headers.d.ts +8 -0
- package/dist/src/services/dev-client/request-headers.js +1 -1
- package/dist/src/services/dev-client/runtime-artifacts.d.ts +1 -0
- package/dist/src/services/dev-client/runtime-artifacts.js +1 -1
- package/dist/src/services/dev-client.d.ts +8 -0
- package/dist/src/services/dev-client.js +1 -1
- package/dist/src/setup/boxes/add-connections.d.ts +10 -8
- package/dist/src/setup/boxes/add-connections.js +1 -1
- package/dist/src/setup/boxes/resolve-provisioning.d.ts +1 -0
- package/dist/src/setup/boxes/resolve-provisioning.js +1 -1
- package/dist/src/setup/cli/channel-setup-prompter.d.ts +9 -2
- package/dist/src/setup/cli/channel-setup-prompter.js +1 -1
- package/dist/src/setup/cli/index.d.ts +1 -1
- package/dist/src/setup/cli/prompt-ui.d.ts +2 -0
- package/dist/src/setup/cli/select-state.js +1 -1
- package/dist/src/setup/connection-connector.d.ts +26 -52
- package/dist/src/setup/connection-connector.js +2 -1
- package/dist/src/setup/flows/channels.js +1 -1
- package/dist/src/setup/flows/connections.d.ts +36 -0
- package/dist/src/setup/flows/connections.js +3 -0
- package/dist/src/setup/flows/link.d.ts +1 -0
- package/dist/src/setup/flows/link.js +1 -1
- package/dist/src/setup/project-resolution.d.ts +2 -8
- package/dist/src/setup/project-resolution.js +1 -1
- package/dist/src/setup/prompter.d.ts +2 -0
- package/dist/src/setup/scaffold/connections/catalog.d.ts +10 -5
- package/dist/src/setup/scaffold/connections/catalog.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +11 -11
- package/dist/src/setup/scaffold/create/web-template.d.ts +1 -1
- package/dist/src/setup/scaffold/create/web-template.js +2 -2
- package/dist/src/setup/scaffold/index.d.ts +1 -1
- package/dist/src/setup/scaffold/index.js +1 -1
- package/dist/src/setup/scaffold/update/connections.d.ts +6 -0
- package/dist/src/setup/scaffold/update/connections.js +3 -3
- package/docs/channels/eve.mdx +3 -3
- package/docs/concepts/sessions-runs-and-streaming.md +1 -1
- package/docs/guides/auth-and-route-protection.md +5 -5
- package/docs/guides/dev-tui.md +11 -4
- package/docs/guides/frontend/nextjs.mdx +2 -2
- package/docs/guides/frontend/nuxt.mdx +2 -2
- package/docs/guides/frontend/sveltekit.mdx +2 -2
- package/docs/reference/cli.md +3 -1
- package/docs/tutorial/ship-it.mdx +1 -1
- package/docs/tutorial/team-playbooks.mdx +1 -1
- package/package.json +2 -2
- package/dist/src/internal/nitro/host/dev-rebuild-registry.d.ts +0 -5
- package/dist/src/internal/nitro/host/dev-rebuild-registry.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# eve
|
|
2
2
|
|
|
3
|
+
## 0.16.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 24faac0: Add a searchable `/connect` flow to the local dev TUI. It scaffolds an MCP connection, resolves its Vercel Connect connector, and reuses the model setup flow to create or link a Vercel project when needed. Local Vercel users now authorize Connect with their Vercel user ID instead of a reserved OIDC issuer.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- ddda14c: Fresh agents now start model setup from their prefilled `/model` prompt, installing the Vercel CLI and logging in when those prerequisites are missing. Other `eve dev` sessions leave missing model setup as an attention prompt.
|
|
12
|
+
- ca8512a: Generated projects now emit peer-resolution metadata only for their selected package manager. pnpm scaffolds no longer include npm or Yarn fields that can make frozen Vercel installs fail.
|
|
13
|
+
|
|
3
14
|
## 0.15.5
|
|
4
15
|
|
|
5
16
|
### Patch Changes
|
|
@@ -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{initAgentDevHandoff,initAgentInstructions,initAgentReplPrompt}from"./agent-instructions.js";import{tryInitializeGit}from"./init-git.js";import{selectInitHandoff,spawnCodingAgentRepl}from"./init-repl.js";import{createLogger,isLogLevelEnabled}from"#internal/logging.js";import{basename,join,resolve}from"node:path";import{ensureChannel,scaffoldBaseProject}from"#setup/scaffold/index.js";import{mkdtemp,readdir,rename,rm,stat}from"node:fs/promises";import{performance}from"node:perf_hooks";import{isCodingAgentLaunch}from"#cli/agent-detection.js";import{EVE_WORDMARK}from"#cli/banner.js";import{formatElapsed}from"#cli/format-elapsed.js";import{startCliLiveRow}from"#cli/ui/live-row.js";import{DEFAULT_AGENT_MODEL_ID}from"#shared/default-agent-model.js";import{formatNodeEngineOverrideWarning}from"#setup/node-engine.js";import{detectInvokingPackageManager,detectPackageManager}from"#setup/package-manager.js";import{pathExists}from"#setup/path-exists.js";import{parseProjectName}from"#setup/project-name.js";import{eveDevArguments,runPackageManagerInstall,spawnPackageManager}from"#setup/primitives/index.js";import{addAgentToProject}from"#setup/scaffold/create/add-to-project.js";import{WizardCancelledError}from"#setup/step.js";import{DEFAULT_EVE_PACKAGE_CONTRACT}from"#setup/scaffold/create/project.js";var import_picocolors=__toESM(require_picocolors(),1);const defaultDependencies={addAgentToProject,detectInvokingPackageManager,detectPackageManager,ensureChannel,isCodingAgentLaunch,now:()=>performance.now(),runPackageManagerInstall,scaffoldBaseProject,selectInitHandoff,spawnCodingAgentRepl,spawnPackageManager,tryInitializeGit},ALLOWED_CREATE_IN_PLACE_ENTRIES=new Set([`.DS_Store`,`.git`,`.gitkeep`,`.hg`]),EVE_INIT_PACKAGE_SPEC_ENV=`EVE_INIT_PACKAGE_SPEC`,initLog=createLogger(`init`);async function resolveTargetDirectory(e,t){let n=resolve(e,t);return(await stat(n).catch(()=>void 0))?.isDirectory()?n:void 0}function isCurrentDirectoryTarget(e){return/^\.(?:[/\\]+\.?)*$/u.test(e.trim())}async function assertCanScaffoldInPlace(e){let t=(await readdir(e)).filter(e=>!ALLOWED_CREATE_IN_PLACE_ENTRIES.has(e));if(t.length===0)return;let n=t.slice(0,5).join(`, `),r=t.length>5?`, and ${t.length-5} more`:``;throw Error(`Cannot create project in current directory because it is not empty. Found: ${n}${r}. Use an empty directory.`)}async function moveDirectoryContents(e,t){for(let n of await readdir(e))await rename(join(e,n),join(t,n))}function uniqueWorkspaceRootMutations(e){let t=new Map;for(let n of e){let e=`${n.kind}:${n.path}`,r=t.get(e);t.set(e,{...n,nodeEngineOverride:n.nodeEngineOverride??r?.nodeEngineOverride})}return[...t.values()]}function formatWorkspaceRootMutationWarning(e){let t=e.kind===`package-json`?`package.json`:`configuration`,n=e.nodeEngineOverride===void 0?``:` (${formatNodeEngineOverrideWarning(e.nodeEngineOverride)})`;return`Updated workspace root ${t} at ${e.path}${n}`}async function addToExistingProject(e,t,n,r){if(t.channelWebNextjs===!0)throw Error("`--channel-web-nextjs` is not supported when adding an agent to an existing project. Run `eve channels add web` from the project afterwards instead.");let i=await n.detectPackageManager(e),a=await n.addAgentToProject({projectRoot:e,model:DEFAULT_AGENT_MODEL_ID,packageManager:i.kind,evePackage:r});return{packageManager:i.kind,nodeEngineOverride:a.nodeEngineOverride}}async function resolveScaffoldPackageManager(e,t){let n=await t.detectPackageManager(e);return n.source==="default"?t.detectInvokingPackageManager()??`pnpm`:n.kind}async function scaffoldProject(e,t,n,r,i,a){let o=resolve(e),s=t===`.`,c=s?o:join(o,t);if(s)await assertCanScaffoldInPlace(c);else if(await pathExists(c))throw Error(`Cannot create project because "${c}" already exists.`);let l=await mkdtemp(join(o,`.eve-init-`)),p=[];try{let e={projectName:s?basename(c):t,model:DEFAULT_AGENT_MODEL_ID,evePackage:a,targetDirectory:l,workspaceProbeDirectory:c,packageManager:n,onWorkspaceRootMutation:e=>{p.push(e)}},o=await i.scaffoldBaseProject(e);return r.channelWebNextjs===!0&&await i.ensureChannel({projectRoot:o,kind:`web`,packageManager:n,workspaceProbeDirectory:c,configureVercelServices:!1,onWorkspaceRootMutation:e=>{p.push(e)}}),s?await moveDirectoryContents(o,c):await rename(o,c),{projectPath:c,workspaceRootMutations:uniqueWorkspaceRootMutations(p)}}finally{await rm(l,{recursive:!0,force:!0})}}function installProgressDetail(e,t){let n=t.text.trim();if(n===``||e!==`npm`)return n||void 0;let r=/^npm silly fetch manifest (.+)$/u.exec(n);if(r!==null)return`Resolving ${r[1]}`;let i=/^npm http fetch \S+ \S+ attempt (\d+) failed with (\S+)$/u.exec(n);if(i!==null)return`npm registry · attempt ${i[1]} failed: ${i[2]}`;if(t.stream===`stdout`||/^npm (?:error|warn)\b/u.test(n))return n}const NPM_NOISE_LINE=/^\s*npm (?:silly|verbose|http|timing)\b/u;async function runInitSteps(e){let{dependencies:t,logger:n,options:r,parentDirectory:i,target:a}=e,o=isLogLevelEnabled(`debug`),s=startCliLiveRow(n);s.update(`Preparing project`);try{let e=await t.isCodingAgentLaunch(),c=a??`.`,l=isCurrentDirectoryTarget(c),u=l?await pathExists(join(resolve(i),`package.json`))?resolve(i):void 0:await resolveTargetDirectory(i,c),p=resolveInitEvePackageOverride(),m=u===void 0?`creating agent`:`adding agent`;s.update(u===void 0?`Creating agent`:`Adding agent`),initLog.debug(m);let h=t.now(),g;if(u===void 0){let e=l?`.`:parseProjectName(c),n=resolve(i),a=await resolveScaffoldPackageManager(e===`.`?n:join(n,e),t),o=await scaffoldProject(i,e,a,r,t,p);g={kind:`created`,packageManager:a,projectPath:o.projectPath,workspaceRootMutations:o.workspaceRootMutations}}else{let e=await addToExistingProject(u,r,t,p);g=e.nodeEngineOverride===void 0?{kind:`added`,packageManager:e.packageManager,projectPath:u}:{kind:`added`,nodeEngineOverride:e.nodeEngineOverride,packageManager:e.packageManager,projectPath:u}}let _=t.now()-h;initLog.debug(`${m} done`,{ms:_}),s.update(`Installing dependencies`,`${g.packageManager} install`),initLog.debug(`installing dependencies with ${g.packageManager}`);let v=t.now(),y=[],b=[],x=await t.runPackageManagerInstall(g.packageManager,g.projectPath,{bypassMinimumReleaseAge:!0,progressDetails:process.stdout.isTTY===!0&&!o,onOutput:e=>{e.text.trim()!==``&&(b.push(e.text),b.length>20&&b.shift(),NPM_NOISE_LINE.test(e.text)||y.push(e.text)),o&&initLog.debug(e.text);let t=installProgressDetail(g.packageManager,e);t!==void 0&&s.update(`Installing dependencies`,t)}}),S=t.now()-v;if(!x){initLog.debug(`dependency installation failed`,{ms:S}),s.stop();let e=y.length>0?y:b;for(let t of e)n.error(t);throw Error(`Failed to install dependencies in "${g.projectPath}".`)}return initLog.debug(`dependencies installed`,{ms:S}),g.kind===`created`?(s.update(`Initializing Git repository`),initLog.debug(`initializing git repository`),{...g,agentElapsedMs:_,agentLaunched:e,gitResult:await t.tryInitializeGit(g.projectPath),installElapsedMs:S}):{...g,agentElapsedMs:_,agentLaunched:e,installElapsedMs:S}}finally{s.stop()}}async function runInitCommand(e,t,a,o,s=defaultDependencies){if(a===void 0&&await s.isCodingAgentLaunch()){e.log(initAgentInstructions());return}let c=await runInitSteps({dependencies:s,logger:e,options:o,parentDirectory:t,target:a});if(c.kind===`created`){e.log(`${import_picocolors.default.green(`✓`)} Created an ${EVE_WORDMARK} agent in ${import_picocolors.default.bold(c.projectPath)} ${import_picocolors.default.dim(`in ${formatElapsed(c.agentElapsedMs)}`)}`);for(let t of c.workspaceRootMutations)e.log(import_picocolors.default.yellow(`⚠ ${formatWorkspaceRootMutationWarning(t)}`))}else e.log(`${import_picocolors.default.green(`✓`)} Added an ${EVE_WORDMARK} agent to ${import_picocolors.default.bold(c.projectPath)} ${import_picocolors.default.dim(`in ${formatElapsed(c.agentElapsedMs)}`)}`),c.nodeEngineOverride!==void 0&&e.log(import_picocolors.default.yellow(`⚠ ${formatNodeEngineOverrideWarning(c.nodeEngineOverride)}`));e.log(`${import_picocolors.default.green(`✓`)} Installed dependencies ${import_picocolors.default.dim(`in ${formatElapsed(c.installElapsedMs)}`)}`),c.kind===`created`&&c.gitResult.kind===`failed`&&e.error(import_picocolors.default.yellow(`Git initialization failed: ${c.gitResult.reason}`));let l=[c.packageManager,...eveDevArguments(c.packageManager)].join(` `),d=initAgentDevHandoff({projectPath:c.projectPath,devCommand:l});if(c.agentLaunched){e.log(d);return}let f;try{f=await s.selectInitHandoff({agentName:basename(c.projectPath)})}catch(e){if(e instanceof WizardCancelledError)return;throw e}if(f!==`eve-dev`){if(e.log(import_picocolors.default.dim(`$ ${f}`)),!await s.spawnCodingAgentRepl({command:f,cwd:c.projectPath,prompt:initAgentReplPrompt({devCommand:l}),onPromptUnseeded:t=>{e.log(import_picocolors.default.yellow(`Could not seed ${f} automatically. Paste this prompt into it:`)),e.log(t)}}))throw Error(`Coding-agent REPL exited unsuccessfully in "${c.projectPath}".`);return}let p=eveDevArguments(c.packageManager);if(e.log(import_picocolors.default.dim(
|
|
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{initAgentDevHandoff,initAgentInstructions,initAgentReplPrompt}from"./agent-instructions.js";import{tryInitializeGit}from"./init-git.js";import{selectInitHandoff,spawnCodingAgentRepl}from"./init-repl.js";import{createLogger,isLogLevelEnabled}from"#internal/logging.js";import{basename,join,resolve}from"node:path";import{ensureChannel,scaffoldBaseProject}from"#setup/scaffold/index.js";import{mkdtemp,readdir,rename,rm,stat}from"node:fs/promises";import{performance}from"node:perf_hooks";import{isCodingAgentLaunch}from"#cli/agent-detection.js";import{EVE_WORDMARK}from"#cli/banner.js";import{formatElapsed}from"#cli/format-elapsed.js";import{startCliLiveRow}from"#cli/ui/live-row.js";import{DEFAULT_AGENT_MODEL_ID}from"#shared/default-agent-model.js";import{formatNodeEngineOverrideWarning}from"#setup/node-engine.js";import{detectInvokingPackageManager,detectPackageManager}from"#setup/package-manager.js";import{pathExists}from"#setup/path-exists.js";import{parseProjectName}from"#setup/project-name.js";import{eveDevArguments,runPackageManagerInstall,spawnPackageManager}from"#setup/primitives/index.js";import{addAgentToProject}from"#setup/scaffold/create/add-to-project.js";import{WizardCancelledError}from"#setup/step.js";import{DEFAULT_EVE_PACKAGE_CONTRACT}from"#setup/scaffold/create/project.js";var import_picocolors=__toESM(require_picocolors(),1);const defaultDependencies={addAgentToProject,detectInvokingPackageManager,detectPackageManager,ensureChannel,isCodingAgentLaunch,now:()=>performance.now(),runPackageManagerInstall,scaffoldBaseProject,selectInitHandoff,spawnCodingAgentRepl,spawnPackageManager,tryInitializeGit},ALLOWED_CREATE_IN_PLACE_ENTRIES=new Set([`.DS_Store`,`.git`,`.gitkeep`,`.hg`]),EVE_INIT_PACKAGE_SPEC_ENV=`EVE_INIT_PACKAGE_SPEC`,initLog=createLogger(`init`);async function resolveTargetDirectory(e,t){let n=resolve(e,t);return(await stat(n).catch(()=>void 0))?.isDirectory()?n:void 0}function isCurrentDirectoryTarget(e){return/^\.(?:[/\\]+\.?)*$/u.test(e.trim())}async function assertCanScaffoldInPlace(e){let t=(await readdir(e)).filter(e=>!ALLOWED_CREATE_IN_PLACE_ENTRIES.has(e));if(t.length===0)return;let n=t.slice(0,5).join(`, `),r=t.length>5?`, and ${t.length-5} more`:``;throw Error(`Cannot create project in current directory because it is not empty. Found: ${n}${r}. Use an empty directory.`)}async function moveDirectoryContents(e,t){for(let n of await readdir(e))await rename(join(e,n),join(t,n))}function uniqueWorkspaceRootMutations(e){let t=new Map;for(let n of e){let e=`${n.kind}:${n.path}`,r=t.get(e);t.set(e,{...n,nodeEngineOverride:n.nodeEngineOverride??r?.nodeEngineOverride})}return[...t.values()]}function formatWorkspaceRootMutationWarning(e){let t=e.kind===`package-json`?`package.json`:`configuration`,n=e.nodeEngineOverride===void 0?``:` (${formatNodeEngineOverrideWarning(e.nodeEngineOverride)})`;return`Updated workspace root ${t} at ${e.path}${n}`}async function addToExistingProject(e,t,n,r){if(t.channelWebNextjs===!0)throw Error("`--channel-web-nextjs` is not supported when adding an agent to an existing project. Run `eve channels add web` from the project afterwards instead.");let i=await n.detectPackageManager(e),a=await n.addAgentToProject({projectRoot:e,model:DEFAULT_AGENT_MODEL_ID,packageManager:i.kind,evePackage:r});return{packageManager:i.kind,nodeEngineOverride:a.nodeEngineOverride}}async function resolveScaffoldPackageManager(e,t){let n=await t.detectPackageManager(e);return n.source==="default"?t.detectInvokingPackageManager()??`pnpm`:n.kind}async function scaffoldProject(e,t,n,r,i,a){let o=resolve(e),s=t===`.`,c=s?o:join(o,t);if(s)await assertCanScaffoldInPlace(c);else if(await pathExists(c))throw Error(`Cannot create project because "${c}" already exists.`);let l=await mkdtemp(join(o,`.eve-init-`)),p=[];try{let e={projectName:s?basename(c):t,model:DEFAULT_AGENT_MODEL_ID,evePackage:a,targetDirectory:l,workspaceProbeDirectory:c,packageManager:n,onWorkspaceRootMutation:e=>{p.push(e)}},o=await i.scaffoldBaseProject(e);return r.channelWebNextjs===!0&&await i.ensureChannel({projectRoot:o,kind:`web`,packageManager:n,workspaceProbeDirectory:c,configureVercelServices:!1,onWorkspaceRootMutation:e=>{p.push(e)}}),s?await moveDirectoryContents(o,c):await rename(o,c),{projectPath:c,workspaceRootMutations:uniqueWorkspaceRootMutations(p)}}finally{await rm(l,{recursive:!0,force:!0})}}function installProgressDetail(e,t){let n=t.text.trim();if(n===``||e!==`npm`)return n||void 0;let r=/^npm silly fetch manifest (.+)$/u.exec(n);if(r!==null)return`Resolving ${r[1]}`;let i=/^npm http fetch \S+ \S+ attempt (\d+) failed with (\S+)$/u.exec(n);if(i!==null)return`npm registry · attempt ${i[1]} failed: ${i[2]}`;if(t.stream===`stdout`||/^npm (?:error|warn)\b/u.test(n))return n}const NPM_NOISE_LINE=/^\s*npm (?:silly|verbose|http|timing)\b/u;async function runInitSteps(e){let{dependencies:t,logger:n,options:r,parentDirectory:i,target:a}=e,o=isLogLevelEnabled(`debug`),s=startCliLiveRow(n);s.update(`Preparing project`);try{let e=await t.isCodingAgentLaunch(),c=a??`.`,l=isCurrentDirectoryTarget(c),u=l?await pathExists(join(resolve(i),`package.json`))?resolve(i):void 0:await resolveTargetDirectory(i,c),p=resolveInitEvePackageOverride(),m=u===void 0?`creating agent`:`adding agent`;s.update(u===void 0?`Creating agent`:`Adding agent`),initLog.debug(m);let h=t.now(),g;if(u===void 0){let e=l?`.`:parseProjectName(c),n=resolve(i),a=await resolveScaffoldPackageManager(e===`.`?n:join(n,e),t),o=await scaffoldProject(i,e,a,r,t,p);g={kind:`created`,packageManager:a,projectPath:o.projectPath,workspaceRootMutations:o.workspaceRootMutations}}else{let e=await addToExistingProject(u,r,t,p);g=e.nodeEngineOverride===void 0?{kind:`added`,packageManager:e.packageManager,projectPath:u}:{kind:`added`,nodeEngineOverride:e.nodeEngineOverride,packageManager:e.packageManager,projectPath:u}}let _=t.now()-h;initLog.debug(`${m} done`,{ms:_}),s.update(`Installing dependencies`,`${g.packageManager} install`),initLog.debug(`installing dependencies with ${g.packageManager}`);let v=t.now(),y=[],b=[],x=await t.runPackageManagerInstall(g.packageManager,g.projectPath,{bypassMinimumReleaseAge:!0,progressDetails:process.stdout.isTTY===!0&&!o,onOutput:e=>{e.text.trim()!==``&&(b.push(e.text),b.length>20&&b.shift(),NPM_NOISE_LINE.test(e.text)||y.push(e.text)),o&&initLog.debug(e.text);let t=installProgressDetail(g.packageManager,e);t!==void 0&&s.update(`Installing dependencies`,t)}}),S=t.now()-v;if(!x){initLog.debug(`dependency installation failed`,{ms:S}),s.stop();let e=y.length>0?y:b;for(let t of e)n.error(t);throw Error(`Failed to install dependencies in "${g.projectPath}".`)}return initLog.debug(`dependencies installed`,{ms:S}),g.kind===`created`?(s.update(`Initializing Git repository`),initLog.debug(`initializing git repository`),{...g,agentElapsedMs:_,agentLaunched:e,gitResult:await t.tryInitializeGit(g.projectPath),installElapsedMs:S}):{...g,agentElapsedMs:_,agentLaunched:e,installElapsedMs:S}}finally{s.stop()}}async function runInitCommand(e,t,a,o,s=defaultDependencies){if(a===void 0&&await s.isCodingAgentLaunch()){e.log(initAgentInstructions());return}let c=await runInitSteps({dependencies:s,logger:e,options:o,parentDirectory:t,target:a});if(c.kind===`created`){e.log(`${import_picocolors.default.green(`✓`)} Created an ${EVE_WORDMARK} agent in ${import_picocolors.default.bold(c.projectPath)} ${import_picocolors.default.dim(`in ${formatElapsed(c.agentElapsedMs)}`)}`);for(let t of c.workspaceRootMutations)e.log(import_picocolors.default.yellow(`⚠ ${formatWorkspaceRootMutationWarning(t)}`))}else e.log(`${import_picocolors.default.green(`✓`)} Added an ${EVE_WORDMARK} agent to ${import_picocolors.default.bold(c.projectPath)} ${import_picocolors.default.dim(`in ${formatElapsed(c.agentElapsedMs)}`)}`),c.nodeEngineOverride!==void 0&&e.log(import_picocolors.default.yellow(`⚠ ${formatNodeEngineOverrideWarning(c.nodeEngineOverride)}`));e.log(`${import_picocolors.default.green(`✓`)} Installed dependencies ${import_picocolors.default.dim(`in ${formatElapsed(c.installElapsedMs)}`)}`),c.kind===`created`&&c.gitResult.kind===`failed`&&e.error(import_picocolors.default.yellow(`Git initialization failed: ${c.gitResult.reason}`));let l=[c.packageManager,...eveDevArguments(c.packageManager)].join(` `),d=initAgentDevHandoff({projectPath:c.projectPath,devCommand:l});if(c.agentLaunched){e.log(d);return}let f;try{f=await s.selectInitHandoff({agentName:basename(c.projectPath)})}catch(e){if(e instanceof WizardCancelledError)return;throw e}if(f!==`eve-dev`){if(e.log(import_picocolors.default.dim(`$ ${f}`)),!await s.spawnCodingAgentRepl({command:f,cwd:c.projectPath,prompt:initAgentReplPrompt({devCommand:l}),onPromptUnseeded:t=>{e.log(import_picocolors.default.yellow(`Could not seed ${f} automatically. Paste this prompt into it:`)),e.log(t)}}))throw Error(`Coding-agent REPL exited unsuccessfully in "${c.projectPath}".`);return}let p=c.kind===`created`,m=p?[...eveDevArguments(c.packageManager),`--input`,`/model`]:eveDevArguments(c.packageManager);if(e.log(import_picocolors.default.dim(p?`$ eve dev --input /model`:`$ eve dev`)),!await s.spawnPackageManager(c.packageManager,c.projectPath,m))throw Error(`Development server exited unsuccessfully in "${c.projectPath}".`)}function resolveInitEvePackageOverride(){let e=process.env[EVE_INIT_PACKAGE_SPEC_ENV]?.trim();if(!(e===void 0||e.length===0))return{nodeEngine:DEFAULT_EVE_PACKAGE_CONTRACT.nodeEngine,version:e}}export{EVE_INIT_PACKAGE_SPEC_ENV,runInitCommand};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{truncate}from"./tool-format.js";const AGENT_HEADER_TIPS=[`Use /channels to add more ways to reach your agent.`,`Use /deploy to see your agent go live.`,`Type /help to see every command
|
|
1
|
+
import{isPromptControlCommand}from"./prompt-commands.js";import{truncate}from"./tool-format.js";const AGENT_HEADER_TIPS=[`Use /channels to add more ways to reach your agent.`,`Use /deploy to see your agent go live.`,`Type /help to see every command.`,`Tip: /connect to seamlessly add MCP Connections to your agent`];function pickAgentHeaderTip(e=Math.random){return AGENT_HEADER_TIPS[Math.min(AGENT_HEADER_TIPS.length-1,Math.floor(e()*AGENT_HEADER_TIPS.length))]}function buildAgentHeader(e){let{theme:n,info:r,name:i,width:a}=e,o=n.colors,s=[],c=o.bold(`eve`);if(s.push(` ${c} ${o.dim(truncate(i,Math.max(8,a-8)))}`),r&&(r.diagnostics.discoveryErrors>0||r.diagnostics.discoveryWarnings>0)){let e=[];r.diagnostics.discoveryErrors>0&&e.push(o.red(`${r.diagnostics.discoveryErrors} error${plural(r.diagnostics.discoveryErrors)}`)),r.diagnostics.discoveryWarnings>0&&e.push(o.yellow(`${r.diagnostics.discoveryWarnings} warning${plural(r.diagnostics.discoveryWarnings)}`)),s.push(` ${o.dim(n.glyph.warning)} ${e.join(o.dim(` · `))}`)}return e.tip!==void 0&&s.push(` ${renderTip(e.tip,Math.max(8,a-2),n)}`),s}function renderTip(n,r,i){return truncate(n,r).split(/(\/[a-z:-]+)/u).map(t=>isPromptControlCommand(t)?i.colors.blue(t):i.colors.dim(t)).join(``)}function plural(e){return e===1?``:`s`}export{AGENT_HEADER_TIPS,buildAgentHeader,pickAgentHeaderTip};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{sliceVisible,visibleLength,wrapVisibleLine}from"./terminal-text.js";import{formatValuePretty,truncate}from"./tool-format.js";import{renderMarkdown}from"./markdown.js";
|
|
2
|
-
`)}}function renderUser(e,t,n){let r=n.colors.cyan(n.glyph.user);return wrap(e.body??``,t-2).map(e=>`${r} ${e}`)}function renderProse(e,t,
|
|
3
|
-
`).flatMap(e=>wrapVisibleLine(e,t-c.length)).forEach((e,t)=>{t===0&&!
|
|
4
|
-
`),i=r.slice(0,12),a=i.map(e=>` ${n.colors.dim(truncatePlain(e,Math.max(1,t-2)))}`),o=r.length-i.length;return o>0&&a.push(` ${n.colors.dim(`${n.glyph.ellipsis} +${o} more line${o===1?``:`s`}`)}`),a}const URL_PATTERN=/(https?:\/\/\S+)/u;function colorizeError(e,t){return URL_PATTERN.test(e)?e.split(URL_PATTERN).map((e,n)=>n%2==1?t.colors.cyan(e):t.colors.red(e)).join(``):t.colors.red(e)}function renderNotice(e,t,n){let r=n.colors.dim(n.glyph.dot),i=wrap(e.body??``,t-2);return i.length===0?[r]:i.map(e=>`${r} ${n.colors.dim(e)}`)}function renderAttentionRows(e,t,n){let r=n.colors.yellow(n.glyph.warning);return wrap(e,t-2).map((e,t)=>`${t===0?r:` `} ${paintCommands(e,n)}`)}function renderWarning(e,t,n){return renderAttentionRows(e.body??``,t,n)}function paintCommands(
|
|
5
|
-
`))for(let e of wrapVisibleLine(
|
|
6
|
-
`),f=[];for(let e of d){let
|
|
7
|
-
`),h=[];for(let e of m){let
|
|
8
|
-
`).flatMap(e=>wrapVisibleLine(e,Math.max(1,t)))}function truncatePlain(
|
|
1
|
+
import{isPromptControlCommand}from"./prompt-commands.js";import{sliceVisible,visibleLength,wrapVisibleLine}from"./terminal-text.js";import{formatValuePretty,truncate}from"./tool-format.js";import{renderMarkdown}from"./markdown.js";function renderBlockLines(e,t,r,i){let a=nestingPrefix(e.depth??0,r);return renderBody(e,Math.max(8,t-visibleLength(a)),r,i).map(e=>`${a}${e}`)}function nestingPrefix(e,t){return e<=0?``:`${t.colors.orange(t.glyph.rule)} `.repeat(e)}function renderBody(e,t,n,r){switch(e.kind){case`user`:return renderUser(e,t,n);case`assistant`:case`subagent-step`:return renderProse(e,t,n);case`reasoning`:return renderReasoning(e,t,n);case`tool`:case`subagent-tool`:return renderTool(e,t,n,r);case`error`:return renderError(e,t,n);case`notice`:return renderNotice(e,t,n);case`warning`:return renderWarning(e,t,n);case`result`:return renderResult(e,t,n);case`flow`:return renderFlow(e,t,n);case`command`:return renderCommand(e,n);case`question`:case`connection-auth`:return renderPreformatted(e,t,n);case`sandbox`:return renderSandbox(e,t,n,r);case`log`:return renderLog(e,t,n,r);case`subagent`:return renderSubagentHeader(e,t,n);case`agent-header`:return(e.body??``).split(`
|
|
2
|
+
`)}}function renderUser(e,t,n){let r=n.colors.cyan(n.glyph.user);return wrap(e.body??``,t-2).map(e=>`${r} ${e}`)}function renderProse(e,t,n){let i=[],a=e.kind===`subagent-step`,s=a?``:`${n.colors.bold(n.colors.white(n.glyph.brand))} `,c=a?``:` `;e.reasoning&&e.reasoning.trim().length>0&&i.push(...renderReasoningLines(e.reasoning,t,n));let l=(e.body??``).trim();return l.length===0&&i.length===0?[`${s}${n.colors.dim(`thinking${n.glyph.ellipsis}`)}`]:(l.length>0&&renderMarkdown(l).split(`
|
|
3
|
+
`).flatMap(e=>wrapVisibleLine(e,t-c.length)).forEach((e,t)=>{t===0&&!a&&i.length===0?i.push(`${s}${e}`):i.push(`${c}${e}`)}),i.length>0?i:[`${s}`])}function renderReasoning(e,t,n){return e.collapsed?[`${n.colors.gray(n.glyph.reasoning)} ${n.colors.dim(`thinking`)}`]:renderReasoningLines(e.body??``,t,n,n.glyph.reasoning)}function renderReasoningLines(e,t,n,r){let i=r?2:0,a=wrap(e.trim(),t-i);return a.length===0?[]:a.map((e,t)=>`${r?t===0?`${n.colors.gray(r)} `:` `:``}${n.colors.dim(n.colors.italic(e))}`)}function renderTool(e,t,n,r){let{icon:i,accent:o}=toolGlyph(e.status??`running`,n,r),s=e.title??`tool`,c=t-2,l=truncatePlain(s,c),u=`${i} ${n.colors.bold(l)}`,d=c-l.length-2,f=e.subtitle??``;f.length>0&&d>=6&&(u+=` ${n.colors.gray(truncate(f,d))}`);let p=[u];return e.expanded?p.push(...renderToolExpanded(e,t,n)):e.status===`done`&&e.result&&e.result.length>0?p.push(resultLine(n.glyph.arrow,e.result,t,n,o)):e.status===`error`&&e.result?p.push(resultLine(n.glyph.arrow,e.result,t,n,n.colors.red)):e.status===`denied`&&p.push(resultLine(n.glyph.arrow,`denied`,t,n,n.colors.yellow)),p}function renderToolExpanded(e,t,n){let r=[],push=(e,a,o)=>{if(a!==void 0){r.push(` ${n.colors.dim(e)}`);for(let e of wrap(formatValuePretty(a),t-4))r.push(` ${o(e)}`)}};return push(`input`,e.toolInput,n.colors.gray),e.status===`error`&&e.result?push(`error`,e.result,n.colors.red):push(`output`,e.toolOutput,n.colors.gray),r}function resultLine(e,t,n,r,i){let o=n-4;return` ${r.colors.dim(e)} ${i(truncate(t,o))}`}function toolGlyph(e,t,n){switch(e){case`done`:return{icon:t.colors.green(t.glyph.success),accent:t.colors.gray};case`error`:return{icon:t.colors.red(t.glyph.error),accent:t.colors.red};case`denied`:return{icon:t.colors.yellow(t.glyph.warning),accent:t.colors.yellow};case`approval`:return{icon:t.colors.yellow(t.glyph.question),accent:t.colors.yellow};default:return{icon:t.colors.yellow(n.spinner),accent:t.colors.gray}}}function renderError(e,t,n){let r=n.colors.red(n.colors.bold(n.glyph.error)),i=e.title??`Error`,a=[`${r} ${n.colors.red(n.colors.bold(i))}`];for(let r of wrap(e.body??``,t-2))a.push(` ${colorizeError(r,n)}`);return a.push(...renderErrorDetail(e.detail,t,n)),a}function renderErrorDetail(e,t,n){if(e===void 0||e.trim().length===0)return[];let r=e.split(`
|
|
4
|
+
`),i=r.slice(0,12),a=i.map(e=>` ${n.colors.dim(truncatePlain(e,Math.max(1,t-2)))}`),o=r.length-i.length;return o>0&&a.push(` ${n.colors.dim(`${n.glyph.ellipsis} +${o} more line${o===1?``:`s`}`)}`),a}const URL_PATTERN=/(https?:\/\/\S+)/u;function colorizeError(e,t){return URL_PATTERN.test(e)?e.split(URL_PATTERN).map((e,n)=>n%2==1?t.colors.cyan(e):t.colors.red(e)).join(``):t.colors.red(e)}function renderNotice(e,t,n){let r=n.colors.dim(n.glyph.dot),i=wrap(e.body??``,t-2);return i.length===0?[r]:i.map(e=>`${r} ${n.colors.dim(e)}`)}function renderAttentionRows(e,t,n){let r=n.colors.yellow(n.glyph.warning);return wrap(e,t-2).map((e,t)=>`${t===0?r:` `} ${paintCommands(e,n)}`)}function renderWarning(e,t,n){return renderAttentionRows(e.body??``,t,n)}function paintCommands(t,n){return t.replace(/\/[a-z:-]+/g,t=>isPromptControlCommand(t)?n.colors.blue(t):t)}function renderCommand(e,t){let n=t.colors,r=e.status===`error`?`${n.red(t.glyph.error)} `:``;return[`${n.cyan(t.glyph.user)} ${r}${n.blue(e.body??``)}`]}function renderFlow(e,t,n){let r=n.colors,i=e.title??`info`,a=i===`success`?r.green(n.glyph.success):i===`warning`?r.yellow(n.glyph.warning):i===`error`?r.red(n.glyph.error):r.dim(n.glyph.dot),o=wrap(e.body??``,t-2),paint=e=>i===`info`?r.dim(e):e;return o.map((e,t)=>`${t===0?a:` `} ${paint(e)}`)}function renderResult(e,t,n){let r=n.colors.dim(n.glyph.elbow),i=wrap(e.body??``,t-7);if(i.length===0)return[` ${r}`];let dim=e=>n.colors.dim(e.replaceAll(`\x1B[22m`,`\x1B[22m\x1B[2m`));return i.map((e,t)=>t===0?` ${r} ${dim(e)}`:` ${dim(e)}`)}function renderPreformatted(e,t,n){let i=e.kind===`connection-auth`?n.colors.yellow(n.glyph.connection):n.colors.yellow(n.colors.bold(n.glyph.question)),a=wrap(e.title??``,t-2),o=a.length===0?[`${i} `]:a.map((e,t)=>t===0?`${i} ${n.colors.bold(e)}`:` ${n.colors.bold(e)}`);for(let n of(e.body??``).split(`
|
|
5
|
+
`))for(let e of wrapVisibleLine(n,t-2))o.push(` ${e}`);return o}function renderSandbox(e,t,i,a){let o=i.colors.cyan(i.glyph.rule),s=i.colors.dim(`sandbox ${i.glyph.dot} `),c=visibleLength(s),l=` `.repeat(c),u=a.previous?.kind===`sandbox`,d=(e.body??``).split(`
|
|
6
|
+
`),f=[];for(let e of d){let n=wrapVisibleLine(e,Math.max(1,t-2-c));for(let e of n){let t=f.length===0&&!u?s:l;f.push(`${o} ${t}${i.colors.gray(e)}`)}}return f.length>0?f:[`${o}`]}function renderLog(e,t,i,a){let o=e.title===`stderr`,s=o?i.colors.red:i.colors.gray,c=i.colors.dim(i.glyph.rule),l=o?`stderr`:`stdout`,u=i.colors.dim(`${l} ${i.glyph.dot} `),d=visibleLength(u),f=` `.repeat(d),p=a.previous?.kind===`log`&&a.previous.title===e.title,m=(e.body??``).split(`
|
|
7
|
+
`),h=[];for(let e of m){let n=wrapVisibleLine(e,Math.max(1,t-2-d));for(let e of n){let t=h.length===0&&!p?u:f;h.push(`${c} ${t}${i.colors.dim(s(e))}`)}}return h.length>0?h:[`${c}`]}function renderSubagentHeader(e,t,n){let r=truncatePlain(e.title??`subagent`,Math.max(8,t-14));return[`${n.colors.orange(n.glyph.subagent)} ${n.colors.bold(r)} ${n.colors.dim(`subagent`)}`]}function wrap(e,t){return e.trim().length===0?[]:e.split(`
|
|
8
|
+
`).flatMap(e=>wrapVisibleLine(e,Math.max(1,t)))}function truncatePlain(e,r){return visibleLength(e)<=r?e:sliceVisible(e,r)}export{renderAttentionRows,renderBlockLines};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isPromptCommandAvailableFor}from"./prompt-commands.js";import{toErrorMessage}from"#shared/errors.js";function createPromptCommandHandler(n){return{async handle(r,i){let{target:a}=n;if(a.kind===`remote`&&!isPromptCommandAvailableFor(r.name,`remote`))return{message:`/${r.name} needs eve dev running the local server (it is not available with --url).`};if(r.name===`model`&&r.argument.length>0){if(a.kind!==`local`)return{message:`/model needs eve dev running the local server (it is not available with --url).`};let e=a.workspaceRoot;try{let{changeAgentModel:t,formatApplyModelOutcome:i,modelChangeRefusalForUneditableModel:a}=await import(`#setup/flows/model.js`),o=await(n.modelChangeRefusal??a)(e);return o===null?{message:i(await(n.applyModel??t)({appRoot:e,slug:r.argument}))}:{message:o}}catch(e){return{message:`Couldn't change the model: ${toErrorMessage(e)}`}}}let o=i.renderer.setupFlow;if(o===void 0)return{message:`/${r.name} is not supported by this renderer.`};if(r.name===`vc:login`&&a.kind===`remote`){if(i.remoteConnection===void 0)return{message:`/vc:login is not available in this session.`};let e;try{({runRemoteAuthCommand:e}=await import(`./remote-auth-command.js`))}catch(e){return{message:`/vc:login failed: ${toErrorMessage(e)}`}}return{message:await e({connection:i.remoteConnection,flow:n.remoteAuthFlow,renderer:o})}}let s;try{s=await import(`./setup-commands.js`)}catch(e){return{message:`/${r.name} failed: ${toErrorMessage(e)}`}}let{runTuiSetupCommand:c,SETUP_FLOW_CONFIG:l}=s,u=l[r.name];o.begin(u.title,u.indicator);let d=!0;try{let e={command:r.name,appRoot:a.workspaceRoot,renderer:o};i.initialModelStep!==void 0&&(e.initialModelStep=i.initialModelStep),n.flows!==void 0&&(e.flows=n.flows);let t=await c(e);d=t.preserveFlowDiagnostics;let s={message:t.message};return t.effect!==void 0&&(s.effect=t.effect),s}finally{o.end({preserveDiagnostics:d})}}}}export{createPromptCommandHandler};
|
|
1
|
+
import{isPromptCommandAvailableFor}from"./prompt-commands.js";import{toErrorMessage}from"#shared/errors.js";function createPromptCommandHandler(n){return{async handle(r,i){let{target:a}=n;if(a.kind===`remote`&&!isPromptCommandAvailableFor(r.name,`remote`))return{message:`/${r.name} needs eve dev running the local server (it is not available with --url).`};if(r.name===`model`&&r.argument.length>0){if(a.kind!==`local`)return{message:`/model needs eve dev running the local server (it is not available with --url).`};let e=a.workspaceRoot;try{let{changeAgentModel:t,formatApplyModelOutcome:i,modelChangeRefusalForUneditableModel:a}=await import(`#setup/flows/model.js`),o=await(n.modelChangeRefusal??a)(e);return o===null?{message:i(await(n.applyModel??t)({appRoot:e,slug:r.argument}))}:{message:o}}catch(e){return{message:`Couldn't change the model: ${toErrorMessage(e)}`}}}let o=i.renderer.setupFlow;if(o===void 0)return{message:`/${r.name} is not supported by this renderer.`};if(r.name===`vc:login`&&a.kind===`remote`){if(i.remoteConnection===void 0)return{message:`/vc:login is not available in this session.`};let e;try{({runRemoteAuthCommand:e}=await import(`./remote-auth-command.js`))}catch(e){return{message:`/vc:login failed: ${toErrorMessage(e)}`}}return{message:await e({connection:i.remoteConnection,flow:n.remoteAuthFlow,renderer:o})}}let s;try{s=await import(`./setup-commands.js`)}catch(e){return{message:`/${r.name} failed: ${toErrorMessage(e)}`}}let{runTuiSetupCommand:c,SETUP_FLOW_CONFIG:l}=s,u=l[r.name];o.begin(u.title,u.indicator);let d=!0;try{let e={command:r.name,appRoot:a.workspaceRoot,renderer:o};i.initialModelStep!==void 0&&(e.initialModelStep=i.initialModelStep),n.flows!==void 0&&(e.flows=n.flows);let t=await c(e);d=t.preserveFlowDiagnostics;let s={message:t.message};return t.effect!==void 0&&(s.effect=t.effect),s}finally{i.keepSetupFlowOpen!==!0&&o.end({preserveDiagnostics:d})}}}}export{createPromptCommandHandler};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type PromptCommandExtensionName = "model" | "channels" | "deploy" | "vc:install" | "vc:login";
|
|
1
|
+
export type PromptCommandExtensionName = "model" | "channels" | "connect" | "deploy" | "vc:install" | "vc:login";
|
|
2
2
|
type PromptCommandTarget = "local" | "remote";
|
|
3
3
|
/** The slash commands the prompt accepts. */
|
|
4
4
|
export type PromptCommand = {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const PROMPT_COMMAND_DEFINITIONS=[{name:`help`,aliases:[],description:`Show available commands`,takesArgument:!1,build:()=>({type:`help`}),targets:[`local`,`remote`]},{name:`new`,aliases:[],description:`Start a fresh session`,takesArgument:!1,build:()=>({type:`new`}),targets:[`local`,`remote`]},{name:`vc:install`,aliases:[],description:`Install the Vercel CLI`,takesArgument:!1,build:()=>({type:`extension`,name:`vc:install`,argument:``}),targets:[`local`,`remote`]},{name:`vc:login`,aliases:[],description:`Authenticate with Vercel`,takesArgument:!1,build:()=>({type:`extension`,name:`vc:login`,argument:``}),targets:[`local`,`remote`]},{name:`model`,aliases:[],description:`Configure the agent's model and provider`,argumentHint:`[provider/model]`,takesArgument:!0,build:e=>({type:`extension`,name:`model`,argument:e}),targets:[`local`]},{name:`loglevel`,aliases:[],description:`Show or hide captured stdout/stderr/sandbox logs`,argumentHint:`[all|stderr|sandbox|none]`,takesArgument:!0,build:e=>({type:`loglevel`,argument:e}),targets:[`local`,`remote`]},{name:`channels`,aliases:[],description:`Add chat channels to the agent`,takesArgument:!1,build:()=>({type:`extension`,name:`channels`,argument:``}),targets:[`local`]},{name:`deploy`,aliases:[],description:`Deploy the agent to Vercel`,takesArgument:!1,build:()=>({type:`extension`,name:`deploy`,argument:``}),targets:[`local`]},{name:`exit`,aliases:[`quit`],description:`Quit the TUI`,takesArgument:!1,build:()=>({type:`exit`}),targets:[`local`,`remote`]}],PROMPT_COMMANDS=PROMPT_COMMAND_DEFINITIONS;function promptCommandsFor(t){return PROMPT_COMMAND_DEFINITIONS.filter(e=>e.targets.some(e=>e===t))}function isPromptCommandAvailableFor(t,n){return(PROMPT_COMMAND_DEFINITIONS.find(e=>e.name===t)?.targets)?.includes(n)??!1}function parsePromptCommand(e){let n=e.trim();if(!n.startsWith(`/`))return null;for(let e of PROMPT_COMMANDS)for(let t of[e.name,...e.aliases]){let r=`/${t}`;if(n===r)return e.build(``);if(e.takesArgument&&n.startsWith(`${r} `))return e.build(n.slice(r.length).trim())}return null}function isPromptControlCommand(e){return parsePromptCommand(e)!==null}function formatPromptCommandHelp(e=PROMPT_COMMANDS){let n=e.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}}),r=Math.max(...n.map(e=>e.invocation.length))+2;return n.map(e=>e.invocation.padEnd(r)+e.description).join(`
|
|
1
|
+
const PROMPT_COMMAND_DEFINITIONS=[{name:`help`,aliases:[],description:`Show available commands`,takesArgument:!1,build:()=>({type:`help`}),targets:[`local`,`remote`]},{name:`new`,aliases:[],description:`Start a fresh session`,takesArgument:!1,build:()=>({type:`new`}),targets:[`local`,`remote`]},{name:`vc:install`,aliases:[],description:`Install the Vercel CLI`,takesArgument:!1,build:()=>({type:`extension`,name:`vc:install`,argument:``}),targets:[`local`,`remote`]},{name:`vc:login`,aliases:[],description:`Authenticate with Vercel`,takesArgument:!1,build:()=>({type:`extension`,name:`vc:login`,argument:``}),targets:[`local`,`remote`]},{name:`model`,aliases:[],description:`Configure the agent's model and provider`,argumentHint:`[provider/model]`,takesArgument:!0,build:e=>({type:`extension`,name:`model`,argument:e}),targets:[`local`]},{name:`loglevel`,aliases:[],description:`Show or hide captured stdout/stderr/sandbox logs`,argumentHint:`[all|stderr|sandbox|none]`,takesArgument:!0,build:e=>({type:`loglevel`,argument:e}),targets:[`local`,`remote`]},{name:`channels`,aliases:[],description:`Add chat channels to the agent`,takesArgument:!1,build:()=>({type:`extension`,name:`channels`,argument:``}),targets:[`local`]},{name:`connect`,aliases:[],description:`Add an MCP server through Vercel Connect`,takesArgument:!1,build:()=>({type:`extension`,name:`connect`,argument:``}),targets:[`local`]},{name:`deploy`,aliases:[],description:`Deploy the agent to Vercel`,takesArgument:!1,build:()=>({type:`extension`,name:`deploy`,argument:``}),targets:[`local`]},{name:`exit`,aliases:[`quit`],description:`Quit the TUI`,takesArgument:!1,build:()=>({type:`exit`}),targets:[`local`,`remote`]}],PROMPT_COMMANDS=PROMPT_COMMAND_DEFINITIONS;function promptCommandsFor(t){return PROMPT_COMMAND_DEFINITIONS.filter(e=>e.targets.some(e=>e===t))}function isPromptCommandAvailableFor(t,n){return(PROMPT_COMMAND_DEFINITIONS.find(e=>e.name===t)?.targets)?.includes(n)??!1}function parsePromptCommand(e){let n=e.trim();if(!n.startsWith(`/`))return null;for(let e of PROMPT_COMMANDS)for(let t of[e.name,...e.aliases]){let r=`/${t}`;if(n===r)return e.build(``);if(e.takesArgument&&n.startsWith(`${r} `))return e.build(n.slice(r.length).trim())}return null}function isPromptControlCommand(e){return parsePromptCommand(e)!==null}function formatPromptCommandHelp(e=PROMPT_COMMANDS){let n=e.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}}),r=Math.max(...n.map(e=>e.invocation.length))+2;return n.map(e=>e.invocation.padEnd(r)+e.description).join(`
|
|
2
2
|
`)}export{PROMPT_COMMANDS,formatPromptCommandHelp,isPromptCommandAvailableFor,isPromptControlCommand,parsePromptCommand,promptCommandsFor};
|
|
@@ -230,14 +230,21 @@ export interface PromptCommandHandlerContext {
|
|
|
230
230
|
readonly title: string;
|
|
231
231
|
/** Provider entry authorized by confirmed boot-time model-access evidence. */
|
|
232
232
|
readonly initialModelStep?: "provider";
|
|
233
|
+
/**
|
|
234
|
+
* Leaves the current setup panel mounted for the next automatic onboarding
|
|
235
|
+
* command. The runner closes it if no next command can proceed.
|
|
236
|
+
*/
|
|
237
|
+
readonly keepSetupFlowOpen?: true;
|
|
233
238
|
readonly remoteConnection?: RemoteConnectionController;
|
|
234
239
|
}
|
|
235
240
|
/** What one handled slash command leaves behind for the runner to apply. */
|
|
236
241
|
export interface PromptCommandOutcome {
|
|
237
242
|
/** Outcome line rendered under the echoed command; absent renders nothing. */
|
|
238
243
|
message?: string;
|
|
239
|
-
/** Post-command work
|
|
244
|
+
/** Post-command work after setup settles. */
|
|
240
245
|
effect?: VercelStatusEffect | {
|
|
246
|
+
kind: "connection-added";
|
|
247
|
+
} | {
|
|
241
248
|
kind: "model-access-changed";
|
|
242
249
|
};
|
|
243
250
|
}
|
|
@@ -277,8 +284,8 @@ export type EveTUIRunnerOptions = TuiDisplayOptions & {
|
|
|
277
284
|
/** Absolute local application root; omitted for remote `--url` sessions. */
|
|
278
285
|
appRoot?: string;
|
|
279
286
|
/**
|
|
280
|
-
* Seeds the editable prompt buffer for the first prompt
|
|
281
|
-
*
|
|
287
|
+
* Seeds the editable prompt buffer for the first prompt. A bare local
|
|
288
|
+
* `/model` starts initial model onboarding.
|
|
282
289
|
*/
|
|
283
290
|
initialInput?: string;
|
|
284
291
|
/** Handles non-core slash commands without adding feature branches to the runner. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{pickAgentHeaderTip}from"./agent-header.js";import{PROMPT_COMMANDS,formatPromptCommandHelp,parsePromptCommand}from"./prompt-commands.js";import{failureKey,formatFailureDetail,formatFailureMessage,formatGatewayAuthFailureNotice,isAbortLikeError,isGatewayAuthFailure,isInterruptedError}from"./errors.js";import{parseLogDisplayMode}from"./log-display-mode.js";import{createRemoteConnectionController}from"./remote-connection.js";import{BOOT_DETECTIONS,CLI_MISSING_SETUP_ISSUE,LOGIN_SETUP_ISSUE,automaticSetupCommand,detectSetupIssues,formatSetupIssuesLine,orderedSetupIssues,resolveModelProviderState}from"./setup-issues.js";import{TerminalRenderer}from"./terminal-renderer.js";import{createVercelStatusTracker}from"./vercel-status.js";import{toErrorMessage}from"#shared/errors.js";import{getVercelAuthStatus}from"#setup/vercel-project.js";import{isCurrentTurnBoundaryEvent}from"#client/index.js";import{loadDevelopmentEnvironmentFiles}from"#cli/dev/environment.js";import{subscribeDevelopmentSandboxPrewarmLogs}from"#execution/sandbox/development-prewarm.js";import{createDevelopmentRuntimeArtifactSessionRefresher}from"#services/dev-client.js";import{devBootPhase}from"#internal/dev-boot-progress.js";function authIssueForStatus(e){if(e===`logged-out`)return LOGIN_SETUP_ISSUE;if(e===`cli-missing`)return CLI_MISSING_SETUP_ISSUE}var EveTUIRunner=class{#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;#u;#d;#f;#p;#m;#h;#g;#_;#v;#y;#b;#x=!1;#S=new AbortController;#C=!1;#w=[];#T;#E;#D=pickAgentHeaderTip();#O;#k=new Map;#A=new Map;#j=new Map;#M=new Map;#N=new Set;#P=!1;#F;constructor(e){if(this.#e=e.session,e.client!==void 0&&(this.#t=e.client),this.#n=createRenderer(e),this.#r=e.name??`eve`,this.#i=e.tools??`full`,this.#a=e.reasoning??`full`,this.#o=e.subagents??`full`,this.#s=e.connectionAuth??`full`,this.#c=e.assistantResponseStats??`tokensPerSecond`,this.#l=e.contextSize,this.#u=e.formatTransportError??toErrorMessage,e.initialInput!==void 0&&(this.#m=e.initialInput),e.appRoot!==void 0){this.#p=e.appRoot;let t={appRoot:e.appRoot,onChange:e=>this.#n.setVercelStatus?.(e)};e.detectProjectIdentity!==void 0&&(t.detectIdentity=e.detectProjectIdentity),this.#E=createVercelStatusTracker(t)}if(e.promptCommandHandler!==void 0&&(this.#h=e.promptCommandHandler),this.#g=e.availablePromptCommands??PROMPT_COMMANDS,e.remote!==void 0){if(this.#t===void 0)throw Error(`A remote TUI requires a configured development client.`);this.#_=createRemoteConnectionController({client:this.#t,credentials:e.remote.credentials,target:e.remote.target,onChange:e=>this.#n.setRemoteConnectionStatus?.(e),resolveOidcToken:e.remote.resolveOidcToken,resolveDeployment:e.remote.resolveDeployment})}this.#v=e.bootDetections??BOOT_DETECTIONS,this.#y=e.getVercelAuthStatus??getVercelAuthStatus,e.onBootProgress!==void 0&&(this.#b=e.onBootProgress),e.serverUrl!==void 0&&(this.#f=e.serverUrl),e.serverUrl!==void 0&&e.remote===void 0&&(this.#d=createDevelopmentRuntimeArtifactSessionRefresher({serverUrl:e.serverUrl}))}async#I(){if(this.#f===void 0){this.#R(),await this.#W(void 0);return}let e;if(this.#_!==void 0){let t=await this.#_.check();t.state===`ready`&&(e=t.info)}else try{e=await devBootPhase(`connecting to agent`,()=>this.#t?this.#t.info():Promise.resolve(void 0),this.#b)}catch{e=void 0}this.#R();let t=this.#L(e);await this.#W(t)}#L(e){let t=this.#p===void 0?e:resolveModelProviderState(e,process.env);this.#O=t;let n=this.#f;if(n===void 0)return t;let r={name:this.#r,serverUrl:n};return t!==void 0&&(r.info=t),this.#p!==void 0&&(r.tip=this.#D),this.#n.renderAgentHeader?.(r),t}#R(){let e=this.#b;this.#b=void 0,e?.({type:`before-first-paint`})}async run(){try{await this.#z()}finally{this.#x=!0,this.#S.abort(),this.#V(),this.#F?.(),this.#F=void 0,this.#n.shutdown?.(),this.#E?.dispose(),this.#_?.dispose()}}async#z(){let e=this.#r,t,i,a,o=!1,s=!1,c=this.#m;for(await this.#I(),this.#_?.current().connection.state===`auth-required`&&await this.#$({type:`extension`,name:`vc:login`,argument:``},e,`startup`),this.#J(),this.#E?.refreshIdentity(),this.#h!==void 0&&this.#n.setupFlow!==void 0&&(i=automaticSetupCommand(this.#w),t=i?.prompt);;){if(!s){if(t==null){if(!this.#n.readPrompt){if(o)return;throw Error(`No prompt was provided and the renderer does not support prompt input.`)}let n={title:e};c!==void 0&&(n.initialDraft=c,c=void 0);try{t=await this.#H(n)}catch(e){if(isInterruptedError(e))return;throw e}if(t==null)return}let l=parsePromptCommand(t);if(l?.type===`exit`)return;if(l?.type===`new`){this.#B(),a=void 0,s=!1,t=void 0,this.#n.reset?.();continue}if(l?.type===`help`){this.#Y(formatPromptCommandHelp(this.#g)),a=void 0,s=!1,t=void 0;continue}if(l?.type===`loglevel`){this.#Y(this.#te(l.argument)),a=void 0,s=!1,t=void 0;continue}if(l?.type===`extension`){try{let t=l.name===`model`?i?.initialModelStep:void 0;i=void 0,await this.#$(l,e,`command`,t)}catch(e){if(isInterruptedError(e))return;throw e}a=void 0,t=void 0,s=!1;continue}o=!0}let l=await this.#U({prompt:s?void 0:t,inputResponses:a});try{await this.#n.renderStream(l,{title:e,submittedPrompt:t,continueSession:!!this.#n.readPrompt,tools:this.#i,reasoning:this.#a,subagents:this.#o,connectionAuth:this.#s,assistantResponseStats:this.#c,contextSize:this.#l});let n=l.turnState?.pendingApprovals??[],r=l.turnState?.pendingQuestions??[];if(n.length>0||r.length>0){let i=[];if(n.length>0){if(!this.#n.readToolApproval)throw Error(`Tool approval was requested, but the renderer does not support tool approval input.`);for(let t of n){let n=await this.#n.readToolApproval(t,{title:e});i.push({requestId:t.approvalId,optionId:n.approved?`approve`:`deny`}),this.#k.delete(t.approvalId)}}if(r.length>0){if(!this.#n.readInputQuestion)throw Error(`An interactive question was requested, but the renderer does not support input questions.`);for(let t of r){let n=toAgentTUIInputQuestion(t),r=await this.#n.readInputQuestion(n,{title:e});if(r===void 0)continue;let a={requestId:t.requestId};r.optionId!==void 0&&(a.optionId=r.optionId),r.text!==void 0&&(a.text=r.text),i.push(a),this.#k.delete(t.requestId)}}s=!0,a=i,t=void 0;continue}l.turnState&&l.turnState.boundaryEvent===void 0&&(this.#P=!0)}catch(e){if(isInterruptedError(e))return;throw e}s=!1,a=void 0,t=void 0,this.#P&&(this.#P=!1,this.#B(),this.#n.renderNotice?.(`Session ended — started a new session. Earlier context was cleared.`))}}#B(){this.#V(),this.#A.clear(),this.#k.clear(),this.#M.clear(),this.#N.clear(),this.#t&&(this.#e=this.#t.session()),this.#d?.clear()}#V(){for(let e of this.#j.values())e.abort();this.#j.clear()}async#H(e){if(!this.#n.readPrompt)return;let t=this.#n.readPrompt(e),n=this.#t,r=this.#d;if(n===void 0||r===void 0)return await t;let i=!1,a=!1,o,refresh=async()=>{if(!(i||a)){a=!0;try{this.#e=await r.refreshIdle({createSession:()=>n.session(),onRuntimeArtifactsChanged:()=>this.#ie(),session:this.#e})}finally{a=!1}}},startRefresh=()=>{if(i||a)return;let e=refresh().finally(()=>{o===e&&(o=void 0)});o=e};startRefresh();let s=setInterval(()=>{startRefresh()},500);s.unref?.();try{return await t}finally{i=!0,clearInterval(s),await o}}async#U(e){let t=new AbortController,n={signal:t.signal};e.prompt!==void 0&&(n.message=e.prompt),e.inputResponses!==void 0&&e.inputResponses.length>0&&(n.inputResponses=e.inputResponses);let r;try{let e=this.#t;e!==void 0&&this.#d!==void 0&&(this.#e=await this.#d.refresh({createSession:()=>e.session(),inputResponses:n.inputResponses,message:n.message,onRuntimeArtifactsChanged:()=>this.#ie(),session:this.#e})),n.message!==void 0&&(n.inputResponses?.length??0)===0&&this.#n.flushDelayedDevBuildErrors?.(),r=await this.#e.send(n)}catch(e){if(isInterruptedError(e))throw e;return this.#_?.reportFailure(e),this.#P=!0,{events:errorOnlyTUIStream({errorText:this.#u(e)}),turnState:createTurnState()}}let i=createTurnState();return{abort:()=>t.abort(),events:eveEventsToTUIStream({events:r,pendingInputRequests:this.#k,subagentRuns:this.#A,turnState:i,onSubagentCalled:e=>this.#ce(e),onSubagentCompleted:e=>this.#ue(e),onConnectionAuthRequired:e=>this.#ae(e),onConnectionAuthCompleted:e=>this.#oe(e),onTerminalFailure:()=>{this.#P=!0},failureOverride:this.#p===void 0?void 0:e=>isGatewayAuthFailure(e)?formatGatewayAuthFailureNotice(e):void 0}),turnState:i}}async#W(e){if(this.#p===void 0)return;let t={appRoot:this.#p,env:process.env};e!==void 0&&(t.info=e),this.#w=await detectSetupIssues(t,this.#v),this.#n.renderSetupWarning!==void 0&&(this.#G(),this.#K())}#G(){let e=orderedSetupIssues(this.#w,this.#T);e.length>0?this.#n.renderSetupWarning?.(formatSetupIssuesLine(e)):this.#n.clearSetupWarning?.()}async#K(){let e=this.#p;if(e===void 0)return;let t;try{t=await this.#y(e,{signal:this.#S.signal})}catch{return}this.#x||this.#C||(this.#T=authIssueForStatus(t),this.#G())}async#q(e){let t=this.#p;if(t===void 0||this.#n.renderSetupWarning===void 0)return;let n={appRoot:t,env:process.env};e!==void 0&&(n.info=e);try{this.#w=await detectSetupIssues(n,this.#v);let e=await this.#y(t,{signal:this.#S.signal});this.#T=authIssueForStatus(e)}catch{return}this.#x||this.#G()}#J(){this.#p===void 0||this.#n.renderSandboxLog===void 0||this.#F===void 0&&(this.#F=subscribeDevelopmentSandboxPrewarmLogs({appRoot:this.#p,log:e=>this.#n.renderSandboxLog?.(e)}))}#Y(e){if(e!==void 0){if(this.#n.renderCommandResult!==void 0){this.#n.renderCommandResult(e);return}this.#n.renderNotice?.(e)}}async#X(e,t){let n=this.#h;return n===void 0?{message:`/${e.name} is not available in this session.`}:await n.handle(e,{renderer:this.#n,title:t.title,initialModelStep:t.initialModelStep,remoteConnection:this.#_})}#Z(e,t){if(t!==`startup`)return;let n=this.#_?.current().connection.state,r=n===`auth-failed`||n===`unavailable`?`failed`:void 0,i=e.argument.length===0?``:` ${e.argument}`;this.#n.renderCommandInvocation?.(`/${e.name}${i}`,r)}async#Q(e){if(e?.kind===`model-access-changed`){this.#E?.applyEffect({kind:`refresh-identity`}),this.#C=!0,await this.#ne();return}e!==void 0&&(this.#E?.applyEffect(e),this.#C=!0,this.#q(this.#O))}async#$(e,t,n,r){let i=await this.#X(e,{initialModelStep:r,title:t});this.#Z(e,n),this.#Y(i?.message),await this.#Q(i?.effect),this.#ee()}#ee(){let e=this.#_?.current().connection;e?.state!==`ready`||e.info===this.#O||(this.#O=e.info,this.#f!==void 0&&this.#n.renderAgentHeader?.({info:e.info,name:this.#r,serverUrl:this.#f}))}#te(e){let t=this.#n;if(t.logDisplayMode===void 0||t.setLogDisplayMode===void 0)return`/loglevel is not available in this session.`;if(e===``)return`Logs: ${t.logDisplayMode()}. Use /loglevel all|stderr|sandbox|none — logs stay buffered, so switching also hides or restores past lines.`;let n=parseLogDisplayMode(e);if(n===void 0)return`Unknown log level "${e}". Use all, stderr, sandbox, or none.`;if(n===t.logDisplayMode())return`Logs already set to ${n}.`;switch(t.setLogDisplayMode(n),n){case`none`:return`Logs hidden. Output stays buffered — /loglevel all restores it.`;case`stderr`:return`Showing stderr logs only.`;case`sandbox`:return`Showing sandbox logs only.`;case`all`:return`Showing all logs.`}}async#ne(){let e=this.#p;if(e===void 0)return;loadDevelopmentEnvironmentFiles(e);let t=this.#L(await this.#re());this.#q(t)}async#re(){try{return await this.#t?.info()}catch{return}}async#ie(){let e=this.#O,t=await this.#re();t!==void 0&&this.#L(t),(!this.#n.renderAgentHeader||t===void 0)&&this.#n.renderNotice?.(formatAgentUpdateNotice(e,t))}#ae(e){let t={name:e.data.name,description:e.data.description,state:`required`};e.data.authorization!==void 0&&(t.challenge=e.data.authorization),e.data.webhookUrl!==void 0&&(t.webhookUrl=e.data.webhookUrl),this.#M.set(e.data.name,t),this.#se(t)}#oe(e){let t=this.#M.get(e.data.name)??{name:e.data.name,description:``,state:e.data.outcome};t.state=e.data.outcome,e.data.reason!==void 0&&(t.reason=e.data.reason),this.#M.set(e.data.name,t),this.#N.delete(e.data.name),this.#se(t),this.#n.setConnectionAuthPendingCount?.(this.#N.size)}#se(e){let t={name:e.name,description:e.description,state:e.state};e.challenge!==void 0&&(t.challenge=e.challenge),e.reason!==void 0&&(t.reason=e.reason),this.#n.upsertConnectionAuth?.(t)}#ce(e){let t=e.data.callId;if(this.#j.has(t))return;let n=this.#t;if(!n)return;let r=new AbortController;this.#j.set(t,r),(async()=>{try{let i=n.session({sessionId:e.data.childSessionId,streamIndex:0}).stream({signal:r.signal});for await(let e of i)if(r.signal.aborted||(this.#de(t,e),isCurrentTurnBoundaryEvent(e)))break}catch(e){if(!isAbortLikeError(e)){let n=toErrorMessage(e),r=this.#A.get(t);if(r){let{key:e,step:i}=openCurrentSubagentSection(r);i.message=i.message?`${i.message}\n\nstream error: ${n}`:`stream error: ${n}`,i.finalized=!0,r.currentSectionKey=null,this.#n.upsertSubagentStep?.({callId:t,subagentName:r.name,sectionKey:e,reasoning:i.reasoning,message:i.message,finalized:!0})}}}finally{this.#j.delete(t)}})()}#le(e,t,n){let r=t.tools.get(n.childCallId),i=r??{toolName:n.toolName,input:n.input,status:n.status};if(r){let e={"approval-requested":0,executing:1,done:2,failed:2};e[n.status]>e[r.status]&&(r.status=n.status),r.input=n.input}else t.tools.set(n.childCallId,i);this.#n.markChildToolCallId?.(n.childCallId),this.#n.upsertSubagentTool?.({callId:e,subagentName:t.name,childCallId:n.childCallId,toolName:i.toolName,input:i.input,status:i.status})}#ue(e){let t=this.#A.get(e);if(t){for(let[n,r]of t.steps)r.finalized||(r.finalized=!0,this.#n.upsertSubagentStep?.({callId:e,subagentName:t.name,sectionKey:n,reasoning:r.reasoning,message:r.message,finalized:!0}));t.currentSectionKey=null}}#de(e,t){let n=this.#A.get(e);if(!n)return;let r=this.#n,emit=(t,i)=>{r.upsertSubagentStep?.({callId:e,subagentName:n.name,sectionKey:t,reasoning:i.reasoning,message:i.message,finalized:i.finalized})},finalizeCurrent=()=>{if(n.currentSectionKey===null)return;let e=n.steps.get(n.currentSectionKey);e&&(e.finalized=!0,emit(n.currentSectionKey,e)),n.currentSectionKey=null};switch(t.type){case`reasoning.appended`:{let{key:e,step:r}=openCurrentSubagentSection(n);r.reasoning+=t.data.reasoningDelta,emit(e,r);break}case`reasoning.completed`:break;case`message.appended`:{let{key:e,step:r}=openCurrentSubagentSection(n);r.message+=t.data.messageDelta,emit(e,r);break}case`message.completed`:{let{key:e,step:r}=openCurrentSubagentSection(n);t.data.message!==null&&r.message.length===0&&(r.message=t.data.message),r.finalized=!0,emit(e,r),n.currentSectionKey=null;break}case`step.completed`:finalizeCurrent();break;case`actions.requested`:finalizeCurrent();for(let r of t.data.actions)r.kind===`tool-call`&&this.#le(e,n,{childCallId:r.callId,toolName:r.toolName,input:r.input,status:`executing`});break;case`input.requested`:finalizeCurrent();for(let r of t.data.requests)r.action.kind===`tool-call`&&this.#le(e,n,{childCallId:r.action.callId,toolName:r.action.toolName,input:r.action.input,status:`approval-requested`});break;case`action.result`:{let i=t.data.result;if(i.kind!==`tool-result`)break;let a=n.tools.get(i.callId);if(!a)break;t.data.status===`failed`?(a.status=`failed`,a.errorText=formatActionResultError(t)):(a.status=`done`,a.output=i.output);let o={callId:e,subagentName:n.name,childCallId:i.callId,toolName:a.toolName,input:a.input,status:a.status};a.output!==void 0&&(o.output=a.output),a.errorText!==void 0&&(o.errorText=a.errorText),r.upsertSubagentTool?.(o);break}default:break}}};function createRenderer(e){return e.renderer?e.renderer:new TerminalRenderer({tools:e.tools,reasoning:e.reasoning,subagents:e.subagents,connectionAuth:e.connectionAuth,assistantResponseStats:e.assistantResponseStats,contextSize:e.contextSize,logs:e.logs,availablePromptCommands:e.availablePromptCommands,input:e.userInput,output:e.screen})}function formatAgentUpdateNotice(e,t){let n=e?.agent.model.id,r=t?.agent.model.id;return n!==void 0&&r!==void 0&&n!==r?`Agent updated: Model ${n} -> ${r}`:`Agent updated.`}async function*eveEventsToTUIStream(e){let{events:t,pendingInputRequests:n,subagentRuns:r,turnState:i,onSubagentCalled:a,onSubagentCompleted:o,onConnectionAuthRequired:s,onConnectionAuthCompleted:c,onTerminalFailure:l,failureOverride:u}=e,d=new Map,f=new Map,p=0,m=new Set,h=new Set,g=new Set,_=!1,v=!1,y;for await(let e of t)if(!(v&&isPostTurnVisibleEvent(e)))switch(e.type){case`session.started`:case`turn.started`:case`message.received`:break;case`step.started`:p+=1,yield{type:`step-start`};break;case`step.completed`:{let t=e;y=t.data.usage,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`step-finish`,usage:t.data.usage};break}case`message.appended`:{let t=e,n=textPartId(t.data.turnId,t.data.stepIndex),r=partStateFor(d,n),i=t.data.messageSoFar;if(r.completed){if(r.text.startsWith(i)||p<=r.completedEpoch)break;r.generation+=1,r.text=``,r.completed=!1}if(!i.startsWith(r.text)||i.length<=r.text.length)break;let a=i.slice(r.text.length);r.text=i,yield{type:`assistant-delta`,id:partGenerationId(n,r.generation),delta:a};break}case`message.completed`:{let t=textPartId(e.data.turnId,e.data.stepIndex),n=partStateFor(d,t),r=e.data.message;if(n.completed){if(r===null||r===n.text||p<=n.completedEpoch)break;n.generation+=1,n.text=r,n.completedEpoch=p,yield{type:`assistant-complete`,id:partGenerationId(t,n.generation),text:r};break}let i=partGenerationId(t,n.generation);if(r!==null){if(n.text.length===0)n.text=r,n.completed=!0,n.completedEpoch=p,yield{type:`assistant-complete`,id:i,text:r};else if(r.startsWith(n.text)){let e=r.slice(n.text.length);e.length>0&&(yield{type:`assistant-delta`,id:i,delta:e}),n.text=r,n.completed=!0,n.completedEpoch=p,yield{type:`assistant-complete`,id:i}}}else n.text.length>0&&(n.completed=!0,n.completedEpoch=p,yield{type:`assistant-complete`,id:i});break}case`reasoning.appended`:{let t=e,n=reasoningPartId(t.data.turnId,t.data.stepIndex),r=partStateFor(f,n),i=t.data.reasoningSoFar;if(r.completed){if(r.text.startsWith(i)||p<=r.completedEpoch)break;r.generation+=1,r.text=``,r.completed=!1}if(!i.startsWith(r.text)||i.length<=r.text.length)break;let a=i.slice(r.text.length);r.text=i,yield{type:`reasoning-delta`,id:partGenerationId(n,r.generation),delta:a};break}case`reasoning.completed`:{let t=reasoningPartId(e.data.turnId,e.data.stepIndex),n=partStateFor(f,t),r=e.data.reasoning;if(n.completed){if(r.length===0||r===n.text||n.text.startsWith(r)||p<=n.completedEpoch)break;n.generation+=1,n.text=r,n.completedEpoch=p;let e=partGenerationId(t,n.generation);yield{type:`reasoning-delta`,id:e,delta:r},yield{type:`reasoning-complete`,id:e};break}let i=partGenerationId(t,n.generation);if(n.text.length===0&&r.length>0)n.text=r,yield{type:`reasoning-delta`,id:i,delta:r};else if(r.length>0&&!r.startsWith(n.text))break;n.completed=!0,n.completedEpoch=p,yield{type:`reasoning-complete`,id:i};break}case`actions.requested`:{let t=e.data.actions.filter(e=>e.kind===`tool-call`);if(t.length===0)break;for(let e of t)m.has(e.callId)||(m.add(e.callId),yield{type:`tool-call`,toolCallId:e.callId,toolName:e.toolName,input:e.input});break}case`input.requested`:{let t=e.data.requests.filter(e=>e.action.kind===`tool-call`);if(t.length===0)break;for(let e of t){let t=e.action.callId;if(m.has(t)||(m.add(t),yield{type:`tool-call`,toolCallId:t,toolName:e.action.toolName,input:e.action.input}),!h.has(e.requestId)){if(h.add(e.requestId),n.set(e.requestId,e),isQuestionRequest(e)){upsertPendingQuestion(i,e);continue}upsertPendingApproval(i,e),yield{type:`tool-approval-request`,approvalId:e.requestId,toolCallId:t}}}break}case`action.result`:{let t=e;if(t.data.result.kind!==`tool-result`)break;let n=t.data.result.callId;if(!m.has(n))break;t.data.status===`failed`?yield{type:`tool-error`,toolCallId:n,errorText:formatActionResultError(t)}:yield{type:`tool-result`,toolCallId:n,output:t.data.result.output};break}case`step.failed`:case`turn.failed`:{let t=toFailureEvent(e,g,u);t&&(yield t);break}case`session.failed`:{i.sawSessionFailure=!0,l?.(e);let t=toFailureEvent(e,g,u);t&&(yield t),i.boundaryEvent=e.type,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`finish`,usage:y},_=!0;return}case`session.waiting`:case`session.completed`:i.boundaryEvent=e.type,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`finish`,usage:y},_=!0;return;case`turn.completed`:v=!0,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p);break;case`subagent.called`:{let t=e;if(!r.has(t.data.callId))r.set(t.data.callId,{name:t.data.name,steps:new Map,currentSectionKey:null,nextSectionKey:0,tools:new Map});else{let e=r.get(t.data.callId);e&&(e.name=t.data.name)}a?.(t);break}case`subagent.started`:case`subagent.event`:break;case`subagent.completed`:o?.(e.data.callId);break;case`authorization.required`:s?.(e);break;case`authorization.completed`:c?.(e);break;default:break}_||(yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`finish`,usage:y})}async function*errorOnlyTUIStream(e){yield{type:`error`,errorText:e.errorText},yield{type:`finish`}}function createTurnState(){return{pendingApprovals:[],pendingQuestions:[],sawSessionFailure:!1}}function upsertPendingApproval(e,t){let n=toAgentTUIToolApprovalRequest(t),r=e.pendingApprovals.findIndex(e=>e.approvalId===n.approvalId);r===-1?e.pendingApprovals.push(n):e.pendingApprovals[r]=n}function toAgentTUIToolApprovalRequest(e){return{approvalId:e.requestId,toolCallId:e.action.callId,toolName:e.action.toolName,input:e.action.input}}function upsertPendingQuestion(e,t){let n=e.pendingQuestions.findIndex(e=>e.requestId===t.requestId);n===-1?e.pendingQuestions.push(t):e.pendingQuestions[n]=t}function textPartId(e,t){return`text:${e}:${t}`}function reasoningPartId(e,t){return`reasoning:${e}:${t}`}function partStateFor(e,t){let n=e.get(t);return n===void 0&&(n={generation:0,text:``,completed:!1,completedEpoch:0},e.set(t,n)),n}function partGenerationId(e,t){return t===0?e:`${e}#${t}`}function*closeOpenParts(e,t,n){for(let[r,i]of e)i.completed||i.text.length===0||(i.completed=!0,i.completedEpoch=n,yield{type:t,id:partGenerationId(r,i.generation)})}function isPostTurnVisibleEvent(e){switch(e.type){case`actions.requested`:case`authorization.completed`:case`authorization.required`:case`input.requested`:case`message.appended`:case`message.completed`:case`reasoning.appended`:case`reasoning.completed`:case`result.completed`:case`step.completed`:case`step.failed`:case`step.started`:case`subagent.called`:case`subagent.completed`:case`subagent.event`:case`subagent.started`:case`turn.completed`:case`turn.failed`:return!0;default:return!1}}function formatActionResultError(e){if(e.data.error?.message)return e.data.error.message;let t=e.data.result.output;if(typeof t==`string`)return t;try{return JSON.stringify(t)}catch{return`Tool execution failed.`}}function toFailureEvent(e,t,n){let r=failureKey(e);if(t.has(r))return;t.add(r);let s=n?.(e),c={type:`error`,errorText:s??formatFailureMessage(e)};if(s!==void 0)return c;let l=formatFailureDetail(e);return l!==void 0&&(c.detail=l),c}function isQuestionRequest(e){return e.display===`select`||e.display===`text`?!0:e.display===`confirmation`?!1:e.options!==void 0&&e.options.length>0}function toAgentTUIInputQuestion(e){let t=e.display===`text`?`text`:e.display===`select`||e.options!==void 0&&e.options.length>0?`select`:`text`,n={requestId:e.requestId,prompt:e.prompt,display:t};return e.options!==void 0&&(n.options=e.options.map(e=>{let t={id:e.id,label:e.label};return e.description!==void 0&&(t.description=e.description),e.style!==void 0&&(t.style=e.style),t})),e.allowFreeform!==void 0&&(n.allowFreeform=e.allowFreeform),n}function openCurrentSubagentSection(e){e.currentSectionKey===null&&(e.currentSectionKey=e.nextSectionKey++,e.steps.set(e.currentSectionKey,{reasoning:``,message:``,finalized:!1}));let t=e.steps.get(e.currentSectionKey);if(!t)throw Error(`invariant: subagent section state missing for current key`);return{key:e.currentSectionKey,step:t}}export{EveTUIRunner,parsePromptCommand};
|
|
1
|
+
import{PROMPT_COMMANDS,formatPromptCommandHelp,parsePromptCommand}from"./prompt-commands.js";import{pickAgentHeaderTip}from"./agent-header.js";import{failureKey,formatFailureDetail,formatFailureMessage,formatGatewayAuthFailureNotice,isAbortLikeError,isGatewayAuthFailure,isInterruptedError}from"./errors.js";import{parseLogDisplayMode}from"./log-display-mode.js";import{createRemoteConnectionController}from"./remote-connection.js";import{BOOT_DETECTIONS,CLI_MISSING_SETUP_ISSUE,LOGIN_SETUP_ISSUE,detectSetupIssues,formatSetupIssuesLine,orderedSetupIssues,resolveModelProviderState}from"./setup-issues.js";import{TerminalRenderer}from"./terminal-renderer.js";import{createVercelStatusTracker}from"./vercel-status.js";import{toErrorMessage}from"#shared/errors.js";import{getVercelAuthStatus}from"#setup/vercel-project.js";import{isCurrentTurnBoundaryEvent}from"#client/index.js";import{loadDevelopmentEnvironmentFiles}from"#cli/dev/environment.js";import{subscribeDevelopmentSandboxPrewarmLogs}from"#execution/sandbox/development-prewarm.js";import{createDevelopmentRuntimeArtifactSessionRefresher}from"#services/dev-client.js";import{devBootPhase}from"#internal/dev-boot-progress.js";function authIssueForStatus(e){if(e===`logged-out`)return LOGIN_SETUP_ISSUE;if(e===`cli-missing`)return CLI_MISSING_SETUP_ISSUE}var EveTUIRunner=class{#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;#u;#d;#f;#p;#m;#h;#g;#_;#v;#y;#b;#x=!1;#S=new AbortController;#C=!1;#w=[];#T;#E;#D=pickAgentHeaderTip();#O;#k=new Map;#A=new Map;#j=new Map;#M=new Map;#N=new Set;#P=!1;#F;constructor(t){if(this.#e=t.session,t.client!==void 0&&(this.#t=t.client),this.#n=createRenderer(t),this.#r=t.name??`eve`,this.#i=t.tools??`full`,this.#a=t.reasoning??`full`,this.#o=t.subagents??`full`,this.#s=t.connectionAuth??`full`,this.#c=t.assistantResponseStats??`tokensPerSecond`,this.#l=t.contextSize,this.#u=t.formatTransportError??toErrorMessage,t.initialInput!==void 0&&(this.#m=t.initialInput),t.appRoot!==void 0){this.#p=t.appRoot;let e={appRoot:t.appRoot,onChange:e=>this.#n.setVercelStatus?.(e)};t.detectProjectIdentity!==void 0&&(e.detectIdentity=t.detectProjectIdentity),this.#E=createVercelStatusTracker(e)}if(t.promptCommandHandler!==void 0&&(this.#h=t.promptCommandHandler),this.#g=t.availablePromptCommands??PROMPT_COMMANDS,t.remote!==void 0){if(this.#t===void 0)throw Error(`A remote TUI requires a configured development client.`);this.#_=createRemoteConnectionController({client:this.#t,credentials:t.remote.credentials,target:t.remote.target,onChange:e=>this.#n.setRemoteConnectionStatus?.(e),resolveOidcToken:t.remote.resolveOidcToken,resolveDeployment:t.remote.resolveDeployment})}this.#v=t.bootDetections??BOOT_DETECTIONS,this.#y=t.getVercelAuthStatus??getVercelAuthStatus,t.onBootProgress!==void 0&&(this.#b=t.onBootProgress),t.serverUrl!==void 0&&(this.#f=t.serverUrl),t.serverUrl!==void 0&&t.remote===void 0&&(this.#d=createDevelopmentRuntimeArtifactSessionRefresher({serverUrl:t.serverUrl}))}async#I(){if(this.#f===void 0){this.#R(),await this.#K(void 0);return}let e;if(this.#_!==void 0){let t=await this.#_.check();t.state===`ready`&&(e=t.info)}else try{e=await devBootPhase(`connecting to agent`,()=>this.#t?this.#t.info():Promise.resolve(void 0),this.#b)}catch{e=void 0}this.#R();let t=this.#L(e);await this.#K(t)}#L(e){let t=this.#p===void 0?e:resolveModelProviderState(e,process.env);this.#O=t;let n=this.#f;if(n===void 0)return t;let r={name:this.#r,serverUrl:n};return t!==void 0&&(r.info=t),this.#p!==void 0&&(r.tip=this.#D),this.#n.renderAgentHeader?.(r),t}#R(){let e=this.#b;this.#b=void 0,e?.({type:`before-first-paint`})}async run(){try{await this.#z()}finally{this.#x=!0,this.#S.abort(),this.#V(),this.#F?.(),this.#F=void 0,this.#n.shutdown?.(),this.#E?.dispose(),this.#_?.dispose()}}async#z(){let e=this.#r,r,i,a=!1,o=!1,s=this.#m;await this.#I(),this.#_?.current().connection.state===`auth-required`&&await this.#ne({type:`extension`,name:`vc:login`,argument:``},e,{trigger:`startup`}),this.#X(),this.#E?.refreshIdentity();let c=this.#m===void 0?void 0:parsePromptCommand(this.#m);for(c?.type===`extension`&&c.name===`model`&&c.argument===``&&this.#p!==void 0&&this.#h!==void 0&&this.#n.setupFlow!==void 0&&(s=void 0,await this.#re(e));;){if(!o){if(r==null){if(!this.#n.readPrompt){if(a)return;throw Error(`No prompt was provided and the renderer does not support prompt input.`)}let t={title:e};s!==void 0&&(t.initialDraft=s,s=void 0);try{r=await this.#H(t)}catch(e){if(isInterruptedError(e))return;throw e}if(r==null)return}let c=parsePromptCommand(r);if(c?.type===`exit`)return;if(c?.type===`new`){this.#B(),i=void 0,o=!1,r=void 0,this.#n.reset?.();continue}if(c?.type===`help`){this.#Z(formatPromptCommandHelp(this.#g)),i=void 0,o=!1,r=void 0;continue}if(c?.type===`loglevel`){this.#Z(this.#ae(c.argument)),i=void 0,o=!1,r=void 0;continue}if(c?.type===`extension`){try{await this.#ne(c,e,{trigger:`command`})}catch(e){if(isInterruptedError(e))return;throw e}i=void 0,r=void 0,o=!1;continue}a=!0}let c=await this.#U({prompt:o?void 0:r,inputResponses:i}),l=r,d=!1;try{for(;;){await this.#n.renderStream(c,{title:e,submittedPrompt:l,continueSession:!!this.#n.readPrompt,tools:this.#i,reasoning:this.#a,subagents:this.#o,connectionAuth:this.#s,assistantResponseStats:this.#c,contextSize:this.#l});let t=c.turnState?.pendingApprovals??[],n=c.turnState?.pendingQuestions??[];if(t.length>0||n.length>0){let a=[];if(t.length>0){if(!this.#n.readToolApproval)throw Error(`Tool approval was requested, but the renderer does not support tool approval input.`);for(let n of t){let t=await this.#n.readToolApproval(n,{title:e});a.push({requestId:n.approvalId,optionId:t.approved?`approve`:`deny`}),this.#k.delete(n.approvalId)}}if(n.length>0){if(!this.#n.readInputQuestion)throw Error(`An interactive question was requested, but the renderer does not support input questions.`);for(let t of n){let n=toAgentTUIInputQuestion(t),r=await this.#n.readInputQuestion(n,{title:e});if(r===void 0)continue;let i={requestId:t.requestId};r.optionId!==void 0&&(i.optionId=r.optionId),r.text!==void 0&&(i.text=r.text),a.push(i),this.#k.delete(t.requestId)}}o=!0,i=a,r=void 0,d=!0;break}if(this.#ue(c)){c=this.#W(),l=void 0;continue}c.turnState&&c.turnState.boundaryEvent===void 0&&(this.#P=!0);break}}catch(e){if(isInterruptedError(e))return;throw e}d||(o=!1,i=void 0,r=void 0,this.#P&&(this.#P=!1,this.#B(),this.#n.renderNotice?.(`Session ended — started a new session. Earlier context was cleared.`)))}}#B(){this.#V(),this.#A.clear(),this.#k.clear(),this.#M.clear(),this.#N.clear(),this.#n.setConnectionAuthPendingCount?.(0),this.#t&&(this.#e=this.#t.session()),this.#d?.clear()}#V(){for(let e of this.#j.values())e.abort();this.#j.clear()}async#H(e){if(!this.#n.readPrompt)return;let t=this.#n.readPrompt(e),n=this.#t,r=this.#d;if(n===void 0||r===void 0)return await t;let i=!1,a=!1,o,refresh=async()=>{if(!(i||a)){a=!0;try{this.#e=await r.refreshIdle({createSession:()=>n.session(),onRuntimeArtifactsChanged:()=>this.#ce(),session:this.#e})}finally{a=!1}}},startRefresh=()=>{if(i||a)return;let e=refresh().finally(()=>{o===e&&(o=void 0)});o=e};startRefresh();let s=setInterval(()=>{startRefresh()},500);s.unref?.();try{return await t}finally{i=!0,clearInterval(s),await o}}async#U(e){let t=new AbortController,n={signal:t.signal};e.prompt!==void 0&&(n.message=e.prompt),e.inputResponses!==void 0&&e.inputResponses.length>0&&(n.inputResponses=e.inputResponses);let r;try{let e=this.#t;e!==void 0&&this.#d!==void 0&&(this.#e=await this.#d.refresh({createSession:()=>e.session(),inputResponses:n.inputResponses,message:n.message,onRuntimeArtifactsChanged:()=>this.#ce(),session:this.#e})),n.message!==void 0&&(n.inputResponses?.length??0)===0&&this.#n.flushDelayedDevBuildErrors?.(),r=await this.#e.send(n)}catch(e){if(isInterruptedError(e))throw e;return this.#_?.reportFailure(e),this.#P=!0,{events:errorOnlyTUIStream({errorText:this.#u(e)}),turnState:createTurnState()}}return this.#G(r,()=>t.abort())}#W(){let e=new AbortController;return this.#G(this.#e.stream({signal:e.signal}),()=>e.abort())}#G(e,t){let n=createTurnState();return{abort:t,events:eveEventsToTUIStream({events:e,pendingInputRequests:this.#k,subagentRuns:this.#A,turnState:n,onSubagentCalled:e=>this.#pe(e),onSubagentCompleted:e=>this.#he(e),onConnectionAuthRequired:e=>this.#le(e),onConnectionAuthCompleted:e=>this.#de(e),onTerminalFailure:()=>{this.#P=!0},failureOverride:this.#p===void 0?void 0:e=>isGatewayAuthFailure(e)?formatGatewayAuthFailureNotice(e):void 0}),turnState:n}}async#K(e){if(this.#p===void 0)return;let t={appRoot:this.#p,env:process.env};e!==void 0&&(t.info=e),this.#w=await detectSetupIssues(t,this.#v),this.#n.renderSetupWarning!==void 0&&(this.#q(),this.#J())}#q(){let e=orderedSetupIssues(this.#w,this.#T);e.length>0?this.#n.renderSetupWarning?.(formatSetupIssuesLine(e)):this.#n.clearSetupWarning?.()}async#J(){let e=this.#p;if(e===void 0)return;let t;try{t=await this.#y(e,{signal:this.#S.signal})}catch{return}this.#x||this.#C||(this.#T=authIssueForStatus(t),this.#q())}async#Y(e){let t=this.#p;if(t===void 0||this.#n.renderSetupWarning===void 0)return;let n={appRoot:t,env:process.env};e!==void 0&&(n.info=e);try{this.#w=await detectSetupIssues(n,this.#v);let e=await this.#y(t,{signal:this.#S.signal});this.#T=authIssueForStatus(e)}catch{return}this.#x||this.#q()}#X(){this.#p===void 0||this.#n.renderSandboxLog===void 0||this.#F===void 0&&(this.#F=subscribeDevelopmentSandboxPrewarmLogs({appRoot:this.#p,log:e=>this.#n.renderSandboxLog?.(e)}))}#Z(e){if(e!==void 0){if(this.#n.renderCommandResult!==void 0){this.#n.renderCommandResult(e);return}this.#n.renderNotice?.(e)}}async#Q(e,t){let n=this.#h;if(n===void 0)return{message:`/${e.name} is not available in this session.`};let r={renderer:this.#n,title:t.title,initialModelStep:t.initialModelStep,remoteConnection:this.#_};return t.keepSetupFlowOpen===!0?await n.handle(e,{...r,keepSetupFlowOpen:!0}):await n.handle(e,r)}#$(e,t){if(t!==`startup`)return;let n=this.#_?.current().connection.state,r=n===`auth-failed`||n===`unavailable`?`failed`:void 0,i=e.argument.length===0?``:` ${e.argument}`;this.#n.renderCommandInvocation?.(`/${e.name}${i}`,r)}async#ee(e){if(e?.kind===`connection-added`){this.#E?.applyEffect({kind:`refresh-identity`}),this.#C=!0,await this.#te(),await this.#oe();return}if(e?.kind===`model-access-changed`){this.#E?.applyEffect({kind:`refresh-identity`}),this.#C=!0,await this.#oe();return}e!==void 0&&(this.#E?.applyEffect(e),this.#C=!0,this.#Y(this.#O))}async#te(){let e=this.#t,t=this.#d;e===void 0||t===void 0||(this.#e=await t.refreshAfterSourceChange({createSession:()=>e.session(),onRuntimeArtifactsChanged:()=>this.#ce(),session:this.#e}))}async#ne(e,t,n){let r=await this.#Q(e,{initialModelStep:n.initialModelStep,keepSetupFlowOpen:n.keepSetupFlowOpen,title:t});this.#$(e,n.trigger),this.#Z(r?.message),await this.#ee(r?.effect),this.#ie()}async#re(e){let t=this.#p;if(t===void 0)return;let authStatus=async()=>{try{return await this.#y(t,{signal:this.#S.signal})}catch{return}},n=await authStatus();if(n===`cli-missing`&&(await this.#ne({type:`extension`,name:`vc:install`,argument:``},e,{trigger:`startup`,keepSetupFlowOpen:!0}),n=await authStatus(),n===`cli-missing`)){this.#n.setupFlow?.end();return}if(n===`logged-out`&&(await this.#ne({type:`extension`,name:`vc:login`,argument:``},e,{trigger:`startup`,keepSetupFlowOpen:!0}),n=await authStatus(),n===`cli-missing`||n===`logged-out`)){this.#n.setupFlow?.end();return}await this.#ne({type:`extension`,name:`model`,argument:``},e,{trigger:`startup`,initialModelStep:`provider`})}#ie(){let e=this.#_?.current().connection;e?.state!==`ready`||e.info===this.#O||(this.#O=e.info,this.#f!==void 0&&this.#n.renderAgentHeader?.({info:e.info,name:this.#r,serverUrl:this.#f}))}#ae(e){let t=this.#n;if(t.logDisplayMode===void 0||t.setLogDisplayMode===void 0)return`/loglevel is not available in this session.`;if(e===``)return`Logs: ${t.logDisplayMode()}. Use /loglevel all|stderr|sandbox|none — logs stay buffered, so switching also hides or restores past lines.`;let n=parseLogDisplayMode(e);if(n===void 0)return`Unknown log level "${e}". Use all, stderr, sandbox, or none.`;if(n===t.logDisplayMode())return`Logs already set to ${n}.`;switch(t.setLogDisplayMode(n),n){case`none`:return`Logs hidden. Output stays buffered — /loglevel all restores it.`;case`stderr`:return`Showing stderr logs only.`;case`sandbox`:return`Showing sandbox logs only.`;case`all`:return`Showing all logs.`}}async#oe(){let e=this.#p;if(e===void 0)return;loadDevelopmentEnvironmentFiles(e);let t=this.#L(await this.#se());this.#Y(t)}async#se(){try{return await this.#t?.info()}catch{return}}async#ce(){let e=this.#O,t=await this.#se();t!==void 0&&this.#L(t),(!this.#n.renderAgentHeader||t===void 0)&&this.#n.renderNotice?.(formatAgentUpdateNotice(e,t))}#le(e){let t={name:e.data.name,description:e.data.description,state:`required`};e.data.authorization!==void 0&&(t.challenge=e.data.authorization),e.data.webhookUrl!==void 0&&(t.webhookUrl=e.data.webhookUrl),this.#M.set(e.data.name,t),this.#fe(t)}#ue(e){if(e.turnState?.boundaryEvent!==`session.waiting`)return!1;let t=!1;for(let e of this.#M.values())e.state!==`required`||e.webhookUrl===void 0||(e.state=`pending`,this.#N.add(e.name),this.#fe(e),t=!0);return t&&this.#n.setConnectionAuthPendingCount?.(this.#N.size),this.#N.size>0}#de(e){let t=this.#M.get(e.data.name)??{name:e.data.name,description:``,state:e.data.outcome};t.state=e.data.outcome,e.data.reason!==void 0&&(t.reason=e.data.reason),this.#M.set(e.data.name,t),this.#N.delete(e.data.name),this.#fe(t),this.#n.setConnectionAuthPendingCount?.(this.#N.size)}#fe(e){let t={name:e.name,description:e.description,state:e.state};e.challenge!==void 0&&(t.challenge=e.challenge),e.reason!==void 0&&(t.reason=e.reason),this.#n.upsertConnectionAuth?.(t)}#pe(e){let t=e.data.callId;if(this.#j.has(t))return;let n=this.#t;if(!n)return;let r=new AbortController;this.#j.set(t,r),(async()=>{try{let i=n.session({sessionId:e.data.childSessionId,streamIndex:0}).stream({signal:r.signal});for await(let e of i)if(r.signal.aborted||(this.#ge(t,e),isCurrentTurnBoundaryEvent(e)))break}catch(e){if(!isAbortLikeError(e)){let n=toErrorMessage(e),r=this.#A.get(t);if(r){let{key:e,step:i}=openCurrentSubagentSection(r);i.message=i.message?`${i.message}\n\nstream error: ${n}`:`stream error: ${n}`,i.finalized=!0,r.currentSectionKey=null,this.#n.upsertSubagentStep?.({callId:t,subagentName:r.name,sectionKey:e,reasoning:i.reasoning,message:i.message,finalized:!0})}}}finally{this.#j.delete(t)}})()}#me(e,t,n){let r=t.tools.get(n.childCallId),i=r??{toolName:n.toolName,input:n.input,status:n.status};if(r){let e={"approval-requested":0,executing:1,done:2,failed:2};e[n.status]>e[r.status]&&(r.status=n.status),r.input=n.input}else t.tools.set(n.childCallId,i);this.#n.markChildToolCallId?.(n.childCallId),this.#n.upsertSubagentTool?.({callId:e,subagentName:t.name,childCallId:n.childCallId,toolName:i.toolName,input:i.input,status:i.status})}#he(e){let t=this.#A.get(e);if(t){for(let[n,r]of t.steps)r.finalized||(r.finalized=!0,this.#n.upsertSubagentStep?.({callId:e,subagentName:t.name,sectionKey:n,reasoning:r.reasoning,message:r.message,finalized:!0}));t.currentSectionKey=null}}#ge(e,t){let n=this.#A.get(e);if(!n)return;let r=this.#n,emit=(t,i)=>{r.upsertSubagentStep?.({callId:e,subagentName:n.name,sectionKey:t,reasoning:i.reasoning,message:i.message,finalized:i.finalized})},finalizeCurrent=()=>{if(n.currentSectionKey===null)return;let e=n.steps.get(n.currentSectionKey);e&&(e.finalized=!0,emit(n.currentSectionKey,e)),n.currentSectionKey=null};switch(t.type){case`reasoning.appended`:{let{key:e,step:r}=openCurrentSubagentSection(n);r.reasoning+=t.data.reasoningDelta,emit(e,r);break}case`reasoning.completed`:break;case`message.appended`:{let{key:e,step:r}=openCurrentSubagentSection(n);r.message+=t.data.messageDelta,emit(e,r);break}case`message.completed`:{let{key:e,step:r}=openCurrentSubagentSection(n);t.data.message!==null&&r.message.length===0&&(r.message=t.data.message),r.finalized=!0,emit(e,r),n.currentSectionKey=null;break}case`step.completed`:finalizeCurrent();break;case`actions.requested`:finalizeCurrent();for(let r of t.data.actions)r.kind===`tool-call`&&this.#me(e,n,{childCallId:r.callId,toolName:r.toolName,input:r.input,status:`executing`});break;case`input.requested`:finalizeCurrent();for(let r of t.data.requests)r.action.kind===`tool-call`&&this.#me(e,n,{childCallId:r.action.callId,toolName:r.action.toolName,input:r.action.input,status:`approval-requested`});break;case`action.result`:{let i=t.data.result;if(i.kind!==`tool-result`)break;let a=n.tools.get(i.callId);if(!a)break;t.data.status===`failed`?(a.status=`failed`,a.errorText=formatActionResultError(t)):(a.status=`done`,a.output=i.output);let o={callId:e,subagentName:n.name,childCallId:i.callId,toolName:a.toolName,input:a.input,status:a.status};a.output!==void 0&&(o.output=a.output),a.errorText!==void 0&&(o.errorText=a.errorText),r.upsertSubagentTool?.(o);break}default:break}}};function createRenderer(e){return e.renderer?e.renderer:new TerminalRenderer({tools:e.tools,reasoning:e.reasoning,subagents:e.subagents,connectionAuth:e.connectionAuth,assistantResponseStats:e.assistantResponseStats,contextSize:e.contextSize,logs:e.logs,availablePromptCommands:e.availablePromptCommands,input:e.userInput,output:e.screen})}function formatAgentUpdateNotice(e,t){let n=e?.agent.model.id,r=t?.agent.model.id;return n!==void 0&&r!==void 0&&n!==r?`Agent updated: Model ${n} -> ${r}`:`Agent updated.`}async function*eveEventsToTUIStream(e){let{events:t,pendingInputRequests:n,subagentRuns:r,turnState:i,onSubagentCalled:a,onSubagentCompleted:o,onConnectionAuthRequired:s,onConnectionAuthCompleted:c,onTerminalFailure:l,failureOverride:u}=e,d=new Map,f=new Map,p=0,m=new Set,h=new Set,g=new Set,_=!1,v=!1,y;for await(let e of t)if(!(v&&isPostTurnVisibleEvent(e)))switch(e.type){case`session.started`:case`turn.started`:case`message.received`:break;case`step.started`:p+=1,yield{type:`step-start`};break;case`step.completed`:{let t=e;y=t.data.usage,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`step-finish`,usage:t.data.usage};break}case`message.appended`:{let t=e,n=textPartId(t.data.turnId,t.data.stepIndex),r=partStateFor(d,n),i=t.data.messageSoFar;if(r.completed){if(r.text.startsWith(i)||p<=r.completedEpoch)break;r.generation+=1,r.text=``,r.completed=!1}if(!i.startsWith(r.text)||i.length<=r.text.length)break;let a=i.slice(r.text.length);r.text=i,yield{type:`assistant-delta`,id:partGenerationId(n,r.generation),delta:a};break}case`message.completed`:{let t=textPartId(e.data.turnId,e.data.stepIndex),n=partStateFor(d,t),r=e.data.message;if(n.completed){if(r===null||r===n.text||p<=n.completedEpoch)break;n.generation+=1,n.text=r,n.completedEpoch=p,yield{type:`assistant-complete`,id:partGenerationId(t,n.generation),text:r};break}let i=partGenerationId(t,n.generation);if(r!==null){if(n.text.length===0)n.text=r,n.completed=!0,n.completedEpoch=p,yield{type:`assistant-complete`,id:i,text:r};else if(r.startsWith(n.text)){let e=r.slice(n.text.length);e.length>0&&(yield{type:`assistant-delta`,id:i,delta:e}),n.text=r,n.completed=!0,n.completedEpoch=p,yield{type:`assistant-complete`,id:i}}}else n.text.length>0&&(n.completed=!0,n.completedEpoch=p,yield{type:`assistant-complete`,id:i});break}case`reasoning.appended`:{let t=e,n=reasoningPartId(t.data.turnId,t.data.stepIndex),r=partStateFor(f,n),i=t.data.reasoningSoFar;if(r.completed){if(r.text.startsWith(i)||p<=r.completedEpoch)break;r.generation+=1,r.text=``,r.completed=!1}if(!i.startsWith(r.text)||i.length<=r.text.length)break;let a=i.slice(r.text.length);r.text=i,yield{type:`reasoning-delta`,id:partGenerationId(n,r.generation),delta:a};break}case`reasoning.completed`:{let t=reasoningPartId(e.data.turnId,e.data.stepIndex),n=partStateFor(f,t),r=e.data.reasoning;if(n.completed){if(r.length===0||r===n.text||n.text.startsWith(r)||p<=n.completedEpoch)break;n.generation+=1,n.text=r,n.completedEpoch=p;let e=partGenerationId(t,n.generation);yield{type:`reasoning-delta`,id:e,delta:r},yield{type:`reasoning-complete`,id:e};break}let i=partGenerationId(t,n.generation);if(n.text.length===0&&r.length>0)n.text=r,yield{type:`reasoning-delta`,id:i,delta:r};else if(r.length>0&&!r.startsWith(n.text))break;n.completed=!0,n.completedEpoch=p,yield{type:`reasoning-complete`,id:i};break}case`actions.requested`:{let t=e.data.actions.filter(e=>e.kind===`tool-call`);if(t.length===0)break;for(let e of t)m.has(e.callId)||(m.add(e.callId),yield{type:`tool-call`,toolCallId:e.callId,toolName:e.toolName,input:e.input});break}case`input.requested`:{let t=e.data.requests.filter(e=>e.action.kind===`tool-call`);if(t.length===0)break;for(let e of t){let t=e.action.callId;if(m.has(t)||(m.add(t),yield{type:`tool-call`,toolCallId:t,toolName:e.action.toolName,input:e.action.input}),!h.has(e.requestId)){if(h.add(e.requestId),n.set(e.requestId,e),isQuestionRequest(e)){upsertPendingQuestion(i,e);continue}upsertPendingApproval(i,e),yield{type:`tool-approval-request`,approvalId:e.requestId,toolCallId:t}}}break}case`action.result`:{let t=e;if(t.data.result.kind!==`tool-result`)break;let n=t.data.result.callId;if(!m.has(n))break;t.data.status===`failed`?yield{type:`tool-error`,toolCallId:n,errorText:formatActionResultError(t)}:yield{type:`tool-result`,toolCallId:n,output:t.data.result.output};break}case`step.failed`:case`turn.failed`:{let t=toFailureEvent(e,g,u);t&&(yield t);break}case`session.failed`:{i.sawSessionFailure=!0,l?.(e);let t=toFailureEvent(e,g,u);t&&(yield t),i.boundaryEvent=e.type,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`finish`,usage:y},_=!0;return}case`session.waiting`:case`session.completed`:i.boundaryEvent=e.type,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`finish`,usage:y},_=!0;return;case`turn.completed`:v=!0,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p);break;case`subagent.called`:{let t=e;if(!r.has(t.data.callId))r.set(t.data.callId,{name:t.data.name,steps:new Map,currentSectionKey:null,nextSectionKey:0,tools:new Map});else{let e=r.get(t.data.callId);e&&(e.name=t.data.name)}a?.(t);break}case`subagent.started`:case`subagent.event`:break;case`subagent.completed`:o?.(e.data.callId);break;case`authorization.required`:s?.(e);break;case`authorization.completed`:c?.(e);break;default:break}_||(yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`finish`,usage:y})}async function*errorOnlyTUIStream(e){yield{type:`error`,errorText:e.errorText},yield{type:`finish`}}function createTurnState(){return{pendingApprovals:[],pendingQuestions:[],sawSessionFailure:!1}}function upsertPendingApproval(e,t){let n=toAgentTUIToolApprovalRequest(t),r=e.pendingApprovals.findIndex(e=>e.approvalId===n.approvalId);r===-1?e.pendingApprovals.push(n):e.pendingApprovals[r]=n}function toAgentTUIToolApprovalRequest(e){return{approvalId:e.requestId,toolCallId:e.action.callId,toolName:e.action.toolName,input:e.action.input}}function upsertPendingQuestion(e,t){let n=e.pendingQuestions.findIndex(e=>e.requestId===t.requestId);n===-1?e.pendingQuestions.push(t):e.pendingQuestions[n]=t}function textPartId(e,t){return`text:${e}:${t}`}function reasoningPartId(e,t){return`reasoning:${e}:${t}`}function partStateFor(e,t){let n=e.get(t);return n===void 0&&(n={generation:0,text:``,completed:!1,completedEpoch:0},e.set(t,n)),n}function partGenerationId(e,t){return t===0?e:`${e}#${t}`}function*closeOpenParts(e,t,n){for(let[r,i]of e)i.completed||i.text.length===0||(i.completed=!0,i.completedEpoch=n,yield{type:t,id:partGenerationId(r,i.generation)})}function isPostTurnVisibleEvent(e){switch(e.type){case`actions.requested`:case`authorization.completed`:case`authorization.required`:case`input.requested`:case`message.appended`:case`message.completed`:case`reasoning.appended`:case`reasoning.completed`:case`result.completed`:case`step.completed`:case`step.failed`:case`step.started`:case`subagent.called`:case`subagent.completed`:case`subagent.event`:case`subagent.started`:case`turn.completed`:case`turn.failed`:return!0;default:return!1}}function formatActionResultError(e){if(e.data.error?.message)return e.data.error.message;let t=e.data.result.output;if(typeof t==`string`)return t;try{return JSON.stringify(t)}catch{return`Tool execution failed.`}}function toFailureEvent(e,t,n){let r=failureKey(e);if(t.has(r))return;t.add(r);let s=n?.(e),c={type:`error`,errorText:s??formatFailureMessage(e)};if(s!==void 0)return c;let l=formatFailureDetail(e);return l!==void 0&&(c.detail=l),c}function isQuestionRequest(e){return e.display===`select`||e.display===`text`?!0:e.display===`confirmation`?!1:e.options!==void 0&&e.options.length>0}function toAgentTUIInputQuestion(e){let t=e.display===`text`?`text`:e.display===`select`||e.options!==void 0&&e.options.length>0?`select`:`text`,n={requestId:e.requestId,prompt:e.prompt,display:t};return e.options!==void 0&&(n.options=e.options.map(e=>{let t={id:e.id,label:e.label};return e.description!==void 0&&(t.description=e.description),e.style!==void 0&&(t.style=e.style),t})),e.allowFreeform!==void 0&&(n.allowFreeform=e.allowFreeform),n}function openCurrentSubagentSection(e){e.currentSectionKey===null&&(e.currentSectionKey=e.nextSectionKey++,e.steps.set(e.currentSectionKey,{reasoning:``,message:``,finalized:!1}));let t=e.steps.get(e.currentSectionKey);if(!t)throw Error(`invariant: subagent section state missing for current key`);return{key:e.currentSectionKey,step:t}}export{EveTUIRunner,parsePromptCommand};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { runChannelsFlow } from "#setup/flows/channels.js";
|
|
2
|
+
import { runConnectionsFlow } from "#setup/flows/connections.js";
|
|
2
3
|
import { runDeployFlow } from "#setup/flows/deploy.js";
|
|
3
4
|
import { runInstallVercelCliFlow } from "#setup/flows/install-vercel-cli.js";
|
|
4
5
|
import { runLoginFlow } from "#setup/flows/login.js";
|
|
@@ -31,6 +32,10 @@ export declare const SETUP_FLOW_CONFIG: {
|
|
|
31
32
|
title: string;
|
|
32
33
|
indicator: "pulse";
|
|
33
34
|
};
|
|
35
|
+
connect: {
|
|
36
|
+
title: string;
|
|
37
|
+
indicator: "pulse";
|
|
38
|
+
};
|
|
34
39
|
deploy: {
|
|
35
40
|
title: string;
|
|
36
41
|
indicator: "spinner";
|
|
@@ -57,6 +62,7 @@ export interface TuiSetupFlows {
|
|
|
57
62
|
runLoginFlow: typeof runLoginFlow;
|
|
58
63
|
runModelFlow: typeof runModelFlow;
|
|
59
64
|
runChannelsFlow: typeof runChannelsFlow;
|
|
65
|
+
runConnectionsFlow: typeof runConnectionsFlow;
|
|
60
66
|
runDeployFlow: typeof runDeployFlow;
|
|
61
67
|
}
|
|
62
68
|
export interface TuiSetupCommandResult {
|
|
@@ -65,11 +71,13 @@ export interface TuiSetupCommandResult {
|
|
|
65
71
|
preserveFlowDiagnostics: boolean;
|
|
66
72
|
/** Status refresh required after the command settles. */
|
|
67
73
|
effect?: VercelStatusEffect | {
|
|
74
|
+
kind: "connection-added";
|
|
75
|
+
} | {
|
|
68
76
|
kind: "model-access-changed";
|
|
69
77
|
};
|
|
70
78
|
}
|
|
71
79
|
/**
|
|
72
|
-
* Runs one TUI setup command (/model, /channels, /deploy) over the
|
|
80
|
+
* Runs one TUI setup command (/model, /channels, /connect, /deploy) over the
|
|
73
81
|
* shared setup flows, asking through the TUI's own bordered panel. Never throws:
|
|
74
82
|
* every outcome — done, cancelled, failed — folds into the returned command
|
|
75
83
|
* result. Ctrl-C or Esc on the working indicator (no question open) aborts the
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{createTuiPrompter}from"./tui-prompter.js";import{runDeployFlow}from"#setup/flows/deploy.js";import{WizardCancelledError}from"#setup/step.js";import{runLoginFlow}from"#setup/flows/login.js";import{HumanActionRequiredError}from"#setup/human-action.js";import{runChannelsFlow}from"#setup/flows/channels.js";import{runInstallVercelCliFlow}from"#setup/flows/install-vercel-cli.js";import{runModelFlow}from"#setup/flows/model.js";import{runProviderFlow}from"#setup/flows/provider.js";import{openUrl}from"#setup/primitives/open-url.js";import{slackMessageDeepLink}from"#setup/slack-connect.js";const SETUP_FLOW_CONFIG={"vc:install":{title:`Install the Vercel CLI`,indicator:`pulse`},"vc:login":{title:`Log in to Vercel`,indicator:`pulse`},model:{title:`Configure the agent model`,indicator:`pulse`},channels:{title:`Agent channels`,indicator:`pulse`},deploy:{title:`Deploy to Vercel`,indicator:`spinner`}};function muteableRenderer(e,t){return{readSelect:n=>t()?Promise.resolve(void 0):e.readSelect(n),readEditableSelect:n=>t()?Promise.resolve(void 0):e.readEditableSelect(n),readProviderPicker:n=>t()?Promise.resolve(void 0):e.readProviderPicker(n),readText:n=>t()?Promise.resolve(void 0):e.readText(n),readAcknowledge:n=>t()?Promise.resolve():e.readAcknowledge(n),readChoice:n=>t()?{choice:Promise.resolve(void 0),close:()=>{}}:e.readChoice(n),setStatus:n=>{t()||e.setStatus(n)},renderLine:(n,r)=>{(!t()||r===`warning`||r===`error`)&&e.renderLine(n,r)},renderOutput:n=>{t()||e.renderOutput(n)}}}async function runTuiSetupCommand(t){let{command:r}=t,i=!1,a=new AbortController,o=muteableRenderer(t.renderer,()=>i),s=(t.createPrompter??createTuiPrompter)(o),c=t.renderer.waitForInterrupt(),l=Symbol(`interrupted`),u=executeSetupCommand(t,s,o,a.signal);try{let e=await Promise.race([u,c.promise.then(()=>l)]);return e===l?(i=!0,a.abort(new WizardCancelledError),{...await u,message:`/${r} interrupted.`,preserveFlowDiagnostics:!0}):e}finally{c.dispose(),t.renderer.setStatus(void 0)}}async function executeSetupCommand(e,i,
|
|
2
|
-
`),preserveFlowDiagnostics:!1};return n.providerOutcome!==void 0&&(a.effect={kind:`model-access-changed`}),a}case`channels`:{let e=await
|
|
1
|
+
import{createTuiPrompter}from"./tui-prompter.js";import{runDeployFlow}from"#setup/flows/deploy.js";import{WizardCancelledError}from"#setup/step.js";import{runLoginFlow}from"#setup/flows/login.js";import{HumanActionRequiredError}from"#setup/human-action.js";import{runChannelsFlow}from"#setup/flows/channels.js";import{runConnectionsFlow}from"#setup/flows/connections.js";import{runInstallVercelCliFlow}from"#setup/flows/install-vercel-cli.js";import{runModelFlow}from"#setup/flows/model.js";import{runProviderFlow}from"#setup/flows/provider.js";import{openUrl}from"#setup/primitives/open-url.js";import{slackMessageDeepLink}from"#setup/slack-connect.js";const SETUP_FLOW_CONFIG={"vc:install":{title:`Install the Vercel CLI`,indicator:`pulse`},"vc:login":{title:`Log in to Vercel`,indicator:`pulse`},model:{title:`Configure the agent model`,indicator:`pulse`},channels:{title:`Agent channels`,indicator:`pulse`},connect:{title:`Agent connections`,indicator:`pulse`},deploy:{title:`Deploy to Vercel`,indicator:`spinner`}};function muteableRenderer(e,t){return{readSelect:n=>t()?Promise.resolve(void 0):e.readSelect(n),readEditableSelect:n=>t()?Promise.resolve(void 0):e.readEditableSelect(n),readProviderPicker:n=>t()?Promise.resolve(void 0):e.readProviderPicker(n),readText:n=>t()?Promise.resolve(void 0):e.readText(n),readAcknowledge:n=>t()?Promise.resolve():e.readAcknowledge(n),readChoice:n=>t()?{choice:Promise.resolve(void 0),close:()=>{}}:e.readChoice(n),setStatus:n=>{t()||e.setStatus(n)},renderLine:(n,r)=>{(!t()||r===`warning`||r===`error`)&&e.renderLine(n,r)},renderOutput:n=>{t()||e.renderOutput(n)}}}async function runTuiSetupCommand(t){let{command:r}=t,i=!1,a=new AbortController,o=muteableRenderer(t.renderer,()=>i),s=(t.createPrompter??createTuiPrompter)(o),c=t.renderer.waitForInterrupt(),l=Symbol(`interrupted`),u=executeSetupCommand(t,s,o,a.signal);try{let e=await Promise.race([u,c.promise.then(()=>l)]);return e===l?(i=!0,a.abort(new WizardCancelledError),{...await u,message:`/${r} interrupted.`,preserveFlowDiagnostics:!0}):e}finally{c.dispose(),t.renderer.setStatus(void 0)}}async function executeSetupCommand(e,i,u,d){let{command:f,appRoot:p}=e,m={runInstallVercelCliFlow,runLoginFlow,runModelFlow,runChannelsFlow,runConnectionsFlow,runDeployFlow,...e.flows};try{switch(f){case`vc:install`:return installVercelCliResultMessage(await m.runInstallVercelCliFlow({appRoot:p,prompter:i,signal:d}));case`vc:login`:return loginResultMessage(await m.runLoginFlow({appRoot:p,prompter:i,signal:d}));case`model`:{let pickProvider=e=>u.readProviderPicker(e),t={appRoot:p,prompter:i,signal:d,deps:{runProviderFlow:e=>runProviderFlow({...e,picker:pickProvider})}};e.initialModelStep!==void 0&&(t.initialStep=e.initialModelStep);let n=await m.runModelFlow(t);if(n.kind===`cancelled`)return{message:`/model cancelled.`,preserveFlowDiagnostics:!1};let r=[];n.modelMessage!==void 0&&r.push(n.modelMessage),n.providerOutcome!==void 0&&r.push(providerOutcomeMessage(n.providerOutcome));let a={message:r.join(`
|
|
2
|
+
`),preserveFlowDiagnostics:!1};return n.providerOutcome!==void 0&&(a.effect={kind:`model-access-changed`}),a}case`channels`:{let e=await m.runChannelsFlow({appRoot:p,prompter:i,signal:d});switch(e.kind){case`failed`:return pendingChannelsResult(`Channel files changed, but /channels failed: ${e.message}`);case`cancelled`:return{message:`/channels cancelled.`,preserveFlowDiagnostics:!0};case`deploy-and-chat`:return await runDeployAndChat(m,{appRoot:p,prompter:i,signal:d},e.chat);case`done`:return e.addedChannels.length===0?{message:`No channels added.`,preserveFlowDiagnostics:!0}:{message:`Channels added: ${e.addedChannels.join(`, `)} — run /deploy to ship them.`,preserveFlowDiagnostics:!0,effect:{kind:`channels-added`}}}}case`connect`:{let e=await m.runConnectionsFlow({appRoot:p,prompter:i,signal:d});switch(e.kind){case`cancelled`:return{message:`/connect cancelled.`,preserveFlowDiagnostics:!0,effect:{kind:`model-access-changed`}};case`failed`:return{message:e.addedConnections.length===0?`/connect failed: ${e.message}`:`Connection files changed, but /connect failed: ${e.message}`,preserveFlowDiagnostics:!0,effect:e.addedConnections.length===0?{kind:`model-access-changed`}:{kind:`connection-added`}};case`done`:return{message:e.addedConnections.length===0?`No connections added.`:`Connections added: ${e.addedConnections.join(`, `)}.`,preserveFlowDiagnostics:!0,effect:e.addedConnections.length===0?{kind:`model-access-changed`}:{kind:`connection-added`}}}}case`deploy`:{let e=await m.runDeployFlow({appRoot:p,prompter:i,interactive:!0,signal:d});return e.kind===`cancelled`?{message:`/deploy cancelled.`,preserveFlowDiagnostics:!0}:e.kind===`needs-link`?{message:`Not linked to a Vercel project — run /model to connect one first.`,preserveFlowDiagnostics:!0}:{message:e.productionUrl===void 0?`Deployed.`:`Deployed: ${e.productionUrl}`,preserveFlowDiagnostics:!0,effect:{kind:`deployed`}}}}}catch(e){if(e instanceof WizardCancelledError)return{message:`/${f} cancelled.`,preserveFlowDiagnostics:f!==`model`};let t=vercelActionOutcome(e,f);return t===void 0?{message:`/${f} failed: ${e instanceof Error?e.message:String(e)}`,preserveFlowDiagnostics:!0}:t}}function vercelActionOutcome(e,t){if(!(e instanceof HumanActionRequiredError))return;let n=vercelActionMessage(e.action.kind,t);return n===void 0?void 0:{message:n,preserveFlowDiagnostics:!0}}function vercelActionMessage(e,t){switch(e){case`vercel-login`:return`You're not logged in to Vercel — run /vc:login, then retry /${t}.`;case`vercel-forbidden`:return`Vercel denied access to that team — run /vc:login to re-authenticate (for example to complete SSO), or pick a team you can access, then retry /${t}.`;case`vercel-cli-missing`:return`The Vercel CLI isn't installed — run /vc:install to install it, then retry /${t}.`;default:return}}async function runDeployAndChat(e,t,r){let i;try{i=await e.runDeployFlow({...t,interactive:!0})}catch(e){if(e instanceof WizardCancelledError)return pendingChannelsResult(`Channels added, but /deploy was cancelled. Run /deploy to ship them.`);let t=vercelActionOutcome(e,`deploy`);return pendingChannelsResult(t===void 0?`Channels added, but /deploy failed: ${e instanceof Error?e.message:String(e)}`:`Channels added. ${t.message}`)}if(i.kind===`cancelled`)return pendingChannelsResult(`Channels added, but /deploy was cancelled. Run /deploy to ship them.`);if(i.kind===`needs-link`)return pendingChannelsResult(`Channels added, but this directory is not linked to Vercel. Run /model, then /deploy.`);let a=i.productionUrl===void 0?`Deployed.`:`Deployed: ${i.productionUrl}`,o;if(r.chatUrl===void 0)o=`Message your agent in Slack to see it live.`;else{let e=slackMessageDeepLink(r.chatUrl);openUrl(e),o=`Chat with your agent in Slack: ${e}`}return{message:`${a}\n${o}`,preserveFlowDiagnostics:!0,effect:{kind:`deployed`}}}function installVercelCliResultMessage(e){switch(e.kind){case`cancelled`:return{message:`/vc:install cancelled.`,preserveFlowDiagnostics:!1};case`already`:return{message:`The Vercel CLI is already installed.`,preserveFlowDiagnostics:!1};case`failed`:return{message:"Couldn't install the Vercel CLI — install it manually with `npm i -g vercel@latest`.",preserveFlowDiagnostics:!0};case`installed`:return{message:`Installed the Vercel CLI. Run /vc:login next.`,preserveFlowDiagnostics:!1,effect:{kind:`refresh-identity`}}}}function loginResultMessage(e){switch(e.kind){case`cancelled`:return{message:`/vc:login cancelled.`,preserveFlowDiagnostics:!1};case`already`:return{message:`You're already logged in to Vercel.`,preserveFlowDiagnostics:!1};case`cli-missing`:return{message:`The Vercel CLI isn't installed — run /vc:install to install it, then retry /vc:login.`,preserveFlowDiagnostics:!0};case`failed`:return{message:`Vercel login didn't complete — run /vc:login to try again.`,preserveFlowDiagnostics:!0};case`logged-in`:return{message:`Logged in to Vercel.`,preserveFlowDiagnostics:!1,effect:{kind:`refresh-identity`}};case`unavailable`:return{message:`Couldn't reach Vercel — check your connection, then retry /vc:login.`,preserveFlowDiagnostics:!0}}}function pendingChannelsResult(e){return{message:e,preserveFlowDiagnostics:!0,effect:{kind:`channels-added`}}}function providerOutcomeMessage(e){let{credential:t,status:n}=e;return n.kind===`gateway-project`?t===void 0?`Project linked. No model credential found; set AI_GATEWAY_API_KEY in .env.local.`:`Project linked. Connected to AI Gateway via ${t}.`:n.kind===`gateway-key`?`Connected to AI Gateway via ${n.envKey} in ${n.envFile}.`:`Provider updated — no gateway credential detected; set AI_GATEWAY_API_KEY in .env.local.`}export{SETUP_FLOW_CONFIG,runTuiSetupCommand};
|
|
@@ -13,6 +13,12 @@ export type SetupEditableSelectResult = {
|
|
|
13
13
|
};
|
|
14
14
|
/** Animation shown while a setup flow is between questions. */
|
|
15
15
|
export type SetupFlowIndicator = "spinner" | "pulse";
|
|
16
|
+
/** Ephemeral setup status, with external user action distinct from background work. */
|
|
17
|
+
export type SetupFlowStatus = string | {
|
|
18
|
+
kind: "external-action";
|
|
19
|
+
text: string;
|
|
20
|
+
emphasis: string;
|
|
21
|
+
};
|
|
16
22
|
interface SetupSelectRequestBase {
|
|
17
23
|
message: string;
|
|
18
24
|
options: readonly SetupPanelOption[];
|
|
@@ -27,6 +33,7 @@ interface SetupSearchAction extends SearchActionOption {
|
|
|
27
33
|
}
|
|
28
34
|
interface SetupSearchSelectRequest extends SetupSelectRequestBase {
|
|
29
35
|
kind: "search";
|
|
36
|
+
layout?: "task-list";
|
|
30
37
|
initialValue?: string;
|
|
31
38
|
placeholder?: string;
|
|
32
39
|
searchAction?: SetupSearchAction;
|
|
@@ -87,7 +94,7 @@ export interface SetupFlowRenderer {
|
|
|
87
94
|
* whichever settles first wins.
|
|
88
95
|
*/
|
|
89
96
|
readChoice(options: ChannelSetupChoiceOptions): ChannelSetupChoice;
|
|
90
|
-
setStatus(
|
|
97
|
+
setStatus(status: SetupFlowStatus | undefined): void;
|
|
91
98
|
renderLine(text: string, tone: "info" | "success" | "warning" | "error"): void;
|
|
92
99
|
renderOutput(text: string): void;
|
|
93
100
|
/**
|
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
import type { AgentInfoResult } from "#client/index.js";
|
|
2
2
|
/** One boot-time setup problem the TUI can point at a fixing command. */
|
|
3
|
-
export
|
|
3
|
+
export interface SetupIssue {
|
|
4
4
|
/** Diagnostics never authorize a command by themselves. */
|
|
5
5
|
kind: "attention";
|
|
6
6
|
/** Short category label, e.g. "AI Gateway credentials". */
|
|
7
7
|
label: string;
|
|
8
8
|
/** The slash command that fixes it, e.g. "/model". */
|
|
9
9
|
command: string;
|
|
10
|
-
}
|
|
11
|
-
/** Positive runtime evidence that no model provider is configured. */
|
|
12
|
-
kind: "model-provider-unconfigured";
|
|
13
|
-
label: string;
|
|
14
|
-
command: "/model";
|
|
15
|
-
};
|
|
10
|
+
}
|
|
16
11
|
/** What a boot detection may inspect. */
|
|
17
12
|
export interface BootDetectionContext {
|
|
18
13
|
/** The local project the in-process dev server is running. */
|
|
@@ -63,13 +58,6 @@ export declare const CLI_MISSING_SETUP_ISSUE: SetupIssue;
|
|
|
63
58
|
export declare function detectSetupIssues(context: BootDetectionContext, detections?: readonly BootDetection[]): Promise<SetupIssue[]>;
|
|
64
59
|
/** Places the auth issue before boot-time setup issues. */
|
|
65
60
|
export declare function orderedSetupIssues(bootIssues: readonly SetupIssue[], authIssue: SetupIssue | undefined): SetupIssue[];
|
|
66
|
-
/** The command and entry step authorized by positive setup evidence. */
|
|
67
|
-
export interface AutomaticSetupCommand {
|
|
68
|
-
prompt: "/model";
|
|
69
|
-
initialModelStep: "provider";
|
|
70
|
-
}
|
|
71
|
-
/** Returns the only command authorized to run from positive setup evidence. */
|
|
72
|
-
export declare function automaticSetupCommand(issues: readonly SetupIssue[]): AutomaticSetupCommand | undefined;
|
|
73
61
|
/**
|
|
74
62
|
* The attention line's body, mirroring Claude Code's
|
|
75
63
|
* `1 setup issue: MCP · /doctor` shape; the renderer prefixes the warning
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{join}from"node:path";import{pathExists}from"#setup/path-exists.js";function hasEnvValue(e,t){let n=e[t];return n!==void 0&&n.trim().length>0}function resolveModelProviderState(e,t){let n=modelProviderAccess({env:t,info:e});if(e===void 0||n.kind!==`gateway`||n.runtime.status!==`connected`)return e;let{credential:r}=n.runtime,i=e.agent.model,a=i.endpoint;return a?.kind===`gateway`&&a.connected&&a.credential===r?e:{...e,agent:{...e.agent,model:{...i,endpoint:{kind:`gateway`,connected:!0,credential:r}}}}}function modelProviderAccess(e){let t=e.info?.agent.model;if(t?.routing?.kind===`external`)return{kind:`external`};if(t?.routing?.kind!==`gateway`)return{kind:`unknown`};if(hasEnvValue(e.env,`AI_GATEWAY_API_KEY`))return{kind:`gateway`,runtime:{status:`connected`,credential:`api-key`}};let n=t.endpoint;return n?.kind===`gateway`&&n.connected?{kind:`gateway`,runtime:{status:`connected`,credential:n.credential}}:hasEnvValue(e.env,`VERCEL_OIDC_TOKEN`)?{kind:`gateway`,runtime:{status:`connected`,credential:`oidc`}}:n?.kind===`gateway`?{kind:`gateway`,runtime:{status:`disconnected`}}:{kind:`gateway`,runtime:{status:`unknown`}}}const BOOT_DETECTIONS=[{id:`model-provider`,async detect({appRoot:n,env:r,info:i}){let a=modelProviderAccess({env:r,info:i});if(a.kind===`external`)return[];if(a.kind===`gateway`){if(a.runtime.status===`connected`)return[];if(a.runtime.status===`disconnected`)return[{kind:`
|
|
1
|
+
import{join}from"node:path";import{pathExists}from"#setup/path-exists.js";function hasEnvValue(e,t){let n=e[t];return n!==void 0&&n.trim().length>0}function resolveModelProviderState(e,t){let n=modelProviderAccess({env:t,info:e});if(e===void 0||n.kind!==`gateway`||n.runtime.status!==`connected`)return e;let{credential:r}=n.runtime,i=e.agent.model,a=i.endpoint;return a?.kind===`gateway`&&a.connected&&a.credential===r?e:{...e,agent:{...e.agent,model:{...i,endpoint:{kind:`gateway`,connected:!0,credential:r}}}}}function modelProviderAccess(e){let t=e.info?.agent.model;if(t?.routing?.kind===`external`)return{kind:`external`};if(t?.routing?.kind!==`gateway`)return{kind:`unknown`};if(hasEnvValue(e.env,`AI_GATEWAY_API_KEY`))return{kind:`gateway`,runtime:{status:`connected`,credential:`api-key`}};let n=t.endpoint;return n?.kind===`gateway`&&n.connected?{kind:`gateway`,runtime:{status:`connected`,credential:n.credential}}:hasEnvValue(e.env,`VERCEL_OIDC_TOKEN`)?{kind:`gateway`,runtime:{status:`connected`,credential:`oidc`}}:n?.kind===`gateway`?{kind:`gateway`,runtime:{status:`disconnected`}}:{kind:`gateway`,runtime:{status:`unknown`}}}const BOOT_DETECTIONS=[{id:`model-provider`,async detect({appRoot:n,env:r,info:i}){let a=modelProviderAccess({env:r,info:i});if(a.kind===`external`)return[];if(a.kind===`gateway`){if(a.runtime.status===`connected`)return[];if(a.runtime.status===`disconnected`)return[{kind:`attention`,label:await pathExists(join(n,`.vercel`,`project.json`))?`AI Gateway credentials missing`:`model provider not linked`,command:`/model`}]}return await pathExists(join(n,`.vercel`,`project.json`))?[{kind:`attention`,label:`AI Gateway credentials missing`,command:`/model`}]:[{kind:`attention`,label:`model provider not linked`,command:`/model`}]}}],LOGIN_SETUP_ISSUE={kind:`attention`,label:`not logged in`,command:`/vc:login`},CLI_MISSING_SETUP_ISSUE={kind:`attention`,label:`Vercel CLI not found`,command:`/vc:install`};async function detectSetupIssues(e,t=BOOT_DETECTIONS){return(await Promise.all(t.map(async t=>{try{return await t.detect(e)}catch{return[]}}))).flat()}function orderedSetupIssues(e,t){return t===void 0?[...e]:[t,...e]}function formatSetupIssuesLine(e){let t=e.length===1?`setup issue`:`setup issues`,n=e.map(e=>`${e.label} · ${e.command}`).join(`, `);return`${e.length} ${t}: ${n}`}export{BOOT_DETECTIONS,CLI_MISSING_SETUP_ISSUE,LOGIN_SETUP_ISSUE,detectSetupIssues,formatSetupIssuesLine,orderedSetupIssues,resolveModelProviderState};
|
|
@@ -65,6 +65,7 @@ type SetupOptionSelectPanelState = (SetupSelectPanelBase & {
|
|
|
65
65
|
kind: "single";
|
|
66
66
|
}) | (SetupSelectPanelBase & {
|
|
67
67
|
kind: "search";
|
|
68
|
+
layout?: "task-list";
|
|
68
69
|
placeholder?: string;
|
|
69
70
|
}) | (SetupSelectPanelBase & {
|
|
70
71
|
kind: "multi";
|
|
@@ -118,20 +119,25 @@ export interface FlowPanelIndicator {
|
|
|
118
119
|
glyph: string;
|
|
119
120
|
color: "green" | "yellow";
|
|
120
121
|
}
|
|
122
|
+
/** One live flow status after its animation frame and visual intent are resolved. */
|
|
123
|
+
export type FlowPanelStatus = {
|
|
124
|
+
kind: "progress";
|
|
125
|
+
text: string;
|
|
126
|
+
indicator: FlowPanelIndicator;
|
|
127
|
+
} | {
|
|
128
|
+
kind: "external-action";
|
|
129
|
+
text: string;
|
|
130
|
+
emphasis: string;
|
|
131
|
+
indicator: FlowPanelIndicator;
|
|
132
|
+
};
|
|
121
133
|
export type FlowPanelContent = {
|
|
122
134
|
kind: "question";
|
|
123
135
|
rows: readonly string[];
|
|
124
136
|
/** The install wait keeps its indicator above the concurrent actions. */
|
|
125
|
-
status?:
|
|
126
|
-
text: string;
|
|
127
|
-
indicator: FlowPanelIndicator;
|
|
128
|
-
};
|
|
137
|
+
status?: FlowPanelStatus;
|
|
129
138
|
} | {
|
|
130
139
|
kind: "status";
|
|
131
|
-
status:
|
|
132
|
-
text: string;
|
|
133
|
-
indicator: FlowPanelIndicator;
|
|
134
|
-
};
|
|
140
|
+
status: FlowPanelStatus;
|
|
135
141
|
/** Latest child-process output shown transiently beneath the status. */
|
|
136
142
|
preview?: string;
|
|
137
143
|
} | {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{clipVisible,renderInputText,renderInputWithBlockCursor,visibleLength,wrapVisibleLine}from"./terminal-text.js";import{maskLine,visibleLine}from"./line-editor.js";import{renderCursorRow,renderOptionRow,renderOptionRowContinuation,resolveOptionRowState}from"#setup/cli/option-row.js";import{filterOptions,submitRowIndex}from"#setup/cli/select-state.js";function clip(t,n){return clipVisible(t,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`,DIM_OPEN=`\x1B[2m`,ANSI_FOREGROUND_COLOR=RegExp(`\x1B\\[(?:3[0-9]|9[0-7])m`,`g`);function dimWithEmphasis(e,t){return t.colors.dim(e.replaceAll(BOLD_OR_DIM_CLOSE,`${BOLD_OR_DIM_CLOSE}${DIM_OPEN}`))}function solidWithinDim(e,t){return t.color?`${BOLD_OR_DIM_CLOSE}${e}${DIM_OPEN}`:e}function foregroundWithEmphasis(e){return e.replaceAll(DIM_OPEN,``).replace(ANSI_FOREGROUND_COLOR,``)}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 renderIndicator(e,t){return e.color===`green`?t.colors.green(e.glyph):t.colors.yellow(e.glyph)}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.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}`)}switch(a.length>0&&i.push(``),e.content.kind){case`question`:e.content.status!==void 0&&i.push(` ${
|
|
2
|
-
`).map((e,r)=>` ${t===`stacked`||r>0?n.colors.bold(e):e}`);return r.push(``),r}function searchFilter(e,t,n,r){let i=r.colors.dim(r.glyph.caret),a=i;return e.length>0?a=e+i:t!==void 0&&(a=r.colors.dim(`> ${t}`)),n===void 0?a:`${a} ${r.colors.yellow(n)}`}function selectViewSize(e){return e.search?e.filter===``&&e.featuredLead>0?Math.min(e.featuredLead,8):8:e.optionCount}function noticeBody(e,t,n){return e.tone===`info`?n.colors.dim(e.text):e.tone===`success`&&t===`task-list`?n.colors.bold(e.text):e.text}function renameHint(e,t,r,i){let a=renderInputWithBlockCursor({...visibleLine({text:r.editor.text||r.defaultValue,cursor:r.editor.cursor},1/0),visible:t,inverse:i.colors.inverse});return r.editor.text.length>0&&(a=solidWithinDim(a,i)),{...e,hint:r.formatHint(a)}}function keyHint(e,i,s,c,l){let u=s.phase;if(u.kind===`inactive`)return e;let d=maskLine(u.editor),f=u.kind!==`validating`&&u.kind!==`invalid`,p=``,m=``;u.kind===`validating`?p=`Validating… `:u.kind===`invalid`&&(m=` ${c.colors.red(`${c.glyph.error} ${c.colors.bold(`Invalid key`)}`)}`);let h=u.editor.text.length===0?`type your key`:void 0,g=visibleLine(h===void 0?d:{text:h,cursor:0},Math.max(1,l-visibleLength(`> ${p}${m}`)),c.glyph.ellipsis),_=f?renderInputWithBlockCursor({...g,visible:i,inverse:c.colors.inverse}):renderInputText(`${g.before}${g.under}${g.after}`);return{...e,hint:`> ${p}${_}${m}`}}function inlineEditOption(e,t,n,r,i){if(!t||n===void 0||e.value!==n.optionValue)return e;switch(n.editor.kind){case`rename`:return renameHint(e,n.caretVisible,n.editor,r);case`key`:return keyHint(e,n.caretVisible,n.editor,r,i)}}function optionWithoutStackedHint(e,t){if(t!==`stacked`||e.hint===void 0)return{option:e,stackedHint:void 0};let{hint:n,...r}=e;return{option:r,stackedHint:n}}function optionUsesPlaceholder(e,t
|
|
3
|
-
`)){let r=
|
|
1
|
+
import{clipVisible,renderInputText,renderInputWithBlockCursor,visibleLength,wrapVisibleLine}from"./terminal-text.js";import{maskLine,visibleLine}from"./line-editor.js";import{renderCursorRow,renderOptionRow,renderOptionRowContinuation,resolveOptionRowState}from"#setup/cli/option-row.js";import{filterOptions,submitRowIndex}from"#setup/cli/select-state.js";function clip(t,n){return clipVisible(t,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`,DIM_OPEN=`\x1B[2m`,ANSI_FOREGROUND_COLOR=RegExp(`\x1B\\[(?:3[0-9]|9[0-7])m`,`g`);function dimWithEmphasis(e,t){return t.colors.dim(e.replaceAll(BOLD_OR_DIM_CLOSE,`${BOLD_OR_DIM_CLOSE}${DIM_OPEN}`))}function solidWithinDim(e,t){return t.color?`${BOLD_OR_DIM_CLOSE}${e}${DIM_OPEN}`:e}function foregroundWithEmphasis(e){return e.replaceAll(DIM_OPEN,``).replace(ANSI_FOREGROUND_COLOR,``)}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 renderIndicator(e,t){return e.color===`green`?t.colors.green(e.glyph):t.colors.yellow(e.glyph)}function renderStatusText(e,t){if(e.kind===`progress`)return t.colors.dim(e.text);let n=e.text.indexOf(e.emphasis);if(n===-1)return t.colors.dim(e.text);let r=n+e.emphasis.length;return`${t.colors.dim(e.text.slice(0,n))}${t.colors.yellow(e.text.slice(n,r))}${t.colors.dim(e.text.slice(r))}`}function renderFlowPanelStatus(e,t){return`${renderIndicator(e.indicator,t)} ${renderStatusText(e,t)}`}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.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}`)}switch(a.length>0&&i.push(``),e.content.kind){case`question`:e.content.status!==void 0&&i.push(` ${renderFlowPanelStatus(e.content.status,t)}`,``),i.push(...e.content.rows);break;case`status`:i.push(` ${renderFlowPanelStatus(e.content.status,t)}`),e.content.preview!==void 0&&i.push(` ${r.dim(e.content.preview)}`);break;case`preview`:i.push(` ${renderIndicator(e.content.indicator,t)} ${r.dim(e.content.text)}`);break;case`idle`:i.push(` ${renderIndicator(e.content.indicator,t)} ${r.dim(`Working…`)}`);break}return i.map((e,t)=>t===0||e.length===0?clip(e,n):clip(` ${e}`,n))}function optionRow(e){let{option:t,theme:n}=e;return renderOptionRow({colors:n.colors,glyphs:{pointer:n.glyph.pointer,selectedPointer:n.glyph.selectedPointer,success:n.glyph.success,placeholder:n.glyph.option,dot:n.glyph.dot},label:t.label,hint:t.hint,focusHint:t.focusHint,accent:t.accent,isCursor:e.isCursor,state:resolveOptionRowState(t,e.isChecked),placeholder:e.placeholder,hintPadding:e.hintPadding})}function selectPresentation(e){switch(e.kind){case`single`:return{selection:`single`,filter:void 0,layout:`plain`,edit:void 0};case`search`:return{selection:`single`,filter:{placeholder:e.placeholder},layout:e.layout??`plain`,edit:void 0};case`multi`:return{selection:`multiple`,filter:void 0,layout:`plain`,edit:void 0};case`searchable-multi`:return{selection:`multiple`,filter:{placeholder:e.placeholder},layout:`plain`,edit:void 0};case`stacked`:return{selection:`single`,filter:void 0,layout:`stacked`,edit:void 0};case`task-list`:return{selection:`single`,filter:void 0,layout:`task-list`,edit:void 0};case`inline-edit`:return{selection:`single`,filter:void 0,layout:e.layout,edit:e.edit}}}function selectMessageRows(e,t,n){if(e===``)return[];let r=e.split(`
|
|
2
|
+
`).map((e,r)=>` ${t===`stacked`||r>0?n.colors.bold(e):e}`);return r.push(``),r}function searchFilter(e,t,n,r){let i=r.colors.dim(r.glyph.caret),a=i;return e.length>0?a=e+i:t!==void 0&&(a=r.colors.dim(`> ${t}`)),n===void 0?a:`${a} ${r.colors.yellow(n)}`}function selectViewSize(e){return e.search?e.filter===``&&e.featuredLead>0?Math.min(e.featuredLead,8):8:e.optionCount}function noticeBody(e,t,n){return e.tone===`info`?n.colors.dim(e.text):e.tone===`success`&&t===`task-list`?n.colors.bold(e.text):e.text}function renameHint(e,t,r,i){let a=renderInputWithBlockCursor({...visibleLine({text:r.editor.text||r.defaultValue,cursor:r.editor.cursor},1/0),visible:t,inverse:i.colors.inverse});return r.editor.text.length>0&&(a=solidWithinDim(a,i)),{...e,hint:r.formatHint(a)}}function keyHint(e,i,s,c,l){let u=s.phase;if(u.kind===`inactive`)return e;let d=maskLine(u.editor),f=u.kind!==`validating`&&u.kind!==`invalid`,p=``,m=``;u.kind===`validating`?p=`Validating… `:u.kind===`invalid`&&(m=` ${c.colors.red(`${c.glyph.error} ${c.colors.bold(`Invalid key`)}`)}`);let h=u.editor.text.length===0?`type your key`:void 0,g=visibleLine(h===void 0?d:{text:h,cursor:0},Math.max(1,l-visibleLength(`> ${p}${m}`)),c.glyph.ellipsis),_=f?renderInputWithBlockCursor({...g,visible:i,inverse:c.colors.inverse}):renderInputText(`${g.before}${g.under}${g.after}`);return{...e,hint:`> ${p}${_}${m}`}}function inlineEditOption(e,t,n,r,i){if(!t||n===void 0||e.value!==n.optionValue)return e;switch(n.editor.kind){case`rename`:return renameHint(e,n.caretVisible,n.editor,r);case`key`:return keyHint(e,n.caretVisible,n.editor,r,i)}}function optionWithoutStackedHint(e,t){if(t!==`stacked`||e.hint===void 0)return{option:e,stackedHint:void 0};let{hint:n,...r}=e;return{option:r,stackedHint:n}}function optionUsesPlaceholder(e,t){let n=e.filter!==void 0&&e.layout!==`task-list`,r=e.selection===`multiple`,i=e.layout!==`plain`;return!n&&!t&&(r||i)}function appendSelectOptionRows(e){let{rows:t,state:n,presentation:r,visible:i,start:a,end:o,cursor:s,visibleLabelWidth:c,width:u,theme:d}=e,f=d.colors,p=!1;for(let e=a;e<o;e+=1){let m=i[e],h=e===s,g=r.layout===`task-list`&&m.trailingAction===!0;g&&(appendSelectNotices(t,n.notices,r.layout,d,u),p=!0),g&&(e>a||(n.notices?.length??0)>0)&&t.push(``);let _=r.layout===`stacked`?Math.max(1,u-6):Math.max(1,u-Math.max(c,m.label.length)-9),{option:v,stackedHint:y}=optionWithoutStackedHint(inlineEditOption(m,h,r.edit,d,_),r.layout);if(t.push(` ${optionRow({option:v,isCursor:h,isChecked:r.selection===`multiple`&&n.select.selected.has(m.value),placeholder:optionUsesPlaceholder(r,g),hintPadding:Math.max(0,c-v.label.length),theme:d})}`),y!==void 0){let e=r.edit,n=h&&e!==void 0&&e.optionValue===m.value&&e.editor.kind===`key`&&e.editor.phase.kind!==`inactive`;for(let e of y.split(`
|
|
3
|
+
`)){let r=h?n?e:foregroundWithEmphasis(e):dimWithEmphasis(e,d);t.push(` ${renderOptionRowContinuation(r)}`)}}if(m.description!==void 0&&(m.disabled===!0||h)){let e=f.dim(m.description);t.push(r.layout===`stacked`?` ${renderOptionRowContinuation(e)}`:` ${e}`)}r.layout===`stacked`&&e<o-1&&t.push(``)}return p}function appendSubmitRow(e,t,n,r){if(n<0)return;let i=t===n,a=i?`${r.glyph.selectedPointer} ${r.colors.bold(`Submit`)}`:` Submit`;e.push(``,` ${renderCursorRow(a,i,r.colors)}`)}function appendSelectNotices(e,t,n,a,o){if(!(t===void 0||t.length===0)){e.push(``);for(let s of t){let t=toneGlyph(s.tone,a),c=` `.repeat(visibleLength(t)+1),l=Math.max(1,o-2-visibleLength(t)-1),u=wrapVisibleLine(s.text,l);for(let[r,i]of u.entries()){let o=noticeBody({...s,text:i},n,a);e.push(r===0?` ${t} ${o}`:` ${c}${o}`)}}}}function selectFooterHints(e,t,n){let r=[],i=`esc to cancel`,a=e.edit;if(a!==void 0&&t[n]?.value===a.optionValue)if(a.editor.kind===`key`){let e=a.editor.phase;if(e.kind!==`inactive`&&e.editor.text.length>0&&(i=`esc to clear`),e.kind===`validating`)return[i];r.push(`type your key`)}else r.push(`type to rename`);return e.filter!==void 0&&r.push(`type to filter`),r.push(`↑/↓ move`),r.push(e.selection===`multiple`?`space to toggle`:`enter to select`),e.selection===`multiple`&&r.push(`enter on Submit to confirm`),r.push(i),r}function renderActionQuestion(e,t,n){let r=[` ${t.colors.dim(`${t.glyph.dot} ${e.context}`)}`,``];for(let[n,i]of e.actions.entries())r.push(` ${optionRow({option:i,isCursor:n===e.cursor,isChecked:!1,placeholder:!0,hintPadding:0,theme:t})}`);return r.push(...questionFooter([`↑/↓ move`,`enter to select`,`esc to cancel`],t)),r.map(e=>clip(e,n))}function renderSelectQuestion(e,t,n){if(e.kind===`actions`)return renderActionQuestion(e,t,n);let r=t.colors,i=selectPresentation(e),a=i.filter?filterOptions(e.options,e.select.filter,e.searchAction):e.options,o=i.selection===`multiple`?submitRowIndex(a):-1,s=e.select.cursor,c=selectMessageRows(e.message,i.layout,t);i.filter!==void 0&&c.push(` ${searchFilter(e.select.filter,i.filter.placeholder,e.loadingFrame,t)}`);let l=0;for(;a[l]?.featured;)l+=1;let u=selectViewSize({search:i.filter!==void 0,filter:e.select.filter,featuredLead:l,optionCount:a.length}),p=Math.max(0,Math.min(s-Math.floor(u/2),Math.max(0,a.length-u))),m=Math.min(p+u,a.length),h=a.slice(p,m).filter(e=>e.hint!==void 0||e.focusHint!==void 0).reduce((e,t)=>Math.max(e,t.label.length),0);a.length===0&&c.push(` ${r.dim(`(no matches)`)}`);let g=appendSelectOptionRows({rows:c,state:e,presentation:i,visible:a,start:p,end:m,cursor:s,visibleLabelWidth:h,width:n,theme:t});return appendSubmitRow(c,s,o,t),a.length>m-p&&c.push(` ${r.dim(`↑↓ ${a.length} options, showing ${p+1}–${m}`)}`),g||appendSelectNotices(c,e.notices,i.layout,t,n),e.error!==void 0&&c.push(``,` ${r.red(e.error)}`),c.push(...questionFooter(selectFooterHints(i,a,s),t)),c.map(e=>clip(e,n))}function renderTextQuestion(e,r,i,s){let c=r.colors,l=[];for(let t of e.notices??[]){let e=t.tone===`info`?c.dim(t.text):t.text;l.push(`${toneGlyph(t.tone,r)} ${e}`)}l.push(...e.message.split(`
|
|
4
4
|
`).map(e=>` ${c.bold(e)}`));let u=Math.max(4,i-4),d=e.mask?maskLine(e.editor):e.editor,f=e.editor.text.length===0?e.placeholder:void 0,p=renderInputWithBlockCursor({...visibleLine(f===void 0?d:{text:f,cursor:0},u,r.glyph.ellipsis),visible:s,inverse:c.inverse,render:f===void 0?renderInputText:e=>c.dim(renderInputText(e))});return l.push(` ${p}`),e.error!==void 0&&l.push(``,` ${c.red(e.error)}`),l.push(...questionFooter([`enter to submit`,`esc to cancel`],r)),l.map(e=>clip(e,i))}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{renderAcknowledgeQuestion,renderFlowPanel,renderSelectQuestion,renderTextQuestion};
|