eve 0.26.0 → 0.26.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/dist/src/chunks/{use-eve-agent-CruinZmd.js → use-eve-agent-AeQLLhu9.js} +118 -92
- package/dist/src/chunks/{use-eve-agent-BkztZA0v.js → use-eve-agent-PMY2WkAt.js} +118 -92
- package/dist/src/cli/banner.d.ts +5 -0
- package/dist/src/cli/banner.js +1 -1
- package/dist/src/cli/commands/info.d.ts +2 -0
- package/dist/src/cli/commands/info.js +1 -1
- package/dist/src/cli/dev/tui/blocks.d.ts +56 -8
- package/dist/src/cli/dev/tui/blocks.js +7 -7
- package/dist/src/cli/dev/tui/diagnostic-presentation.d.ts +2 -0
- package/dist/src/cli/dev/tui/diagnostic-presentation.js +3 -2
- package/dist/src/cli/dev/tui/file-content-cache.d.ts +35 -0
- package/dist/src/cli/dev/tui/file-content-cache.js +3 -0
- package/dist/src/cli/dev/tui/line-diff.d.ts +24 -0
- package/dist/src/cli/dev/tui/line-diff.js +1 -0
- package/dist/src/cli/dev/tui/markdown.d.ts +2 -1
- package/dist/src/cli/dev/tui/markdown.js +7 -3
- package/dist/src/cli/dev/tui/prompt-placeholder.d.ts +12 -0
- package/dist/src/cli/dev/tui/prompt-placeholder.js +1 -0
- package/dist/src/cli/dev/tui/question-panel.d.ts +24 -0
- package/dist/src/cli/dev/tui/question-panel.js +1 -0
- package/dist/src/cli/dev/tui/rail.d.ts +15 -0
- package/dist/src/cli/dev/tui/rail.js +1 -0
- package/dist/src/cli/dev/tui/runner.d.ts +22 -65
- package/dist/src/cli/dev/tui/runner.js +1 -1
- package/dist/src/cli/dev/tui/setup-commands.js +1 -1
- package/dist/src/cli/dev/tui/setup-issues.js +1 -1
- package/dist/src/cli/dev/tui/status-line.js +1 -1
- package/dist/src/cli/dev/tui/stream-format.d.ts +16 -3
- package/dist/src/cli/dev/tui/stream-format.js +1 -1
- package/dist/src/cli/dev/tui/subagent-pump.d.ts +127 -0
- package/dist/src/cli/dev/tui/subagent-pump.js +1 -0
- package/dist/src/cli/dev/tui/terminal-renderer.d.ts +34 -1
- package/dist/src/cli/dev/tui/terminal-renderer.js +11 -10
- package/dist/src/cli/dev/tui/test/mock-terminal.d.ts +7 -0
- package/dist/src/cli/dev/tui/test/mock-terminal.js +1 -1
- package/dist/src/cli/dev/tui/theme.d.ts +16 -2
- package/dist/src/cli/dev/tui/theme.js +1 -1
- package/dist/src/cli/dev/tui/todo-panel.d.ts +44 -0
- package/dist/src/cli/dev/tui/todo-panel.js +1 -0
- package/dist/src/cli/dev/tui/tool-block-groups.d.ts +40 -0
- package/dist/src/cli/dev/tui/tool-block-groups.js +1 -0
- package/dist/src/cli/dev/tui/tool-presentation.d.ts +67 -0
- package/dist/src/cli/dev/tui/tool-presentation.js +1 -0
- package/dist/src/cli/dev/tui/tool-rows.d.ts +15 -0
- package/dist/src/cli/dev/tui/tool-rows.js +2 -0
- package/dist/src/cli/dev/tui/turn-clock.d.ts +36 -0
- package/dist/src/cli/dev/tui/turn-clock.js +1 -0
- package/dist/src/cli/dev/tui/types.d.ts +2 -2
- package/dist/src/cli/dev/ui-options.js +1 -1
- package/dist/src/client/index.js +1 -1
- package/dist/src/client/message-action-parts.d.ts +43 -0
- package/dist/src/client/message-action-parts.js +1 -0
- package/dist/src/client/message-reducer.js +1 -1
- package/dist/src/client/session.js +1 -1
- package/dist/src/compiled/.vendor-stamp.json +6 -5
- package/dist/src/compiled/@chat-adapter/slack/blocks.d.ts +47 -2
- package/dist/src/compiled/@chat-adapter/slack/blocks.js +10 -8
- package/dist/src/compiled/@chat-adapter/slack/index.d.ts +168 -8
- package/dist/src/compiled/@chat-adapter/slack/index.js +28 -28
- package/dist/src/compiled/@chat-adapter/slack/{types-AntsVifS.d.ts → types-CdGmMyOr.d.ts} +1 -1
- package/dist/src/compiled/@chat-adapter/slack/webhook.d.ts +2 -2
- package/dist/src/compiled/@chat-adapter/twilio/index.d.ts +1 -1
- package/dist/src/compiled/@chat-adapter/twilio/index.js +1 -1
- package/dist/src/compiled/@chat-adapter/twilio/webhook.d.ts +2 -2
- package/dist/src/compiled/@vercel/sandbox/index.js +12 -12
- package/dist/src/compiled/_chunks/node/{auth-Cuszvn7l.js → auth-BuQkq4Gr.js} +2 -2
- package/dist/src/compiled/_chunks/node/{dist-CdH_Yoxt.js → dist-BweCayKF.js} +42 -35
- package/dist/src/compiled/_chunks/node/{dist-Drt-_JVK.js → dist-DvkWiagq.js} +6 -4
- package/dist/src/compiled/chat/index.d.ts +17 -6
- package/dist/src/compiled/chat/index.js +1 -1
- package/dist/src/compiled/chat/{jsx-runtime-CzthIo1o.d.ts → jsx-runtime-_JEEAotp.d.ts} +125 -5
- package/dist/src/compiled/marked/LICENSE.md +44 -0
- package/dist/src/compiled/marked/index.d.ts +24 -0
- package/dist/src/compiled/marked/index.js +59 -0
- package/dist/src/compiler/model-catalog.js +1 -1
- package/dist/src/evals/autoevals-client.js +1 -1
- package/dist/src/evals/session.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel-credentials.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel-lookup.js +1 -1
- package/dist/src/execution/session.d.ts +0 -2
- package/dist/src/execution/session.js +1 -1
- package/dist/src/execution/skills/instructions.d.ts +3 -3
- package/dist/src/execution/skills/instructions.js +2 -2
- package/dist/src/execution/terminal-session-failure-step.js +1 -1
- package/dist/src/execution/workflow-steps.js +1 -1
- package/dist/src/harness/messages.d.ts +7 -0
- package/dist/src/harness/messages.js +1 -1
- package/dist/src/harness/stale-input-responses.js +2 -2
- package/dist/src/harness/tool-loop.js +2 -2
- package/dist/src/internal/application/compiled-artifacts.js +9 -3
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/gateway.d.ts +19 -0
- package/dist/src/internal/gateway.js +1 -0
- package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response-from-manifest.js +1 -1
- package/dist/src/internal/nitro/routes/info.js +1 -1
- package/dist/src/internal/resolve-model-endpoint-status.d.ts +46 -3
- package/dist/src/internal/resolve-model-endpoint-status.js +1 -1
- package/dist/src/internal/user-agent.d.ts +11 -0
- package/dist/src/internal/user-agent.js +1 -0
- package/dist/src/public/tools/defaults.d.ts +3 -3
- package/dist/src/runtime/framework-tools/index.d.ts +3 -2
- package/dist/src/runtime/framework-tools/index.js +1 -1
- package/dist/src/runtime/framework-tools/skill.d.ts +6 -1
- package/dist/src/runtime/framework-tools/skill.js +1 -1
- package/dist/src/runtime/resolve-agent-graph.js +1 -1
- package/dist/src/setup/boxes/select-model.js +1 -1
- package/dist/src/setup/flows/link.d.ts +13 -3
- package/dist/src/setup/flows/link.js +1 -1
- package/dist/src/setup/flows/model.d.ts +4 -3
- package/dist/src/setup/flows/model.js +1 -1
- package/dist/src/setup/flows/provider.d.ts +3 -1
- package/dist/src/setup/flows/provider.js +2 -2
- package/dist/src/setup/gateway-models.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/setup/validate-gateway-key.js +1 -1
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-eve-agent.js +1 -1
- package/dist/src/vue/index.js +1 -1
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/docs/concepts/sessions-runs-and-streaming.md +7 -7
- package/docs/reference/cli.md +1 -1
- package/docs/schedules.mdx +1 -1
- package/docs/skills.mdx +1 -1
- package/package.json +6 -5
- package/dist/src/execution/sandbox/bindings/vercel-user-agent.d.ts +0 -6
- package/dist/src/execution/sandbox/bindings/vercel-user-agent.js +0 -1
- package/dist/src/execution/workflow-skill-root.d.ts +0 -6
- package/dist/src/execution/workflow-skill-root.js +0 -1
|
@@ -9,9 +9,11 @@
|
|
|
9
9
|
* boxes anywhere. Every returned row is already styled and fits within the
|
|
10
10
|
* given width, so the live region can place rows verbatim.
|
|
11
11
|
*/
|
|
12
|
+
import type { ToolDetailLine } from "./line-diff.js";
|
|
12
13
|
import type { Theme } from "./theme.js";
|
|
14
|
+
import type { ToolGroupPresentation } from "./tool-presentation.js";
|
|
13
15
|
export type ToolStatus = "running" | "done" | "error" | "denied" | "approval";
|
|
14
|
-
export type BlockKind = "user" | "assistant" | "reasoning" | "tool" | "error" | "notice" | "warning" | "result" | "flow" | "command" | "question" | "subagent" | "subagent-step" | "subagent-tool" | "connection-auth" | "sandbox" | "log" | "agent-header";
|
|
16
|
+
export type BlockKind = "user" | "assistant" | "reasoning" | "tool" | "error" | "notice" | "warning" | "result" | "flow" | "command" | "question" | "subagent" | "subagent-step" | "subagent-tool" | "subagent-close" | "connection-auth" | "sandbox" | "log" | "turn-stats" | "session-boundary" | "todo-list" | "agent-header";
|
|
15
17
|
/**
|
|
16
18
|
* One renderable transcript unit. Fields are interpreted per `kind`; unset
|
|
17
19
|
* fields are simply omitted from the rendered output.
|
|
@@ -22,10 +24,12 @@ export interface Block {
|
|
|
22
24
|
id?: string;
|
|
23
25
|
/** Nesting depth: 0 = top level, 1 = inside a subagent, etc. */
|
|
24
26
|
depth?: number;
|
|
25
|
-
/** Whether the block is still streaming / mutating (drives the
|
|
27
|
+
/** Whether the block is still streaming / mutating (drives the activity pulse). */
|
|
26
28
|
live?: boolean;
|
|
27
29
|
/** Primary label — tool name, subagent name, log source, error title. */
|
|
28
30
|
title?: string;
|
|
31
|
+
/** Past-tense tool label swapped in once the call settles successfully. */
|
|
32
|
+
doneTitle?: string;
|
|
29
33
|
/** Compact secondary text — summarized tool args. */
|
|
30
34
|
subtitle?: string;
|
|
31
35
|
/** Main multi-line content (markdown for prose, plain for logs). */
|
|
@@ -54,15 +58,59 @@ export interface Block {
|
|
|
54
58
|
/** Raw tool input / output for the expanded view. */
|
|
55
59
|
toolInput?: unknown;
|
|
56
60
|
toolOutput?: unknown;
|
|
61
|
+
/** Original execution name, kept separate from a semantic display title. */
|
|
62
|
+
toolName?: string;
|
|
63
|
+
/** Optional aggregation metadata; execution state remains on this call's block. */
|
|
64
|
+
toolGroup?: ToolGroupPresentation;
|
|
65
|
+
/** Salient body lines rendered behind the `│` rail under the tool header. */
|
|
66
|
+
detailLines?: readonly ToolDetailLine[];
|
|
67
|
+
/** When true, `detailLines` stay visible after the call settles (writes). */
|
|
68
|
+
keepDetailWhenDone?: boolean;
|
|
69
|
+
/** Links a subagent section's header and children so calls can coalesce. */
|
|
70
|
+
subagentCallId?: string;
|
|
71
|
+
/**
|
|
72
|
+
* Monotonic activity stamp, bumped on every push and in-place update.
|
|
73
|
+
* Recency windows key on it so a parallel-announced call that just
|
|
74
|
+
* settled counts as newer than a later-announced one still idle.
|
|
75
|
+
*/
|
|
76
|
+
updateSeq?: number;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* What the renderers actually draw: an execution {@link Block} plus the
|
|
80
|
+
* synthesized presentation the display grouping may attach. Only the
|
|
81
|
+
* grouping layer creates these fields, so an execution block can never
|
|
82
|
+
* smuggle display state — the type boundary enforces what used to be a
|
|
83
|
+
* comment.
|
|
84
|
+
*/
|
|
85
|
+
export interface DisplayBlock extends Block {
|
|
86
|
+
/** Items listed when equivalent tool calls are coalesced into one row. */
|
|
87
|
+
toolGroupItems?: readonly ToolGroupItem[];
|
|
88
|
+
/**
|
|
89
|
+
* Stand-in for this many earlier sibling rows elided from a capped
|
|
90
|
+
* subagent run; renders as a single dim `… +N more` line.
|
|
91
|
+
*/
|
|
92
|
+
elided?: number;
|
|
93
|
+
/**
|
|
94
|
+
* This block is the last of its section, so its final row swaps the
|
|
95
|
+
* nesting rule for the closing `└` — the rail ends on the newest child
|
|
96
|
+
* instead of a bare corner row.
|
|
97
|
+
*/
|
|
98
|
+
closesRail?: boolean;
|
|
99
|
+
}
|
|
100
|
+
/** One coalesced call's row beneath an aggregated tool header. */
|
|
101
|
+
export interface ToolGroupItem {
|
|
102
|
+
readonly text: string;
|
|
103
|
+
/** Per-call failure summary, present when a failed batch is aggregated. */
|
|
104
|
+
readonly result?: string;
|
|
57
105
|
}
|
|
58
106
|
export interface RenderBlockContext {
|
|
59
|
-
/** Current
|
|
60
|
-
|
|
107
|
+
/** Current shared square-pulse frame for live activity blocks. */
|
|
108
|
+
activityPulse: string;
|
|
61
109
|
/**
|
|
62
110
|
* Kind and title of the block rendered immediately above this one. Lets a
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
111
|
+
* sandbox block detect that it continues a run (label suppressed, lines
|
|
112
|
+
* hang under the previous block's label) without any mutable run state —
|
|
113
|
+
* each captured write stays its own immediately-committed block.
|
|
66
114
|
*/
|
|
67
115
|
previous?: {
|
|
68
116
|
kind: BlockKind;
|
|
@@ -73,7 +121,7 @@ export interface RenderBlockContext {
|
|
|
73
121
|
* Renders a block to its terminal rows. Each row is fully styled and clipped
|
|
74
122
|
* to `width` visible columns.
|
|
75
123
|
*/
|
|
76
|
-
export declare function renderBlockLines(block:
|
|
124
|
+
export declare function renderBlockLines(block: DisplayBlock, width: number, theme: Theme, context: RenderBlockContext): string[];
|
|
77
125
|
/**
|
|
78
126
|
* The setup attention line (`⚠ 1 setup issue: … · /model`): yellow glyph, body
|
|
79
127
|
* at full intensity, slash commands painted blue so the fix reads as actionable
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{isPromptControlCommand}from"./prompt-commands.js";import{
|
|
2
|
-
`)}}function renderUser(e,t,n){let r=n.colors.cyan(n.glyph.user);return wrap(e.body??``,t-2).map(e=>`${r} ${e}`)}function renderProse(e,
|
|
3
|
-
`).flatMap(e=>wrapVisibleLine(e,
|
|
4
|
-
`),i=r.slice(0,12),a=i.map(e=>` ${n.colors.dim(truncatePlain(e,Math.max(1,t-2)))}`),o=r.length-i.length;return o>0&&a.push(` ${n.colors.dim(`${n.glyph.ellipsis} +${o} more line${o===1?``:`s`}`)}`),a}const URL_PATTERN=/(https?:\/\/\S+)/u;function colorizeError(e,t){return URL_PATTERN.test(e)?e.split(URL_PATTERN).map((e,n)=>n%2==1?t.colors.cyan(e):t.colors.red(e)).join(``):t.colors.red(e)}function renderNotice(e,t,n){let r=n.colors.dim(n.glyph.dot),i=wrap(e.body??``,t-2);return i.length===0?[r]:i.map(e=>`${r} ${n.colors.dim(e)}`)}function renderAttentionRows(e,t,n){let r=n.colors.yellow(n.glyph.warning);return wrap(e,t-2).map((e,t)=>`${t===0?r:` `} ${paintCommands(e,n)}`)}function renderWarning(e,t,n){return renderAttentionRows(e.body??``,t,n)}function paintCommands(t,n){return t.replace(/\/[a-z:-]+/g,t=>isPromptControlCommand(t)?n.colors.blue(t):t)}function renderCommand(e,t){let n=t.colors,r=e.status===`error`?`${n.red(t.glyph.error)} `:``;return[`${n.cyan(t.glyph.user)} ${r}${n.blue(e.body??``)}`]}function renderFlow(e,t,n){let r=n.colors,i=e.title??`info`,a=i===`success`?r.green(n.glyph.success):i===`warning`?r.yellow(n.glyph.warning):i===`error`?r.red(n.glyph.error):r.dim(n.glyph.dot),o=wrap(e.body??``,t-2),paint=e=>i===`info`?r.dim(e):e;return o.map((e,t)=>`${t===0?a:` `} ${paint(e)}`)}function renderResult(e,t,n){let r=n.colors.dim(n.glyph.elbow),i=wrap(e.body??``,t-7);if(i.length===0)return[` ${r}`];let dim=e=>n.colors.dim(e.replaceAll(`\x1B[22m`,`\x1B[22m\x1B[2m`));return i.map((e,t)=>t===0?` ${r} ${dim(e)}`:` ${dim(e)}`)}function renderPreformatted(e,t,n){let r=e.kind===`connection-auth`?n.colors.yellow(n.glyph.connection):n.colors.yellow(n.colors.bold(n.glyph.question)),i=wrap(e.title??``,t-2),a
|
|
5
|
-
`))for(let e of wrapVisibleLine(n,t-
|
|
6
|
-
`),f=[];for(let e of d){let r=wrapVisibleLine(e,Math.max(1,t-2-c));for(let e of r){let t=f.length===0&&!u?
|
|
7
|
-
`)
|
|
1
|
+
import{isPromptControlCommand}from"./prompt-commands.js";import{renderMarkdown}from"./markdown.js";import{elisionText}from"./rail.js";import{renderTool}from"./tool-rows.js";import{clipVisible,sliceVisible,visibleLength,wrapVisibleLine}from"#cli/ui/terminal-text.js";function renderBlockLines(e,t,n,r){let i=e.depth??0,a=nestingPrefix(i,n),s=renderBody(e,Math.max(8,t-visibleLength(a)),n,r);if(e.closesRail===!0&&i>0){let e=closingPrefix(i,n);return s.map((t,n)=>`${n===s.length-1?e:a}${t}`)}return s.map(e=>`${a}${e}`)}function nestingPrefix(e,t){return e<=0?``:` ${`${t.colors.dim(t.glyph.rule)} `.repeat(e)}`}function closingPrefix(e,t){return` ${`${t.colors.dim(t.glyph.rule)} `.repeat(e-1)}${t.colors.dim(t.glyph.corner)} `}function renderBody(e,t,a,o){if(e.elided!==void 0&&e.kind===`subagent-step`)return[` ${elisionText(e.elided,a)}`];switch(e.kind){case`user`:return renderUser(e,t,a);case`assistant`:case`subagent-step`:return renderProse(e,t,a);case`reasoning`:return renderReasoning(e,t,a);case`tool`:case`subagent-tool`:return renderTool(e,t,a,o);case`error`:return renderError(e,t,a);case`notice`:return renderNotice(e,t,a);case`warning`:return renderWarning(e,t,a);case`result`:return renderResult(e,t,a);case`flow`:return renderFlow(e,t,a);case`command`:return renderCommand(e,a);case`question`:case`connection-auth`:return renderPreformatted(e,t,a);case`sandbox`:return renderSandbox(e,t,a,o);case`log`:return renderLog(e,t,a);case`subagent`:return renderSubagentHeader(e,t,a);case`subagent-close`:{let n=` ${a.colors.dim(a.glyph.corner)}`;return e.body!==void 0&&e.body.length>0?[clipVisible(`${n} ${a.colors.dim(e.body)}`,Math.max(1,t))]:[n]}case`turn-stats`:return renderTurnStats(e,t,a);case`session-boundary`:case`todo-list`:case`agent-header`:return(e.body??``).split(`
|
|
2
|
+
`)}}function renderUser(e,t,n){let r=n.colors.cyan(n.glyph.user);return wrap(e.body??``,t-2).map(e=>`${r} ${e}`)}function renderProse(e,n,r){let i=[],o=e.kind===`subagent-step`;if(o&&e.collapsed===!0){let t=firstNonEmptyLine(e.body)??(e.reasoning===void 0?void 0:firstNonEmptyLine(e.reasoning));return t===void 0?[]:[r.colors.dim(sliceVisible(t,Math.max(1,n)))]}let c=o?``:`${r.colors.bold(r.glyph.brand)} `,l=o?``:` `;e.reasoning&&e.reasoning.trim().length>0&&i.push(...renderReasoningLines(e.reasoning,n,r));let u=(e.body??``).trim();return u.length===0&&i.length===0?[`${c}${r.colors.dim(`thinking${r.glyph.ellipsis}`)}`]:(u.length>0&&renderMarkdown(u,n-l.length).split(`
|
|
3
|
+
`).flatMap(e=>wrapVisibleLine(e,n-l.length)).forEach((e,t)=>{t===0&&!o&&i.length===0?i.push(`${c}${e}`):i.push(`${l}${e}`)}),i.length>0?i:[`${c}`])}function renderReasoning(e,t,n){return e.collapsed?[`${n.colors.gray(n.glyph.reasoning)} ${n.colors.dim(e.title??`thinking`)}`]:renderReasoningLines(e.body??``,t,n,n.glyph.reasoning)}function renderReasoningLines(e,t,n,r){let i=r?2:0,a=wrap(e.trim(),t-i);return a.length===0?[]:a.map((e,t)=>`${r?t===0?`${n.colors.gray(r)} `:` `:``}${n.colors.dim(n.colors.italic(e))}`)}function renderError(e,t,n){let r=n.colors.red(n.colors.bold(n.glyph.error)),i=e.title??`Error`,a=[`${r} ${n.colors.red(n.colors.bold(i))}`];for(let r of wrap(e.body??``,t-2))a.push(` ${colorizeError(r,n)}`);if(e.hint!==void 0&&e.hint.trim().length>0)for(let[r,i]of wrap(e.hint,t-4).entries()){let e=r===0?`${n.glyph.arrow} `:` `;a.push(` ${n.colors.cyan(`${e}${i}`)}`)}return a.push(...renderErrorDetail(e.detail,t,n)),a}function renderErrorDetail(e,t,n){if(e===void 0||e.trim().length===0)return[];let r=e.split(`
|
|
4
|
+
`),i=r.slice(0,12),a=i.map(e=>` ${n.colors.dim(truncatePlain(e,Math.max(1,t-2)))}`),o=r.length-i.length;return o>0&&a.push(` ${n.colors.dim(`${n.glyph.ellipsis} +${o} more line${o===1?``:`s`}`)}`),a}const URL_PATTERN=/(https?:\/\/\S+)/u;function colorizeError(e,t){return URL_PATTERN.test(e)?e.split(URL_PATTERN).map((e,n)=>n%2==1?t.colors.cyan(e):t.colors.red(e)).join(``):t.colors.red(e)}function renderNotice(e,t,n){let r=n.colors.dim(n.glyph.dot),i=wrap(e.body??``,t-2);return i.length===0?[r]:i.map(e=>`${r} ${n.colors.dim(e)}`)}function renderAttentionRows(e,t,n){let r=n.colors.yellow(n.glyph.warning);return wrap(e,t-2).map((e,t)=>`${t===0?r:` `} ${paintCommands(e,n)}`)}function renderWarning(e,t,n){return renderAttentionRows(e.body??``,t,n)}function paintCommands(t,n){return t.replace(/\/[a-z:-]+/g,t=>isPromptControlCommand(t)?n.colors.blue(t):t)}function renderCommand(e,t){let n=t.colors,r=e.status===`error`?`${n.red(t.glyph.error)} `:``;return[`${n.cyan(t.glyph.user)} ${r}${n.blue(e.body??``)}`]}function renderFlow(e,t,n){let r=n.colors,i=e.title??`info`,a=i===`success`?r.green(n.glyph.success):i===`warning`?r.yellow(n.glyph.warning):i===`error`?r.red(n.glyph.error):r.dim(n.glyph.dot),o=wrap(e.body??``,t-2),paint=e=>i===`info`?r.dim(e):e;return o.map((e,t)=>`${t===0?a:` `} ${paint(e)}`)}function renderResult(e,t,n){let r=n.colors.dim(n.glyph.elbow),i=wrap(e.body??``,t-7);if(i.length===0)return[` ${r}`];let dim=e=>n.colors.dim(e.replaceAll(`\x1B[22m`,`\x1B[22m\x1B[2m`));return i.map((e,t)=>t===0?` ${r} ${dim(e)}`:` ${dim(e)}`)}function renderPreformatted(e,t,n){let r=e.kind===`connection-auth`?n.colors.yellow(n.glyph.connection):n.colors.yellow(n.colors.bold(n.glyph.question)),i=e.kind===`question`?` `:` `,a=wrap(e.title??``,t-2),o=a.length===0?[`${r} `]:a.map((e,t)=>t===0?`${r} ${n.colors.bold(e)}`:` ${n.colors.bold(e)}`);for(let n of(e.body??``).split(`
|
|
5
|
+
`))for(let e of wrapVisibleLine(n,Math.max(1,t-i.length)))o.push(`${i}${e}`);return o}function renderSandbox(e,t,n,r){let i=n.colors.cyan(n.glyph.rule),a=n.colors.dim(`sandbox ${n.glyph.dot} `),c=visibleLength(a),l=` `.repeat(c),u=r.previous?.kind===`sandbox`,d=(e.body??``).split(`
|
|
6
|
+
`),f=[];for(let e of d){let r=wrapVisibleLine(e,Math.max(1,t-2-c));for(let e of r){let t=f.length===0&&!u?a:l;f.push(`${i} ${t}${n.colors.gray(e)}`)}}return f.length>0?f:[`${i}`]}function renderLog(e,t,r){let i=e.title===`stderr`,a=i?r.colors.red:r.colors.gray,o=r.colors.dim(r.glyph.rule),c=i?`stderr`:`stdout`,l=[`${r.colors.dim(r.glyph.reasoning)} ${r.colors.dim(c)}`];e.elided!==void 0&&e.elided>0&&l.push(`${o} ${elisionText(e.elided,r)}`);for(let n of(e.body??``).split(`
|
|
7
|
+
`))for(let e of wrapVisibleLine(n,Math.max(1,t-2)))l.push(`${o} ${r.colors.dim(a(e))}`);return l}function renderTurnStats(e,t,n){let r=`${n.glyph.corner} ${e.body??``}`;return[n.colors.dim(truncatePlain(r,Math.max(1,t)))]}function renderSubagentHeader(e,t,n){let r=truncatePlain(e.title===void 0||e.title===`agent`?`self`:e.title,Math.max(8,t-16)),i=e.subtitle!==void 0&&e.subtitle.startsWith(`#`),a=i?`:${e.subtitle.slice(1)}`:``,o=` ${e.status===`done`?n.colors.green(n.glyph.subagent):n.colors.orange(n.glyph.subagent)} ${n.colors.bold(`subagent(${r}${a})`)}`;return!i&&e.subtitle!==void 0&&e.subtitle.length>0&&(o+=` ${n.colors.dim(e.subtitle)}`),[o]}function firstNonEmptyLine(e){return e===void 0?void 0:e.split(/\r?\n/u).find(e=>e.trim().length>0)?.trim()}function wrap(e,t){return e.trim().length===0?[]:e.split(`
|
|
8
8
|
`).flatMap(e=>wrapVisibleLine(e,Math.max(1,t)))}function truncatePlain(e,t){return visibleLength(e)<=t?e:sliceVisible(e,t)}export{renderAttentionRows,renderBlockLines};
|
|
@@ -4,6 +4,8 @@ export type DiagnosticPresentation = {
|
|
|
4
4
|
} | {
|
|
5
5
|
readonly kind: "stored";
|
|
6
6
|
readonly summary: string;
|
|
7
|
+
/** First error-naming line of the collapsed body, when one exists. */
|
|
8
|
+
readonly headline?: string;
|
|
7
9
|
readonly omittedLines: number;
|
|
8
10
|
readonly path: string;
|
|
9
11
|
};
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
function presentDiagnostic(
|
|
2
|
-
`);if(
|
|
1
|
+
const ERROR_HEADLINE_PATTERN=/^\s*(?:message|name):\s*\S|^\s*[A-Z][\w$]*Error\b/u;function presentDiagnostic(t,n){let r=t.split(`
|
|
2
|
+
`);if(r.length<=4&&t.length<=600)return{kind:`inline`,text:t};let i=r.findIndex(e=>e.trim().length>0),a=i===-1?`Diagnostic output`:r[i].trim(),o=r.slice(i+1).find(t=>ERROR_HEADLINE_PATTERN.test(t))?.trim(),s=1+(o===void 0?0:1),c={kind:`stored`,summary:clip(a),omittedLines:Math.max(0,r.length-s),path:n};return o===void 0?c:{...c,headline:clip(o)}}function formatStoredDiagnostic(e){let t=e.omittedLines,n=t===0?`diagnostic details`:`${t} diagnostic line${t===1?``:`s`}`,r=[e.summary];return e.headline!==void 0&&r.push(e.headline),r.push(`… ${n} · details: ${e.path}`),r.join(`
|
|
3
|
+
`)}function clip(e){return e.length<=240?e:`${e.slice(0,239)}…`}export{formatStoredDiagnostic,presentDiagnostic};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session-local knowledge of file contents, so the write block can show a
|
|
3
|
+
* real diff without any protocol addition. Two feeds keep it current: every
|
|
4
|
+
* `write_file` input is a full replacement (exact), and every full-file
|
|
5
|
+
* `read_file` result reconstructs to the file's exact lines. Files touched
|
|
6
|
+
* outside these two paths (e.g. by `bash`) are invisible here — a write over
|
|
7
|
+
* unknown prior content renders plain rather than pretending to be a diff.
|
|
8
|
+
*/
|
|
9
|
+
export declare class FileContentCache {
|
|
10
|
+
#private;
|
|
11
|
+
/**
|
|
12
|
+
* Records one write and returns the content it replaced. Tool blocks
|
|
13
|
+
* re-render on every lifecycle event of the same call, so a repeated
|
|
14
|
+
* observation of `callId` keeps returning the original previous content
|
|
15
|
+
* instead of diffing the write against itself.
|
|
16
|
+
*/
|
|
17
|
+
observeWrite(input: {
|
|
18
|
+
path: string;
|
|
19
|
+
content: string;
|
|
20
|
+
callId: string;
|
|
21
|
+
}): string | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Forgets everything. A new conversation runs against a fresh session —
|
|
24
|
+
* possibly a fresh sandbox — so stale bases would produce confidently
|
|
25
|
+
* wrong diffs.
|
|
26
|
+
*/
|
|
27
|
+
clear(): void;
|
|
28
|
+
/**
|
|
29
|
+
* Records a read result when it provably covers the whole file: not
|
|
30
|
+
* truncated, starting at line 1, with exactly `totalLines` numbered lines.
|
|
31
|
+
* Partial or truncated reads are ignored — caching them would produce
|
|
32
|
+
* confidently wrong diffs later.
|
|
33
|
+
*/
|
|
34
|
+
observeRead(output: unknown): void;
|
|
35
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
const MAX_CACHED_CONTENT_CHARS=2e5;var FileContentCache=class{#e=new Map;observeWrite(t){let n=this.#e.get(t.path);if(n?.writerCallId===t.callId)return n.previous;if(t.content.length>MAX_CACHED_CONTENT_CHARS){this.#e.delete(t.path);return}let r=n?.content,i={content:t.content,writerCallId:t.callId};return r!==void 0&&(i.previous=r),this.#e.set(t.path,i),r}clear(){this.#e.clear()}observeRead(t){let n=readFileResultShape(t);if(n===void 0||n.truncated||n.content.length>MAX_CACHED_CONTENT_CHARS)return;let r=reconstructNumberedLines(n.content);r===void 0||r.length!==n.totalLines||this.#e.set(n.path,{content:r.join(`
|
|
2
|
+
`)})}};function readFileResultShape(e){if(typeof e!=`object`||!e||Array.isArray(e))return;let{content:t,path:n,totalLines:r,truncated:i}=e;if(!(typeof t!=`string`||typeof n!=`string`)&&!(typeof r!=`number`||typeof i!=`boolean`))return{content:t,path:n,totalLines:r,truncated:i}}function reconstructNumberedLines(e){if(e===``)return[];let t=[];for(let[n,r]of e.split(`
|
|
3
|
+
`).entries()){let e=/^(\d+): (.*)$/su.exec(r);if(e===null||Number(e[1])!==n+1)return;t.push(e[2])}return t}export{FileContentCache};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure line diffing for the write block's rail. The TUI computes diffs
|
|
3
|
+
* client-side from content it has already seen (write inputs, full-file read
|
|
4
|
+
* results) — putting prior content into the tool's output would feed it
|
|
5
|
+
* straight back into model context, paying tokens for something only the
|
|
6
|
+
* terminal needs.
|
|
7
|
+
*/
|
|
8
|
+
/** One rail row under a tool header. `kind` is unset for plain/context text. */
|
|
9
|
+
export interface ToolDetailLine {
|
|
10
|
+
readonly text: string;
|
|
11
|
+
readonly kind?: "added" | "removed" | "gap";
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Builds the write rail for `content` against what it replaced.
|
|
15
|
+
*
|
|
16
|
+
* - `previous` known → a windowed line diff (changes with two context lines,
|
|
17
|
+
* unchanged stretches collapsed behind `gap` rows); identical content
|
|
18
|
+
* yields no rows.
|
|
19
|
+
* - `previous` unknown but the file provably did not exist → every line is
|
|
20
|
+
* an addition.
|
|
21
|
+
* - otherwise → plain content rows, because inventing `+` markers for an
|
|
22
|
+
* overwrite would misread as "everything changed".
|
|
23
|
+
*/
|
|
24
|
+
export declare function diffWriteDetail(previous: string | undefined, content: string, existed?: boolean): ToolDetailLine[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function diffWriteDetail(e,t,n){let r=splitContentLines(t);if(e===void 0)return n===!1?r.map(e=>({text:e,kind:`added`})):r.map(e=>({text:e}));let i=splitContentLines(e);return(i.length+1)*(r.length+1)>25e4?r.map(e=>({text:e})):windowHunks(lcsDiff(i,r))}function splitContentLines(e){let t=e.split(/\r?\n/u);for(;t.length>0&&t.at(-1)?.trim()===``;)t.pop();return t}function lcsDiff(e,t){let n=t.length+1,r=new Uint32Array((e.length+1)*n);for(let i=e.length-1;i>=0;--i)for(let a=t.length-1;a>=0;--a)r[i*n+a]=e[i]===t[a]?r[(i+1)*n+a+1]+1:Math.max(r[(i+1)*n+a],r[i*n+a+1]);let i=[],a=0,o=0;for(;a<e.length&&o<t.length;)e[a]===t[o]?(i.push({text:e[a]}),a+=1,o+=1):r[(a+1)*n+o]>=r[a*n+o+1]?(i.push({text:e[a],kind:`removed`}),a+=1):(i.push({text:t[o],kind:`added`}),o+=1);for(;a<e.length;a+=1)i.push({text:e[a],kind:`removed`});for(;o<t.length;o+=1)i.push({text:t[o],kind:`added`});return i}function windowHunks(e){let t=e.map(e=>e.kind===`added`||e.kind===`removed`);if(!t.includes(!0))return[];let n=e.map((n,r)=>{for(let n=Math.max(0,r-2);n<=Math.min(e.length-1,r+2);n+=1)if(t[n])return!0;return!1}),r=[];for(let[t,i]of e.entries())n[t]?r.push(i):r.at(-1)?.kind!==`gap`&&r.push({text:``,kind:`gap`});return r}export{diffWriteDetail};
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
/** Renders parsed GFM blocks to terminal text, fitting tables to `width`. */
|
|
2
|
+
export declare function renderMarkdown(input: string, width?: number): string;
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
-
import{visibleLength}from"#cli/ui/terminal-text.js";const ansi={bold:`\x1B[1m`,boldOff:`\x1B[22m`,italic:`\x1B[3m`,italicOff:`\x1B[23m`};function renderMarkdown(e){
|
|
2
|
-
`),n=[];for(let e
|
|
3
|
-
`)
|
|
1
|
+
import{sliceVisible,visibleLength}from"#cli/ui/terminal-text.js";import{lexer}from"#compiled/marked/index.js";const ansi={bold:`\x1B[1m`,boldOff:`\x1B[22m`,cyan:`\x1B[36m`,cyanOff:`\x1B[39m`,dim:`\x1B[2m`,dimOff:`\x1B[22m`,italic:`\x1B[3m`,italicOff:`\x1B[23m`,strike:`\x1B[9m`,strikeOff:`\x1B[29m`};function renderMarkdown(e,t=1/0){return trimTrailingBlankRows(renderBlocks(lexer(e),t)).join(`
|
|
2
|
+
`)}function renderBlocks(e,t){let n=[];for(let i of e)switch(i.type){case`space`:pushBlankRow(n);break;case`heading`:{let e=i.depth===1?`█`:i.depth===2?`■`:`▶`;n.push(`${e} ${ansi.bold}${renderInline(i.tokens)}${ansi.boldOff}`);break}case`paragraph`:case`text`:n.push(...renderInline(i.tokens,i.text).split(`
|
|
3
|
+
`));break;case`code`:n.push(...renderCodeBlock(i));break;case`blockquote`:n.push(...renderBlocks(i.tokens??[],Math.max(8,t-2)).map(e=>`${ansi.dim}│${ansi.dimOff} ${e}`));break;case`list`:n.push(...renderList(i,t));break;case`table`:n.push(...renderTable(i,t));break;case`hr`:n.push(ansi.dim+`─`.repeat(horizontalRuleWidth(t))+ansi.dimOff);break;case`html`:n.push(...(i.text??i.raw??``).split(`
|
|
4
|
+
`));break;case`def`:break;default:i.tokens===void 0?i.text!==void 0&&n.push(i.text):n.push(...renderBlocks(i.tokens,t));break}return n}function renderCodeBlock(e){let t=[];e.lang?.trim()&&t.push(` ${ansi.dim}${e.lang.trim()}${ansi.dimOff}`);let n=(e.text??``).replace(/\n$/u,``).split(`
|
|
5
|
+
`);for(let e of n)t.push(`${ansi.dim}│${ansi.dimOff} ${ansi.cyan}${e}${ansi.cyanOff}`);return t}function renderList(e,t){let n=[],r=typeof e.start==`number`?e.start:1;for(let i of e.items??[]){let a=e.ordered?`${r}.`:`•`,o=i.checked===!0?`☑ `:i.checked===!1?`☐ `:``,s=renderBlocks(i.tokens??[],Math.max(8,t-a.length-1));(s.length===0?[``]:s).forEach((e,t)=>{n.push(t===0?`${a} ${o}${e}`:`${` `.repeat(a.length+1)}${e}`)}),r+=1}return n}function renderInline(e,t=``){return e===void 0?t:e.map(renderInlineToken).join(``)}function renderInlineToken(e){switch(e.type){case`text`:return renderInline(e.tokens,e.text??``);case`strong`:return`${ansi.bold}${renderInline(e.tokens,e.text)}${ansi.boldOff}`;case`em`:return`${ansi.italic}${renderInline(e.tokens,e.text)}${ansi.italicOff}`;case`del`:return`${ansi.strike}${renderInline(e.tokens,e.text)}${ansi.strikeOff}`;case`codespan`:return`${ansi.cyan}${e.text??``}${ansi.cyanOff}`;case`link`:{let t=renderInline(e.tokens,e.text),n=e.href??``;return n.length===0||t===n?`${ansi.cyan}${t}${ansi.cyanOff}`:`${t} (${ansi.cyan}${n}${ansi.cyanOff})`}case`image`:{let t=e.text?.trim()||`image`,n=e.href??``;return n.length===0?`[${t}]`:`[${t}] (${ansi.cyan}${n}${ansi.cyanOff})`}case`br`:return`
|
|
6
|
+
`;case`checkbox`:return e.checked?`☑ `:`☐ `;case`escape`:return e.text??``;case`html`:return e.text??e.raw??``;default:return renderInline(e.tokens,e.text??e.raw??``)}}function renderTable(e,n){let i=e.header??[];if(i.length===0)return[];let a=i.map((t,n)=>normalizeAlignment(e.align?.[n])),o=i.map(renderTableCell),s=(e.rows??[]).map(e=>normalizeTableRow(e,i.length).map(renderTableCell)),c=[o,...s],l=a.map((e,n)=>Math.max(3,...c.map(e=>visibleLength(e[n]??``))));return fitTableWidths(l,n),[formatTableRow(o.map(e=>`${ansi.bold}${e}${ansi.boldOff}`),l,a),l.map(e=>`─`.repeat(e)).join(` `),...s.map(e=>formatTableRow(e,l,a))]}function renderTableCell(e){return renderInline(e.tokens,e.text).replaceAll(`
|
|
7
|
+
`,` `)}function normalizeTableRow(e,t){return Array.from({length:t},(t,n)=>e[n]??{text:``,tokens:[]})}function normalizeAlignment(e){return e??`left`}function fitTableWidths(e,t){if(!Number.isFinite(t))return;let n=Math.max(0,e.length-1)*2,r=Math.max(e.length*3,Math.floor(t)-n);for(;e.reduce((e,t)=>e+t,0)>r;){let t=Math.max(...e),n=e.findIndex(e=>e===t&&e>3);if(n===-1)return;e[n]=t-1}}function formatTableRow(e,t,n){return e.map((e,r)=>alignTableCell(fitTableCell(e,t[r]??3),t[r]??3,n[r]??`left`)).join(` `)}function fitTableCell(n,r){return visibleLength(n)<=r?n:`${sliceVisible(n,Math.max(1,r-1))}…`}function alignTableCell(e,n,r){let i=Math.max(0,n-visibleLength(e));if(r===`right`)return`${` `.repeat(i)}${e}`;if(r===`center`){let t=Math.floor(i/2);return`${` `.repeat(t)}${e}${` `.repeat(i-t)}`}return`${e}${` `.repeat(i)}`}function horizontalRuleWidth(e){return Number.isFinite(e)?Math.max(3,Math.min(40,Math.floor(e))):40}function pushBlankRow(e){e.length>0&&e.at(-1)!==``&&e.push(``)}function trimTrailingBlankRows(e){for(;e.at(-1)===``;)e.pop();return e}export{renderMarkdown};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The empty prompt's rotating invitation, written in the agent's own voice
|
|
3
|
+
* ("my capabilities") since the prompt is a message to it. Messages point at
|
|
4
|
+
* things an eve agent can actually do out of the box, so an idle prompt
|
|
5
|
+
* doubles as a hint surface. The caret-blink repaint keeps the rotation
|
|
6
|
+
* moving without its own timer.
|
|
7
|
+
*/
|
|
8
|
+
export declare const PROMPT_PLACEHOLDER_MESSAGES: readonly string[];
|
|
9
|
+
/** How long each message holds before the rotation advances. */
|
|
10
|
+
export declare const promptPlaceholderCycleMs = 6000;
|
|
11
|
+
/** Picks the message for the given time since the renderer started. */
|
|
12
|
+
export declare function promptPlaceholder(elapsedMs: number): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const PROMPT_PLACEHOLDER_MESSAGES=[`Ask about my capabilities`,`Have me explore the workspace`,`Refine my instructions`],promptPlaceholderCycleMs=6e3;function promptPlaceholder(e){return PROMPT_PLACEHOLDER_MESSAGES[Math.floor(Math.max(0,e)/promptPlaceholderCycleMs)%PROMPT_PLACEHOLDER_MESSAGES.length]}export{PROMPT_PLACEHOLDER_MESSAGES,promptPlaceholder,promptPlaceholderCycleMs};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure rendering for the HITL question panel — the overlay the agent's
|
|
3
|
+
* `ask_question` tool opens above the input area. A full-width rule separates
|
|
4
|
+
* it from the transcript, options render as numbered rows with their
|
|
5
|
+
* descriptions always visible, and the trailing "Type your own answer" row
|
|
6
|
+
* carries an inline elbow editor that receives focus the moment the cursor
|
|
7
|
+
* rests on it (the provider-key grammar from the setup panel). The renderer
|
|
8
|
+
* hosts lifecycle and keys; this module only paints rows.
|
|
9
|
+
*/
|
|
10
|
+
import type { AgentTUIInputOption } from "./runner.js";
|
|
11
|
+
import { type LineState } from "./line-editor.js";
|
|
12
|
+
import type { Theme } from "./theme.js";
|
|
13
|
+
export interface QuestionPanelState {
|
|
14
|
+
readonly prompt: string;
|
|
15
|
+
readonly options: readonly AgentTUIInputOption[];
|
|
16
|
+
/** Row index under the cursor; `options.length` is the freeform row. */
|
|
17
|
+
readonly cursor: number;
|
|
18
|
+
/** Whether the trailing freeform row exists. */
|
|
19
|
+
readonly allowFreeform: boolean;
|
|
20
|
+
/** The freeform row's inline editor; focused while the cursor rests on it. */
|
|
21
|
+
readonly editor: LineState;
|
|
22
|
+
readonly caretVisible: boolean;
|
|
23
|
+
}
|
|
24
|
+
export declare function renderQuestionPanel(state: QuestionPanelState, theme: Theme, width: number): string[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{visibleLine}from"./line-editor.js";import{clipVisible,renderInputWithBlockCursor,wrapVisibleLine}from"#cli/ui/terminal-text.js";function selectedRow(e,t){let n=t.colors;return`${n.inverse(n.blue(` ${t.glyph.selectedPointer} ${e} `))} ${n.dim(`↵`)}`}function renderQuestionPanel(e,n,i){let a=n.colors,o=n.glyph,s=[a.dim(o.hrule.repeat(Math.max(1,i)))];for(let t of e.prompt.split(/\r?\n/u))for(let e of wrapVisibleLine(t,Math.max(8,i-2)))s.push(` ${a.bold(e)}`);s.push(``);for(let[t,r]of e.options.entries())s.push(...optionRows(r.label,r.description,t,e,n));if(e.allowFreeform){let t=e.options.length,r=e.cursor===t;s.push(...optionRows(`Type your own answer`,void 0,t,e,n)),(r||e.editor.text.length>0)&&s.push(` ${a.dim(o.elbow)} ${freeformEditorBody(e,r,n,i)}`)}return s.push(``,` ${a.dim(`Esc to dismiss`)}`),s.map(e=>clipVisible(e,i))}function optionRows(e,t,n,r,i){let a=i.colors,o=`${n+1}. ${e}`,s=[r.cursor===n?` ${selectedRow(o,i)}`:` ${a.dim(`${n+1}.`)} ${e}`];return t!==void 0&&t.length>0&&s.push(` ${a.dim(t)}`),s}function freeformEditorBody(t,r,i,a){let o=i.colors,s=Math.max(4,a-12);if(!r){let n=visibleLine(t.editor,s,i.glyph.ellipsis);return o.dim(`${n.before}${n.under}${n.after}`)}return renderInputWithBlockCursor({...visibleLine(t.editor,s,i.glyph.ellipsis),visible:t.caretVisible,inverse:o.inverse})}export{renderQuestionPanel};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shared atoms of the transcript's rail grammar. Persistent sections
|
|
3
|
+
* (tool rows, subagent sections, the todo panel) all hang their marks at the
|
|
4
|
+
* same two-cell tool column and elide overflow with the same counted row —
|
|
5
|
+
* one definition keeps the alignment a checked fact instead of a set of
|
|
6
|
+
* parallel comments.
|
|
7
|
+
*/
|
|
8
|
+
import type { Theme } from "./theme.js";
|
|
9
|
+
/**
|
|
10
|
+
* The two-cell indent that puts a section's mark at the prose text column
|
|
11
|
+
* (the character after the `│`/`▲` gutter marks).
|
|
12
|
+
*/
|
|
13
|
+
export declare const TOOL_COLUMN_LEAD = " ";
|
|
14
|
+
/** The dim `… (N more)` elision label used by every capped region. */
|
|
15
|
+
export declare function elisionText(hidden: number, theme: Theme): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const TOOL_COLUMN_LEAD=` `;function elisionText(e,t){return t.colors.dim(`${t.glyph.ellipsis} (${e} more)`)}export{TOOL_COLUMN_LEAD,elisionText};
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { type AgentInfoResult, type ConnectionAuthorizationOutcome, type InputRequest, Client, ClientSession } from "#client/index.js";
|
|
2
|
+
import { type SubagentView } from "./subagent-pump.js";
|
|
3
|
+
export type { SubagentRun, SubagentStepUpdate, SubagentToolUpdate, SubagentView, } from "./subagent-pump.js";
|
|
2
4
|
import { type DevBootProgressReporter } from "#internal/dev-boot-progress.js";
|
|
3
5
|
import { type PromptCommand, type PromptCommandSpec } from "./prompt-commands.js";
|
|
4
6
|
import { type RemoteConnectionController, type RemoteConnectionControllerOptions, type RemoteConnectionSnapshot } from "./remote-connection.js";
|
|
@@ -43,6 +45,10 @@ export type AgentTUIStreamEvent = {
|
|
|
43
45
|
} | {
|
|
44
46
|
type: "reasoning-complete";
|
|
45
47
|
id: string;
|
|
48
|
+
} | {
|
|
49
|
+
type: "tool-call-preparing";
|
|
50
|
+
toolCallId: string;
|
|
51
|
+
toolName: string;
|
|
46
52
|
} | {
|
|
47
53
|
type: "tool-call";
|
|
48
54
|
toolCallId: string;
|
|
@@ -60,6 +66,10 @@ export type AgentTUIStreamEvent = {
|
|
|
60
66
|
type: "tool-error";
|
|
61
67
|
toolCallId: string;
|
|
62
68
|
errorText: string;
|
|
69
|
+
} | {
|
|
70
|
+
type: "tool-rejected";
|
|
71
|
+
toolCallId: string;
|
|
72
|
+
reason: string;
|
|
63
73
|
} | {
|
|
64
74
|
type: "error";
|
|
65
75
|
errorText: string;
|
|
@@ -140,6 +150,12 @@ export type AgentTUIRenderer = {
|
|
|
140
150
|
* recovery and slash-command results. Optional.
|
|
141
151
|
*/
|
|
142
152
|
renderNotice?(text: string): void;
|
|
153
|
+
/**
|
|
154
|
+
* Commits the session boundary (`┌── Session restarted, clear context.`)
|
|
155
|
+
* when a dead session is replaced mid-conversation. Optional; renderers
|
|
156
|
+
* without it get the plain notice.
|
|
157
|
+
*/
|
|
158
|
+
renderSessionBoundary?(): void;
|
|
143
159
|
/**
|
|
144
160
|
* Commits one development sandbox lifecycle line to the transcript.
|
|
145
161
|
* Optional so non-terminal renderers can ignore local prewarm progress.
|
|
@@ -157,22 +173,13 @@ export type AgentTUIRenderer = {
|
|
|
157
173
|
readInputQuestion?(question: AgentTUIInputQuestion, options?: AgentTUISessionOptions): Promise<AgentTUIInputQuestionResponse | undefined>;
|
|
158
174
|
renderStream(result: AgentTUIStreamResult, options?: AgentTUISessionOptions): Promise<void>;
|
|
159
175
|
/**
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
176
|
+
* The renderer's whole subagent surface — sections, nested steps and
|
|
177
|
+
* tools, ghost sweeps, completion. One optional capability with required
|
|
178
|
+
* members: a renderer either has a subagent view or it doesn't, and a
|
|
179
|
+
* type-legal partial implementation (which would ghost placeholders or
|
|
180
|
+
* duplicate parent tool rows) cannot exist.
|
|
164
181
|
*/
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Out-of-band update for one child tool call of a subagent dispatch.
|
|
168
|
-
*/
|
|
169
|
-
upsertSubagentTool?(update: SubagentToolUpdate): void;
|
|
170
|
-
/**
|
|
171
|
-
* Registers a tool call id as originating from a subagent's child
|
|
172
|
-
* session. The renderer must skip or remove parent-level tool blocks for
|
|
173
|
-
* these ids — they are surfaced via {@link upsertSubagentTool} instead.
|
|
174
|
-
*/
|
|
175
|
-
markChildToolCallId?(callId: string): void;
|
|
182
|
+
readonly subagents?: SubagentView;
|
|
176
183
|
/**
|
|
177
184
|
* Out-of-band update for one MCP connection authorization lifecycle.
|
|
178
185
|
* Called by the runner as `authorization.*` events arrive.
|
|
@@ -322,56 +329,6 @@ export declare class EveTUIRunner {
|
|
|
322
329
|
constructor(options: EveTUIRunnerOptions);
|
|
323
330
|
run(): Promise<void>;
|
|
324
331
|
}
|
|
325
|
-
type SubagentChildStep = {
|
|
326
|
-
reasoning: string;
|
|
327
|
-
message: string;
|
|
328
|
-
finalized: boolean;
|
|
329
|
-
};
|
|
330
|
-
type SubagentToolState = {
|
|
331
|
-
toolName: string;
|
|
332
|
-
input: unknown;
|
|
333
|
-
status: "approval-requested" | "executing" | "done" | "failed";
|
|
334
|
-
output?: unknown;
|
|
335
|
-
errorText?: string;
|
|
336
|
-
};
|
|
337
|
-
export type SubagentRun = {
|
|
338
|
-
name: string;
|
|
339
|
-
/**
|
|
340
|
-
* One entry per logical "child message" — independent of the child's
|
|
341
|
-
* `stepIndex` field, which the harness can reuse across multiple
|
|
342
|
-
* assistant messages within a turn (e.g. a message before a tool call
|
|
343
|
-
* and another message after the tool result both arrive under
|
|
344
|
-
* `stepIndex: 0`). The key is a monotonic counter so each
|
|
345
|
-
* `message.completed` opens a new box on the next inbound delta.
|
|
346
|
-
*/
|
|
347
|
-
steps: Map<number, SubagentChildStep>;
|
|
348
|
-
/**
|
|
349
|
-
* Section currently accepting reasoning/message deltas. `null` means
|
|
350
|
-
* the next delta opens a new section.
|
|
351
|
-
*/
|
|
352
|
-
currentSectionKey: number | null;
|
|
353
|
-
/** Monotonic counter for new section keys. */
|
|
354
|
-
nextSectionKey: number;
|
|
355
|
-
tools: Map<string, SubagentToolState>;
|
|
356
|
-
};
|
|
357
|
-
export type SubagentStepUpdate = {
|
|
358
|
-
callId: string;
|
|
359
|
-
subagentName: string;
|
|
360
|
-
sectionKey: number;
|
|
361
|
-
reasoning: string;
|
|
362
|
-
message: string;
|
|
363
|
-
finalized: boolean;
|
|
364
|
-
};
|
|
365
|
-
export type SubagentToolUpdate = {
|
|
366
|
-
callId: string;
|
|
367
|
-
subagentName: string;
|
|
368
|
-
childCallId: string;
|
|
369
|
-
toolName: string;
|
|
370
|
-
input: unknown;
|
|
371
|
-
status: "approval-requested" | "executing" | "done" | "failed";
|
|
372
|
-
output?: unknown;
|
|
373
|
-
errorText?: string;
|
|
374
|
-
};
|
|
375
332
|
export type ConnectionAuthChallenge = {
|
|
376
333
|
url?: string;
|
|
377
334
|
userCode?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{PROMPT_COMMANDS,formatPromptCommandHelp,parsePromptCommand}from"./prompt-commands.js";import{pickAgentHeaderTip}from"./agent-header.js";import{probeAgentInfo}from"./agent-info-probe.js";import{failureKey,formatFailureDetail,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};
|