eve 0.26.0 → 0.26.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/src/cli/banner.d.ts +5 -0
  3. package/dist/src/cli/banner.js +1 -1
  4. package/dist/src/cli/dev/tui/blocks.d.ts +56 -8
  5. package/dist/src/cli/dev/tui/blocks.js +7 -7
  6. package/dist/src/cli/dev/tui/diagnostic-presentation.d.ts +2 -0
  7. package/dist/src/cli/dev/tui/diagnostic-presentation.js +3 -2
  8. package/dist/src/cli/dev/tui/file-content-cache.d.ts +35 -0
  9. package/dist/src/cli/dev/tui/file-content-cache.js +3 -0
  10. package/dist/src/cli/dev/tui/line-diff.d.ts +24 -0
  11. package/dist/src/cli/dev/tui/line-diff.js +1 -0
  12. package/dist/src/cli/dev/tui/markdown.d.ts +2 -1
  13. package/dist/src/cli/dev/tui/markdown.js +7 -3
  14. package/dist/src/cli/dev/tui/prompt-placeholder.d.ts +12 -0
  15. package/dist/src/cli/dev/tui/prompt-placeholder.js +1 -0
  16. package/dist/src/cli/dev/tui/question-panel.d.ts +24 -0
  17. package/dist/src/cli/dev/tui/question-panel.js +1 -0
  18. package/dist/src/cli/dev/tui/rail.d.ts +15 -0
  19. package/dist/src/cli/dev/tui/rail.js +1 -0
  20. package/dist/src/cli/dev/tui/runner.d.ts +22 -65
  21. package/dist/src/cli/dev/tui/runner.js +1 -1
  22. package/dist/src/cli/dev/tui/setup-commands.js +1 -1
  23. package/dist/src/cli/dev/tui/setup-issues.js +1 -1
  24. package/dist/src/cli/dev/tui/status-line.js +1 -1
  25. package/dist/src/cli/dev/tui/stream-format.d.ts +16 -3
  26. package/dist/src/cli/dev/tui/stream-format.js +1 -1
  27. package/dist/src/cli/dev/tui/subagent-pump.d.ts +127 -0
  28. package/dist/src/cli/dev/tui/subagent-pump.js +1 -0
  29. package/dist/src/cli/dev/tui/terminal-renderer.d.ts +34 -1
  30. package/dist/src/cli/dev/tui/terminal-renderer.js +11 -10
  31. package/dist/src/cli/dev/tui/test/mock-terminal.d.ts +7 -0
  32. package/dist/src/cli/dev/tui/test/mock-terminal.js +1 -1
  33. package/dist/src/cli/dev/tui/theme.d.ts +16 -2
  34. package/dist/src/cli/dev/tui/theme.js +1 -1
  35. package/dist/src/cli/dev/tui/todo-panel.d.ts +44 -0
  36. package/dist/src/cli/dev/tui/todo-panel.js +1 -0
  37. package/dist/src/cli/dev/tui/tool-block-groups.d.ts +40 -0
  38. package/dist/src/cli/dev/tui/tool-block-groups.js +1 -0
  39. package/dist/src/cli/dev/tui/tool-presentation.d.ts +67 -0
  40. package/dist/src/cli/dev/tui/tool-presentation.js +1 -0
  41. package/dist/src/cli/dev/tui/tool-rows.d.ts +15 -0
  42. package/dist/src/cli/dev/tui/tool-rows.js +2 -0
  43. package/dist/src/cli/dev/tui/turn-clock.d.ts +36 -0
  44. package/dist/src/cli/dev/tui/turn-clock.js +1 -0
  45. package/dist/src/cli/dev/tui/types.d.ts +2 -2
  46. package/dist/src/cli/dev/ui-options.js +1 -1
  47. package/dist/src/client/index.js +1 -1
  48. package/dist/src/client/session.js +1 -1
  49. package/dist/src/compiled/.vendor-stamp.json +2 -1
  50. package/dist/src/compiled/marked/LICENSE.md +44 -0
  51. package/dist/src/compiled/marked/index.d.ts +24 -0
  52. package/dist/src/compiled/marked/index.js +59 -0
  53. package/dist/src/evals/session.js +1 -1
  54. package/dist/src/execution/terminal-session-failure-step.js +1 -1
  55. package/dist/src/harness/tool-loop.js +2 -2
  56. package/dist/src/internal/application/package.js +1 -1
  57. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response-from-manifest.js +1 -1
  58. package/dist/src/internal/nitro/routes/info.js +1 -1
  59. package/dist/src/internal/resolve-model-endpoint-status.d.ts +46 -3
  60. package/dist/src/internal/resolve-model-endpoint-status.js +1 -1
  61. package/dist/src/setup/flows/link.d.ts +13 -3
  62. package/dist/src/setup/flows/link.js +1 -1
  63. package/dist/src/setup/flows/model.d.ts +4 -3
  64. package/dist/src/setup/flows/model.js +1 -1
  65. package/dist/src/setup/flows/provider.d.ts +3 -1
  66. package/dist/src/setup/flows/provider.js +2 -2
  67. package/dist/src/setup/scaffold/create/project.js +1 -1
  68. package/package.json +2 -1
@@ -1 +1 @@
1
- import{PROMPT_COMMANDS,formatPromptCommandHelp,parsePromptCommand}from"./prompt-commands.js";import{pickAgentHeaderTip}from"./agent-header.js";import{probeAgentInfo}from"./agent-info-probe.js";import{failureKey,formatFailureDetail,formatFailureHint,formatFailureMessage,isAbortLikeError,isInterruptedError,localFailureHint}from"./errors.js";import{parseLogDisplayMode}from"./log-display-mode.js";import{createMcpConnectionStatusTracker}from"./mcp-connection-status.js";import{createRemoteConnectionController}from"./remote-connection.js";import{BOOT_DETECTIONS,CLI_MISSING_SETUP_ISSUE,LOGIN_SETUP_ISSUE,detectSetupIssues,formatSetupIssuesLine,orderedSetupIssues,resolveModelProviderState}from"./setup-issues.js";import{TerminalRenderer}from"./terminal-renderer.js";import{createVercelStatusTracker}from"./vercel-status.js";import{isCurrentTurnBoundaryEvent}from"#client/index.js";import{toErrorMessage}from"#shared/errors.js";import{getVercelAuthStatus}from"#setup/vercel-project.js";import{loadDevelopmentEnvironmentFiles}from"#cli/dev/environment.js";import{subscribeDevelopmentSandboxPrewarmLogs}from"#execution/sandbox/development-prewarm.js";import{createDevelopmentRuntimeArtifactRefresher}from"#services/dev-client.js";import{devBootPhase}from"#internal/dev-boot-progress.js";function authIssueForStatus(e){if(e===`logged-out`)return LOGIN_SETUP_ISSUE;if(e===`cli-missing`)return CLI_MISSING_SETUP_ISSUE}var EveTUIRunner=class{#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;#u;#d;#f;#p;#m;#h;#g;#_;#v;#y;#b;#x=!1;#S=new AbortController;#C=!1;#w=[];#T;#E;#D;#O=pickAgentHeaderTip();#k;#A=new Map;#j=new Map;#M=new Map;#N=new Map;#P=new Set;#F=!1;#I;constructor(t){if(this.#e=t.session,t.client!==void 0&&(this.#t=t.client),this.#n=createRenderer(t),this.#r=t.name??`eve`,this.#i=t.tools??`full`,this.#a=t.reasoning??`full`,this.#o=t.subagents??`full`,this.#s=t.connectionAuth??`full`,this.#c=t.assistantResponseStats??`tokensPerSecond`,this.#l=t.contextSize,this.#u=t.formatTransportError??toErrorMessage,t.initialInput!==void 0&&(this.#m=t.initialInput),t.appRoot!==void 0){this.#p=t.appRoot;let e={appRoot:t.appRoot,onChange:e=>this.#n.setVercelStatus?.(e)};t.detectProjectIdentity!==void 0&&(e.detectIdentity=t.detectProjectIdentity),this.#E=createVercelStatusTracker(e),t.probeMcpConnection!==void 0&&(this.#D=createMcpConnectionStatusTracker({onChange:()=>{},probe:t.probeMcpConnection}))}if(t.promptCommandHandler!==void 0&&(this.#h=t.promptCommandHandler),this.#g=t.availablePromptCommands??PROMPT_COMMANDS,t.remote!==void 0){if(this.#t===void 0)throw Error(`A remote TUI requires a configured development client.`);this.#_=createRemoteConnectionController({client:this.#t,credentials:t.remote.credentials,target:t.remote.target,onChange:e=>this.#n.setRemoteConnectionStatus?.(e),resolveOidcToken:t.remote.resolveOidcToken,resolveDeployment:t.remote.resolveDeployment})}this.#v=t.bootDetections??BOOT_DETECTIONS,this.#y=t.getVercelAuthStatus??getVercelAuthStatus,t.onBootProgress!==void 0&&(this.#b=t.onBootProgress),t.serverUrl!==void 0&&(this.#f=t.serverUrl),t.serverUrl!==void 0&&t.remote===void 0&&(this.#d=createDevelopmentRuntimeArtifactRefresher({serverUrl:t.serverUrl}))}async#L(){if(this.#f===void 0){this.#z(),await this.#q(void 0);return}let e;if(this.#_!==void 0){let t=await this.#_.check();t.state===`ready`&&(e=t.info)}else{let t=this.#t;if(t!==void 0)try{let n=await devBootPhase(`connecting to agent`,()=>probeAgentInfo({client:t}),this.#b);n.kind===`ready`&&(e=n.info)}catch{e=void 0}}this.#z();let t=this.#R(e);await this.#q(t)}#R(e){let t=this.#p===void 0?e:resolveModelProviderState(e,process.env);this.#k=t;let n=this.#f;if(n===void 0)return t;let r={name:this.#r,serverUrl:n};return t!==void 0&&(r.info=t),this.#p!==void 0&&(r.tip=this.#O),this.#n.renderAgentHeader?.(r),t}#z(){let e=this.#b;this.#b=void 0,e?.({type:`before-first-paint`})}async run(){try{await this.#B()}finally{this.#x=!0,this.#S.abort(),this.#H(),this.#I?.(),this.#I=void 0,this.#n.shutdown?.(),this.#E?.dispose(),this.#D?.dispose(),this.#_?.dispose()}}async#B(){let e=this.#r,r,i,a=!1,o=!1,s=this.#m;await this.#L(),this.#_?.current().connection.state===`auth-required`&&await this.#re({type:`extension`,name:`vc:login`,argument:``},e,{trigger:`startup`}),this.#Z(),this.#E?.refreshIdentity(),this.#D?.refresh();let c=this.#m===void 0?void 0:parsePromptCommand(this.#m);for(c?.type===`extension`&&c.name===`model`&&c.argument===``&&this.#p!==void 0&&this.#h!==void 0&&this.#n.setupFlow!==void 0&&(s=void 0,await this.#ie(e));;){if(!o){if(r==null){if(!this.#n.readPrompt){if(a)return;throw Error(`No prompt was provided and the renderer does not support prompt input.`)}let t={title:e};s!==void 0&&(t.initialDraft=s,s=void 0);try{r=await this.#U(t)}catch(e){if(isInterruptedError(e))return;throw e}if(r==null)return}let c=parsePromptCommand(r);if(c?.type===`exit`)return;if(c?.type===`new`){this.#V(),i=void 0,o=!1,r=void 0,this.#n.reset?.();continue}if(c?.type===`help`){this.#Q(formatPromptCommandHelp(this.#g)),i=void 0,o=!1,r=void 0;continue}if(c?.type===`loglevel`){this.#Q(this.#oe(c.argument)),i=void 0,o=!1,r=void 0;continue}if(c?.type===`extension`){try{await this.#re(c,e,{trigger:`command`})}catch(e){if(isInterruptedError(e))return;throw e}i=void 0,r=void 0,o=!1;continue}a=!0}let c=await this.#W({prompt:o?void 0:r,inputResponses:i}),l=r,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.#A.delete(n.approvalId)}}if(n.length>0){if(!this.#n.readInputQuestion)throw Error(`An interactive question was requested, but the renderer does not support input questions.`);for(let t of n){let n=toAgentTUIInputQuestion(t),r=await this.#n.readInputQuestion(n,{title:e});if(r===void 0)continue;let i={requestId:t.requestId};r.optionId!==void 0&&(i.optionId=r.optionId),r.text!==void 0&&(i.text=r.text),a.push(i),this.#A.delete(t.requestId)}}o=!0,i=a,r=void 0,d=!0;break}if(this.#de(c)){c=this.#G(),l=void 0;continue}if(c.turnState&&c.turnState.boundaryEvent===void 0)if(c.turnState.aborted)this.#F=!0;else{let e=this.#e.state.sessionId;this.#n.renderNotice?.(e?`Lost the event stream — the turn may still be running on the server (session ${e}). Your next message resumes this session; use /cancel to stop the turn.`:`Lost the connection to the running turn.`)}break}}catch(e){if(isInterruptedError(e))return;throw e}d||(o=!1,i=void 0,r=void 0,this.#F&&(this.#F=!1,this.#V(),this.#n.renderNotice?.(c.turnState?.aborted?`Stopped following the turn and started a new session. Earlier context was cleared; the interrupted turn may still be running on the server.`:`Session ended — started a new session. Earlier context was cleared.`)))}}#V(){this.#H(),this.#j.clear(),this.#A.clear(),this.#N.clear(),this.#P.clear(),this.#n.setConnectionAuthPendingCount?.(0),this.#t&&(this.#e=this.#t.session()),this.#d?.clear()}#H(){for(let e of this.#M.values())e.abort();this.#M.clear()}async#U(e){if(!this.#n.readPrompt)return;let t=this.#n.readPrompt(e),n=this.#d;if(n===void 0)return await t;let r=!1,i=!1,a,refresh=async()=>{if(!(r||i)){i=!0;try{await n.refreshIdle({onRuntimeArtifactsChanged:()=>this.#le()})}finally{i=!1}}},startRefresh=()=>{if(r||i)return;let e=refresh().finally(()=>{a===e&&(a=void 0)});a=e};startRefresh();let o=setInterval(()=>{startRefresh()},500);o.unref?.();try{return await t}finally{r=!0,clearInterval(o),await a}}async#W(e){let t=new AbortController,n={signal:t.signal};e.prompt!==void 0&&(n.message=e.prompt),e.inputResponses!==void 0&&e.inputResponses.length>0&&(n.inputResponses=e.inputResponses);let r;try{this.#d!==void 0&&await this.#d.refresh({inputResponses:n.inputResponses,message:n.message,onRuntimeArtifactsChanged:()=>this.#le()}),n.message!==void 0&&(n.inputResponses?.length??0)===0&&this.#n.flushDelayedDevBuildErrors?.(),r=await this.#e.send(n)}catch(e){if(isInterruptedError(e))throw e;return this.#_?.reportFailure(e),this.#F=!0,{events:errorOnlyTUIStream({errorText:this.#u(e)}),turnState:createTurnState()}}return this.#K(r,()=>t.abort())}#G(){let e=new AbortController;return this.#K(this.#e.stream({signal:e.signal}),()=>e.abort())}#K(e,t){let n=createTurnState();return{abort:()=>{n.aborted=!0,t()},events:eveEventsToTUIStream({events:e,pendingInputRequests:this.#A,subagentRuns:this.#j,turnState:n,onSubagentCalled:e=>this.#me(e),onSubagentCompleted:e=>this.#ge(e),onConnectionAuthRequired:e=>this.#ue(e),onConnectionAuthCompleted:e=>this.#fe(e),onTerminalFailure:()=>{this.#F=!0},failureHintOverride:this.#p===void 0?void 0:localFailureHint}),turnState:n}}async#q(e){if(this.#p===void 0)return;let t={appRoot:this.#p,env:process.env};e!==void 0&&(t.info=e),this.#w=await detectSetupIssues(t,this.#v),this.#n.renderSetupWarning!==void 0&&(this.#J(),this.#Y())}#J(){let e=orderedSetupIssues(this.#w,this.#T);e.length>0?this.#n.renderSetupWarning?.(formatSetupIssuesLine(e)):this.#n.clearSetupWarning?.()}async#Y(){let e=this.#p;if(e===void 0)return;let t;try{t=await this.#y(e,{signal:this.#S.signal})}catch{return}this.#x||this.#C||(this.#T=authIssueForStatus(t),this.#J())}async#X(e){let t=this.#p;if(t===void 0||this.#n.renderSetupWarning===void 0)return;let n={appRoot:t,env:process.env};e!==void 0&&(n.info=e);try{this.#w=await detectSetupIssues(n,this.#v);let e=await this.#y(t,{signal:this.#S.signal});this.#T=authIssueForStatus(e)}catch{return}this.#x||this.#J()}#Z(){this.#p===void 0||this.#n.renderSandboxLog===void 0||this.#I===void 0&&(this.#I=subscribeDevelopmentSandboxPrewarmLogs({appRoot:this.#p,log:e=>this.#n.renderSandboxLog?.(e)}))}#Q(e){if(e!==void 0){if(this.#n.renderCommandResult!==void 0){this.#n.renderCommandResult(e);return}this.#n.renderNotice?.(e)}}async#$(e,t){let n=this.#h;if(n===void 0)return{message:`/${e.name} is not available in this session.`};let r={renderer:this.#n,title:t.title,initialModelStep:t.initialModelStep,remoteConnection:this.#_},i=this.#D?.current(),a=i!==void 0&&Object.keys(i).length>0?{...r,disabledConnectionReasons:i}:r;return t.keepSetupFlowOpen===!0?await n.handle(e,{...a,keepSetupFlowOpen:!0}):await n.handle(e,a)}#ee(e,t){if(t!==`startup`)return;let n=this.#_?.current().connection.state,r=n===`auth-failed`||n===`unavailable`?`failed`:void 0,i=e.argument.length===0?``:` ${e.argument}`;this.#n.renderCommandInvocation?.(`/${e.name}${i}`,r)}async#te(e){if(e?.kind===`connection-added`){this.#E?.applyEffect({kind:`refresh-identity`}),this.#C=!0,await this.#ne(),await this.#se();return}if(e?.kind===`model-access-changed`){this.#E?.applyEffect({kind:`refresh-identity`}),this.#C=!0,await this.#se();return}e!==void 0&&(this.#E?.applyEffect(e),this.#C=!0,this.#X(this.#k))}async#ne(){let e=this.#d;e!==void 0&&await e.refreshAfterSourceChange({onRuntimeArtifactsChanged:()=>this.#le()})}async#re(e,t,n){let r=await this.#$(e,{initialModelStep:n.initialModelStep,keepSetupFlowOpen:n.keepSetupFlowOpen,title:t});this.#ee(e,n.trigger),this.#Q(r?.message),await this.#te(r?.effect),this.#ae()}async#ie(e){let t=this.#p;if(t===void 0)return;let authStatus=async()=>{try{return await this.#y(t,{signal:this.#S.signal})}catch{return}},n=await authStatus();if(n===`cli-missing`&&(await this.#re({type:`extension`,name:`vc:install`,argument:``},e,{trigger:`startup`,keepSetupFlowOpen:!0}),n=await authStatus(),n===`cli-missing`)){this.#n.setupFlow?.end();return}if(n===`logged-out`&&(await this.#re({type:`extension`,name:`vc:login`,argument:``},e,{trigger:`startup`,keepSetupFlowOpen:!0}),n=await authStatus(),n===`cli-missing`||n===`logged-out`)){this.#n.setupFlow?.end();return}await this.#re({type:`extension`,name:`model`,argument:``},e,{trigger:`startup`,initialModelStep:`provider`})}#ae(){let e=this.#_?.current().connection;e?.state!==`ready`||e.info===this.#k||(this.#k=e.info,this.#f!==void 0&&this.#n.renderAgentHeader?.({info:e.info,name:this.#r,serverUrl:this.#f}))}#oe(e){let t=this.#n;if(t.logDisplayMode===void 0||t.setLogDisplayMode===void 0)return`/loglevel is not available in this session.`;if(e===``)return`Logs: ${t.logDisplayMode()}. Use /loglevel all|stderr|sandbox|none — logs stay buffered, so switching also hides or restores past lines.`;let n=parseLogDisplayMode(e);if(n===void 0)return`Unknown log level "${e}". Use all, stderr, sandbox, or none.`;if(n===t.logDisplayMode())return`Logs already set to ${n}.`;switch(t.setLogDisplayMode(n),n){case`none`:return`Logs hidden. Output stays buffered — /loglevel all restores it.`;case`stderr`:return`Showing stderr logs only.`;case`sandbox`:return`Showing sandbox logs only.`;case`all`:return`Showing all logs.`}}async#se(){let e=this.#p;if(e===void 0)return;loadDevelopmentEnvironmentFiles(e);let t=this.#R(await this.#ce());this.#X(t)}async#ce(){let e=this.#t;if(e===void 0)return;let t=await probeAgentInfo({client:e});return t.kind===`ready`?t.info:void 0}async#le(){let e=this.#k,t=await this.#ce();t!==void 0&&this.#R(t),(!this.#n.renderAgentHeader||t===void 0)&&this.#n.renderNotice?.(formatAgentUpdateNotice(e,t))}#ue(e){let t={name:e.data.name,description:e.data.description,state:`required`};e.data.authorization!==void 0&&(t.challenge=e.data.authorization),e.data.webhookUrl!==void 0&&(t.webhookUrl=e.data.webhookUrl),this.#N.set(e.data.name,t),this.#pe(t)}#de(e){if(e.turnState?.boundaryEvent!==`session.waiting`)return!1;let t=!1;for(let e of this.#N.values())e.state!==`required`||e.webhookUrl===void 0||(e.state=`pending`,this.#P.add(e.name),this.#pe(e),t=!0);return t&&this.#n.setConnectionAuthPendingCount?.(this.#P.size),this.#P.size>0}#fe(e){let t=this.#N.get(e.data.name)??{name:e.data.name,description:``,state:e.data.outcome};t.state=e.data.outcome,e.data.reason!==void 0&&(t.reason=e.data.reason),this.#N.set(e.data.name,t),this.#P.delete(e.data.name),this.#pe(t),this.#n.setConnectionAuthPendingCount?.(this.#P.size)}#pe(e){let t={name:e.name,description:e.description,state:e.state};e.challenge!==void 0&&(t.challenge=e.challenge),e.reason!==void 0&&(t.reason=e.reason),this.#n.upsertConnectionAuth?.(t)}#me(e){let t=e.data.callId;if(this.#M.has(t))return;let n=this.#t;if(!n)return;let r=new AbortController;this.#M.set(t,r),(async()=>{try{let i=n.session({sessionId:e.data.childSessionId,streamIndex:0}).stream({signal:r.signal});for await(let e of i)if(r.signal.aborted||(this.#_e(t,e),isCurrentTurnBoundaryEvent(e)))break}catch(e){if(!isAbortLikeError(e)){let n=toErrorMessage(e),r=this.#j.get(t);if(r){let{key:e,step:i}=openCurrentSubagentSection(r);i.message=i.message?`${i.message}\n\nstream error: ${n}`:`stream error: ${n}`,i.finalized=!0,r.currentSectionKey=null,this.#n.upsertSubagentStep?.({callId:t,subagentName:r.name,sectionKey:e,reasoning:i.reasoning,message:i.message,finalized:!0})}}}finally{this.#M.delete(t)}})()}#he(e,t,n){let r=t.tools.get(n.childCallId),i=r??{toolName:n.toolName,input:n.input,status:n.status};if(r){let e={"approval-requested":0,executing:1,done:2,failed:2};e[n.status]>e[r.status]&&(r.status=n.status),r.input=n.input}else t.tools.set(n.childCallId,i);this.#n.markChildToolCallId?.(n.childCallId),this.#n.upsertSubagentTool?.({callId:e,subagentName:t.name,childCallId:n.childCallId,toolName:i.toolName,input:i.input,status:i.status})}#ge(e){let t=this.#j.get(e);if(t){for(let[n,r]of t.steps)r.finalized||(r.finalized=!0,this.#n.upsertSubagentStep?.({callId:e,subagentName:t.name,sectionKey:n,reasoning:r.reasoning,message:r.message,finalized:!0}));t.currentSectionKey=null}}#_e(e,t){let n=this.#j.get(e);if(!n)return;let r=this.#n,emit=(t,i)=>{r.upsertSubagentStep?.({callId:e,subagentName:n.name,sectionKey:t,reasoning:i.reasoning,message:i.message,finalized:i.finalized})},finalizeCurrent=()=>{if(n.currentSectionKey===null)return;let e=n.steps.get(n.currentSectionKey);e&&(e.finalized=!0,emit(n.currentSectionKey,e)),n.currentSectionKey=null};switch(t.type){case`reasoning.appended`:{let{key:e,step:r}=openCurrentSubagentSection(n);r.reasoning+=t.data.reasoningDelta,emit(e,r);break}case`reasoning.completed`:break;case`message.appended`:{let{key:e,step:r}=openCurrentSubagentSection(n);r.message+=t.data.messageDelta,emit(e,r);break}case`message.completed`:{let{key:e,step:r}=openCurrentSubagentSection(n);t.data.message!==null&&r.message.length===0&&(r.message=t.data.message),r.finalized=!0,emit(e,r),n.currentSectionKey=null;break}case`step.completed`:finalizeCurrent();break;case`actions.requested`:finalizeCurrent();for(let r of t.data.actions)r.kind===`tool-call`&&this.#he(e,n,{childCallId:r.callId,toolName:r.toolName,input:r.input,status:`executing`});break;case`input.requested`:finalizeCurrent();for(let r of t.data.requests)r.action.kind===`tool-call`&&this.#he(e,n,{childCallId:r.action.callId,toolName:r.action.toolName,input:r.action.input,status:`approval-requested`});break;case`action.result`:{let i=t.data.result;if(i.kind!==`tool-result`)break;let a=n.tools.get(i.callId);if(!a)break;t.data.status===`failed`?(a.status=`failed`,a.errorText=formatActionResultError(t)):(a.status=`done`,a.output=i.output);let o={callId:e,subagentName:n.name,childCallId:i.callId,toolName:a.toolName,input:a.input,status:a.status};a.output!==void 0&&(o.output=a.output),a.errorText!==void 0&&(o.errorText=a.errorText),r.upsertSubagentTool?.(o);break}default:break}}};function createRenderer(e){return e.renderer?e.renderer:new TerminalRenderer({tools:e.tools,reasoning:e.reasoning,subagents:e.subagents,connectionAuth:e.connectionAuth,assistantResponseStats:e.assistantResponseStats,contextSize:e.contextSize,logs:e.logs,availablePromptCommands:e.availablePromptCommands,input:e.userInput,output:e.screen,diagnostics:e.diagnostics})}function formatAgentUpdateNotice(e,t){let n=e?.agent.model.id,r=t?.agent.model.id;return n!==void 0&&r!==void 0&&n!==r?`Agent updated: Model ${n} -> ${r}`:`Agent updated.`}async function*eveEventsToTUIStream(e){let{events:t,pendingInputRequests:n,subagentRuns:r,turnState:i,onSubagentCalled:a,onSubagentCompleted:o,onConnectionAuthRequired:s,onConnectionAuthCompleted:c,onTerminalFailure:l,failureHintOverride: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{aborted:!1,pendingApprovals:[],pendingQuestions:[],sawSessionFailure:!1}}function upsertPendingApproval(e,t){let n=toAgentTUIToolApprovalRequest(t),r=e.pendingApprovals.findIndex(e=>e.approvalId===n.approvalId);r===-1?e.pendingApprovals.push(n):e.pendingApprovals[r]=n}function toAgentTUIToolApprovalRequest(e){return{approvalId:e.requestId,toolCallId:e.action.callId,toolName:e.action.toolName,input:e.action.input}}function upsertPendingQuestion(e,t){let n=e.pendingQuestions.findIndex(e=>e.requestId===t.requestId);n===-1?e.pendingQuestions.push(t):e.pendingQuestions[n]=t}function textPartId(e,t){return`text:${e}:${t}`}function reasoningPartId(e,t){return`reasoning:${e}:${t}`}function partStateFor(e,t){let n=e.get(t);return n===void 0&&(n={generation:0,text:``,completed:!1,completedEpoch:0},e.set(t,n)),n}function partGenerationId(e,t){return t===0?e:`${e}#${t}`}function*closeOpenParts(e,t,n){for(let[r,i]of e)i.completed||i.text.length===0||(i.completed=!0,i.completedEpoch=n,yield{type:t,id:partGenerationId(r,i.generation)})}function isPostTurnVisibleEvent(e){switch(e.type){case`actions.requested`:case`authorization.completed`:case`authorization.required`:case`input.requested`:case`message.appended`:case`message.completed`:case`reasoning.appended`:case`reasoning.completed`:case`result.completed`:case`step.completed`:case`step.failed`:case`step.started`:case`subagent.called`:case`subagent.completed`:case`subagent.event`:case`subagent.started`:case`turn.completed`:case`turn.failed`:return!0;default:return!1}}function formatActionResultError(e){if(e.data.error?.message)return e.data.error.message;let t=e.data.result.output;if(typeof t==`string`)return t;try{return JSON.stringify(t)}catch{return`Tool execution failed.`}}function toFailureEvent(e,t,n){let r=failureKey(e);if(t.has(r))return;t.add(r);let i={type:`error`,errorText:formatFailureMessage(e)},l=n?.(e)??formatFailureHint(e);l!==void 0&&(i.hint=l);let u=formatFailureDetail(e);return u!==void 0&&(i.detail=u),i}function isQuestionRequest(e){return e.display===`select`||e.display===`text`?!0:e.display===`confirmation`?!1:e.options!==void 0&&e.options.length>0}function toAgentTUIInputQuestion(e){let t=e.display===`text`?`text`:e.display===`select`||e.options!==void 0&&e.options.length>0?`select`:`text`,n={requestId:e.requestId,prompt:e.prompt,display:t};return e.options!==void 0&&(n.options=e.options.map(e=>{let t={id:e.id,label:e.label};return e.description!==void 0&&(t.description=e.description),e.style!==void 0&&(t.style=e.style),t})),e.allowFreeform!==void 0&&(n.allowFreeform=e.allowFreeform),n}function openCurrentSubagentSection(e){e.currentSectionKey===null&&(e.currentSectionKey=e.nextSectionKey++,e.steps.set(e.currentSectionKey,{reasoning:``,message:``,finalized:!1}));let t=e.steps.get(e.currentSectionKey);if(!t)throw Error(`invariant: subagent section state missing for current key`);return{key:e.currentSectionKey,step:t}}export{EveTUIRunner,parsePromptCommand};
1
+ import{PROMPT_COMMANDS,formatPromptCommandHelp,parsePromptCommand}from"./prompt-commands.js";import{pickAgentHeaderTip}from"./agent-header.js";import{probeAgentInfo}from"./agent-info-probe.js";import{failureKey,formatFailureDetail,formatFailureHint,formatFailureMessage,isInterruptedError,localFailureHint}from"./errors.js";import{parseLogDisplayMode}from"./log-display-mode.js";import{createMcpConnectionStatusTracker}from"./mcp-connection-status.js";import{createRemoteConnectionController}from"./remote-connection.js";import{SubagentPump}from"./subagent-pump.js";import{BOOT_DETECTIONS,CLI_MISSING_SETUP_ISSUE,LOGIN_SETUP_ISSUE,detectSetupIssues,formatSetupIssuesLine,orderedSetupIssues,resolveModelProviderState}from"./setup-issues.js";import{TerminalRenderer}from"./terminal-renderer.js";import{createVercelStatusTracker}from"./vercel-status.js";import"#client/index.js";import{toErrorMessage}from"#shared/errors.js";import{getVercelAuthStatus}from"#setup/vercel-project.js";import{loadDevelopmentEnvironmentFiles}from"#cli/dev/environment.js";import{subscribeDevelopmentSandboxPrewarmLogs}from"#execution/sandbox/development-prewarm.js";import{createDevelopmentRuntimeArtifactRefresher}from"#services/dev-client.js";import{devBootPhase}from"#internal/dev-boot-progress.js";function authIssueForStatus(e){if(e===`logged-out`)return LOGIN_SETUP_ISSUE;if(e===`cli-missing`)return CLI_MISSING_SETUP_ISSUE}var EveTUIRunner=class{#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;#u;#d;#f;#p;#m;#h;#g;#_;#v;#y;#b;#x=!1;#S=new AbortController;#C=!1;#w=[];#T;#E;#D;#O=pickAgentHeaderTip();#k;#A=new Map;#j;#M=new Map;#N=new Set;#P=!1;#F;constructor(t){this.#e=t.session,t.client!==void 0&&(this.#t=t.client),this.#n=createRenderer(t);let n={formatActionResultError};if(this.#t!==void 0&&(n.client=this.#t),this.#n.subagents!==void 0&&(n.view=this.#n.subagents),this.#j=new SubagentPump(n),this.#r=t.name??`eve`,this.#i=t.tools??`full`,this.#a=t.reasoning??`full`,this.#o=t.subagents??`full`,this.#s=t.connectionAuth??`full`,this.#c=t.assistantResponseStats??`tokensPerSecond`,this.#l=t.contextSize,this.#u=t.formatTransportError??toErrorMessage,t.initialInput!==void 0&&(this.#m=t.initialInput),t.appRoot!==void 0){this.#p=t.appRoot;let e={appRoot:t.appRoot,onChange:e=>this.#n.setVercelStatus?.(e)};t.detectProjectIdentity!==void 0&&(e.detectIdentity=t.detectProjectIdentity),this.#E=createVercelStatusTracker(e),t.probeMcpConnection!==void 0&&(this.#D=createMcpConnectionStatusTracker({onChange:()=>{},probe:t.probeMcpConnection}))}if(t.promptCommandHandler!==void 0&&(this.#h=t.promptCommandHandler),this.#g=t.availablePromptCommands??PROMPT_COMMANDS,t.remote!==void 0){if(this.#t===void 0)throw Error(`A remote TUI requires a configured development client.`);this.#_=createRemoteConnectionController({client:this.#t,credentials:t.remote.credentials,target:t.remote.target,onChange:e=>this.#n.setRemoteConnectionStatus?.(e),resolveOidcToken:t.remote.resolveOidcToken,resolveDeployment:t.remote.resolveDeployment})}this.#v=t.bootDetections??BOOT_DETECTIONS,this.#y=t.getVercelAuthStatus??getVercelAuthStatus,t.onBootProgress!==void 0&&(this.#b=t.onBootProgress),t.serverUrl!==void 0&&(this.#f=t.serverUrl),t.serverUrl!==void 0&&t.remote===void 0&&(this.#d=createDevelopmentRuntimeArtifactRefresher({serverUrl:t.serverUrl}))}async#I(){if(this.#f===void 0){this.#R(),await this.#G(void 0);return}let e;if(this.#_!==void 0){let t=await this.#_.check();t.state===`ready`&&(e=t.info)}else{let t=this.#t;if(t!==void 0)try{let n=await devBootPhase(`connecting to agent`,()=>probeAgentInfo({client:t}),this.#b);n.kind===`ready`&&(e=n.info)}catch{e=void 0}}this.#R();let t=this.#L(e);await this.#G(t)}#L(e){let t=this.#p===void 0?e:resolveModelProviderState(e,process.env);this.#k=t;let n=this.#f;if(n===void 0)return t;let r={name:this.#r,serverUrl:n};return t!==void 0&&(r.info=t),this.#p!==void 0&&(r.tip=this.#O),this.#n.renderAgentHeader?.(r),t}#R(){let e=this.#b;this.#b=void 0,e?.({type:`before-first-paint`})}async run(){try{await this.#z()}finally{this.#x=!0,this.#S.abort(),this.#j.abortAll(),this.#F?.(),this.#F=void 0,this.#n.shutdown?.(),this.#E?.dispose(),this.#D?.dispose(),this.#_?.dispose()}}async#z(){let e=this.#r,r,i,a=!1,o=!1,s=this.#m;await this.#I(),this.#_?.current().connection.state===`auth-required`&&await this.#te({type:`extension`,name:`vc:login`,argument:``},e,{trigger:`startup`}),this.#Y(),this.#E?.refreshIdentity(),this.#D?.refresh();let c=this.#m===void 0?void 0:parsePromptCommand(this.#m);for(c?.type===`extension`&&c.name===`model`&&c.argument===``&&this.#p!==void 0&&this.#h!==void 0&&this.#n.setupFlow!==void 0&&(s=void 0,await this.#ne(e));;){if(!o){if(r==null){if(!this.#n.readPrompt){if(a)return;throw Error(`No prompt was provided and the renderer does not support prompt input.`)}let t={title:e};s!==void 0&&(t.initialDraft=s,s=void 0);try{r=await this.#V(t)}catch(e){if(isInterruptedError(e))return;throw e}if(r==null)return}let c=parsePromptCommand(r);if(c?.type===`exit`)return;if(c?.type===`new`){this.#B(),i=void 0,o=!1,r=void 0,this.#n.reset?.();continue}if(c?.type===`help`){this.#X(formatPromptCommandHelp(this.#g)),i=void 0,o=!1,r=void 0;continue}if(c?.type===`loglevel`){this.#X(this.#ie(c.argument)),i=void 0,o=!1,r=void 0;continue}if(c?.type===`extension`){try{await this.#te(c,e,{trigger:`command`})}catch(e){if(isInterruptedError(e))return;throw e}i=void 0,r=void 0,o=!1;continue}a=!0}let c=await this.#H({prompt:o?void 0:r,inputResponses:i}),u=r,d=!1;try{for(;;){await this.#n.renderStream(c,{title:e,submittedPrompt:u,continueSession:!!this.#n.readPrompt,tools:this.#i,reasoning:this.#a,subagents:this.#o,connectionAuth:this.#s,assistantResponseStats:this.#c,contextSize:this.#l});let t=c.turnState?.pendingApprovals??[],n=c.turnState?.pendingQuestions??[];if(t.length>0||n.length>0){let a=[];if(t.length>0){if(!this.#n.readToolApproval)throw Error(`Tool approval was requested, but the renderer does not support tool approval input.`);for(let n of t){let t=await this.#n.readToolApproval(n,{title:e});a.push({requestId:n.approvalId,optionId:t.approved?`approve`:`deny`}),this.#A.delete(n.approvalId)}}if(n.length>0){if(!this.#n.readInputQuestion)throw Error(`An interactive question was requested, but the renderer does not support input questions.`);for(let t of n){let n=toAgentTUIInputQuestion(t),r=await this.#n.readInputQuestion(n,{title:e});if(r===void 0)continue;let i={requestId:t.requestId};r.optionId!==void 0&&(i.optionId=r.optionId),r.text!==void 0&&(i.text=r.text),a.push(i),this.#A.delete(t.requestId)}}if(a.length===0)break;o=!0,i=a,r=void 0,d=!0;break}if(this.#le(c)){c=this.#U(),u=void 0;continue}if(c.turnState&&c.turnState.boundaryEvent===void 0)if(c.turnState.aborted)this.#P=!0;else{let e=this.#e.state.sessionId;this.#n.renderNotice?.(e?`Lost the event stream — the turn may still be running on the server (session ${e}). Your next message resumes this session; use /cancel to stop the turn.`:`Lost the connection to the running turn.`)}break}}catch(e){if(isInterruptedError(e))return;throw e}d||(o=!1,i=void 0,r=void 0,this.#P&&(this.#P=!1,this.#B(),c.turnState?.aborted?this.#n.renderNotice?.(`Stopped following the turn and started a new session. Earlier context was cleared; the interrupted turn may still be running on the server.`):this.#n.renderSessionBoundary===void 0?this.#n.renderNotice?.(`Session ended — started a new session. Earlier context was cleared.`):this.#n.renderSessionBoundary()))}}#B(){this.#j.abortAll(),this.#A.clear(),this.#M.clear(),this.#N.clear(),this.#n.setConnectionAuthPendingCount?.(0),this.#t&&(this.#e=this.#t.session()),this.#d?.clear()}async#V(e){if(!this.#n.readPrompt)return;let t=this.#n.readPrompt(e),n=this.#d;if(n===void 0)return await t;let r=!1,i=!1,a,refresh=async()=>{if(!(r||i)){i=!0;try{await n.refreshIdle({onRuntimeArtifactsChanged:()=>this.#se()})}finally{i=!1}}},startRefresh=()=>{if(r||i)return;let e=refresh().finally(()=>{a===e&&(a=void 0)});a=e};startRefresh();let o=setInterval(()=>{startRefresh()},500);o.unref?.();try{return await t}finally{r=!0,clearInterval(o),await a}}async#H(e){let t=new AbortController,n={signal:t.signal};e.prompt!==void 0&&(n.message=e.prompt),e.inputResponses!==void 0&&e.inputResponses.length>0&&(n.inputResponses=e.inputResponses);let r;try{this.#d!==void 0&&await this.#d.refresh({inputResponses:n.inputResponses,message:n.message,onRuntimeArtifactsChanged:()=>this.#se()}),n.message!==void 0&&(n.inputResponses?.length??0)===0&&this.#n.flushDelayedDevBuildErrors?.(),r=await this.#e.send(n)}catch(e){if(isInterruptedError(e))throw e;return this.#_?.reportFailure(e),this.#P=!0,{events:errorOnlyTUIStream({errorText:this.#u(e)}),turnState:createTurnState()}}return this.#W(r,()=>t.abort())}#U(){let e=new AbortController;return this.#W(this.#e.stream({signal:e.signal}),()=>e.abort())}#W(e,t){let n=createTurnState();return{abort:()=>{n.aborted=!0,t()},events:eveEventsToTUIStream({events:e,pendingInputRequests:this.#A,turnState:n,onSubagentCalled:e=>this.#j.begin(e),onSubagentCompleted:e=>this.#j.settle(e),onConnectionAuthRequired:e=>this.#ce(e),onConnectionAuthCompleted:e=>this.#ue(e),onTerminalFailure:()=>{this.#P=!0},failureHintOverride:this.#p===void 0?void 0:localFailureHint}),turnState:n}}async#G(e){if(this.#p===void 0)return;let t={appRoot:this.#p,env:process.env};e!==void 0&&(t.info=e),this.#w=await detectSetupIssues(t,this.#v),this.#n.renderSetupWarning!==void 0&&(this.#K(),this.#q())}#K(){let e=orderedSetupIssues(this.#w,this.#T);e.length>0?this.#n.renderSetupWarning?.(formatSetupIssuesLine(e)):this.#n.clearSetupWarning?.()}async#q(){let e=this.#p;if(e===void 0)return;let t;try{t=await this.#y(e,{signal:this.#S.signal})}catch{return}this.#x||this.#C||(this.#T=authIssueForStatus(t),this.#K())}async#J(e){let t=this.#p;if(t===void 0||this.#n.renderSetupWarning===void 0)return;let n={appRoot:t,env:process.env};e!==void 0&&(n.info=e);try{this.#w=await detectSetupIssues(n,this.#v);let e=await this.#y(t,{signal:this.#S.signal});this.#T=authIssueForStatus(e)}catch{return}this.#x||this.#K()}#Y(){this.#p===void 0||this.#n.renderSandboxLog===void 0||this.#F===void 0&&(this.#F=subscribeDevelopmentSandboxPrewarmLogs({appRoot:this.#p,log:e=>this.#n.renderSandboxLog?.(e)}))}#X(e){if(e!==void 0){if(this.#n.renderCommandResult!==void 0){this.#n.renderCommandResult(e);return}this.#n.renderNotice?.(e)}}async#Z(e,t){let n=this.#h;if(n===void 0)return{message:`/${e.name} is not available in this session.`};let r={renderer:this.#n,title:t.title,initialModelStep:t.initialModelStep,remoteConnection:this.#_},i=this.#D?.current(),a=i!==void 0&&Object.keys(i).length>0?{...r,disabledConnectionReasons:i}:r;return t.keepSetupFlowOpen===!0?await n.handle(e,{...a,keepSetupFlowOpen:!0}):await n.handle(e,a)}#Q(e,t){if(t!==`startup`)return;let n=this.#_?.current().connection.state,r=n===`auth-failed`||n===`unavailable`?`failed`:void 0,i=e.argument.length===0?``:` ${e.argument}`;this.#n.renderCommandInvocation?.(`/${e.name}${i}`,r)}async#$(e){if(e?.kind===`connection-added`){this.#E?.applyEffect({kind:`refresh-identity`}),this.#C=!0,await this.#ee(),await this.#ae();return}if(e?.kind===`model-access-changed`){this.#E?.applyEffect({kind:`refresh-identity`}),this.#C=!0,await this.#ae();return}e!==void 0&&(this.#E?.applyEffect(e),this.#C=!0,this.#J(this.#k))}async#ee(){let e=this.#d;e!==void 0&&await e.refreshAfterSourceChange({onRuntimeArtifactsChanged:()=>this.#se()})}async#te(e,t,n){let r=await this.#Z(e,{initialModelStep:n.initialModelStep,keepSetupFlowOpen:n.keepSetupFlowOpen,title:t});this.#Q(e,n.trigger),this.#X(r?.message),await this.#$(r?.effect),this.#re()}async#ne(e){let t=this.#p;if(t===void 0)return;let authStatus=async()=>{try{return await this.#y(t,{signal:this.#S.signal})}catch{return}},n=await authStatus();if(n===`cli-missing`&&(await this.#te({type:`extension`,name:`vc:install`,argument:``},e,{trigger:`startup`,keepSetupFlowOpen:!0}),n=await authStatus(),n===`cli-missing`)){this.#n.setupFlow?.end();return}if(n===`logged-out`&&(await this.#te({type:`extension`,name:`vc:login`,argument:``},e,{trigger:`startup`,keepSetupFlowOpen:!0}),n=await authStatus(),n===`cli-missing`||n===`logged-out`)){this.#n.setupFlow?.end();return}await this.#te({type:`extension`,name:`model`,argument:``},e,{trigger:`startup`,initialModelStep:`provider`})}#re(){let e=this.#_?.current().connection;e?.state!==`ready`||e.info===this.#k||(this.#k=e.info,this.#f!==void 0&&this.#n.renderAgentHeader?.({info:e.info,name:this.#r,serverUrl:this.#f}))}#ie(e){let t=this.#n;if(t.logDisplayMode===void 0||t.setLogDisplayMode===void 0)return`/loglevel is not available in this session.`;if(e===``)return`Logs: ${t.logDisplayMode()}. Use /loglevel all|stderr|sandbox|none — logs stay buffered, so switching also hides or restores past lines.`;let n=parseLogDisplayMode(e);if(n===void 0)return`Unknown log level "${e}". Use all, stderr, sandbox, or none.`;if(n===t.logDisplayMode())return`Logs already set to ${n}.`;switch(t.setLogDisplayMode(n),n){case`none`:return`Logs hidden. Output stays buffered — /loglevel all restores it.`;case`stderr`:return`Showing stderr logs only.`;case`sandbox`:return`Showing sandbox logs only.`;case`all`:return`Showing all logs.`}}async#ae(){let e=this.#p;if(e===void 0)return;loadDevelopmentEnvironmentFiles(e);let t=this.#L(await this.#oe());this.#J(t)}async#oe(){let e=this.#t;if(e===void 0)return;let t=await probeAgentInfo({client:e});return t.kind===`ready`?t.info:void 0}async#se(){let e=this.#k,t=await this.#oe();t!==void 0&&this.#L(t),(!this.#n.renderAgentHeader||t===void 0)&&this.#n.renderNotice?.(formatAgentUpdateNotice(e,t))}#ce(e){let t={name:e.data.name,description:e.data.description,state:`required`};e.data.authorization!==void 0&&(t.challenge=e.data.authorization),e.data.webhookUrl!==void 0&&(t.webhookUrl=e.data.webhookUrl),this.#M.set(e.data.name,t),this.#de(t)}#le(e){if(e.turnState?.boundaryEvent!==`session.waiting`)return!1;let t=!1;for(let e of this.#M.values())e.state!==`required`||e.webhookUrl===void 0||(e.state=`pending`,this.#N.add(e.name),this.#de(e),t=!0);return t&&this.#n.setConnectionAuthPendingCount?.(this.#N.size),this.#N.size>0}#ue(e){let t=this.#M.get(e.data.name)??{name:e.data.name,description:``,state:e.data.outcome};t.state=e.data.outcome,e.data.reason!==void 0&&(t.reason=e.data.reason),this.#M.set(e.data.name,t),this.#N.delete(e.data.name),this.#de(t),this.#n.setConnectionAuthPendingCount?.(this.#N.size)}#de(e){let t={name:e.name,description:e.description,state:e.state};e.challenge!==void 0&&(t.challenge=e.challenge),e.reason!==void 0&&(t.reason=e.reason),this.#n.upsertConnectionAuth?.(t)}};function createRenderer(e){return e.renderer?e.renderer:new TerminalRenderer({tools:e.tools,reasoning:e.reasoning,subagents:e.subagents,connectionAuth:e.connectionAuth,assistantResponseStats:e.assistantResponseStats,contextSize:e.contextSize,logs:e.logs,availablePromptCommands:e.availablePromptCommands,input:e.userInput,output:e.screen,diagnostics:e.diagnostics})}function formatAgentUpdateNotice(e,t){let n=e?.agent.model.id,r=t?.agent.model.id;return n!==void 0&&r!==void 0&&n!==r?`Agent updated: Model ${n} -> ${r}`:`Agent updated.`}async function*eveEventsToTUIStream(e){let{events:t,pendingInputRequests:n,turnState:r,onSubagentCalled:i,onSubagentCompleted:a,onConnectionAuthRequired:o,onConnectionAuthCompleted:s,onTerminalFailure:c,failureHintOverride:l}=e,u=new Map,d=new Map,f=0,p=new Set,m=new Set,h=new Set,g=!1,_=!1,v;for await(let e of t)if(!(_&&isPostTurnVisibleEvent(e)))switch(e.type){case`session.started`:case`turn.started`:case`message.received`:break;case`step.started`:f+=1,yield{type:`step-start`};break;case`step.completed`:{let t=e;v=t.data.usage,yield*closeOpenParts(u,`assistant-complete`,f),yield*closeOpenParts(d,`reasoning-complete`,f),yield{type:`step-finish`,usage:t.data.usage};break}case`message.appended`:{let t=e,n=textPartId(t.data.turnId,t.data.stepIndex),r=partStateFor(u,n),i=t.data.messageSoFar;if(r.completed){if(r.text.startsWith(i)||f<=r.completedEpoch)break;r.generation+=1,r.text=``,r.completed=!1}if(!i.startsWith(r.text)||i.length<=r.text.length)break;let a=i.slice(r.text.length);r.text=i,yield{type:`assistant-delta`,id:partGenerationId(n,r.generation),delta:a};break}case`message.completed`:{let t=textPartId(e.data.turnId,e.data.stepIndex),n=partStateFor(u,t),r=e.data.message;if(n.completed){if(r===null||r===n.text||f<=n.completedEpoch)break;n.generation+=1,n.text=r,n.completedEpoch=f,yield{type:`assistant-complete`,id:partGenerationId(t,n.generation),text:r};break}let i=partGenerationId(t,n.generation);if(r!==null){if(n.text.length===0)n.text=r,n.completed=!0,n.completedEpoch=f,yield{type:`assistant-complete`,id:i,text:r};else if(r.startsWith(n.text)){let e=r.slice(n.text.length);e.length>0&&(yield{type:`assistant-delta`,id:i,delta:e}),n.text=r,n.completed=!0,n.completedEpoch=f,yield{type:`assistant-complete`,id:i}}}else n.text.length>0&&(n.completed=!0,n.completedEpoch=f,yield{type:`assistant-complete`,id:i});break}case`reasoning.appended`:{let t=e,n=reasoningPartId(t.data.turnId,t.data.stepIndex),r=partStateFor(d,n),i=t.data.reasoningSoFar;if(r.completed){if(r.text.startsWith(i)||f<=r.completedEpoch)break;r.generation+=1,r.text=``,r.completed=!1}if(!i.startsWith(r.text)||i.length<=r.text.length)break;let a=i.slice(r.text.length);r.text=i,yield{type:`reasoning-delta`,id:partGenerationId(n,r.generation),delta:a};break}case`reasoning.completed`:{let t=reasoningPartId(e.data.turnId,e.data.stepIndex),n=partStateFor(d,t),r=e.data.reasoning;if(n.completed){if(r.length===0||r===n.text||n.text.startsWith(r)||f<=n.completedEpoch)break;n.generation+=1,n.text=r,n.completedEpoch=f;let e=partGenerationId(t,n.generation);yield{type:`reasoning-delta`,id:e,delta:r},yield{type:`reasoning-complete`,id:e};break}let i=partGenerationId(t,n.generation);if(n.text.length===0&&r.length>0)n.text=r,yield{type:`reasoning-delta`,id:i,delta:r};else if(r.length>0&&!r.startsWith(n.text))break;n.completed=!0,n.completedEpoch=f,yield{type:`reasoning-complete`,id:i};break}case`actions.requested`:{let t=e.data.actions.filter(e=>e.kind===`tool-call`);if(t.length===0)break;for(let e of t)p.has(e.callId)||(p.add(e.callId),yield{type:`tool-call`,toolCallId:e.callId,toolName:e.toolName,input:e.input});break}case`input.requested`:{let t=e.data.requests.filter(e=>e.action.kind===`tool-call`);if(t.length===0)break;for(let e of t){let t=e.action.callId;if(p.has(t)||(p.add(t),yield{type:`tool-call`,toolCallId:t,toolName:e.action.toolName,input:e.action.input}),!m.has(e.requestId)){if(m.add(e.requestId),n.set(e.requestId,e),isQuestionRequest(e)){upsertPendingQuestion(r,e);continue}upsertPendingApproval(r,e),yield{type:`tool-approval-request`,approvalId:e.requestId,toolCallId:t}}}break}case`action.result`:{let t=e;if(t.data.result.kind!==`tool-result`)break;let n=t.data.result.callId;if(!p.has(n))break;switch(t.data.status){case`completed`:yield{type:`tool-result`,toolCallId:n,output:t.data.result.output};break;case`failed`:yield{type:`tool-error`,toolCallId:n,errorText:formatActionResultError(t)};break;case`rejected`:yield{type:`tool-rejected`,toolCallId:n,reason:formatActionResultError(t)};break}break}case`step.failed`:case`turn.failed`:{let t=toFailureEvent(e,h,l);t&&(yield t);break}case`session.failed`:{r.sawSessionFailure=!0,c?.(e);let t=toFailureEvent(e,h,l);t&&(yield t),r.boundaryEvent=e.type,yield*closeOpenParts(u,`assistant-complete`,f),yield*closeOpenParts(d,`reasoning-complete`,f),yield{type:`finish`,usage:v},g=!0;return}case`session.waiting`:case`session.completed`:r.boundaryEvent=e.type,yield*closeOpenParts(u,`assistant-complete`,f),yield*closeOpenParts(d,`reasoning-complete`,f),yield{type:`finish`,usage:v},g=!0;return;case`turn.completed`:_=!0,yield*closeOpenParts(u,`assistant-complete`,f),yield*closeOpenParts(d,`reasoning-complete`,f);break;case`subagent.called`:i?.(e);break;case`subagent.started`:case`subagent.event`:break;case`subagent.completed`:a?.(e.data.callId);break;case`authorization.required`:o?.(e);break;case`authorization.completed`:s?.(e);break;default:break}g||(yield*closeOpenParts(u,`assistant-complete`,f),yield*closeOpenParts(d,`reasoning-complete`,f),yield{type:`finish`,usage:v})}async function*errorOnlyTUIStream(e){yield{type:`error`,errorText:e.errorText},yield{type:`finish`}}function createTurnState(){return{aborted:!1,pendingApprovals:[],pendingQuestions:[],sawSessionFailure:!1}}function upsertPendingApproval(e,t){let n=toAgentTUIToolApprovalRequest(t),r=e.pendingApprovals.findIndex(e=>e.approvalId===n.approvalId);r===-1?e.pendingApprovals.push(n):e.pendingApprovals[r]=n}function toAgentTUIToolApprovalRequest(e){return{approvalId:e.requestId,toolCallId:e.action.callId,toolName:e.action.toolName,input:e.action.input}}function upsertPendingQuestion(e,t){let n=e.pendingQuestions.findIndex(e=>e.requestId===t.requestId);n===-1?e.pendingQuestions.push(t):e.pendingQuestions[n]=t}function textPartId(e,t){return`text:${e}:${t}`}function reasoningPartId(e,t){return`reasoning:${e}:${t}`}function partStateFor(e,t){let n=e.get(t);return n===void 0&&(n={generation:0,text:``,completed:!1,completedEpoch:0},e.set(t,n)),n}function partGenerationId(e,t){return t===0?e:`${e}#${t}`}function*closeOpenParts(e,t,n){for(let[r,i]of e)i.completed||i.text.length===0||(i.completed=!0,i.completedEpoch=n,yield{type:t,id:partGenerationId(r,i.generation)})}function isPostTurnVisibleEvent(e){switch(e.type){case`actions.requested`:case`authorization.completed`:case`authorization.required`:case`input.requested`:case`message.appended`:case`message.completed`:case`reasoning.appended`:case`reasoning.completed`:case`result.completed`:case`step.completed`:case`step.failed`:case`step.started`:case`subagent.called`:case`subagent.completed`:case`subagent.event`:case`subagent.started`:case`turn.completed`:case`turn.failed`:return!0;default:return!1}}function formatActionResultError(e){if(e.data.error?.message)return e.data.error.message;let t=e.data.result.output;if(typeof t==`string`)return t;try{return JSON.stringify(t)}catch{return`Tool execution failed.`}}function toFailureEvent(e,t,n){let r=failureKey(e);if(t.has(r))return;t.add(r);let i={type:`error`,errorText:formatFailureMessage(e)},l=n?.(e)??formatFailureHint(e);l!==void 0&&(i.hint=l);let u=formatFailureDetail(e);return u!==void 0&&(i.detail=u),i}function isQuestionRequest(e){return e.display===`select`||e.display===`text`?!0:e.display===`confirmation`?!1:e.options!==void 0&&e.options.length>0}function toAgentTUIInputQuestion(e){let t=e.display===`text`?`text`:e.display===`select`||e.options!==void 0&&e.options.length>0?`select`:`text`,n={requestId:e.requestId,prompt:e.prompt,display:t};return e.options!==void 0&&(n.options=e.options.map(e=>{let t={id:e.id,label:e.label};return e.description!==void 0&&(t.description=e.description),e.style!==void 0&&(t.style=e.style),t})),e.allowFreeform!==void 0&&(n.allowFreeform=e.allowFreeform),n}export{EveTUIRunner,parsePromptCommand};
@@ -1,2 +1,2 @@
1
1
  import{createTuiPrompter}from"./tui-prompter.js";import{runDeployFlow}from"#setup/flows/deploy.js";import{WizardCancelledError}from"#setup/step.js";import{runLoginFlow}from"#setup/flows/login.js";import{HumanActionRequiredError}from"#setup/human-action.js";import{runChannelsFlow}from"#setup/flows/channels.js";import{runConnectionsFlow}from"#setup/flows/connections.js";import{runInstallVercelCliFlow}from"#setup/flows/install-vercel-cli.js";import{runModelFlow}from"#setup/flows/model.js";import{runProviderFlow}from"#setup/flows/provider.js";import{openUrl}from"#setup/primitives/open-url.js";import{slackMessageDeepLink}from"#setup/slack-connect.js";const SETUP_FLOW_CONFIG={"vc:install":{title:`Install the Vercel CLI`,indicator:`pulse`},"vc:login":{title:`Log in to Vercel`,indicator:`pulse`},model:{title:`Configure the agent model`,indicator:`pulse`},channels:{title:`Agent channels`,indicator:`pulse`},connect:{title:`Agent connections`,indicator:`pulse`},deploy:{title:`Deploy to Vercel`,indicator:`spinner`}};function muteableRenderer(e,t){return{readSelect:n=>t()?Promise.resolve(void 0):e.readSelect(n),readEditableSelect:n=>t()?Promise.resolve(void 0):e.readEditableSelect(n),readProviderPicker:n=>t()?Promise.resolve(void 0):e.readProviderPicker(n),readModelEditor:n=>t()?Promise.resolve(void 0):e.readModelEditor(n),readText:n=>t()?Promise.resolve(void 0):e.readText(n),readAcknowledge:n=>t()?Promise.resolve():e.readAcknowledge(n),readChoice:n=>t()?{choice:Promise.resolve(void 0),close:()=>{}}:e.readChoice(n),setStatus:n=>{t()||e.setStatus(n)},renderLine:(n,r)=>{(!t()||r===`warning`||r===`error`)&&e.renderLine(n,r)},renderOutput:n=>{t()||e.renderOutput(n)}}}async function runTuiSetupCommand(t){let{command:r}=t,i=!1,a=new AbortController,o=muteableRenderer(t.renderer,()=>i),s=(t.createPrompter??createTuiPrompter)(o),c=t.renderer.waitForInterrupt(),l=Symbol(`interrupted`),u=executeSetupCommand(t,s,o,a.signal);try{let e=await Promise.race([u,c.promise.then(()=>l)]);return e===l?(i=!0,a.abort(new WizardCancelledError),{...await u,message:`/${r} interrupted.`,preserveFlowDiagnostics:!0}):e}finally{c.dispose(),t.renderer.setStatus(void 0)}}async function executeSetupCommand(e,i,u,d){let{command:f,appRoot:p}=e,m={runInstallVercelCliFlow,runLoginFlow,runModelFlow,runChannelsFlow,runConnectionsFlow,runDeployFlow,...e.flows};try{switch(f){case`vc:install`:return installVercelCliResultMessage(await m.runInstallVercelCliFlow({appRoot:p,prompter:i,signal:d}));case`vc:login`:return loginResultMessage(await m.runLoginFlow({appRoot:p,prompter:i,signal:d}));case`model`:{let pickProvider=e=>u.readProviderPicker(e),t={appRoot:p,prompter:i,signal:d,deps:{pickModelSettings:e=>u.readModelEditor(e),runProviderFlow:e=>runProviderFlow({...e,picker:pickProvider})}};e.initialModelStep!==void 0&&(t.initialStep=e.initialModelStep);let n=await m.runModelFlow(t);if(n.kind===`cancelled`)return{message:n.discardedDraft===!0?`/model dismissed. Drafted changes were discarded; Done commits them.`:`/model dismissed.`,preserveFlowDiagnostics:!1};let r=[];n.modelMessage!==void 0&&r.push(n.modelMessage),n.providerOutcome!==void 0&&r.push(providerOutcomeMessage(n.providerOutcome));let a={message:r.join(`
2
- `),preserveFlowDiagnostics:!1};return n.providerOutcome!==void 0&&(a.effect={kind:`model-access-changed`}),a}case`channels`:{let e=await m.runChannelsFlow({appRoot:p,prompter:i,signal:d});switch(e.kind){case`failed`:return pendingChannelsResult(`Channel files changed, but /channels failed: ${e.message}`);case`cancelled`:return{message:`/channels dismissed.`,preserveFlowDiagnostics:!0};case`deploy-and-chat`:return await runDeployAndChat(m,{appRoot:p,prompter:i,signal:d},e.chat);case`done`:return e.addedChannels.length===0?{message:`No channels added.`,preserveFlowDiagnostics:!0}:{message:`Channels added: ${e.addedChannels.join(`, `)} — run /deploy to ship them.`,preserveFlowDiagnostics:!0,effect:{kind:`channels-added`}}}}case`connect`:{let t=await m.runConnectionsFlow({appRoot:p,prompter:i,signal:d,disabledConnectionReasons:e.disabledConnectionReasons});switch(t.kind){case`cancelled`:return{message:`/connect dismissed.`,preserveFlowDiagnostics:!0,effect:{kind:`model-access-changed`}};case`failed`:return{message:t.addedConnections.length===0?`/connect failed: ${t.message}`:`Connection files changed, but /connect failed: ${t.message}`,preserveFlowDiagnostics:!0,effect:t.addedConnections.length===0?{kind:`model-access-changed`}:{kind:`connection-added`}};case`done`:return{message:t.addedConnections.length===0?`No connections added.`:`Connections added: ${t.addedConnections.join(`, `)}.`,preserveFlowDiagnostics:!0,effect:t.addedConnections.length===0?{kind:`model-access-changed`}:{kind:`connection-added`}}}}case`deploy`:{let e=await m.runDeployFlow({appRoot:p,prompter:i,interactive:!0,signal:d});return e.kind===`cancelled`?{message:`/deploy dismissed.`,preserveFlowDiagnostics:!0}:e.kind===`needs-link`?{message:`Not linked to a Vercel project — run /model to connect one first.`,preserveFlowDiagnostics:!0}:{message:e.productionUrl===void 0?`Deployed.`:`Deployed: ${e.productionUrl}`,preserveFlowDiagnostics:!0,effect:{kind:`deployed`}}}}}catch(e){if(e instanceof WizardCancelledError)return{message:`/${f} dismissed.`,preserveFlowDiagnostics:f!==`model`};let t=vercelActionOutcome(e,f);return t===void 0?{message:`/${f} failed: ${e instanceof Error?e.message:String(e)}`,preserveFlowDiagnostics:!0}:t}}function vercelActionOutcome(e,t){if(!(e instanceof HumanActionRequiredError))return;let n=vercelActionMessage(e.action.kind,t);return n===void 0?void 0:{message:n,preserveFlowDiagnostics:!0}}function vercelActionMessage(e,t){switch(e){case`vercel-login`:return`You're not logged in to Vercel — run /vc:login, then retry /${t}.`;case`vercel-forbidden`:return`Vercel denied access to that team — run /vc:login to re-authenticate (for example to complete SSO), or pick a team you can access, then retry /${t}.`;case`vercel-cli-missing`:return`The Vercel CLI isn't installed — run /vc:install to install it, then retry /${t}.`;default:return}}async function runDeployAndChat(e,t,r){let i;try{i=await e.runDeployFlow({...t,interactive:!0})}catch(e){if(e instanceof WizardCancelledError)return pendingChannelsResult(`Channels added, but /deploy was dismissed. Run /deploy to ship them.`);let t=vercelActionOutcome(e,`deploy`);return pendingChannelsResult(t===void 0?`Channels added, but /deploy failed: ${e instanceof Error?e.message:String(e)}`:`Channels added. ${t.message}`)}if(i.kind===`cancelled`)return pendingChannelsResult(`Channels added, but /deploy was dismissed. Run /deploy to ship them.`);if(i.kind===`needs-link`)return pendingChannelsResult(`Channels added, but this directory is not linked to Vercel. Run /model, then /deploy.`);let a=i.productionUrl===void 0?`Deployed.`:`Deployed: ${i.productionUrl}`,o;if(r.chatUrl===void 0)o=`Message your agent in Slack to see it live.`;else{let e=slackMessageDeepLink(r.chatUrl);openUrl(e),o=`Chat with your agent in Slack: ${e}`}return{message:`${a}\n${o}`,preserveFlowDiagnostics:!0,effect:{kind:`deployed`}}}function installVercelCliResultMessage(e){switch(e.kind){case`cancelled`:return{message:`/vc:install dismissed.`,preserveFlowDiagnostics:!1};case`already`:return{message:`The Vercel CLI is already installed.`,preserveFlowDiagnostics:!1};case`failed`:return{message:"Couldn't install the Vercel CLI — install it manually with `npm i -g vercel@latest`.",preserveFlowDiagnostics:!0};case`installed`:return{message:`Installed the Vercel CLI. Run /vc:login next.`,preserveFlowDiagnostics:!1,effect:{kind:`refresh-identity`}}}}function loginResultMessage(e){switch(e.kind){case`cancelled`:return{message:`/vc:login dismissed.`,preserveFlowDiagnostics:!1};case`already`:return{message:`You're already logged in to Vercel.`,preserveFlowDiagnostics:!1};case`cli-missing`:return{message:`The Vercel CLI isn't installed — run /vc:install to install it, then retry /vc:login.`,preserveFlowDiagnostics:!0};case`failed`:return{message:`Vercel login didn't complete — run /vc:login to try again.`,preserveFlowDiagnostics:!0};case`logged-in`:return{message:`Logged in to Vercel.`,preserveFlowDiagnostics:!1,effect:{kind:`refresh-identity`}};case`unavailable`:return{message:`Couldn't reach Vercel — check your connection, then retry /vc:login.`,preserveFlowDiagnostics:!0}}}function pendingChannelsResult(e){return{message:e,preserveFlowDiagnostics:!0,effect:{kind:`channels-added`}}}function providerOutcomeMessage(e){let{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};
2
+ `),preserveFlowDiagnostics:!1};return n.providerOutcome!==void 0&&(a.effect={kind:`model-access-changed`}),a}case`channels`:{let e=await m.runChannelsFlow({appRoot:p,prompter:i,signal:d});switch(e.kind){case`failed`:return pendingChannelsResult(`Channel files changed, but /channels failed: ${e.message}`);case`cancelled`:return{message:`/channels dismissed.`,preserveFlowDiagnostics:!0};case`deploy-and-chat`:return await runDeployAndChat(m,{appRoot:p,prompter:i,signal:d},e.chat);case`done`:return e.addedChannels.length===0?{message:`No channels added.`,preserveFlowDiagnostics:!0}:{message:`Channels added: ${e.addedChannels.join(`, `)} — run /deploy to ship them.`,preserveFlowDiagnostics:!0,effect:{kind:`channels-added`}}}}case`connect`:{let t=await m.runConnectionsFlow({appRoot:p,prompter:i,signal:d,disabledConnectionReasons:e.disabledConnectionReasons});switch(t.kind){case`cancelled`:return{message:`/connect dismissed.`,preserveFlowDiagnostics:!0,effect:{kind:`model-access-changed`}};case`failed`:return{message:t.addedConnections.length===0?`/connect failed: ${t.message}`:`Connection files changed, but /connect failed: ${t.message}`,preserveFlowDiagnostics:!0,effect:t.addedConnections.length===0?{kind:`model-access-changed`}:{kind:`connection-added`}};case`done`:return{message:t.addedConnections.length===0?`No connections added.`:`Connections added: ${t.addedConnections.join(`, `)}.`,preserveFlowDiagnostics:!0,effect:t.addedConnections.length===0?{kind:`model-access-changed`}:{kind:`connection-added`}}}}case`deploy`:{let e=await m.runDeployFlow({appRoot:p,prompter:i,interactive:!0,signal:d});return e.kind===`cancelled`?{message:`/deploy dismissed.`,preserveFlowDiagnostics:!0}:e.kind===`needs-link`?{message:`Not linked to a Vercel project — run /model to connect one first.`,preserveFlowDiagnostics:!0}:{message:e.productionUrl===void 0?`Deployed.`:`Deployed: ${e.productionUrl}`,preserveFlowDiagnostics:!0,effect:{kind:`deployed`}}}}}catch(e){if(e instanceof WizardCancelledError)return{message:`/${f} dismissed.`,preserveFlowDiagnostics:f!==`model`};let t=vercelActionOutcome(e,f);return t===void 0?{message:`/${f} failed: ${e instanceof Error?e.message:String(e)}`,preserveFlowDiagnostics:!0}:t}}function vercelActionOutcome(e,t){if(!(e instanceof HumanActionRequiredError))return;let n=vercelActionMessage(e.action.kind,t);return n===void 0?void 0:{message:n,preserveFlowDiagnostics:!0}}function vercelActionMessage(e,t){switch(e){case`vercel-login`:return`You're not logged in to Vercel — run /vc:login, then retry /${t}.`;case`vercel-forbidden`:return`Vercel denied access to that team — run /vc:login to re-authenticate (for example to complete SSO), or pick a team you can access, then retry /${t}.`;case`vercel-cli-missing`:return`The Vercel CLI isn't installed — run /vc:install to install it, then retry /${t}.`;default:return}}async function runDeployAndChat(e,t,r){let i;try{i=await e.runDeployFlow({...t,interactive:!0})}catch(e){if(e instanceof WizardCancelledError)return pendingChannelsResult(`Channels added, but /deploy was dismissed. Run /deploy to ship them.`);let t=vercelActionOutcome(e,`deploy`);return pendingChannelsResult(t===void 0?`Channels added, but /deploy failed: ${e instanceof Error?e.message:String(e)}`:`Channels added. ${t.message}`)}if(i.kind===`cancelled`)return pendingChannelsResult(`Channels added, but /deploy was dismissed. Run /deploy to ship them.`);if(i.kind===`needs-link`)return pendingChannelsResult(`Channels added, but this directory is not linked to Vercel. Run /model, then /deploy.`);let a=i.productionUrl===void 0?`Deployed.`:`Deployed: ${i.productionUrl}`,o;if(r.chatUrl===void 0)o=`Message your agent in Slack to see it live.`;else{let e=slackMessageDeepLink(r.chatUrl);openUrl(e),o=`Chat with your agent in Slack: ${e}`}return{message:`${a}\n${o}`,preserveFlowDiagnostics:!0,effect:{kind:`deployed`}}}function installVercelCliResultMessage(e){switch(e.kind){case`cancelled`:return{message:`/vc:install dismissed.`,preserveFlowDiagnostics:!1};case`already`:return{message:`The Vercel CLI is already installed.`,preserveFlowDiagnostics:!1};case`failed`:return{message:"Couldn't install the Vercel CLI — install it manually with `npm i -g vercel@latest`.",preserveFlowDiagnostics:!0};case`installed`:return{message:`Installed the Vercel CLI. Run /vc:login next.`,preserveFlowDiagnostics:!1,effect:{kind:`refresh-identity`}}}}function loginResultMessage(e){switch(e.kind){case`cancelled`:return{message:`/vc:login dismissed.`,preserveFlowDiagnostics:!1};case`already`:return{message:`You're already logged in to Vercel.`,preserveFlowDiagnostics:!1};case`cli-missing`:return{message:`The Vercel CLI isn't installed — run /vc:install to install it, then retry /vc:login.`,preserveFlowDiagnostics:!0};case`failed`:return{message:`Vercel login didn't complete — run /vc:login to try again.`,preserveFlowDiagnostics:!0};case`logged-in`:return{message:`Logged in to Vercel.`,preserveFlowDiagnostics:!1,effect:{kind:`refresh-identity`}};case`unavailable`:return{message:`Couldn't reach Vercel — check your connection, then retry /vc:login.`,preserveFlowDiagnostics:!0}}}function pendingChannelsResult(e){return{message:e,preserveFlowDiagnostics:!0,effect:{kind:`channels-added`}}}function providerOutcomeMessage(e){let{resolution:t,status:n}=e;if(n.kind===`gateway-project`)return t===void 0?`Project linked. No model credential found; set AI_GATEWAY_API_KEY in .env.local.`:t.credential===`oidc`?`Project linked. Connected to AI Gateway via VERCEL_OIDC_TOKEN.`:t.shadowedOidc===void 0?`Project linked. Connected to AI Gateway via AI_GATEWAY_API_KEY.`:`Project linked. AI_GATEWAY_API_KEY (${t.source.kind===`shell`?`shell`:t.source.path}) outranks the project's VERCEL_OIDC_TOKEN and stays the active credential — ${t.source.kind===`shell`?`unset it in your shell`:`remove it from ${t.source.path}`} to run on the project.`;if(n.kind===`gateway-key`){let e=n.source.kind===`shell`?`your shell`:n.source.path;return`Connected to AI Gateway via ${n.envKey} in ${e}.`}return`Provider updated — no gateway credential detected; set AI_GATEWAY_API_KEY in .env.local.`}export{SETUP_FLOW_CONFIG,runTuiSetupCommand};
@@ -1 +1 @@
1
- import{join}from"node:path";import{pathExists}from"#setup/path-exists.js";function hasEnvValue(e,t){let n=e[t];return n!==void 0&&n.trim().length>0}function resolveModelProviderState(e,t){let n=modelProviderAccess({env:t,info:e});if(e===void 0||n.kind!==`gateway`||n.runtime.status!==`connected`)return e;let{credential:r}=n.runtime,i=e.agent.model,a=i.endpoint;return a?.kind===`gateway`&&a.connected&&a.credential===r?e:{...e,agent:{...e.agent,model:{...i,endpoint:{kind:`gateway`,connected:!0,credential:r}}}}}function modelProviderAccess(e){let t=e.info?.agent.model;if(t?.routing?.kind===`external`)return{kind:`external`};if(t?.routing?.kind!==`gateway`)return{kind:`unknown`};if(hasEnvValue(e.env,`AI_GATEWAY_API_KEY`))return{kind:`gateway`,runtime:{status:`connected`,credential:`api-key`}};let n=t.endpoint;return n?.kind===`gateway`&&n.connected?{kind:`gateway`,runtime:{status:`connected`,credential:n.credential}}:hasEnvValue(e.env,`VERCEL_OIDC_TOKEN`)?{kind:`gateway`,runtime:{status:`connected`,credential:`oidc`}}:n?.kind===`gateway`?{kind:`gateway`,runtime:{status:`disconnected`}}:{kind:`gateway`,runtime:{status:`unknown`}}}const BOOT_DETECTIONS=[{id:`model-provider`,async detect({appRoot:n,env:r,info:i}){let a=modelProviderAccess({env:r,info:i});if(a.kind===`external`)return[];if(a.kind===`gateway`){if(a.runtime.status===`connected`)return[];if(a.runtime.status===`disconnected`)return[{kind:`attention`,label:await pathExists(join(n,`.vercel`,`project.json`))?`AI Gateway credentials missing`:`model provider not linked`,command:`/model`}]}return await pathExists(join(n,`.vercel`,`project.json`))?[{kind:`attention`,label:`AI Gateway credentials missing`,command:`/model`}]:[{kind:`attention`,label:`model provider not linked`,command:`/model`}]}}],LOGIN_SETUP_ISSUE={kind:`attention`,label:`not logged in`,command:`/vc:login`},CLI_MISSING_SETUP_ISSUE={kind:`attention`,label:`Vercel CLI not found`,command:`/vc:install`};async function detectSetupIssues(e,t=BOOT_DETECTIONS){return(await Promise.all(t.map(async t=>{try{return await t.detect(e)}catch{return[]}}))).flat()}function orderedSetupIssues(e,t){return t===void 0?[...e]:[t,...e]}function formatSetupIssuesLine(e){let t=e.length===1?`setup issue`:`setup issues`,n=e.map(e=>`${e.label} · ${e.command}`).join(`, `);return`${e.length} ${t}: ${n}`}export{BOOT_DETECTIONS,CLI_MISSING_SETUP_ISSUE,LOGIN_SETUP_ISSUE,detectSetupIssues,formatSetupIssuesLine,orderedSetupIssues,resolveModelProviderState};
1
+ import{join}from"node:path";import{pathExists}from"#setup/path-exists.js";import{hasEnvValue,resolveGatewayCredential}from"#internal/resolve-model-endpoint-status.js";function resolveModelProviderState(e,t){let n=modelProviderAccess({env:t,info:e});if(e===void 0||n.kind!==`gateway`||n.runtime.status!==`connected`)return e;let{credential:r}=n.runtime,i=e.agent.model,a=i.endpoint;return a?.kind===`gateway`&&a.connected&&a.credential===r?e:{...e,agent:{...e.agent,model:{...i,endpoint:{kind:`gateway`,connected:!0,credential:r}}}}}function modelProviderAccess(e){let t=e.info?.agent.model;if(t?.routing?.kind===`external`)return{kind:`external`};if(t?.routing?.kind!==`gateway`)return{kind:`unknown`};let i=resolveGatewayCredential({apiKeyInEnv:hasEnvValue(e.env.AI_GATEWAY_API_KEY),oidcAvailable:hasEnvValue(e.env.VERCEL_OIDC_TOKEN)});if(i?.credential===`api-key`)return{kind:`gateway`,runtime:{status:`connected`,credential:`api-key`}};let a=t.endpoint;return a?.kind===`gateway`&&a.connected?{kind:`gateway`,runtime:{status:`connected`,credential:a.credential}}:i===void 0?a?.kind===`gateway`?{kind:`gateway`,runtime:{status:`disconnected`}}:{kind:`gateway`,runtime:{status:`unknown`}}:{kind:`gateway`,runtime:{status:`connected`,credential:i.credential}}}const BOOT_DETECTIONS=[{id:`model-provider`,async detect({appRoot:n,env:r,info:i}){let a=modelProviderAccess({env:r,info:i});if(a.kind===`external`)return[];if(a.kind===`gateway`){if(a.runtime.status===`connected`)return[];if(a.runtime.status===`disconnected`)return[{kind:`attention`,label:await pathExists(join(n,`.vercel`,`project.json`))?`AI Gateway credentials missing`:`model provider not linked`,command:`/model`}]}return await pathExists(join(n,`.vercel`,`project.json`))?[{kind:`attention`,label:`AI Gateway credentials missing`,command:`/model`}]:[{kind:`attention`,label:`model provider not linked`,command:`/model`}]}}],LOGIN_SETUP_ISSUE={kind:`attention`,label:`not logged in`,command:`/vc:login`},CLI_MISSING_SETUP_ISSUE={kind:`attention`,label:`Vercel CLI not found`,command:`/vc:install`};async function detectSetupIssues(e,t=BOOT_DETECTIONS){return(await Promise.all(t.map(async t=>{try{return await t.detect(e)}catch{return[]}}))).flat()}function orderedSetupIssues(e,t){return t===void 0?[...e]:[t,...e]}function formatSetupIssuesLine(e){let t=e.length===1?`setup issue`:`setup issues`,n=e.map(e=>`${e.label} · ${e.command}`).join(`, `);return`${e.length} ${t}: ${n}`}export{BOOT_DETECTIONS,CLI_MISSING_SETUP_ISSUE,LOGIN_SETUP_ISSUE,detectSetupIssues,formatSetupIssuesLine,orderedSetupIssues,resolveModelProviderState};
@@ -1 +1 @@
1
- import{remoteHost}from"./target.js";import{clipVisible,stripAnsi,visibleLength}from"#cli/ui/terminal-text.js";import{formatModelSummary}from"#shared/model-summary.js";function renderModel(e){if(e.model===void 0)return;let t=e.theme.colors,r={model:e.model};if(e.reasoning!==void 0&&(r.reasoning=e.reasoning),e.fastMode===!0&&(r.fastGlyph=e.theme.glyph.fast),e.remote!==void 0){r.model=stripAnsi(e.model).replace(/\s+/gu,` `).trim();let a=stripAnsi(formatModelSummary(r)).replace(/\s+/gu,` `).trim();return t.dim(a)}return t.dim(formatModelSummary(r))}function renderServerPort(e){if(e.remote!==void 0||e.serverPort===void 0)return;let t=e.theme.colors;return t.inverse(t.gray(` :${e.serverPort} `))}function renderEndpoint(e){if(e.remote!==void 0||e.endpoint===void 0)return;let t=e.theme.colors;if(e.endpoint.kind===`external`)return t.dim(`External endpoint`);if(!e.endpoint.connected)return t.yellow(`${e.theme.glyph.warning} AI Gateway`);let n=e.vercel?.identity?.projectName;return t.dim(n===void 0?`AI Gateway`:`AI Gateway (${n})`)}function buildStatusLine(e){let{theme:n,width:i}=e,a=n.colors,o=e.logLevel===void 0?void 0:a.cyan(`logs: ${e.logLevel}`),s=renderServerPort(e),c=renderModel(e),l=e.vercel?.pendingDeploy?a.yellow(`/deploy pending`):void 0,u=e.remote===void 0?void 0:formatRemoteStatus(e.remote,n),d=renderEndpoint(e),f=u?.full??s,p=u?.badge??s,compose=(e,t)=>{let n=t.filter(e=>e!==void 0).join(` `);return e===void 0||n.length===0?e??n:`${e} ${n}`},m=[compose(f,[o,c,d,l]),compose(f,[o,c,l]),compose(f,[o,l]),compose(f,[o]),compose(p,[o]),compose(p,[])];if(m[0].length!==0){for(let e of m)if(e.length>0&&visibleLength(e)<=i)return e;return clipVisible(m.findLast(e=>e.length>0),i)}}function formatRemoteStatus(t,n){let r=n.colors,i=t.deployment===void 0?remoteHost(t.target):`${t.deployment.projectName} (${t.deployment.environment})`,a=formatRemoteBadge(` ${n.unicode?`↗`:`->`} ${i} `,t.connection.state,n),o;switch(t.connection.state){case`checking`:o=r.dim(`Checking access…`);break;case`ready`:break;case`auth-required`:o=r.yellow(`Authenticate via OIDC`);break;case`authenticating`:o=r.dim(`Authenticating via OIDC…`);break;case`auth-failed`:o=r.yellow(`Authentication failed`);break;case`unavailable`:o=r.yellow(`Remote unavailable`);break}return{badge:a,full:o===void 0?a:`${a} ${o}`}}function formatRemoteBadge(e,t,n){let r=n.colors;switch(t){case`checking`:return r.inverse(r.gray(e));case`ready`:return r.inverse(r.blue(e));case`unavailable`:case`auth-required`:case`authenticating`:case`auth-failed`:return r.inverse(r.yellow(e))}}export{buildStatusLine};
1
+ import{remoteHost}from"./target.js";import{clipVisible,stripAnsi,visibleLength}from"#cli/ui/terminal-text.js";import{formatModelSummary}from"#shared/model-summary.js";function renderModel(e){if(e.model===void 0)return;let t=e.theme.colors,r={model:e.model};if(e.reasoning!==void 0&&(r.reasoning=e.reasoning),e.fastMode===!0&&(r.fastGlyph=e.theme.glyph.fast),e.remote!==void 0){r.model=stripAnsi(e.model).replace(/\s+/gu,` `).trim();let a=stripAnsi(formatModelSummary(r)).replace(/\s+/gu,` `).trim();return t.dim(a)}return t.dim(formatModelSummary(r))}function renderServerPort(e){if(e.remote!==void 0||e.serverPort===void 0)return;let t=e.theme.colors;return t.inverse(t.gray(` :${e.serverPort} `))}const EXTERNAL_PROVIDER_DISPLAY_NAMES={codex:`chatgpt-sub`};function renderEndpoint(e){if(e.remote!==void 0||e.endpoint===void 0)return;let t=e.theme.colors,n=e.theme.glyph,clause=(e,n)=>`${t.dim(`via `)}${e}${t.dim(n)}`;if(e.endpoint.kind===`external`){let r=EXTERNAL_PROVIDER_DISPLAY_NAMES[e.endpoint.provider]??e.endpoint.provider;return{text:`${t.dim(`via ${r}`)}${n.external}`,standalone:!1}}if(!e.endpoint.connected)return{text:t.yellow(`${n.warning} ai-gateway`),standalone:!0};if(e.endpoint.credential===`api-key`)return{text:clause(`ai-gateway`,`(api-key)`),standalone:!1};let r=e.vercel?.identity?.projectName;return{text:clause(`ai-gateway`,`(${r===void 0?`oidc`:`oidc:${r}`})`),standalone:!1}}function buildStatusLine(e){let{theme:n,width:i}=e,a=n.colors,o=e.logLevel===void 0?void 0:a.cyan(`logs: ${e.logLevel}`),s=renderServerPort(e),c=renderModel(e),l=e.vercel?.pendingDeploy?a.yellow(`/deploy pending`):void 0,u=e.remote===void 0?void 0:formatRemoteStatus(e.remote,n),d=renderEndpoint(e),f=u?.full??s,p=u?.badge??s,m=d!==void 0&&!d.standalone&&c!==void 0,h=m?`${c} ${d.text}`:c,g=d===void 0||m?void 0:d.text,compose=(e,t)=>{let n=t.filter(e=>e!==void 0).join(` `);return e===void 0||n.length===0?e??n:`${e} ${n}`},_=[compose(f,[o,h,g,l]),compose(f,[o,c,l]),compose(f,[o,l]),compose(f,[o]),compose(p,[o]),compose(p,[])];if(_[0].length!==0){for(let e of _)if(e.length>0&&visibleLength(e)<=i)return e;return clipVisible(_.findLast(e=>e.length>0),i)}}function formatRemoteStatus(t,n){let r=n.colors,i=t.deployment===void 0?remoteHost(t.target):`${t.deployment.projectName} (${t.deployment.environment})`,a=formatRemoteBadge(` ${n.unicode?`↗`:`->`} ${i} `,t.connection.state,n),o;switch(t.connection.state){case`checking`:o=r.dim(`Checking access…`);break;case`ready`:break;case`auth-required`:o=r.yellow(`Authenticate via OIDC`);break;case`authenticating`:o=r.dim(`Authenticating via OIDC…`);break;case`auth-failed`:o=r.yellow(`Authentication failed`);break;case`unavailable`:o=r.yellow(`Remote unavailable`);break}return{badge:a,full:o===void 0?a:`${a} ${o}`}}function formatRemoteBadge(e,t,n){let r=n.colors;switch(t){case`checking`:return r.inverse(r.gray(e));case`ready`:return r.inverse(r.blue(e));case`unavailable`:case`auth-required`:case`authenticating`:case`auth-failed`:return r.inverse(r.yellow(e))}}export{buildStatusLine};
@@ -100,9 +100,22 @@ export declare function takeUntil<T>(source: AsyncIterable<T>, stop: Promise<voi
100
100
  /** `394.4K`-style compact count: plain below 1000, then K/M with one trimmed decimal. */
101
101
  export declare function formatCompactTokenCount(count: number): string;
102
102
  /**
103
- * The status line's token-flow segment: `↑ 394.4K 4.3K`, input (prompt)
104
- * tokens up, output tokens down, both from the latest usage report. A known
105
- * `--context-size` appends the context-fill percentage of the input side.
103
+ * Reveals `text` one character per `stepMs` of elapsed time, typewriter
104
+ * style: the first character shows immediately, the full text after
105
+ * `(length - 1) * stepMs`. Painted on the shared ticker beat, so no timer
106
+ * of its own.
107
+ */
108
+ export declare function typewriterText(text: string, elapsedMs: number, stepMs: number): string;
109
+ /**
110
+ * Formats a turn's wall-clock duration for the end-of-turn stats line:
111
+ * `42s`, `3min 24s`, `1h 12min`. Sub-second turns round up to `1s` — a
112
+ * `0s` coda would read as a measurement error.
113
+ */
114
+ export declare function formatTurnDuration(elapsedMs: number): string;
115
+ /**
116
+ * The turn bar and coda's token-flow segment: `↑ 394.4K ↓ 4.3K`, input
117
+ * (prompt) tokens up, output tokens down. A known `--context-size` appends
118
+ * the context-fill percentage of the input side.
106
119
  */
107
120
  export declare function formatTokenFlow(flow: {
108
121
  inputTokens: number;
@@ -1,4 +1,4 @@
1
1
  const CSI_FINAL=/[\u0040-\u007e]/u,PASTE_START=`\x1B[200~`,PASTE_END=`\x1B[201~`;function sanitizePastedText(e){let t=``;for(let n of e.replace(/\r\n?/gu,`
2
2
  `)){if(n===`
3
3
  `||n===` `){t+=n;continue}let e=n.codePointAt(0);e!==void 0&&(e<32||e===127||e>=128&&e<=159||(t+=n))}return t}function isIncompletePaste(e){return e.startsWith(PASTE_START)&&!e.includes(PASTE_END,6)}function stripPasteStart(e){return e.startsWith(PASTE_START)?e.slice(6):e}function stripPromptControlCharacters(e){let t=``;for(let n of e)n>=` `&&n!==``&&(t+=n);return t}function nextKey(r){let i=r[0];if(i===void 0)return{consumed:0,incomplete:!0};if(i===`\x1B`){if(r.length===1)return{consumed:0,incomplete:!0};let i=r[1];if(i===`O`)return r.length<3?{consumed:0,incomplete:!0}:{key:parseKey(Buffer.from(r.slice(0,3))),consumed:3};if(i===`[`){if(r.startsWith(PASTE_START)){let e=r.indexOf(PASTE_END,6);return e===-1?{consumed:0,incomplete:!0}:{key:{type:`text`,value:sanitizePastedText(r.slice(6,e)),framing:`bracketed-paste`},consumed:e+6}}for(let t=2;t<r.length;t+=1)if(CSI_FINAL.test(r[t]))return{key:parseKey(Buffer.from(r.slice(0,t+1))),consumed:t+1};return{consumed:0,incomplete:!0}}return{key:{type:`escape`},consumed:1}}if(i<` `||i===``)return{key:parseKey(Buffer.from(i)),consumed:1};let a=1;for(;a<r.length;){let e=r[a];if(e===`\x1B`||e<` `||e===``)break;a+=1}return{key:parseKey(Buffer.from(r.slice(0,a))),consumed:a}}function parseKey(e){let t=e.toString(`utf8`);switch(t){case``:return{type:`ctrl-a`};case``:return{type:`ctrl-e`};case``:return{type:`ctrl-d`};case`\v`:return{type:`ctrl-k`};case``:return{type:`ctrl-n`};case``:return{type:`ctrl-p`};case`\f`:return{type:`ctrl-l`};case``:return{type:`ctrl-r`};case``:return{type:`ctrl-u`};case``:return{type:`ctrl-w`};case``:return{type:`ctrl-c`};case`\r`:case`
4
- `:return{type:`enter`};case`\x1B[27;2;13~`:case`\x1B[13;2u`:return{type:`newline`};case``:case`\b`:return{type:`backspace`};case`\x1B[A`:case`\x1BOA`:return{type:`up`};case`\x1B[B`:case`\x1BOB`:return{type:`down`};case`\x1B[C`:case`\x1BOC`:return{type:`right`};case`\x1B[D`:case`\x1BOD`:return{type:`left`};case`\x1B[H`:case`\x1BOH`:case`\x1B[1~`:return{type:`home`};case`\x1B[F`:case`\x1BOF`:case`\x1B[4~`:return{type:`end`};case`\x1B[3~`:return{type:`delete`};case` `:return{type:`tab`};case`\x1B`:return{type:`escape`};default:{let e=stripPromptControlCharacters(t);return e.length>0?{type:`text`,value:e,framing:`unframed`}:{type:`ignore`}}}}async function*takeUntil(e,t){let n=e[Symbol.asyncIterator](),r=t.then(()=>({done:!0,value:void 0}));try{for(;;){let e=n.next();e.catch(()=>{});let t=await Promise.race([e,r]);if(t.done)break;yield t.value}}finally{n.return?.()?.catch(()=>{})}}function formatCompactTokenCount(e){if(e<1e3)return`${e}`;let t=e<1e6?e/1e3:e/1e6,n=e<1e6?`K`:`M`;return`${t.toFixed(1).replace(/\.0$/,``)}${n}`}function formatTokenFlow(e,t){let n=formatCompactTokenCount(e.inputTokens),r=formatCompactTokenCount(e.outputTokens),i=`${t.arrowUp} ${n} ${t.arrowDown} ${r}`,a=formatContextPercentage(e.inputTokens,e.contextSize);return a==null?i:`${i} ${a}`}function formatContextPercentage(e,t){if(!(t==null||t<=0||!Number.isFinite(t)))return`${Math.round(e/t*100).toLocaleString()}%`}function formatAssistantResponseStats(e,t){if(t===`tokensPerSecond`)return formatTokensPerSecond(e.tokensPerSecond);if(e.outputTokens!=null)return`${e.outputTokens.toLocaleString()} output tokens`}function formatTokensPerSecond(e){if(e!=null)return`${formatNumber(e)} tok/s`}function formatNumber(e){return Number.isInteger(e)?e.toLocaleString():e.toLocaleString(void 0,{maximumFractionDigits:1})}export{formatAssistantResponseStats,formatCompactTokenCount,formatTokenFlow,isIncompletePaste,nextKey,parseKey,sanitizePastedText,stripPasteStart,stripPromptControlCharacters,takeUntil};
4
+ `:return{type:`enter`};case`\x1B[27;2;13~`:case`\x1B[13;2u`:return{type:`newline`};case``:case`\b`:return{type:`backspace`};case`\x1B[A`:case`\x1BOA`:return{type:`up`};case`\x1B[B`:case`\x1BOB`:return{type:`down`};case`\x1B[C`:case`\x1BOC`:return{type:`right`};case`\x1B[D`:case`\x1BOD`:return{type:`left`};case`\x1B[H`:case`\x1BOH`:case`\x1B[1~`:return{type:`home`};case`\x1B[F`:case`\x1BOF`:case`\x1B[4~`:return{type:`end`};case`\x1B[3~`:return{type:`delete`};case` `:return{type:`tab`};case`\x1B`:return{type:`escape`};default:{let e=stripPromptControlCharacters(t);return e.length>0?{type:`text`,value:e,framing:`unframed`}:{type:`ignore`}}}}async function*takeUntil(e,t){let n=e[Symbol.asyncIterator](),r=t.then(()=>({done:!0,value:void 0}));try{for(;;){let e=n.next();e.catch(()=>{});let t=await Promise.race([e,r]);if(t.done)break;yield t.value}}finally{n.return?.()?.catch(()=>{})}}function formatCompactTokenCount(e){if(e<1e3)return`${e}`;let t=e<1e6?e/1e3:e/1e6,n=e<1e6?`K`:`M`;return`${t.toFixed(1).replace(/\.0$/,``)}${n}`}function typewriterText(e,t,n){let r=Math.floor(Math.max(0,t)/n)+1;return r>=e.length?e:e.slice(0,r)}function formatTurnDuration(e){let t=Math.max(1,Math.round(e/1e3)),n=t%60,r=Math.floor(t/60);if(r===0)return`${n}s`;let i=r%60,a=Math.floor(r/60);return a===0?n===0?`${i}min`:`${i}min ${n}s`:i===0?`${a}h`:`${a}h ${i}min`}function formatTokenFlow(e,t){let n=formatCompactTokenCount(e.inputTokens),r=formatCompactTokenCount(e.outputTokens),i=`${t.arrowUp} ${n} ${t.arrowDown} ${r}`,a=formatContextPercentage(e.inputTokens,e.contextSize);return a==null?i:`${i} ${a}`}function formatContextPercentage(e,t){if(!(t==null||t<=0||!Number.isFinite(t)))return`${Math.round(e/t*100).toLocaleString()}%`}function formatAssistantResponseStats(e,t){if(t===`tokensPerSecond`)return formatTokensPerSecond(e.tokensPerSecond);if(e.outputTokens!=null)return`${e.outputTokens.toLocaleString()} output tokens`}function formatTokensPerSecond(e){if(e!=null)return`${formatNumber(e)} tok/s`}function formatNumber(e){return Number.isInteger(e)?e.toLocaleString():e.toLocaleString(void 0,{maximumFractionDigits:1})}export{formatAssistantResponseStats,formatCompactTokenCount,formatTokenFlow,formatTurnDuration,isIncompletePaste,nextKey,parseKey,sanitizePastedText,stripPasteStart,stripPromptControlCharacters,takeUntil,typewriterText};
@@ -0,0 +1,127 @@
1
+ /**
2
+ * The subagent child-stream subsystem: for every `subagent.called` on the
3
+ * parent stream, a parallel pump over the child session folds its events
4
+ * into the renderer's nested subagent view. Extracted from the runner —
5
+ * the subsystem touches nothing but its own run state, the client, and the
6
+ * {@link SubagentView} seam.
7
+ */
8
+ import type { Client } from "#client/index.js";
9
+ import { type ActionResultStreamEvent, type SubagentCalledStreamEvent } from "#protocol/message.js";
10
+ /**
11
+ * The renderer's subagent surface. One cohesive capability: a renderer that
12
+ * implements it renders whole sections — header, nested steps and tools,
13
+ * ghost sweeps, completion — and a renderer without it simply has no
14
+ * subagent view. Individually-optional methods would let a renderer
15
+ * implement a type-legal subset that ghosts placeholders or duplicates
16
+ * parent tool rows.
17
+ */
18
+ export interface SubagentView {
19
+ /** Opens a call's section the moment its dispatch is announced. */
20
+ begin(update: {
21
+ callId: string;
22
+ name: string;
23
+ }): void;
24
+ upsertStep(update: SubagentStepUpdate): void;
25
+ upsertTool(update: SubagentToolUpdate): void;
26
+ /** Drops a child tool row whose call never materialized. */
27
+ removeTool(update: {
28
+ callId: string;
29
+ childCallId: string;
30
+ }): void;
31
+ /** Marks a call complete so its section collapses on `└ Done…`. */
32
+ complete(update: {
33
+ callId: string;
34
+ }): void;
35
+ /** Suppresses the parent-level tool row for a child-owned call id. */
36
+ markChildToolCallId(callId: string): void;
37
+ }
38
+ type SubagentChildStep = {
39
+ reasoning: string;
40
+ message: string;
41
+ finalized: boolean;
42
+ };
43
+ type SubagentToolStatus = "preparing" | "approval-requested" | "executing" | "done" | "failed" | "rejected";
44
+ type SubagentToolState = {
45
+ toolName: string;
46
+ input: unknown;
47
+ status: SubagentToolStatus;
48
+ output?: unknown;
49
+ errorText?: string;
50
+ };
51
+ export type SubagentRun = {
52
+ name: string;
53
+ /**
54
+ * The run's one lifecycle authority. `settled` means the final assistant
55
+ * message is in (the child's turn boundary, or the parent's
56
+ * `subagent.completed` fallback); a late child event — a HITL-parked
57
+ * turn resuming — explicitly reopens the run rather than mutating a
58
+ * completed section by accident.
59
+ */
60
+ status: "running" | "settled";
61
+ /**
62
+ * One entry per logical "child message" — independent of the child's
63
+ * `stepIndex` field, which the harness can reuse across multiple
64
+ * assistant messages within a turn (e.g. a message before a tool call
65
+ * and another message after the tool result both arrive under
66
+ * `stepIndex: 0`). The key is a monotonic counter so each
67
+ * `message.completed` opens a new box on the next inbound delta.
68
+ */
69
+ steps: Map<number, SubagentChildStep>;
70
+ /**
71
+ * Section currently accepting reasoning/message deltas. `null` means
72
+ * the next delta opens a new section.
73
+ */
74
+ currentSectionKey: number | null;
75
+ /** Monotonic counter for new section keys. */
76
+ nextSectionKey: number;
77
+ tools: Map<string, SubagentToolState>;
78
+ };
79
+ export type SubagentStepUpdate = {
80
+ callId: string;
81
+ subagentName: string;
82
+ sectionKey: number;
83
+ reasoning: string;
84
+ message: string;
85
+ finalized: boolean;
86
+ };
87
+ export type SubagentToolUpdate = {
88
+ callId: string;
89
+ subagentName: string;
90
+ childCallId: string;
91
+ toolName: string;
92
+ input: unknown;
93
+ status: SubagentToolStatus;
94
+ output?: unknown;
95
+ errorText?: string;
96
+ };
97
+ export interface SubagentPumpOptions {
98
+ client?: Client;
99
+ view?: SubagentView;
100
+ formatActionResultError: (event: ActionResultStreamEvent) => string;
101
+ }
102
+ export declare class SubagentPump {
103
+ #private;
104
+ constructor(options: SubagentPumpOptions);
105
+ /**
106
+ * The moment a dispatch is known to be a subagent call, its section
107
+ * header replaces the parent-level tool row (or its still-preparing
108
+ * placeholder — subagent dispatches never upgrade one, since their
109
+ * actions are not tool-call kind). Without this the placeholder is
110
+ * swept at the step boundary and nothing shows until the child's first
111
+ * content arrives. Idempotent for SSE-resume re-entries, which only
112
+ * refresh the name.
113
+ */
114
+ begin(called: SubagentCalledStreamEvent): void;
115
+ /**
116
+ * Parent reports subagent.completed. The child stream pump terminates
117
+ * itself on the child's own turn boundary — the authoritative finish
118
+ * signal, which already finalized the section — so this is a fallback
119
+ * for runs whose boundary never reached us (a dropped child stream, a
120
+ * HITL-parked turn resuming later). We do NOT abort the pump here,
121
+ * because the child's `message.completed` event may still be in flight
122
+ * (the parent and child streams are independent HTTP connections).
123
+ */
124
+ settle(callId: string): void;
125
+ abortAll(): void;
126
+ }
127
+ export {};
@@ -0,0 +1 @@
1
+ import{isAbortLikeError}from"./errors.js";import{toErrorMessage}from"#shared/errors.js";import{isCurrentTurnBoundaryEvent}from"#protocol/message.js";var SubagentPump=class{#e;#t;#n;#r=new Map;#i=new Map;constructor(e){this.#e=e.client,this.#t=e.view,this.#n=e.formatActionResultError}begin(e){let t=e.data.callId,n=this.#r.get(t);n===void 0?this.#r.set(t,{name:e.data.name,status:`running`,steps:new Map,currentSectionKey:null,nextSectionKey:0,tools:new Map}):n.name=e.data.name,this.#t?.markChildToolCallId(t),this.#t?.begin({callId:t,name:e.data.name}),this.#a(e)}settle(e){this.#s(e)}abortAll(){for(let e of this.#i.values())e.abort();this.#i.clear(),this.#r.clear()}#a(r){let i=r.data.callId;if(this.#i.has(i))return;let a=this.#e;if(!a)return;let o=new AbortController;this.#i.set(i,o),(async()=>{let s=!1;try{let e=a.session({sessionId:r.data.childSessionId,streamIndex:0}).stream({signal:o.signal});for await(let t of e){if(o.signal.aborted)break;if(this.#l(i,t),isCurrentTurnBoundaryEvent(t)){s=!0;break}}}catch(n){if(!isAbortLikeError(n)){let e=toErrorMessage(n),r=this.#r.get(i);if(r){let{key:t,step:n}=openCurrentSubagentSection(r);n.message=n.message?`${n.message}\n\nstream error: ${e}`:`stream error: ${e}`,n.finalized=!0,r.currentSectionKey=null,this.#t?.upsertStep({callId:i,subagentName:r.name,sectionKey:t,reasoning:n.reasoning,message:n.message,finalized:!0})}}}finally{this.#i.delete(i)}s&&this.#s(i)})()}#o(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={preparing:0,"approval-requested":1,executing:2,done:3,failed:3,rejected:3};e[n.status]>e[r.status]&&(r.status=n.status),n.input!==void 0&&(r.input=n.input)}else t.tools.set(n.childCallId,i);this.#t?.markChildToolCallId(n.childCallId),this.#t?.upsertTool({callId:e,subagentName:t.name,childCallId:n.childCallId,toolName:i.toolName,input:i.input,status:i.status})}#s(e){let t=this.#r.get(e);if(!(!t||t.status===`settled`)){t.status=`settled`;for(let[n,r]of t.steps)r.finalized||(r.finalized=!0,this.#t?.upsertStep({callId:e,subagentName:t.name,sectionKey:n,reasoning:r.reasoning,message:r.message,finalized:!0}));t.currentSectionKey=null,this.#c(e,t),this.#t?.complete({callId:e})}}#c(e,t){for(let[n,r]of t.tools)r.status===`preparing`&&(t.tools.delete(n),this.#t?.removeTool({callId:e,childCallId:n}))}#l(e,t){let n=this.#r.get(e);if(!n)return;n.status===`settled`&&(n.status=`running`,this.#t?.begin({callId:e,name:n.name}));let r=this.#t,emit=(t,i)=>{r?.upsertStep({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(),this.#c(e,n);break;case`actions.requested`:finalizeCurrent();for(let r of t.data.actions)r.kind===`tool-call`&&this.#o(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.#o(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;switch(t.data.status){case`completed`:a.status=`done`,a.output=i.output;break;case`failed`:a.status=`failed`,a.errorText=this.#n(t);break;case`rejected`:a.status=`rejected`,a.errorText=this.#n(t);break}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?.upsertTool(o);break}default:break}}};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{SubagentPump};
@@ -1,5 +1,5 @@
1
1
  import type { DevDiagnostics } from "../diagnostics.js";
2
- import type { AgentTUIInputQuestion, AgentTUIInputQuestionResponse, AgentTUIRenderer, AgentTUISessionOptions, AgentTUIStreamResult, AgentTUIToolApprovalRequest, AgentTUIToolApprovalResponse, ConnectionAuthUpdate, SubagentStepUpdate, SubagentToolUpdate } from "./runner.js";
2
+ import type { AgentTUIInputQuestion, AgentTUIInputQuestionResponse, AgentTUIRenderer, AgentTUISessionOptions, AgentTUIStreamResult, AgentTUIToolApprovalRequest, AgentTUIToolApprovalResponse, ConnectionAuthUpdate, SubagentStepUpdate, SubagentView, SubagentToolUpdate } from "./runner.js";
3
3
  import { type PromptCommandSpec } from "./prompt-commands.js";
4
4
  import type { SetupFlowRenderer } from "./setup-flow.js";
5
5
  import type { AssistantResponseStatsMode, LogDisplayMode, TerminalPartDisplayMode } from "./types.js";
@@ -66,12 +66,45 @@ export declare class TerminalRenderer implements AgentTUIRenderer {
66
66
  readInputQuestion(question: AgentTUIInputQuestion, options?: AgentTUISessionOptions): Promise<AgentTUIInputQuestionResponse | undefined>;
67
67
  upsertSubagentStep(update: SubagentStepUpdate): void;
68
68
  upsertSubagentTool(update: SubagentToolUpdate): void;
69
+ removeSubagentTool(update: {
70
+ callId: string;
71
+ childCallId: string;
72
+ }): void;
73
+ /**
74
+ * The runner-facing subagent surface (see {@link SubagentView}); the
75
+ * public methods below are its implementation and the unit tests' seam.
76
+ */
77
+ readonly subagents: SubagentView;
78
+ /**
79
+ * Opens a subagent's section as soon as the dispatch is announced, so the
80
+ * transcript flows from the `Delegate …` placeholder straight into the
81
+ * `※ subagent(<name>)` header instead of going blank until the child's
82
+ * first content streams in. Re-opening a completed section (a HITL-parked
83
+ * child resuming) clears its Done mark.
84
+ */
85
+ beginSubagent(update: {
86
+ callId: string;
87
+ name: string;
88
+ }): void;
89
+ /**
90
+ * Marks a subagent call complete — its final message has arrived — so the
91
+ * section's closing corner reports `Done`. The header stays live until the
92
+ * turn finalizes (committing mid-turn would freeze its child window).
93
+ */
94
+ completeSubagent(update: {
95
+ callId: string;
96
+ }): void;
69
97
  markChildToolCallId(callId: string): void;
70
98
  upsertConnectionAuth(update: ConnectionAuthUpdate): void;
71
99
  setConnectionAuthPendingCount(count: number): void;
72
100
  setVercelStatus(status: VercelStatusSnapshot): void;
73
101
  setRemoteConnectionStatus(status: RemoteConnectionSnapshot): void;
74
102
  reset(): void;
103
+ /**
104
+ * The mid-conversation session boundary: one opening-corner line marking
105
+ * where the server-side context was cut and a fresh session took over.
106
+ */
107
+ renderSessionBoundary(): void;
75
108
  /**
76
109
  * Commits a single dim informational line to the transcript (e.g. the
77
110
  * session-recovery notice after a terminal server failure). No-op when the