eve 0.15.5 → 0.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/src/channel/compiled-channel.d.ts +2 -0
  3. package/dist/src/channel/cors.d.ts +43 -0
  4. package/dist/src/channel/cors.js +1 -0
  5. package/dist/src/cli/commands/init.js +1 -1
  6. package/dist/src/cli/dev/tui/agent-header.js +1 -1
  7. package/dist/src/cli/dev/tui/agent-info-probe.d.ts +16 -0
  8. package/dist/src/cli/dev/tui/agent-info-probe.js +1 -0
  9. package/dist/src/cli/dev/tui/blocks.js +8 -8
  10. package/dist/src/cli/dev/tui/mcp-connection-status.d.ts +19 -0
  11. package/dist/src/cli/dev/tui/mcp-connection-status.js +1 -0
  12. package/dist/src/cli/dev/tui/prompt-command-handler.js +1 -1
  13. package/dist/src/cli/dev/tui/prompt-commands.d.ts +1 -1
  14. package/dist/src/cli/dev/tui/prompt-commands.js +1 -1
  15. package/dist/src/cli/dev/tui/remote-connection-probe.js +1 -1
  16. package/dist/src/cli/dev/tui/runner.d.ts +14 -3
  17. package/dist/src/cli/dev/tui/runner.js +1 -1
  18. package/dist/src/cli/dev/tui/setup-commands.d.ts +10 -1
  19. package/dist/src/cli/dev/tui/setup-commands.js +2 -2
  20. package/dist/src/cli/dev/tui/setup-flow.d.ts +8 -1
  21. package/dist/src/cli/dev/tui/setup-issues.d.ts +2 -14
  22. package/dist/src/cli/dev/tui/setup-issues.js +1 -1
  23. package/dist/src/cli/dev/tui/setup-panel.d.ts +14 -8
  24. package/dist/src/cli/dev/tui/setup-panel.js +3 -3
  25. package/dist/src/cli/dev/tui/terminal-renderer.js +6 -6
  26. package/dist/src/cli/dev/tui/tui-prompter.js +1 -1
  27. package/dist/src/cli/dev/tui/tui.d.ts +2 -3
  28. package/dist/src/cli/dev/tui/tui.js +1 -1
  29. package/dist/src/cli/dev/ui-options.d.ts +21 -0
  30. package/dist/src/cli/dev/ui-options.js +1 -0
  31. package/dist/src/cli/run.d.ts +6 -42
  32. package/dist/src/cli/run.js +2 -2
  33. package/dist/src/compiled/.vendor-stamp.json +1 -1
  34. package/dist/src/compiled/@ai-sdk/mcp/index.d.ts +71 -1
  35. package/dist/src/compiled/@ai-sdk/mcp/index.js +1 -1
  36. package/dist/src/compiler/manifest.d.ts +8 -2
  37. package/dist/src/compiler/manifest.js +1 -1
  38. package/dist/src/compiler/normalize-channel.js +1 -1
  39. package/dist/src/context/providers/connection-key.d.ts +9 -0
  40. package/dist/src/context/providers/connection-key.js +1 -0
  41. package/dist/src/context/providers/connection.d.ts +1 -9
  42. package/dist/src/context/providers/connection.js +1 -1
  43. package/dist/src/harness/emission.d.ts +3 -3
  44. package/dist/src/harness/emission.js +1 -1
  45. package/dist/src/harness/input-requests.d.ts +1 -0
  46. package/dist/src/harness/input-requests.js +1 -1
  47. package/dist/src/harness/stream-actions.d.ts +17 -0
  48. package/dist/src/harness/stream-actions.js +1 -0
  49. package/dist/src/harness/tool-loop.js +1 -1
  50. package/dist/src/internal/application/package.js +1 -1
  51. package/dist/src/internal/nitro/host/channel-routes.d.ts +2 -0
  52. package/dist/src/internal/nitro/host/channel-routes.js +5 -3
  53. package/dist/src/internal/nitro/host/configure-nitro-routes.js +2 -2
  54. package/dist/src/internal/nitro/host/dev-authored-source-watcher.d.ts +1 -0
  55. package/dist/src/internal/nitro/host/dev-authored-source-watcher.js +1 -1
  56. package/dist/src/internal/nitro/host/start-development-server.d.ts +8 -0
  57. package/dist/src/internal/nitro/host/start-development-server.js +2 -2
  58. package/dist/src/internal/nitro/host.d.ts +1 -1
  59. package/dist/src/internal/nitro/host.js +1 -1
  60. package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
  61. package/dist/src/internal/nitro/routes/dev-runtime-artifacts.d.ts +0 -3
  62. package/dist/src/internal/nitro/routes/dev-runtime-artifacts.js +1 -1
  63. package/dist/src/internal/nitro/routes/info.js +1 -1
  64. package/dist/src/internal/vercel/project-link.d.ts +10 -0
  65. package/dist/src/internal/vercel/project-link.js +1 -0
  66. package/dist/src/packages/eve-catalog/src/index.js +1 -1
  67. package/dist/src/public/channels/auth.d.ts +26 -13
  68. package/dist/src/public/channels/auth.js +1 -1
  69. package/dist/src/public/channels/eve.d.ts +31 -0
  70. package/dist/src/public/channels/eve.js +1 -1
  71. package/dist/src/public/channels/github/githubChannel.js +1 -1
  72. package/dist/src/public/channels/github/inbound-types.d.ts +189 -0
  73. package/dist/src/public/channels/github/inbound-types.js +1 -0
  74. package/dist/src/public/channels/github/inbound.d.ts +2 -190
  75. package/dist/src/public/channels/github/inbound.js +2 -2
  76. package/dist/src/public/channels/index.d.ts +1 -1
  77. package/dist/src/public/definitions/defineChannel.d.ts +10 -0
  78. package/dist/src/public/definitions/defineChannel.js +1 -1
  79. package/dist/src/runtime/agent/mock-model-adapter.d.ts +3 -2
  80. package/dist/src/runtime/agent/mock-model-adapter.js +1 -1
  81. package/dist/src/runtime/connections/principal.d.ts +2 -0
  82. package/dist/src/runtime/connections/principal.js +1 -1
  83. package/dist/src/runtime/connections/scoped-authorization.d.ts +9 -0
  84. package/dist/src/runtime/connections/scoped-authorization.js +1 -1
  85. package/dist/src/runtime/connections/types.d.ts +8 -5
  86. package/dist/src/runtime/framework-channels/index.d.ts +1 -6
  87. package/dist/src/runtime/framework-channels/index.js +1 -1
  88. package/dist/src/runtime/framework-tools/connection-search-dynamic.js +1 -1
  89. package/dist/src/runtime/framework-tools/index.d.ts +1 -1
  90. package/dist/src/runtime/framework-tools/index.js +1 -1
  91. package/dist/src/runtime/framework-tools/skill.js +1 -1
  92. package/dist/src/runtime/governance/auth/oidc.js +1 -1
  93. package/dist/src/runtime/governance/auth/types.d.ts +14 -10
  94. package/dist/src/runtime/governance/auth/vercel-oidc-project.d.ts +12 -0
  95. package/dist/src/runtime/governance/auth/vercel-oidc-project.js +1 -0
  96. package/dist/src/runtime/resolve-channel.js +1 -1
  97. package/dist/src/runtime/types.d.ts +2 -0
  98. package/dist/src/services/dev-client/client-options.d.ts +5 -0
  99. package/dist/src/services/dev-client/client-options.js +1 -1
  100. package/dist/src/services/dev-client/request-headers.d.ts +8 -0
  101. package/dist/src/services/dev-client/request-headers.js +1 -1
  102. package/dist/src/services/dev-client/runtime-artifacts.d.ts +1 -0
  103. package/dist/src/services/dev-client/runtime-artifacts.js +1 -1
  104. package/dist/src/services/dev-client.d.ts +8 -0
  105. package/dist/src/services/dev-client.js +1 -1
  106. package/dist/src/setup/boxes/add-connections.d.ts +10 -8
  107. package/dist/src/setup/boxes/add-connections.js +1 -1
  108. package/dist/src/setup/boxes/resolve-provisioning.d.ts +1 -0
  109. package/dist/src/setup/boxes/resolve-provisioning.js +1 -1
  110. package/dist/src/setup/boxes/select-connections.js +1 -1
  111. package/dist/src/setup/cli/channel-setup-prompter.d.ts +9 -2
  112. package/dist/src/setup/cli/channel-setup-prompter.js +1 -1
  113. package/dist/src/setup/cli/index.d.ts +1 -1
  114. package/dist/src/setup/cli/option-row.d.ts +2 -0
  115. package/dist/src/setup/cli/option-row.js +1 -1
  116. package/dist/src/setup/cli/prompt-ui.d.ts +2 -0
  117. package/dist/src/setup/cli/select-state.js +1 -1
  118. package/dist/src/setup/connection-connector.d.ts +26 -52
  119. package/dist/src/setup/connection-connector.js +2 -1
  120. package/dist/src/setup/flows/channels.js +1 -1
  121. package/dist/src/setup/flows/connections.d.ts +37 -0
  122. package/dist/src/setup/flows/connections.js +3 -0
  123. package/dist/src/setup/flows/link.d.ts +1 -0
  124. package/dist/src/setup/flows/link.js +1 -1
  125. package/dist/src/setup/project-resolution.d.ts +2 -8
  126. package/dist/src/setup/project-resolution.js +1 -1
  127. package/dist/src/setup/prompter.d.ts +2 -0
  128. package/dist/src/setup/scaffold/connections/catalog.d.ts +10 -5
  129. package/dist/src/setup/scaffold/connections/catalog.js +1 -1
  130. package/dist/src/setup/scaffold/create/project.js +11 -11
  131. package/dist/src/setup/scaffold/create/web-template.d.ts +1 -1
  132. package/dist/src/setup/scaffold/create/web-template.js +2 -2
  133. package/dist/src/setup/scaffold/index.d.ts +1 -1
  134. package/dist/src/setup/scaffold/index.js +1 -1
  135. package/dist/src/setup/scaffold/update/connections.d.ts +6 -0
  136. package/dist/src/setup/scaffold/update/connections.js +3 -3
  137. package/docs/channels/custom.mdx +19 -0
  138. package/docs/channels/eve.mdx +26 -3
  139. package/docs/concepts/sessions-runs-and-streaming.md +3 -1
  140. package/docs/connections/mcp.mdx +161 -19
  141. package/docs/connections/openapi.mdx +133 -36
  142. package/docs/connections/overview.mdx +4 -4
  143. package/docs/guides/auth-and-route-protection.md +5 -5
  144. package/docs/guides/dev-tui.md +11 -4
  145. package/docs/guides/frontend/nextjs.mdx +2 -2
  146. package/docs/guides/frontend/nuxt.mdx +2 -2
  147. package/docs/guides/frontend/sveltekit.mdx +2 -2
  148. package/docs/patterns/multi-tenant-approvals.md +4 -0
  149. package/docs/patterns/multi-tenant-auth.md +156 -37
  150. package/docs/reference/cli.md +3 -1
  151. package/docs/tools/human-in-the-loop.md +3 -1
  152. package/docs/tutorial/ship-it.mdx +1 -1
  153. package/docs/tutorial/team-playbooks.mdx +1 -1
  154. package/package.json +2 -2
  155. package/dist/src/internal/nitro/host/dev-rebuild-registry.d.ts +0 -5
  156. package/dist/src/internal/nitro/host/dev-rebuild-registry.js +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # eve
2
2
 
3
+ ## 0.16.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 8470695: HTTP channels can now opt into browser CORS with preflight handling. Use `defineChannel({ cors })` for custom channels or `eveChannel({ cors: true | options })` for the eve channel; omitted CORS remains disabled.
8
+ - aa3aca4: The GitHub channel now accepts Vercel Connect-forwarded webhook payloads that omit `x-github-event` and `x-github-delivery` by inferring the supported event type from the payload shape. Headerless forwarded payloads now emit a warning with the inferred metadata instead of being silently acknowledged and ignored.
9
+ - 8713a71: Fix human-in-the-loop approval resume behavior so text replies like `approve` resolve pending tool approvals and unrelated follow-up messages no longer synthesize a denial. Rejected approval results now include explicit approval and not-run metadata for clients.
10
+ - 7fd53f7: Update the curated Linear MCP connection to use Linear's Streamable HTTP endpoint at `https://mcp.linear.app/mcp`. The MCP and OpenAPI connection docs now include fuller setup guidance for Vercel Connect, static credentials, filters, and approvals.
11
+ - c0f9749: Fix Vercel Connect local interactive connection authorization when the dev server uses an IPv4 or IPv6 loopback address. OAuth callbacks now retain the active port while using the `localhost` hostname accepted by Connect, and local `/connect` refreshes the dev runtime before the next prompt can use the new connection.
12
+ - c14b022: The `eve dev` TUI retries one transient agent-inspection failure before treating a local or remote agent as unavailable.
13
+
14
+ ## 0.16.0
15
+
16
+ ### Minor Changes
17
+
18
+ - 24faac0: Add a searchable `/connect` flow to the local dev TUI. It scaffolds an MCP connection, resolves its Vercel Connect connector, and reuses the model setup flow to create or link a Vercel project when needed. Local Vercel users now authorize Connect with their Vercel user ID instead of a reserved OIDC issuer.
19
+
20
+ ### Patch Changes
21
+
22
+ - ddda14c: Fresh agents now start model setup from their prefilled `/model` prompt, installing the Vercel CLI and logging in when those prerequisites are missing. Other `eve dev` sessions leave missing model setup as an attention prompt.
23
+ - ca8512a: Generated projects now emit peer-resolution metadata only for their selected package manager. pnpm scaffolds no longer include npm or Yarn fields that can make frozen Vercel installs fail.
24
+
3
25
  ## 0.15.5
4
26
 
5
27
  ### Patch Changes
@@ -1,4 +1,5 @@
1
1
  import type { ChannelAdapter } from "#channel/adapter.js";
2
+ import type { NormalizedChannelCorsOptions } from "#channel/cors.js";
2
3
  import type { RouteDefinition, SendFn } from "#channel/routes.js";
3
4
  import type { Session } from "#channel/session.js";
4
5
  import type { SessionAuthContext } from "#channel/types.js";
@@ -7,6 +8,7 @@ export interface CompiledChannel<TState = undefined, TReceiveTarget = Record<str
7
8
  readonly __kind: typeof CHANNEL_SENTINEL;
8
9
  readonly routes: readonly RouteDefinition<TState>[];
9
10
  readonly adapter: ChannelAdapter<any>;
11
+ readonly cors?: NormalizedChannelCorsOptions;
10
12
  readonly __metadata?: TMetadata;
11
13
  readonly receive?: (input: {
12
14
  readonly message: string;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Serializable subset of H3/Nitro CORS options supported by channel routes.
3
+ *
4
+ * Function and RegExp origins are intentionally excluded because channel
5
+ * definitions are compiled into JSON artifacts and virtual Nitro handlers.
6
+ */
7
+ export interface ChannelCorsOptions {
8
+ /**
9
+ * Allowed request origins. Omit or pass `"*"` for all origins, pass
10
+ * `"null"` for the literal `null` origin, or pass an array of exact origins.
11
+ */
12
+ readonly origin?: "*" | "null" | readonly string[];
13
+ /** Methods emitted on preflight responses. Omit or pass `"*"` for all methods. */
14
+ readonly methods?: "*" | readonly string[];
15
+ /**
16
+ * Request headers emitted on preflight responses. Omit or pass `"*"` to
17
+ * allow requested headers.
18
+ */
19
+ readonly allowHeaders?: "*" | readonly string[];
20
+ /** Response headers exposed to browser callers. Omit or pass `"*"` for all headers. */
21
+ readonly exposeHeaders?: "*" | readonly string[];
22
+ /** Whether to emit `access-control-allow-credentials: true`. */
23
+ readonly credentials?: boolean;
24
+ /** Max age, in seconds, emitted on preflight responses. */
25
+ readonly maxAge?: string | number | false;
26
+ /** Preflight response customization. */
27
+ readonly preflight?: {
28
+ readonly statusCode?: number;
29
+ };
30
+ }
31
+ export type ChannelCors = boolean | ChannelCorsOptions;
32
+ export interface NormalizedChannelCorsOptions {
33
+ readonly origin?: "*" | "null" | readonly string[];
34
+ readonly methods?: "*" | readonly string[];
35
+ readonly allowHeaders?: "*" | readonly string[];
36
+ readonly exposeHeaders?: "*" | readonly string[];
37
+ readonly credentials?: boolean;
38
+ readonly maxAge?: string | false;
39
+ readonly preflight?: {
40
+ readonly statusCode?: number;
41
+ };
42
+ }
43
+ export declare function normalizeChannelCors(cors: ChannelCors | undefined): NormalizedChannelCorsOptions | undefined;
@@ -0,0 +1 @@
1
+ function normalizeChannelCors(e){if(e===void 0||e===!1)return;if(e===!0)return{};if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Expected channel cors to be a boolean or a serializable CORS options object.`);let t={};if(e.origin!==void 0&&(t.origin=normalizeOrigin(e.origin)),e.methods!==void 0&&(t.methods=normalizeWildcardOrStringList(e.methods,`methods`)),e.allowHeaders!==void 0&&(t.allowHeaders=normalizeWildcardOrStringList(e.allowHeaders,`allowHeaders`)),e.exposeHeaders!==void 0&&(t.exposeHeaders=normalizeWildcardOrStringList(e.exposeHeaders,`exposeHeaders`)),e.credentials!==void 0){if(typeof e.credentials!=`boolean`)throw Error(`Expected channel cors.credentials to be a boolean.`);t.credentials=e.credentials}return e.maxAge!==void 0&&(t.maxAge=normalizeMaxAge(e.maxAge)),e.preflight!==void 0&&(t.preflight=normalizePreflight(e.preflight)),t}function normalizeOrigin(e){if(e===`*`||e===`null`)return e;if(!Array.isArray(e))throw Error(`Expected channel cors.origin to be "*", "null", or an array of origins.`);return e.map(e=>{if(typeof e!=`string`||e.length===0)throw Error(`Expected channel cors.origin entries to be non-empty strings.`);return e})}function normalizeWildcardOrStringList(e,t){if(e===`*`)return e;if(!Array.isArray(e))throw Error(`Expected channel cors.${t} to be "*" or an array of strings.`);return e.map(e=>{if(typeof e!=`string`||e.length===0)throw Error(`Expected channel cors.${t} entries to be non-empty strings.`);return e})}function normalizeMaxAge(e){if(e===!1)return!1;if(typeof e==`number`){if(!Number.isFinite(e)||e<0)throw Error(`Expected channel cors.maxAge to be a non-negative finite number.`);return String(e)}if(typeof e==`string`&&e.length>0)return e;throw Error(`Expected channel cors.maxAge to be false, a string, or a number.`)}function normalizePreflight(e){if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Expected channel cors.preflight to be an object.`);let t=e.statusCode;if(t===void 0)return{};if(!Number.isInteger(t)||t<100||t>599)throw Error(`Expected channel cors.preflight.statusCode to be an HTTP status code.`);return{statusCode:t}}export{normalizeChannelCors};
@@ -1 +1 @@
1
- import{__toESM}from"../../_virtual/_rolldown/runtime.js";import{require_picocolors}from"../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js";import{initAgentDevHandoff,initAgentInstructions,initAgentReplPrompt}from"./agent-instructions.js";import{tryInitializeGit}from"./init-git.js";import{selectInitHandoff,spawnCodingAgentRepl}from"./init-repl.js";import{createLogger,isLogLevelEnabled}from"#internal/logging.js";import{basename,join,resolve}from"node:path";import{ensureChannel,scaffoldBaseProject}from"#setup/scaffold/index.js";import{mkdtemp,readdir,rename,rm,stat}from"node:fs/promises";import{performance}from"node:perf_hooks";import{isCodingAgentLaunch}from"#cli/agent-detection.js";import{EVE_WORDMARK}from"#cli/banner.js";import{formatElapsed}from"#cli/format-elapsed.js";import{startCliLiveRow}from"#cli/ui/live-row.js";import{DEFAULT_AGENT_MODEL_ID}from"#shared/default-agent-model.js";import{formatNodeEngineOverrideWarning}from"#setup/node-engine.js";import{detectInvokingPackageManager,detectPackageManager}from"#setup/package-manager.js";import{pathExists}from"#setup/path-exists.js";import{parseProjectName}from"#setup/project-name.js";import{eveDevArguments,runPackageManagerInstall,spawnPackageManager}from"#setup/primitives/index.js";import{addAgentToProject}from"#setup/scaffold/create/add-to-project.js";import{WizardCancelledError}from"#setup/step.js";import{DEFAULT_EVE_PACKAGE_CONTRACT}from"#setup/scaffold/create/project.js";var import_picocolors=__toESM(require_picocolors(),1);const defaultDependencies={addAgentToProject,detectInvokingPackageManager,detectPackageManager,ensureChannel,isCodingAgentLaunch,now:()=>performance.now(),runPackageManagerInstall,scaffoldBaseProject,selectInitHandoff,spawnCodingAgentRepl,spawnPackageManager,tryInitializeGit},ALLOWED_CREATE_IN_PLACE_ENTRIES=new Set([`.DS_Store`,`.git`,`.gitkeep`,`.hg`]),EVE_INIT_PACKAGE_SPEC_ENV=`EVE_INIT_PACKAGE_SPEC`,initLog=createLogger(`init`);async function resolveTargetDirectory(e,t){let n=resolve(e,t);return(await stat(n).catch(()=>void 0))?.isDirectory()?n:void 0}function isCurrentDirectoryTarget(e){return/^\.(?:[/\\]+\.?)*$/u.test(e.trim())}async function assertCanScaffoldInPlace(e){let t=(await readdir(e)).filter(e=>!ALLOWED_CREATE_IN_PLACE_ENTRIES.has(e));if(t.length===0)return;let n=t.slice(0,5).join(`, `),r=t.length>5?`, and ${t.length-5} more`:``;throw Error(`Cannot create project in current directory because it is not empty. Found: ${n}${r}. Use an empty directory.`)}async function moveDirectoryContents(e,t){for(let n of await readdir(e))await rename(join(e,n),join(t,n))}function uniqueWorkspaceRootMutations(e){let t=new Map;for(let n of e){let e=`${n.kind}:${n.path}`,r=t.get(e);t.set(e,{...n,nodeEngineOverride:n.nodeEngineOverride??r?.nodeEngineOverride})}return[...t.values()]}function formatWorkspaceRootMutationWarning(e){let t=e.kind===`package-json`?`package.json`:`configuration`,n=e.nodeEngineOverride===void 0?``:` (${formatNodeEngineOverrideWarning(e.nodeEngineOverride)})`;return`Updated workspace root ${t} at ${e.path}${n}`}async function addToExistingProject(e,t,n,r){if(t.channelWebNextjs===!0)throw Error("`--channel-web-nextjs` is not supported when adding an agent to an existing project. Run `eve channels add web` from the project afterwards instead.");let i=await n.detectPackageManager(e),a=await n.addAgentToProject({projectRoot:e,model:DEFAULT_AGENT_MODEL_ID,packageManager:i.kind,evePackage:r});return{packageManager:i.kind,nodeEngineOverride:a.nodeEngineOverride}}async function resolveScaffoldPackageManager(e,t){let n=await t.detectPackageManager(e);return n.source==="default"?t.detectInvokingPackageManager()??`pnpm`:n.kind}async function scaffoldProject(e,t,n,r,i,a){let o=resolve(e),s=t===`.`,c=s?o:join(o,t);if(s)await assertCanScaffoldInPlace(c);else if(await pathExists(c))throw Error(`Cannot create project because "${c}" already exists.`);let l=await mkdtemp(join(o,`.eve-init-`)),p=[];try{let e={projectName:s?basename(c):t,model:DEFAULT_AGENT_MODEL_ID,evePackage:a,targetDirectory:l,workspaceProbeDirectory:c,packageManager:n,onWorkspaceRootMutation:e=>{p.push(e)}},o=await i.scaffoldBaseProject(e);return r.channelWebNextjs===!0&&await i.ensureChannel({projectRoot:o,kind:`web`,packageManager:n,workspaceProbeDirectory:c,configureVercelServices:!1,onWorkspaceRootMutation:e=>{p.push(e)}}),s?await moveDirectoryContents(o,c):await rename(o,c),{projectPath:c,workspaceRootMutations:uniqueWorkspaceRootMutations(p)}}finally{await rm(l,{recursive:!0,force:!0})}}function installProgressDetail(e,t){let n=t.text.trim();if(n===``||e!==`npm`)return n||void 0;let r=/^npm silly fetch manifest (.+)$/u.exec(n);if(r!==null)return`Resolving ${r[1]}`;let i=/^npm http fetch \S+ \S+ attempt (\d+) failed with (\S+)$/u.exec(n);if(i!==null)return`npm registry · attempt ${i[1]} failed: ${i[2]}`;if(t.stream===`stdout`||/^npm (?:error|warn)\b/u.test(n))return n}const NPM_NOISE_LINE=/^\s*npm (?:silly|verbose|http|timing)\b/u;async function runInitSteps(e){let{dependencies:t,logger:n,options:r,parentDirectory:i,target:a}=e,o=isLogLevelEnabled(`debug`),s=startCliLiveRow(n);s.update(`Preparing project`);try{let e=await t.isCodingAgentLaunch(),c=a??`.`,l=isCurrentDirectoryTarget(c),u=l?await pathExists(join(resolve(i),`package.json`))?resolve(i):void 0:await resolveTargetDirectory(i,c),p=resolveInitEvePackageOverride(),m=u===void 0?`creating agent`:`adding agent`;s.update(u===void 0?`Creating agent`:`Adding agent`),initLog.debug(m);let h=t.now(),g;if(u===void 0){let e=l?`.`:parseProjectName(c),n=resolve(i),a=await resolveScaffoldPackageManager(e===`.`?n:join(n,e),t),o=await scaffoldProject(i,e,a,r,t,p);g={kind:`created`,packageManager:a,projectPath:o.projectPath,workspaceRootMutations:o.workspaceRootMutations}}else{let e=await addToExistingProject(u,r,t,p);g=e.nodeEngineOverride===void 0?{kind:`added`,packageManager:e.packageManager,projectPath:u}:{kind:`added`,nodeEngineOverride:e.nodeEngineOverride,packageManager:e.packageManager,projectPath:u}}let _=t.now()-h;initLog.debug(`${m} done`,{ms:_}),s.update(`Installing dependencies`,`${g.packageManager} install`),initLog.debug(`installing dependencies with ${g.packageManager}`);let v=t.now(),y=[],b=[],x=await t.runPackageManagerInstall(g.packageManager,g.projectPath,{bypassMinimumReleaseAge:!0,progressDetails:process.stdout.isTTY===!0&&!o,onOutput:e=>{e.text.trim()!==``&&(b.push(e.text),b.length>20&&b.shift(),NPM_NOISE_LINE.test(e.text)||y.push(e.text)),o&&initLog.debug(e.text);let t=installProgressDetail(g.packageManager,e);t!==void 0&&s.update(`Installing dependencies`,t)}}),S=t.now()-v;if(!x){initLog.debug(`dependency installation failed`,{ms:S}),s.stop();let e=y.length>0?y:b;for(let t of e)n.error(t);throw Error(`Failed to install dependencies in "${g.projectPath}".`)}return initLog.debug(`dependencies installed`,{ms:S}),g.kind===`created`?(s.update(`Initializing Git repository`),initLog.debug(`initializing git repository`),{...g,agentElapsedMs:_,agentLaunched:e,gitResult:await t.tryInitializeGit(g.projectPath),installElapsedMs:S}):{...g,agentElapsedMs:_,agentLaunched:e,installElapsedMs:S}}finally{s.stop()}}async function runInitCommand(e,t,a,o,s=defaultDependencies){if(a===void 0&&await s.isCodingAgentLaunch()){e.log(initAgentInstructions());return}let c=await runInitSteps({dependencies:s,logger:e,options:o,parentDirectory:t,target:a});if(c.kind===`created`){e.log(`${import_picocolors.default.green(`✓`)} Created an ${EVE_WORDMARK} agent in ${import_picocolors.default.bold(c.projectPath)} ${import_picocolors.default.dim(`in ${formatElapsed(c.agentElapsedMs)}`)}`);for(let t of c.workspaceRootMutations)e.log(import_picocolors.default.yellow(`⚠ ${formatWorkspaceRootMutationWarning(t)}`))}else e.log(`${import_picocolors.default.green(`✓`)} Added an ${EVE_WORDMARK} agent to ${import_picocolors.default.bold(c.projectPath)} ${import_picocolors.default.dim(`in ${formatElapsed(c.agentElapsedMs)}`)}`),c.nodeEngineOverride!==void 0&&e.log(import_picocolors.default.yellow(`⚠ ${formatNodeEngineOverrideWarning(c.nodeEngineOverride)}`));e.log(`${import_picocolors.default.green(`✓`)} Installed dependencies ${import_picocolors.default.dim(`in ${formatElapsed(c.installElapsedMs)}`)}`),c.kind===`created`&&c.gitResult.kind===`failed`&&e.error(import_picocolors.default.yellow(`Git initialization failed: ${c.gitResult.reason}`));let l=[c.packageManager,...eveDevArguments(c.packageManager)].join(` `),d=initAgentDevHandoff({projectPath:c.projectPath,devCommand:l});if(c.agentLaunched){e.log(d);return}let f;try{f=await s.selectInitHandoff({agentName:basename(c.projectPath)})}catch(e){if(e instanceof WizardCancelledError)return;throw e}if(f!==`eve-dev`){if(e.log(import_picocolors.default.dim(`$ ${f}`)),!await s.spawnCodingAgentRepl({command:f,cwd:c.projectPath,prompt:initAgentReplPrompt({devCommand:l}),onPromptUnseeded:t=>{e.log(import_picocolors.default.yellow(`Could not seed ${f} automatically. Paste this prompt into it:`)),e.log(t)}}))throw Error(`Coding-agent REPL exited unsuccessfully in "${c.projectPath}".`);return}let p=eveDevArguments(c.packageManager);if(e.log(import_picocolors.default.dim(`$ eve dev`)),!await s.spawnPackageManager(c.packageManager,c.projectPath,p))throw Error(`Development server exited unsuccessfully in "${c.projectPath}".`)}function resolveInitEvePackageOverride(){let e=process.env[EVE_INIT_PACKAGE_SPEC_ENV]?.trim();if(!(e===void 0||e.length===0))return{nodeEngine:DEFAULT_EVE_PACKAGE_CONTRACT.nodeEngine,version:e}}export{EVE_INIT_PACKAGE_SPEC_ENV,runInitCommand};
1
+ import{__toESM}from"../../_virtual/_rolldown/runtime.js";import{require_picocolors}from"../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js";import{initAgentDevHandoff,initAgentInstructions,initAgentReplPrompt}from"./agent-instructions.js";import{tryInitializeGit}from"./init-git.js";import{selectInitHandoff,spawnCodingAgentRepl}from"./init-repl.js";import{createLogger,isLogLevelEnabled}from"#internal/logging.js";import{basename,join,resolve}from"node:path";import{ensureChannel,scaffoldBaseProject}from"#setup/scaffold/index.js";import{mkdtemp,readdir,rename,rm,stat}from"node:fs/promises";import{performance}from"node:perf_hooks";import{isCodingAgentLaunch}from"#cli/agent-detection.js";import{EVE_WORDMARK}from"#cli/banner.js";import{formatElapsed}from"#cli/format-elapsed.js";import{startCliLiveRow}from"#cli/ui/live-row.js";import{DEFAULT_AGENT_MODEL_ID}from"#shared/default-agent-model.js";import{formatNodeEngineOverrideWarning}from"#setup/node-engine.js";import{detectInvokingPackageManager,detectPackageManager}from"#setup/package-manager.js";import{pathExists}from"#setup/path-exists.js";import{parseProjectName}from"#setup/project-name.js";import{eveDevArguments,runPackageManagerInstall,spawnPackageManager}from"#setup/primitives/index.js";import{addAgentToProject}from"#setup/scaffold/create/add-to-project.js";import{WizardCancelledError}from"#setup/step.js";import{DEFAULT_EVE_PACKAGE_CONTRACT}from"#setup/scaffold/create/project.js";var import_picocolors=__toESM(require_picocolors(),1);const defaultDependencies={addAgentToProject,detectInvokingPackageManager,detectPackageManager,ensureChannel,isCodingAgentLaunch,now:()=>performance.now(),runPackageManagerInstall,scaffoldBaseProject,selectInitHandoff,spawnCodingAgentRepl,spawnPackageManager,tryInitializeGit},ALLOWED_CREATE_IN_PLACE_ENTRIES=new Set([`.DS_Store`,`.git`,`.gitkeep`,`.hg`]),EVE_INIT_PACKAGE_SPEC_ENV=`EVE_INIT_PACKAGE_SPEC`,initLog=createLogger(`init`);async function resolveTargetDirectory(e,t){let n=resolve(e,t);return(await stat(n).catch(()=>void 0))?.isDirectory()?n:void 0}function isCurrentDirectoryTarget(e){return/^\.(?:[/\\]+\.?)*$/u.test(e.trim())}async function assertCanScaffoldInPlace(e){let t=(await readdir(e)).filter(e=>!ALLOWED_CREATE_IN_PLACE_ENTRIES.has(e));if(t.length===0)return;let n=t.slice(0,5).join(`, `),r=t.length>5?`, and ${t.length-5} more`:``;throw Error(`Cannot create project in current directory because it is not empty. Found: ${n}${r}. Use an empty directory.`)}async function moveDirectoryContents(e,t){for(let n of await readdir(e))await rename(join(e,n),join(t,n))}function uniqueWorkspaceRootMutations(e){let t=new Map;for(let n of e){let e=`${n.kind}:${n.path}`,r=t.get(e);t.set(e,{...n,nodeEngineOverride:n.nodeEngineOverride??r?.nodeEngineOverride})}return[...t.values()]}function formatWorkspaceRootMutationWarning(e){let t=e.kind===`package-json`?`package.json`:`configuration`,n=e.nodeEngineOverride===void 0?``:` (${formatNodeEngineOverrideWarning(e.nodeEngineOverride)})`;return`Updated workspace root ${t} at ${e.path}${n}`}async function addToExistingProject(e,t,n,r){if(t.channelWebNextjs===!0)throw Error("`--channel-web-nextjs` is not supported when adding an agent to an existing project. Run `eve channels add web` from the project afterwards instead.");let i=await n.detectPackageManager(e),a=await n.addAgentToProject({projectRoot:e,model:DEFAULT_AGENT_MODEL_ID,packageManager:i.kind,evePackage:r});return{packageManager:i.kind,nodeEngineOverride:a.nodeEngineOverride}}async function resolveScaffoldPackageManager(e,t){let n=await t.detectPackageManager(e);return n.source==="default"?t.detectInvokingPackageManager()??`pnpm`:n.kind}async function scaffoldProject(e,t,n,r,i,a){let o=resolve(e),s=t===`.`,c=s?o:join(o,t);if(s)await assertCanScaffoldInPlace(c);else if(await pathExists(c))throw Error(`Cannot create project because "${c}" already exists.`);let l=await mkdtemp(join(o,`.eve-init-`)),p=[];try{let e={projectName:s?basename(c):t,model:DEFAULT_AGENT_MODEL_ID,evePackage:a,targetDirectory:l,workspaceProbeDirectory:c,packageManager:n,onWorkspaceRootMutation:e=>{p.push(e)}},o=await i.scaffoldBaseProject(e);return r.channelWebNextjs===!0&&await i.ensureChannel({projectRoot:o,kind:`web`,packageManager:n,workspaceProbeDirectory:c,configureVercelServices:!1,onWorkspaceRootMutation:e=>{p.push(e)}}),s?await moveDirectoryContents(o,c):await rename(o,c),{projectPath:c,workspaceRootMutations:uniqueWorkspaceRootMutations(p)}}finally{await rm(l,{recursive:!0,force:!0})}}function installProgressDetail(e,t){let n=t.text.trim();if(n===``||e!==`npm`)return n||void 0;let r=/^npm silly fetch manifest (.+)$/u.exec(n);if(r!==null)return`Resolving ${r[1]}`;let i=/^npm http fetch \S+ \S+ attempt (\d+) failed with (\S+)$/u.exec(n);if(i!==null)return`npm registry · attempt ${i[1]} failed: ${i[2]}`;if(t.stream===`stdout`||/^npm (?:error|warn)\b/u.test(n))return n}const NPM_NOISE_LINE=/^\s*npm (?:silly|verbose|http|timing)\b/u;async function runInitSteps(e){let{dependencies:t,logger:n,options:r,parentDirectory:i,target:a}=e,o=isLogLevelEnabled(`debug`),s=startCliLiveRow(n);s.update(`Preparing project`);try{let e=await t.isCodingAgentLaunch(),c=a??`.`,l=isCurrentDirectoryTarget(c),u=l?await pathExists(join(resolve(i),`package.json`))?resolve(i):void 0:await resolveTargetDirectory(i,c),p=resolveInitEvePackageOverride(),m=u===void 0?`creating agent`:`adding agent`;s.update(u===void 0?`Creating agent`:`Adding agent`),initLog.debug(m);let h=t.now(),g;if(u===void 0){let e=l?`.`:parseProjectName(c),n=resolve(i),a=await resolveScaffoldPackageManager(e===`.`?n:join(n,e),t),o=await scaffoldProject(i,e,a,r,t,p);g={kind:`created`,packageManager:a,projectPath:o.projectPath,workspaceRootMutations:o.workspaceRootMutations}}else{let e=await addToExistingProject(u,r,t,p);g=e.nodeEngineOverride===void 0?{kind:`added`,packageManager:e.packageManager,projectPath:u}:{kind:`added`,nodeEngineOverride:e.nodeEngineOverride,packageManager:e.packageManager,projectPath:u}}let _=t.now()-h;initLog.debug(`${m} done`,{ms:_}),s.update(`Installing dependencies`,`${g.packageManager} install`),initLog.debug(`installing dependencies with ${g.packageManager}`);let v=t.now(),y=[],b=[],x=await t.runPackageManagerInstall(g.packageManager,g.projectPath,{bypassMinimumReleaseAge:!0,progressDetails:process.stdout.isTTY===!0&&!o,onOutput:e=>{e.text.trim()!==``&&(b.push(e.text),b.length>20&&b.shift(),NPM_NOISE_LINE.test(e.text)||y.push(e.text)),o&&initLog.debug(e.text);let t=installProgressDetail(g.packageManager,e);t!==void 0&&s.update(`Installing dependencies`,t)}}),S=t.now()-v;if(!x){initLog.debug(`dependency installation failed`,{ms:S}),s.stop();let e=y.length>0?y:b;for(let t of e)n.error(t);throw Error(`Failed to install dependencies in "${g.projectPath}".`)}return initLog.debug(`dependencies installed`,{ms:S}),g.kind===`created`?(s.update(`Initializing Git repository`),initLog.debug(`initializing git repository`),{...g,agentElapsedMs:_,agentLaunched:e,gitResult:await t.tryInitializeGit(g.projectPath),installElapsedMs:S}):{...g,agentElapsedMs:_,agentLaunched:e,installElapsedMs:S}}finally{s.stop()}}async function runInitCommand(e,t,a,o,s=defaultDependencies){if(a===void 0&&await s.isCodingAgentLaunch()){e.log(initAgentInstructions());return}let c=await runInitSteps({dependencies:s,logger:e,options:o,parentDirectory:t,target:a});if(c.kind===`created`){e.log(`${import_picocolors.default.green(`✓`)} Created an ${EVE_WORDMARK} agent in ${import_picocolors.default.bold(c.projectPath)} ${import_picocolors.default.dim(`in ${formatElapsed(c.agentElapsedMs)}`)}`);for(let t of c.workspaceRootMutations)e.log(import_picocolors.default.yellow(`⚠ ${formatWorkspaceRootMutationWarning(t)}`))}else e.log(`${import_picocolors.default.green(`✓`)} Added an ${EVE_WORDMARK} agent to ${import_picocolors.default.bold(c.projectPath)} ${import_picocolors.default.dim(`in ${formatElapsed(c.agentElapsedMs)}`)}`),c.nodeEngineOverride!==void 0&&e.log(import_picocolors.default.yellow(`⚠ ${formatNodeEngineOverrideWarning(c.nodeEngineOverride)}`));e.log(`${import_picocolors.default.green(`✓`)} Installed dependencies ${import_picocolors.default.dim(`in ${formatElapsed(c.installElapsedMs)}`)}`),c.kind===`created`&&c.gitResult.kind===`failed`&&e.error(import_picocolors.default.yellow(`Git initialization failed: ${c.gitResult.reason}`));let l=[c.packageManager,...eveDevArguments(c.packageManager)].join(` `),d=initAgentDevHandoff({projectPath:c.projectPath,devCommand:l});if(c.agentLaunched){e.log(d);return}let f;try{f=await s.selectInitHandoff({agentName:basename(c.projectPath)})}catch(e){if(e instanceof WizardCancelledError)return;throw e}if(f!==`eve-dev`){if(e.log(import_picocolors.default.dim(`$ ${f}`)),!await s.spawnCodingAgentRepl({command:f,cwd:c.projectPath,prompt:initAgentReplPrompt({devCommand:l}),onPromptUnseeded:t=>{e.log(import_picocolors.default.yellow(`Could not seed ${f} automatically. Paste this prompt into it:`)),e.log(t)}}))throw Error(`Coding-agent REPL exited unsuccessfully in "${c.projectPath}".`);return}let p=c.kind===`created`,m=p?[...eveDevArguments(c.packageManager),`--input`,`/model`]:eveDevArguments(c.packageManager);if(e.log(import_picocolors.default.dim(p?`$ eve dev --input /model`:`$ eve dev`)),!await s.spawnPackageManager(c.packageManager,c.projectPath,m))throw Error(`Development server exited unsuccessfully in "${c.projectPath}".`)}function resolveInitEvePackageOverride(){let e=process.env[EVE_INIT_PACKAGE_SPEC_ENV]?.trim();if(!(e===void 0||e.length===0))return{nodeEngine:DEFAULT_EVE_PACKAGE_CONTRACT.nodeEngine,version:e}}export{EVE_INIT_PACKAGE_SPEC_ENV,runInitCommand};
@@ -1 +1 @@
1
- import{truncate}from"./tool-format.js";const AGENT_HEADER_TIPS=[`Use /channels to add more ways to reach your agent.`,`Use /deploy to see your agent go live.`,`Type /help to see every command.`];function pickAgentHeaderTip(e=Math.random){return AGENT_HEADER_TIPS[Math.min(AGENT_HEADER_TIPS.length-1,Math.floor(e()*AGENT_HEADER_TIPS.length))]}function buildAgentHeader(t){let{theme:n,info:r,name:i,width:a}=t,o=n.colors,s=[],c=o.bold(`eve`);if(s.push(` ${c} ${o.dim(truncate(i,Math.max(8,a-8)))}`),r&&(r.diagnostics.discoveryErrors>0||r.diagnostics.discoveryWarnings>0)){let e=[];r.diagnostics.discoveryErrors>0&&e.push(o.red(`${r.diagnostics.discoveryErrors} error${plural(r.diagnostics.discoveryErrors)}`)),r.diagnostics.discoveryWarnings>0&&e.push(o.yellow(`${r.diagnostics.discoveryWarnings} warning${plural(r.diagnostics.discoveryWarnings)}`)),s.push(` ${o.dim(n.glyph.warning)} ${e.join(o.dim(` · `))}`)}return t.tip!==void 0&&s.push(` ${o.dim(truncate(t.tip,Math.max(8,a-2)))}`),s}function plural(e){return e===1?``:`s`}export{AGENT_HEADER_TIPS,buildAgentHeader,pickAgentHeaderTip};
1
+ import{isPromptControlCommand}from"./prompt-commands.js";import{truncate}from"./tool-format.js";const AGENT_HEADER_TIPS=[`Use /channels to add more ways to reach your agent.`,`Use /deploy to see your agent go live.`,`Type /help to see every command.`,`Tip: /connect to seamlessly add MCP Connections to your agent`];function pickAgentHeaderTip(e=Math.random){return AGENT_HEADER_TIPS[Math.min(AGENT_HEADER_TIPS.length-1,Math.floor(e()*AGENT_HEADER_TIPS.length))]}function buildAgentHeader(e){let{theme:n,info:r,name:i,width:a}=e,o=n.colors,s=[],c=o.bold(`eve`);if(s.push(` ${c} ${o.dim(truncate(i,Math.max(8,a-8)))}`),r&&(r.diagnostics.discoveryErrors>0||r.diagnostics.discoveryWarnings>0)){let e=[];r.diagnostics.discoveryErrors>0&&e.push(o.red(`${r.diagnostics.discoveryErrors} error${plural(r.diagnostics.discoveryErrors)}`)),r.diagnostics.discoveryWarnings>0&&e.push(o.yellow(`${r.diagnostics.discoveryWarnings} warning${plural(r.diagnostics.discoveryWarnings)}`)),s.push(` ${o.dim(n.glyph.warning)} ${e.join(o.dim(` · `))}`)}return e.tip!==void 0&&s.push(` ${renderTip(e.tip,Math.max(8,a-2),n)}`),s}function renderTip(n,r,i){return truncate(n,r).split(/(\/[a-z:-]+)/u).map(t=>isPromptControlCommand(t)?i.colors.blue(t):i.colors.dim(t)).join(``)}function plural(e){return e===1?``:`s`}export{AGENT_HEADER_TIPS,buildAgentHeader,pickAgentHeaderTip};
@@ -0,0 +1,16 @@
1
+ import { type AgentInfoResult, type Client } from "#client/index.js";
2
+ export type AgentInfoProbeResult = {
3
+ readonly kind: "ready";
4
+ readonly info: AgentInfoResult;
5
+ } | {
6
+ readonly kind: "unavailable";
7
+ readonly error: unknown;
8
+ };
9
+ /**
10
+ * Reads best-effort inspection data from a server whose lifecycle belongs to
11
+ * another process. Transient transport and server failures can occur while
12
+ * that process reloads, but auth and schema failures cannot be fixed by retry.
13
+ */
14
+ export declare function probeAgentInfo(input: {
15
+ readonly client: Pick<Client, "info">;
16
+ }): Promise<AgentInfoProbeResult>;
@@ -0,0 +1 @@
1
+ import{AgentInfoResponseError,ClientError}from"#client/index.js";function isRetryableAgentInfoFailure(n){return n instanceof AgentInfoResponseError?!1:n instanceof ClientError?n.status>=500:n instanceof TypeError}function sleep(e){return new Promise(t=>setTimeout(t,e))}async function probeAgentInfo(e){try{return{kind:`ready`,info:await e.client.info()}}catch(e){if(!isRetryableAgentInfoFailure(e))return{kind:`unavailable`,error:e}}await sleep(100);try{return{kind:`ready`,info:await e.client.info()}}catch(e){return{kind:`unavailable`,error:e}}}export{probeAgentInfo};
@@ -1,8 +1,8 @@
1
- import{sliceVisible,visibleLength,wrapVisibleLine}from"./terminal-text.js";import{formatValuePretty,truncate}from"./tool-format.js";import{renderMarkdown}from"./markdown.js";import{isPromptControlCommand}from"./prompt-commands.js";function renderBlockLines(e,n,r,i){let a=nestingPrefix(e.depth??0,r);return renderBody(e,Math.max(8,n-visibleLength(a)),r,i).map(e=>`${a}${e}`)}function nestingPrefix(e,t){return e<=0?``:`${t.colors.orange(t.glyph.rule)} `.repeat(e)}function renderBody(e,t,n,r){switch(e.kind){case`user`:return renderUser(e,t,n);case`assistant`:case`subagent-step`:return renderProse(e,t,n);case`reasoning`:return renderReasoning(e,t,n);case`tool`:case`subagent-tool`:return renderTool(e,t,n,r);case`error`:return renderError(e,t,n);case`notice`:return renderNotice(e,t,n);case`warning`:return renderWarning(e,t,n);case`result`:return renderResult(e,t,n);case`flow`:return renderFlow(e,t,n);case`command`:return renderCommand(e,n);case`question`:case`connection-auth`:return renderPreformatted(e,t,n);case`sandbox`:return renderSandbox(e,t,n,r);case`log`:return renderLog(e,t,n,r);case`subagent`:return renderSubagentHeader(e,t,n);case`agent-header`:return(e.body??``).split(`
2
- `)}}function renderUser(e,t,n){let r=n.colors.cyan(n.glyph.user);return wrap(e.body??``,t-2).map(e=>`${r} ${e}`)}function renderProse(e,t,r){let i=[],o=e.kind===`subagent-step`,s=o?``:`${r.colors.bold(r.colors.white(r.glyph.brand))} `,c=o?``:` `;e.reasoning&&e.reasoning.trim().length>0&&i.push(...renderReasoningLines(e.reasoning,t,r));let l=(e.body??``).trim();return l.length===0&&i.length===0?[`${s}${r.colors.dim(`thinking${r.glyph.ellipsis}`)}`]:(l.length>0&&renderMarkdown(l).split(`
3
- `).flatMap(e=>wrapVisibleLine(e,t-c.length)).forEach((e,t)=>{t===0&&!o&&i.length===0?i.push(`${s}${e}`):i.push(`${c}${e}`)}),i.length>0?i:[`${s}`])}function renderReasoning(e,t,n){return e.collapsed?[`${n.colors.gray(n.glyph.reasoning)} ${n.colors.dim(`thinking`)}`]:renderReasoningLines(e.body??``,t,n,n.glyph.reasoning)}function renderReasoningLines(e,t,n,r){let i=r?2:0,a=wrap(e.trim(),t-i);return a.length===0?[]:a.map((e,t)=>`${r?t===0?`${n.colors.gray(r)} `:` `:``}${n.colors.dim(n.colors.italic(e))}`)}function renderTool(e,t,n,r){let{icon:a,accent:o}=toolGlyph(e.status??`running`,n,r),s=e.title??`tool`,c=t-2,l=truncatePlain(s,c),u=`${a} ${n.colors.bold(l)}`,d=c-l.length-2,f=e.subtitle??``;f.length>0&&d>=6&&(u+=` ${n.colors.gray(truncate(f,d))}`);let p=[u];return e.expanded?p.push(...renderToolExpanded(e,t,n)):e.status===`done`&&e.result&&e.result.length>0?p.push(resultLine(n.glyph.arrow,e.result,t,n,o)):e.status===`error`&&e.result?p.push(resultLine(n.glyph.arrow,e.result,t,n,n.colors.red)):e.status===`denied`&&p.push(resultLine(n.glyph.arrow,`denied`,t,n,n.colors.yellow)),p}function renderToolExpanded(e,t,n){let i=[],push=(e,a,o)=>{if(a!==void 0){i.push(` ${n.colors.dim(e)}`);for(let e of wrap(formatValuePretty(a),t-4))i.push(` ${o(e)}`)}};return push(`input`,e.toolInput,n.colors.gray),e.status===`error`&&e.result?push(`error`,e.result,n.colors.red):push(`output`,e.toolOutput,n.colors.gray),i}function resultLine(e,t,n,r,a){let o=n-4;return` ${r.colors.dim(e)} ${a(truncate(t,o))}`}function toolGlyph(e,t,n){switch(e){case`done`:return{icon:t.colors.green(t.glyph.success),accent:t.colors.gray};case`error`:return{icon:t.colors.red(t.glyph.error),accent:t.colors.red};case`denied`:return{icon:t.colors.yellow(t.glyph.warning),accent:t.colors.yellow};case`approval`:return{icon:t.colors.yellow(t.glyph.question),accent:t.colors.yellow};default:return{icon:t.colors.yellow(n.spinner),accent:t.colors.gray}}}function renderError(e,t,n){let r=n.colors.red(n.colors.bold(n.glyph.error)),i=e.title??`Error`,a=[`${r} ${n.colors.red(n.colors.bold(i))}`];for(let r of wrap(e.body??``,t-2))a.push(` ${colorizeError(r,n)}`);return a.push(...renderErrorDetail(e.detail,t,n)),a}function renderErrorDetail(e,t,n){if(e===void 0||e.trim().length===0)return[];let r=e.split(`
4
- `),i=r.slice(0,12),a=i.map(e=>` ${n.colors.dim(truncatePlain(e,Math.max(1,t-2)))}`),o=r.length-i.length;return o>0&&a.push(` ${n.colors.dim(`${n.glyph.ellipsis} +${o} more line${o===1?``:`s`}`)}`),a}const URL_PATTERN=/(https?:\/\/\S+)/u;function colorizeError(e,t){return URL_PATTERN.test(e)?e.split(URL_PATTERN).map((e,n)=>n%2==1?t.colors.cyan(e):t.colors.red(e)).join(``):t.colors.red(e)}function renderNotice(e,t,n){let r=n.colors.dim(n.glyph.dot),i=wrap(e.body??``,t-2);return i.length===0?[r]:i.map(e=>`${r} ${n.colors.dim(e)}`)}function renderAttentionRows(e,t,n){let r=n.colors.yellow(n.glyph.warning);return wrap(e,t-2).map((e,t)=>`${t===0?r:` `} ${paintCommands(e,n)}`)}function renderWarning(e,t,n){return renderAttentionRows(e.body??``,t,n)}function paintCommands(e,t){return e.replace(/\/[a-z:-]+/g,e=>isPromptControlCommand(e)?t.colors.blue(e):e)}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,r){let i=e.kind===`connection-auth`?r.colors.yellow(r.glyph.connection):r.colors.yellow(r.colors.bold(r.glyph.question)),a=wrap(e.title??``,t-2),o=a.length===0?[`${i} `]:a.map((e,t)=>t===0?`${i} ${r.colors.bold(e)}`:` ${r.colors.bold(e)}`);for(let r of(e.body??``).split(`
5
- `))for(let e of wrapVisibleLine(r,t-2))o.push(` ${e}`);return o}function renderSandbox(e,r,i,a){let o=i.colors.cyan(i.glyph.rule),s=i.colors.dim(`sandbox ${i.glyph.dot} `),c=visibleLength(s),l=` `.repeat(c),u=a.previous?.kind===`sandbox`,d=(e.body??``).split(`
6
- `),f=[];for(let e of d){let t=wrapVisibleLine(e,Math.max(1,r-2-c));for(let e of t){let t=f.length===0&&!u?s:l;f.push(`${o} ${t}${i.colors.gray(e)}`)}}return f.length>0?f:[`${o}`]}function renderLog(e,r,i,a){let o=e.title===`stderr`,s=o?i.colors.red:i.colors.gray,c=i.colors.dim(i.glyph.rule),l=o?`stderr`:`stdout`,u=i.colors.dim(`${l} ${i.glyph.dot} `),d=visibleLength(u),f=` `.repeat(d),p=a.previous?.kind===`log`&&a.previous.title===e.title,m=(e.body??``).split(`
7
- `),h=[];for(let e of m){let t=wrapVisibleLine(e,Math.max(1,r-2-d));for(let e of t){let t=h.length===0&&!p?u:f;h.push(`${c} ${t}${i.colors.dim(s(e))}`)}}return h.length>0?h:[`${c}`]}function renderSubagentHeader(e,t,n){let r=truncatePlain(e.title??`subagent`,Math.max(8,t-14));return[`${n.colors.orange(n.glyph.subagent)} ${n.colors.bold(r)} ${n.colors.dim(`subagent`)}`]}function wrap(e,t){return e.trim().length===0?[]:e.split(`
8
- `).flatMap(e=>wrapVisibleLine(e,Math.max(1,t)))}function truncatePlain(n,r){return visibleLength(n)<=r?n:sliceVisible(n,r)}export{renderAttentionRows,renderBlockLines};
1
+ import{isPromptControlCommand}from"./prompt-commands.js";import{sliceVisible,visibleLength,wrapVisibleLine}from"./terminal-text.js";import{formatValuePretty,truncate}from"./tool-format.js";import{renderMarkdown}from"./markdown.js";function renderBlockLines(e,t,r,i){let a=nestingPrefix(e.depth??0,r);return renderBody(e,Math.max(8,t-visibleLength(a)),r,i).map(e=>`${a}${e}`)}function nestingPrefix(e,t){return e<=0?``:`${t.colors.orange(t.glyph.rule)} `.repeat(e)}function renderBody(e,t,n,r){switch(e.kind){case`user`:return renderUser(e,t,n);case`assistant`:case`subagent-step`:return renderProse(e,t,n);case`reasoning`:return renderReasoning(e,t,n);case`tool`:case`subagent-tool`:return renderTool(e,t,n,r);case`error`:return renderError(e,t,n);case`notice`:return renderNotice(e,t,n);case`warning`:return renderWarning(e,t,n);case`result`:return renderResult(e,t,n);case`flow`:return renderFlow(e,t,n);case`command`:return renderCommand(e,n);case`question`:case`connection-auth`:return renderPreformatted(e,t,n);case`sandbox`:return renderSandbox(e,t,n,r);case`log`:return renderLog(e,t,n,r);case`subagent`:return renderSubagentHeader(e,t,n);case`agent-header`:return(e.body??``).split(`
2
+ `)}}function renderUser(e,t,n){let r=n.colors.cyan(n.glyph.user);return wrap(e.body??``,t-2).map(e=>`${r} ${e}`)}function renderProse(e,t,n){let i=[],a=e.kind===`subagent-step`,s=a?``:`${n.colors.bold(n.colors.white(n.glyph.brand))} `,c=a?``:` `;e.reasoning&&e.reasoning.trim().length>0&&i.push(...renderReasoningLines(e.reasoning,t,n));let l=(e.body??``).trim();return l.length===0&&i.length===0?[`${s}${n.colors.dim(`thinking${n.glyph.ellipsis}`)}`]:(l.length>0&&renderMarkdown(l).split(`
3
+ `).flatMap(e=>wrapVisibleLine(e,t-c.length)).forEach((e,t)=>{t===0&&!a&&i.length===0?i.push(`${s}${e}`):i.push(`${c}${e}`)}),i.length>0?i:[`${s}`])}function renderReasoning(e,t,n){return e.collapsed?[`${n.colors.gray(n.glyph.reasoning)} ${n.colors.dim(`thinking`)}`]:renderReasoningLines(e.body??``,t,n,n.glyph.reasoning)}function renderReasoningLines(e,t,n,r){let i=r?2:0,a=wrap(e.trim(),t-i);return a.length===0?[]:a.map((e,t)=>`${r?t===0?`${n.colors.gray(r)} `:` `:``}${n.colors.dim(n.colors.italic(e))}`)}function renderTool(e,t,n,r){let{icon:i,accent:o}=toolGlyph(e.status??`running`,n,r),s=e.title??`tool`,c=t-2,l=truncatePlain(s,c),u=`${i} ${n.colors.bold(l)}`,d=c-l.length-2,f=e.subtitle??``;f.length>0&&d>=6&&(u+=` ${n.colors.gray(truncate(f,d))}`);let p=[u];return e.expanded?p.push(...renderToolExpanded(e,t,n)):e.status===`done`&&e.result&&e.result.length>0?p.push(resultLine(n.glyph.arrow,e.result,t,n,o)):e.status===`error`&&e.result?p.push(resultLine(n.glyph.arrow,e.result,t,n,n.colors.red)):e.status===`denied`&&p.push(resultLine(n.glyph.arrow,`denied`,t,n,n.colors.yellow)),p}function renderToolExpanded(e,t,n){let r=[],push=(e,a,o)=>{if(a!==void 0){r.push(` ${n.colors.dim(e)}`);for(let e of wrap(formatValuePretty(a),t-4))r.push(` ${o(e)}`)}};return push(`input`,e.toolInput,n.colors.gray),e.status===`error`&&e.result?push(`error`,e.result,n.colors.red):push(`output`,e.toolOutput,n.colors.gray),r}function resultLine(e,t,n,r,i){let o=n-4;return` ${r.colors.dim(e)} ${i(truncate(t,o))}`}function toolGlyph(e,t,n){switch(e){case`done`:return{icon:t.colors.green(t.glyph.success),accent:t.colors.gray};case`error`:return{icon:t.colors.red(t.glyph.error),accent:t.colors.red};case`denied`:return{icon:t.colors.yellow(t.glyph.warning),accent:t.colors.yellow};case`approval`:return{icon:t.colors.yellow(t.glyph.question),accent:t.colors.yellow};default:return{icon:t.colors.yellow(n.spinner),accent:t.colors.gray}}}function renderError(e,t,n){let r=n.colors.red(n.colors.bold(n.glyph.error)),i=e.title??`Error`,a=[`${r} ${n.colors.red(n.colors.bold(i))}`];for(let r of wrap(e.body??``,t-2))a.push(` ${colorizeError(r,n)}`);return a.push(...renderErrorDetail(e.detail,t,n)),a}function renderErrorDetail(e,t,n){if(e===void 0||e.trim().length===0)return[];let r=e.split(`
4
+ `),i=r.slice(0,12),a=i.map(e=>` ${n.colors.dim(truncatePlain(e,Math.max(1,t-2)))}`),o=r.length-i.length;return o>0&&a.push(` ${n.colors.dim(`${n.glyph.ellipsis} +${o} more line${o===1?``:`s`}`)}`),a}const URL_PATTERN=/(https?:\/\/\S+)/u;function colorizeError(e,t){return URL_PATTERN.test(e)?e.split(URL_PATTERN).map((e,n)=>n%2==1?t.colors.cyan(e):t.colors.red(e)).join(``):t.colors.red(e)}function renderNotice(e,t,n){let r=n.colors.dim(n.glyph.dot),i=wrap(e.body??``,t-2);return i.length===0?[r]:i.map(e=>`${r} ${n.colors.dim(e)}`)}function renderAttentionRows(e,t,n){let r=n.colors.yellow(n.glyph.warning);return wrap(e,t-2).map((e,t)=>`${t===0?r:` `} ${paintCommands(e,n)}`)}function renderWarning(e,t,n){return renderAttentionRows(e.body??``,t,n)}function paintCommands(t,n){return t.replace(/\/[a-z:-]+/g,t=>isPromptControlCommand(t)?n.colors.blue(t):t)}function renderCommand(e,t){let n=t.colors,r=e.status===`error`?`${n.red(t.glyph.error)} `:``;return[`${n.cyan(t.glyph.user)} ${r}${n.blue(e.body??``)}`]}function renderFlow(e,t,n){let r=n.colors,i=e.title??`info`,a=i===`success`?r.green(n.glyph.success):i===`warning`?r.yellow(n.glyph.warning):i===`error`?r.red(n.glyph.error):r.dim(n.glyph.dot),o=wrap(e.body??``,t-2),paint=e=>i===`info`?r.dim(e):e;return o.map((e,t)=>`${t===0?a:` `} ${paint(e)}`)}function renderResult(e,t,n){let r=n.colors.dim(n.glyph.elbow),i=wrap(e.body??``,t-7);if(i.length===0)return[` ${r}`];let dim=e=>n.colors.dim(e.replaceAll(`\x1B[22m`,`\x1B[22m\x1B[2m`));return i.map((e,t)=>t===0?` ${r} ${dim(e)}`:` ${dim(e)}`)}function renderPreformatted(e,t,n){let i=e.kind===`connection-auth`?n.colors.yellow(n.glyph.connection):n.colors.yellow(n.colors.bold(n.glyph.question)),a=wrap(e.title??``,t-2),o=a.length===0?[`${i} `]:a.map((e,t)=>t===0?`${i} ${n.colors.bold(e)}`:` ${n.colors.bold(e)}`);for(let n of(e.body??``).split(`
5
+ `))for(let e of wrapVisibleLine(n,t-2))o.push(` ${e}`);return o}function renderSandbox(e,t,i,a){let o=i.colors.cyan(i.glyph.rule),s=i.colors.dim(`sandbox ${i.glyph.dot} `),c=visibleLength(s),l=` `.repeat(c),u=a.previous?.kind===`sandbox`,d=(e.body??``).split(`
6
+ `),f=[];for(let e of d){let n=wrapVisibleLine(e,Math.max(1,t-2-c));for(let e of n){let t=f.length===0&&!u?s:l;f.push(`${o} ${t}${i.colors.gray(e)}`)}}return f.length>0?f:[`${o}`]}function renderLog(e,t,i,a){let o=e.title===`stderr`,s=o?i.colors.red:i.colors.gray,c=i.colors.dim(i.glyph.rule),l=o?`stderr`:`stdout`,u=i.colors.dim(`${l} ${i.glyph.dot} `),d=visibleLength(u),f=` `.repeat(d),p=a.previous?.kind===`log`&&a.previous.title===e.title,m=(e.body??``).split(`
7
+ `),h=[];for(let e of m){let n=wrapVisibleLine(e,Math.max(1,t-2-d));for(let e of n){let t=h.length===0&&!p?u:f;h.push(`${c} ${t}${i.colors.dim(s(e))}`)}}return h.length>0?h:[`${c}`]}function renderSubagentHeader(e,t,n){let r=truncatePlain(e.title??`subagent`,Math.max(8,t-14));return[`${n.colors.orange(n.glyph.subagent)} ${n.colors.bold(r)} ${n.colors.dim(`subagent`)}`]}function wrap(e,t){return e.trim().length===0?[]:e.split(`
8
+ `).flatMap(e=>wrapVisibleLine(e,Math.max(1,t)))}function truncatePlain(e,r){return visibleLength(e)<=r?e:sliceVisible(e,r)}export{renderAttentionRows,renderBlockLines};
@@ -0,0 +1,19 @@
1
+ export type McpConnectionProbe = (input: {
2
+ url: string;
3
+ signal: AbortSignal;
4
+ }) => Promise<string | undefined>;
5
+ export declare function probeMcpConnection(input: {
6
+ url: string;
7
+ signal: AbortSignal;
8
+ }): Promise<string | undefined>;
9
+ export interface McpConnectionStatusTracker {
10
+ current(): Readonly<Record<string, string>>;
11
+ refresh(): void;
12
+ dispose(): void;
13
+ }
14
+ export interface McpConnectionStatusTrackerOptions {
15
+ onChange: (disabledConnectionReasons: Readonly<Record<string, string>>) => void;
16
+ probe?: McpConnectionProbe;
17
+ intervalMs?: number;
18
+ }
19
+ export declare function createMcpConnectionStatusTracker(options: McpConnectionStatusTrackerOptions): McpConnectionStatusTracker;
@@ -0,0 +1 @@
1
+ import{CONNECTION_CATALOG}from"#setup/scaffold/index.js";async function probeMcpConnection(e){try{let t=await fetch(e.url,{method:`POST`,signal:e.signal,headers:{Accept:`application/json, text/event-stream`,"Content-Type":`application/json`,"MCP-Protocol-Version":`2025-03-26`},body:JSON.stringify({jsonrpc:`2.0`,id:`eve-connection-probe`,method:`initialize`,params:{protocolVersion:`2025-03-26`,capabilities:{},clientInfo:{name:`eve`,version:`connection-probe`}}})});return t.ok||t.status===401||t.status===403?void 0:`${e.url} is not reachable (HTTP ${t.status}).`}catch(t){if(e.signal.aborted)throw t;let n=t instanceof Error?t.message:`connection failed`;return`${e.url} is not reachable (${n}).`}}function createMcpConnectionStatusTracker(t){let n=t.probe??probeMcpConnection,r=t.intervalMs??6e4,i={},a=!1,o=0,s,c=setInterval(()=>refresh(),r);c.unref();let refresh=()=>{if(a)return;s?.abort(),s=new AbortController;let r=s,c=++o;Promise.all(CONNECTION_CATALOG.flatMap(e=>{let t=e.mcp?.url;return t===void 0?[]:[n({url:t,signal:r.signal}).then(t=>[e.slug,t])]})).then(e=>{a||c!==o||(i=Object.fromEntries(e.flatMap(([e,t])=>t===void 0?[]:[[e,t]])),t.onChange(i))}).catch(()=>{r.signal.aborted})};return{current:()=>i,refresh,dispose:()=>{a||(a=!0,o+=1,s?.abort(),s=void 0,clearInterval(c))}}}export{createMcpConnectionStatusTracker,probeMcpConnection};
@@ -1 +1 @@
1
- import{isPromptCommandAvailableFor}from"./prompt-commands.js";import{toErrorMessage}from"#shared/errors.js";function createPromptCommandHandler(n){return{async handle(r,i){let{target:a}=n;if(a.kind===`remote`&&!isPromptCommandAvailableFor(r.name,`remote`))return{message:`/${r.name} needs eve dev running the local server (it is not available with --url).`};if(r.name===`model`&&r.argument.length>0){if(a.kind!==`local`)return{message:`/model needs eve dev running the local server (it is not available with --url).`};let e=a.workspaceRoot;try{let{changeAgentModel:t,formatApplyModelOutcome:i,modelChangeRefusalForUneditableModel:a}=await import(`#setup/flows/model.js`),o=await(n.modelChangeRefusal??a)(e);return o===null?{message:i(await(n.applyModel??t)({appRoot:e,slug:r.argument}))}:{message:o}}catch(e){return{message:`Couldn't change the model: ${toErrorMessage(e)}`}}}let o=i.renderer.setupFlow;if(o===void 0)return{message:`/${r.name} is not supported by this renderer.`};if(r.name===`vc:login`&&a.kind===`remote`){if(i.remoteConnection===void 0)return{message:`/vc:login is not available in this session.`};let e;try{({runRemoteAuthCommand:e}=await import(`./remote-auth-command.js`))}catch(e){return{message:`/vc:login failed: ${toErrorMessage(e)}`}}return{message:await e({connection:i.remoteConnection,flow:n.remoteAuthFlow,renderer:o})}}let s;try{s=await import(`./setup-commands.js`)}catch(e){return{message:`/${r.name} failed: ${toErrorMessage(e)}`}}let{runTuiSetupCommand:c,SETUP_FLOW_CONFIG:l}=s,u=l[r.name];o.begin(u.title,u.indicator);let d=!0;try{let e={command:r.name,appRoot:a.workspaceRoot,renderer:o};i.initialModelStep!==void 0&&(e.initialModelStep=i.initialModelStep),n.flows!==void 0&&(e.flows=n.flows);let t=await c(e);d=t.preserveFlowDiagnostics;let s={message:t.message};return t.effect!==void 0&&(s.effect=t.effect),s}finally{o.end({preserveDiagnostics:d})}}}}export{createPromptCommandHandler};
1
+ import{isPromptCommandAvailableFor}from"./prompt-commands.js";import{toErrorMessage}from"#shared/errors.js";function createPromptCommandHandler(n){return{async handle(r,i){let{target:a}=n;if(a.kind===`remote`&&!isPromptCommandAvailableFor(r.name,`remote`))return{message:`/${r.name} needs eve dev running the local server (it is not available with --url).`};if(r.name===`model`&&r.argument.length>0){if(a.kind!==`local`)return{message:`/model needs eve dev running the local server (it is not available with --url).`};let e=a.workspaceRoot;try{let{changeAgentModel:t,formatApplyModelOutcome:i,modelChangeRefusalForUneditableModel:a}=await import(`#setup/flows/model.js`),o=await(n.modelChangeRefusal??a)(e);return o===null?{message:i(await(n.applyModel??t)({appRoot:e,slug:r.argument}))}:{message:o}}catch(e){return{message:`Couldn't change the model: ${toErrorMessage(e)}`}}}let o=i.renderer.setupFlow;if(o===void 0)return{message:`/${r.name} is not supported by this renderer.`};if(r.name===`vc:login`&&a.kind===`remote`){if(i.remoteConnection===void 0)return{message:`/vc:login is not available in this session.`};let e;try{({runRemoteAuthCommand:e}=await import(`./remote-auth-command.js`))}catch(e){return{message:`/vc:login failed: ${toErrorMessage(e)}`}}return{message:await e({connection:i.remoteConnection,flow:n.remoteAuthFlow,renderer:o})}}let s;try{s=await import(`./setup-commands.js`)}catch(e){return{message:`/${r.name} failed: ${toErrorMessage(e)}`}}let{runTuiSetupCommand:c,SETUP_FLOW_CONFIG:l}=s,u=l[r.name];o.begin(u.title,u.indicator);let d=!0;try{let e={command:r.name,appRoot:a.workspaceRoot,renderer:o,disabledConnectionReasons:i.disabledConnectionReasons};i.initialModelStep!==void 0&&(e.initialModelStep=i.initialModelStep),n.flows!==void 0&&(e.flows=n.flows);let t=await c(e);d=t.preserveFlowDiagnostics;let s={message:t.message};return t.effect!==void 0&&(s.effect=t.effect),s}finally{i.keepSetupFlowOpen!==!0&&o.end({preserveDiagnostics:d})}}}}export{createPromptCommandHandler};
@@ -1,4 +1,4 @@
1
- export type PromptCommandExtensionName = "model" | "channels" | "deploy" | "vc:install" | "vc:login";
1
+ export type PromptCommandExtensionName = "model" | "channels" | "connect" | "deploy" | "vc:install" | "vc:login";
2
2
  type PromptCommandTarget = "local" | "remote";
3
3
  /** The slash commands the prompt accepts. */
4
4
  export type PromptCommand = {
@@ -1,2 +1,2 @@
1
- const PROMPT_COMMAND_DEFINITIONS=[{name:`help`,aliases:[],description:`Show available commands`,takesArgument:!1,build:()=>({type:`help`}),targets:[`local`,`remote`]},{name:`new`,aliases:[],description:`Start a fresh session`,takesArgument:!1,build:()=>({type:`new`}),targets:[`local`,`remote`]},{name:`vc:install`,aliases:[],description:`Install the Vercel CLI`,takesArgument:!1,build:()=>({type:`extension`,name:`vc:install`,argument:``}),targets:[`local`,`remote`]},{name:`vc:login`,aliases:[],description:`Authenticate with Vercel`,takesArgument:!1,build:()=>({type:`extension`,name:`vc:login`,argument:``}),targets:[`local`,`remote`]},{name:`model`,aliases:[],description:`Configure the agent's model and provider`,argumentHint:`[provider/model]`,takesArgument:!0,build:e=>({type:`extension`,name:`model`,argument:e}),targets:[`local`]},{name:`loglevel`,aliases:[],description:`Show or hide captured stdout/stderr/sandbox logs`,argumentHint:`[all|stderr|sandbox|none]`,takesArgument:!0,build:e=>({type:`loglevel`,argument:e}),targets:[`local`,`remote`]},{name:`channels`,aliases:[],description:`Add chat channels to the agent`,takesArgument:!1,build:()=>({type:`extension`,name:`channels`,argument:``}),targets:[`local`]},{name:`deploy`,aliases:[],description:`Deploy the agent to Vercel`,takesArgument:!1,build:()=>({type:`extension`,name:`deploy`,argument:``}),targets:[`local`]},{name:`exit`,aliases:[`quit`],description:`Quit the TUI`,takesArgument:!1,build:()=>({type:`exit`}),targets:[`local`,`remote`]}],PROMPT_COMMANDS=PROMPT_COMMAND_DEFINITIONS;function promptCommandsFor(t){return PROMPT_COMMAND_DEFINITIONS.filter(e=>e.targets.some(e=>e===t))}function isPromptCommandAvailableFor(t,n){return(PROMPT_COMMAND_DEFINITIONS.find(e=>e.name===t)?.targets)?.includes(n)??!1}function parsePromptCommand(e){let n=e.trim();if(!n.startsWith(`/`))return null;for(let e of PROMPT_COMMANDS)for(let t of[e.name,...e.aliases]){let r=`/${t}`;if(n===r)return e.build(``);if(e.takesArgument&&n.startsWith(`${r} `))return e.build(n.slice(r.length).trim())}return null}function isPromptControlCommand(e){return parsePromptCommand(e)!==null}function formatPromptCommandHelp(e=PROMPT_COMMANDS){let n=e.map(e=>{let t=e.argumentHint===void 0?``:` ${e.argumentHint}`,n=e.aliases.map(e=>` (/${e})`).join(``);return{invocation:`/${e.name}${t}${n}`,description:e.description}}),r=Math.max(...n.map(e=>e.invocation.length))+2;return n.map(e=>e.invocation.padEnd(r)+e.description).join(`
1
+ const PROMPT_COMMAND_DEFINITIONS=[{name:`help`,aliases:[],description:`Show available commands`,takesArgument:!1,build:()=>({type:`help`}),targets:[`local`,`remote`]},{name:`new`,aliases:[],description:`Start a fresh session`,takesArgument:!1,build:()=>({type:`new`}),targets:[`local`,`remote`]},{name:`vc:install`,aliases:[],description:`Install the Vercel CLI`,takesArgument:!1,build:()=>({type:`extension`,name:`vc:install`,argument:``}),targets:[`local`,`remote`]},{name:`vc:login`,aliases:[],description:`Authenticate with Vercel`,takesArgument:!1,build:()=>({type:`extension`,name:`vc:login`,argument:``}),targets:[`local`,`remote`]},{name:`model`,aliases:[],description:`Configure the agent's model and provider`,argumentHint:`[provider/model]`,takesArgument:!0,build:e=>({type:`extension`,name:`model`,argument:e}),targets:[`local`]},{name:`loglevel`,aliases:[],description:`Show or hide captured stdout/stderr/sandbox logs`,argumentHint:`[all|stderr|sandbox|none]`,takesArgument:!0,build:e=>({type:`loglevel`,argument:e}),targets:[`local`,`remote`]},{name:`channels`,aliases:[],description:`Add chat channels to the agent`,takesArgument:!1,build:()=>({type:`extension`,name:`channels`,argument:``}),targets:[`local`]},{name:`connect`,aliases:[],description:`Add an MCP server through Vercel Connect`,takesArgument:!1,build:()=>({type:`extension`,name:`connect`,argument:``}),targets:[`local`]},{name:`deploy`,aliases:[],description:`Deploy the agent to Vercel`,takesArgument:!1,build:()=>({type:`extension`,name:`deploy`,argument:``}),targets:[`local`]},{name:`exit`,aliases:[`quit`],description:`Quit the TUI`,takesArgument:!1,build:()=>({type:`exit`}),targets:[`local`,`remote`]}],PROMPT_COMMANDS=PROMPT_COMMAND_DEFINITIONS;function promptCommandsFor(t){return PROMPT_COMMAND_DEFINITIONS.filter(e=>e.targets.some(e=>e===t))}function isPromptCommandAvailableFor(t,n){return(PROMPT_COMMAND_DEFINITIONS.find(e=>e.name===t)?.targets)?.includes(n)??!1}function parsePromptCommand(e){let n=e.trim();if(!n.startsWith(`/`))return null;for(let e of PROMPT_COMMANDS)for(let t of[e.name,...e.aliases]){let r=`/${t}`;if(n===r)return e.build(``);if(e.takesArgument&&n.startsWith(`${r} `))return e.build(n.slice(r.length).trim())}return null}function isPromptControlCommand(e){return parsePromptCommand(e)!==null}function formatPromptCommandHelp(e=PROMPT_COMMANDS){let n=e.map(e=>{let t=e.argumentHint===void 0?``:` ${e.argumentHint}`,n=e.aliases.map(e=>` (/${e})`).join(``);return{invocation:`/${e.name}${t}${n}`,description:e.description}}),r=Math.max(...n.map(e=>e.invocation.length))+2;return n.map(e=>e.invocation.padEnd(r)+e.description).join(`
2
2
  `)}export{PROMPT_COMMANDS,formatPromptCommandHelp,isPromptCommandAvailableFor,isPromptControlCommand,parsePromptCommand,promptCommandsFor};
@@ -1 +1 @@
1
- import{isObject}from"#shared/guards.js";import{toErrorMessage}from"#shared/errors.js";import{formatVercelTrustedSourcesFailure,isVercelAuthChallenge,vercelTrustedSourcesErrorCode}from"#services/dev-client/vercel-auth-error.js";import{AgentInfoResponseError,ClientError}from"#client/index.js";function isEveOidcChallenge(t){if(!(t instanceof ClientError)||t.status!==401)return!1;try{let n=JSON.parse(t.body);return isObject(n)&&n.ok===!1&&n.code===`unauthorized`&&n.error===`Authorization is required for this route.`}catch{return!1}}function classifyRemoteError(e,i){if(isVercelAuthChallenge(e))return{state:`auth-required`,challenge:{kind:`vercel-deployment-protection`}};if(isEveOidcChallenge(e))return{state:`auth-required`,challenge:{kind:`eve-oidc`}};if(e instanceof ClientError){let t=vercelTrustedSourcesErrorCode(e.message);if(i===`connection-check`&&e.status===403&&t===`TRUSTED_SOURCES_ENVIRONMENT_MISMATCH`)return{state:`auth-required`,challenge:{kind:`vercel-deployment-protection`}};let r={message:formatVercelTrustedSourcesFailure(e.message)};return{state:`unavailable`,failure:t===void 0?r:{...r,code:t}}}return{state:`unavailable`,failure:{message:toErrorMessage(e)}}}async function probeDeploymentHealth(t){try{let n=await t.health();return isObject(n)&&n.ok===!0}catch{return!1}}async function probeRemoteInfo(e){try{return{state:`ready`,info:await e.client.info()}}catch(t){return(t instanceof AgentInfoResponseError||t instanceof ClientError&&t.status===404)&&await probeDeploymentHealth(e.client)?{state:`ready`}:classifyRemoteError(t,e.phase)}}export{classifyRemoteError,probeRemoteInfo};
1
+ import{probeAgentInfo}from"./agent-info-probe.js";import{isObject}from"#shared/guards.js";import{AgentInfoResponseError,ClientError}from"#client/index.js";import{toErrorMessage}from"#shared/errors.js";import{formatVercelTrustedSourcesFailure,isVercelAuthChallenge,vercelTrustedSourcesErrorCode}from"#services/dev-client/vercel-auth-error.js";function isEveOidcChallenge(e){if(!(e instanceof ClientError)||e.status!==401)return!1;try{let n=JSON.parse(e.body);return isObject(n)&&n.ok===!1&&n.code===`unauthorized`&&n.error===`Authorization is required for this route.`}catch{return!1}}function classifyRemoteError(e,t){if(isVercelAuthChallenge(e))return{state:`auth-required`,challenge:{kind:`vercel-deployment-protection`}};if(isEveOidcChallenge(e))return{state:`auth-required`,challenge:{kind:`eve-oidc`}};if(e instanceof ClientError){let n=vercelTrustedSourcesErrorCode(e.message);if(t===`connection-check`&&e.status===403&&n===`TRUSTED_SOURCES_ENVIRONMENT_MISMATCH`)return{state:`auth-required`,challenge:{kind:`vercel-deployment-protection`}};let r={message:formatVercelTrustedSourcesFailure(e.message)};return{state:`unavailable`,failure:n===void 0?r:{...r,code:n}}}return{state:`unavailable`,failure:{message:toErrorMessage(e)}}}async function probeDeploymentHealth(e){try{let n=await e.health();return isObject(n)&&n.ok===!0}catch{return!1}}async function probeRemoteInfo(t){let i=await probeAgentInfo({client:t.client});if(i.kind===`ready`)return{state:`ready`,info:i.info};let{error:a}=i;return(a instanceof AgentInfoResponseError||a instanceof ClientError&&a.status===404)&&await probeDeploymentHealth(t.client)?{state:`ready`}:classifyRemoteError(a,t.phase)}export{classifyRemoteError,probeRemoteInfo};
@@ -9,6 +9,7 @@ import type { RemoteDevelopmentTarget } from "./target.js";
9
9
  import type { AssistantResponseStatsMode, LogDisplayMode, TerminalPartDisplayMode, TuiDisplayOptions } from "./types.js";
10
10
  import { type TerminalInput, type TerminalOutput } from "./terminal-renderer.js";
11
11
  import { type VercelStatusEffect, type VercelStatusSnapshot } from "./vercel-status.js";
12
+ import { type McpConnectionProbe } from "./mcp-connection-status.js";
12
13
  import type { detectProjectIdentity } from "#setup/project-resolution.js";
13
14
  import { getVercelAuthStatus } from "#setup/vercel-project.js";
14
15
  export { parsePromptCommand, type PromptCommand } from "./prompt-commands.js";
@@ -230,14 +231,22 @@ export interface PromptCommandHandlerContext {
230
231
  readonly title: string;
231
232
  /** Provider entry authorized by confirmed boot-time model-access evidence. */
232
233
  readonly initialModelStep?: "provider";
234
+ /**
235
+ * Leaves the current setup panel mounted for the next automatic onboarding
236
+ * command. The runner closes it if no next command can proceed.
237
+ */
238
+ readonly keepSetupFlowOpen?: true;
233
239
  readonly remoteConnection?: RemoteConnectionController;
240
+ readonly disabledConnectionReasons?: Readonly<Record<string, string>>;
234
241
  }
235
242
  /** What one handled slash command leaves behind for the runner to apply. */
236
243
  export interface PromptCommandOutcome {
237
244
  /** Outcome line rendered under the echoed command; absent renders nothing. */
238
245
  message?: string;
239
- /** Post-command work; model access also re-probes the Vercel identity. */
246
+ /** Post-command work after setup settles. */
240
247
  effect?: VercelStatusEffect | {
248
+ kind: "connection-added";
249
+ } | {
241
250
  kind: "model-access-changed";
242
251
  };
243
252
  }
@@ -248,6 +257,8 @@ export interface PromptCommandHandler {
248
257
  }
249
258
  export type EveTUIRunnerOptions = TuiDisplayOptions & {
250
259
  session: ClientSession;
260
+ /** Production TUI probe injected by the launcher; omitted in hermetic runners. */
261
+ probeMcpConnection?: McpConnectionProbe;
251
262
  /**
252
263
  * Optional client used to attach to child sessions for live subagent
253
264
  * stream observation. When omitted, the TUI still shows the subagent
@@ -277,8 +288,8 @@ export type EveTUIRunnerOptions = TuiDisplayOptions & {
277
288
  /** Absolute local application root; omitted for remote `--url` sessions. */
278
289
  appRoot?: string;
279
290
  /**
280
- * Seeds the editable prompt buffer for the first prompt only. The text is
281
- * not auto-submitted the user can edit it and presses Enter to send.
291
+ * Seeds the editable prompt buffer for the first prompt. A bare local
292
+ * `/model` starts initial model onboarding.
282
293
  */
283
294
  initialInput?: string;
284
295
  /** Handles non-core slash commands without adding feature branches to the runner. */
@@ -1 +1 @@
1
- import{pickAgentHeaderTip}from"./agent-header.js";import{PROMPT_COMMANDS,formatPromptCommandHelp,parsePromptCommand}from"./prompt-commands.js";import{failureKey,formatFailureDetail,formatFailureMessage,formatGatewayAuthFailureNotice,isAbortLikeError,isGatewayAuthFailure,isInterruptedError}from"./errors.js";import{parseLogDisplayMode}from"./log-display-mode.js";import{createRemoteConnectionController}from"./remote-connection.js";import{BOOT_DETECTIONS,CLI_MISSING_SETUP_ISSUE,LOGIN_SETUP_ISSUE,automaticSetupCommand,detectSetupIssues,formatSetupIssuesLine,orderedSetupIssues,resolveModelProviderState}from"./setup-issues.js";import{TerminalRenderer}from"./terminal-renderer.js";import{createVercelStatusTracker}from"./vercel-status.js";import{toErrorMessage}from"#shared/errors.js";import{getVercelAuthStatus}from"#setup/vercel-project.js";import{isCurrentTurnBoundaryEvent}from"#client/index.js";import{loadDevelopmentEnvironmentFiles}from"#cli/dev/environment.js";import{subscribeDevelopmentSandboxPrewarmLogs}from"#execution/sandbox/development-prewarm.js";import{createDevelopmentRuntimeArtifactSessionRefresher}from"#services/dev-client.js";import{devBootPhase}from"#internal/dev-boot-progress.js";function authIssueForStatus(e){if(e===`logged-out`)return LOGIN_SETUP_ISSUE;if(e===`cli-missing`)return CLI_MISSING_SETUP_ISSUE}var EveTUIRunner=class{#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;#u;#d;#f;#p;#m;#h;#g;#_;#v;#y;#b;#x=!1;#S=new AbortController;#C=!1;#w=[];#T;#E;#D=pickAgentHeaderTip();#O;#k=new Map;#A=new Map;#j=new Map;#M=new Map;#N=new Set;#P=!1;#F;constructor(e){if(this.#e=e.session,e.client!==void 0&&(this.#t=e.client),this.#n=createRenderer(e),this.#r=e.name??`eve`,this.#i=e.tools??`full`,this.#a=e.reasoning??`full`,this.#o=e.subagents??`full`,this.#s=e.connectionAuth??`full`,this.#c=e.assistantResponseStats??`tokensPerSecond`,this.#l=e.contextSize,this.#u=e.formatTransportError??toErrorMessage,e.initialInput!==void 0&&(this.#m=e.initialInput),e.appRoot!==void 0){this.#p=e.appRoot;let t={appRoot:e.appRoot,onChange:e=>this.#n.setVercelStatus?.(e)};e.detectProjectIdentity!==void 0&&(t.detectIdentity=e.detectProjectIdentity),this.#E=createVercelStatusTracker(t)}if(e.promptCommandHandler!==void 0&&(this.#h=e.promptCommandHandler),this.#g=e.availablePromptCommands??PROMPT_COMMANDS,e.remote!==void 0){if(this.#t===void 0)throw Error(`A remote TUI requires a configured development client.`);this.#_=createRemoteConnectionController({client:this.#t,credentials:e.remote.credentials,target:e.remote.target,onChange:e=>this.#n.setRemoteConnectionStatus?.(e),resolveOidcToken:e.remote.resolveOidcToken,resolveDeployment:e.remote.resolveDeployment})}this.#v=e.bootDetections??BOOT_DETECTIONS,this.#y=e.getVercelAuthStatus??getVercelAuthStatus,e.onBootProgress!==void 0&&(this.#b=e.onBootProgress),e.serverUrl!==void 0&&(this.#f=e.serverUrl),e.serverUrl!==void 0&&e.remote===void 0&&(this.#d=createDevelopmentRuntimeArtifactSessionRefresher({serverUrl:e.serverUrl}))}async#I(){if(this.#f===void 0){this.#R(),await this.#W(void 0);return}let e;if(this.#_!==void 0){let t=await this.#_.check();t.state===`ready`&&(e=t.info)}else try{e=await devBootPhase(`connecting to agent`,()=>this.#t?this.#t.info():Promise.resolve(void 0),this.#b)}catch{e=void 0}this.#R();let t=this.#L(e);await this.#W(t)}#L(e){let t=this.#p===void 0?e:resolveModelProviderState(e,process.env);this.#O=t;let n=this.#f;if(n===void 0)return t;let r={name:this.#r,serverUrl:n};return t!==void 0&&(r.info=t),this.#p!==void 0&&(r.tip=this.#D),this.#n.renderAgentHeader?.(r),t}#R(){let e=this.#b;this.#b=void 0,e?.({type:`before-first-paint`})}async run(){try{await this.#z()}finally{this.#x=!0,this.#S.abort(),this.#V(),this.#F?.(),this.#F=void 0,this.#n.shutdown?.(),this.#E?.dispose(),this.#_?.dispose()}}async#z(){let e=this.#r,t,i,a,o=!1,s=!1,c=this.#m;for(await this.#I(),this.#_?.current().connection.state===`auth-required`&&await this.#$({type:`extension`,name:`vc:login`,argument:``},e,`startup`),this.#J(),this.#E?.refreshIdentity(),this.#h!==void 0&&this.#n.setupFlow!==void 0&&(i=automaticSetupCommand(this.#w),t=i?.prompt);;){if(!s){if(t==null){if(!this.#n.readPrompt){if(o)return;throw Error(`No prompt was provided and the renderer does not support prompt input.`)}let n={title:e};c!==void 0&&(n.initialDraft=c,c=void 0);try{t=await this.#H(n)}catch(e){if(isInterruptedError(e))return;throw e}if(t==null)return}let l=parsePromptCommand(t);if(l?.type===`exit`)return;if(l?.type===`new`){this.#B(),a=void 0,s=!1,t=void 0,this.#n.reset?.();continue}if(l?.type===`help`){this.#Y(formatPromptCommandHelp(this.#g)),a=void 0,s=!1,t=void 0;continue}if(l?.type===`loglevel`){this.#Y(this.#te(l.argument)),a=void 0,s=!1,t=void 0;continue}if(l?.type===`extension`){try{let t=l.name===`model`?i?.initialModelStep:void 0;i=void 0,await this.#$(l,e,`command`,t)}catch(e){if(isInterruptedError(e))return;throw e}a=void 0,t=void 0,s=!1;continue}o=!0}let l=await this.#U({prompt:s?void 0:t,inputResponses:a});try{await this.#n.renderStream(l,{title:e,submittedPrompt:t,continueSession:!!this.#n.readPrompt,tools:this.#i,reasoning:this.#a,subagents:this.#o,connectionAuth:this.#s,assistantResponseStats:this.#c,contextSize:this.#l});let n=l.turnState?.pendingApprovals??[],r=l.turnState?.pendingQuestions??[];if(n.length>0||r.length>0){let i=[];if(n.length>0){if(!this.#n.readToolApproval)throw Error(`Tool approval was requested, but the renderer does not support tool approval input.`);for(let t of n){let n=await this.#n.readToolApproval(t,{title:e});i.push({requestId:t.approvalId,optionId:n.approved?`approve`:`deny`}),this.#k.delete(t.approvalId)}}if(r.length>0){if(!this.#n.readInputQuestion)throw Error(`An interactive question was requested, but the renderer does not support input questions.`);for(let t of r){let n=toAgentTUIInputQuestion(t),r=await this.#n.readInputQuestion(n,{title:e});if(r===void 0)continue;let a={requestId:t.requestId};r.optionId!==void 0&&(a.optionId=r.optionId),r.text!==void 0&&(a.text=r.text),i.push(a),this.#k.delete(t.requestId)}}s=!0,a=i,t=void 0;continue}l.turnState&&l.turnState.boundaryEvent===void 0&&(this.#P=!0)}catch(e){if(isInterruptedError(e))return;throw e}s=!1,a=void 0,t=void 0,this.#P&&(this.#P=!1,this.#B(),this.#n.renderNotice?.(`Session ended — started a new session. Earlier context was cleared.`))}}#B(){this.#V(),this.#A.clear(),this.#k.clear(),this.#M.clear(),this.#N.clear(),this.#t&&(this.#e=this.#t.session()),this.#d?.clear()}#V(){for(let e of this.#j.values())e.abort();this.#j.clear()}async#H(e){if(!this.#n.readPrompt)return;let t=this.#n.readPrompt(e),n=this.#t,r=this.#d;if(n===void 0||r===void 0)return await t;let i=!1,a=!1,o,refresh=async()=>{if(!(i||a)){a=!0;try{this.#e=await r.refreshIdle({createSession:()=>n.session(),onRuntimeArtifactsChanged:()=>this.#ie(),session:this.#e})}finally{a=!1}}},startRefresh=()=>{if(i||a)return;let e=refresh().finally(()=>{o===e&&(o=void 0)});o=e};startRefresh();let s=setInterval(()=>{startRefresh()},500);s.unref?.();try{return await t}finally{i=!0,clearInterval(s),await o}}async#U(e){let t=new AbortController,n={signal:t.signal};e.prompt!==void 0&&(n.message=e.prompt),e.inputResponses!==void 0&&e.inputResponses.length>0&&(n.inputResponses=e.inputResponses);let r;try{let e=this.#t;e!==void 0&&this.#d!==void 0&&(this.#e=await this.#d.refresh({createSession:()=>e.session(),inputResponses:n.inputResponses,message:n.message,onRuntimeArtifactsChanged:()=>this.#ie(),session:this.#e})),n.message!==void 0&&(n.inputResponses?.length??0)===0&&this.#n.flushDelayedDevBuildErrors?.(),r=await this.#e.send(n)}catch(e){if(isInterruptedError(e))throw e;return this.#_?.reportFailure(e),this.#P=!0,{events:errorOnlyTUIStream({errorText:this.#u(e)}),turnState:createTurnState()}}let i=createTurnState();return{abort:()=>t.abort(),events:eveEventsToTUIStream({events:r,pendingInputRequests:this.#k,subagentRuns:this.#A,turnState:i,onSubagentCalled:e=>this.#ce(e),onSubagentCompleted:e=>this.#ue(e),onConnectionAuthRequired:e=>this.#ae(e),onConnectionAuthCompleted:e=>this.#oe(e),onTerminalFailure:()=>{this.#P=!0},failureOverride:this.#p===void 0?void 0:e=>isGatewayAuthFailure(e)?formatGatewayAuthFailureNotice(e):void 0}),turnState:i}}async#W(e){if(this.#p===void 0)return;let t={appRoot:this.#p,env:process.env};e!==void 0&&(t.info=e),this.#w=await detectSetupIssues(t,this.#v),this.#n.renderSetupWarning!==void 0&&(this.#G(),this.#K())}#G(){let e=orderedSetupIssues(this.#w,this.#T);e.length>0?this.#n.renderSetupWarning?.(formatSetupIssuesLine(e)):this.#n.clearSetupWarning?.()}async#K(){let e=this.#p;if(e===void 0)return;let t;try{t=await this.#y(e,{signal:this.#S.signal})}catch{return}this.#x||this.#C||(this.#T=authIssueForStatus(t),this.#G())}async#q(e){let t=this.#p;if(t===void 0||this.#n.renderSetupWarning===void 0)return;let n={appRoot:t,env:process.env};e!==void 0&&(n.info=e);try{this.#w=await detectSetupIssues(n,this.#v);let e=await this.#y(t,{signal:this.#S.signal});this.#T=authIssueForStatus(e)}catch{return}this.#x||this.#G()}#J(){this.#p===void 0||this.#n.renderSandboxLog===void 0||this.#F===void 0&&(this.#F=subscribeDevelopmentSandboxPrewarmLogs({appRoot:this.#p,log:e=>this.#n.renderSandboxLog?.(e)}))}#Y(e){if(e!==void 0){if(this.#n.renderCommandResult!==void 0){this.#n.renderCommandResult(e);return}this.#n.renderNotice?.(e)}}async#X(e,t){let n=this.#h;return n===void 0?{message:`/${e.name} is not available in this session.`}:await n.handle(e,{renderer:this.#n,title:t.title,initialModelStep:t.initialModelStep,remoteConnection:this.#_})}#Z(e,t){if(t!==`startup`)return;let n=this.#_?.current().connection.state,r=n===`auth-failed`||n===`unavailable`?`failed`:void 0,i=e.argument.length===0?``:` ${e.argument}`;this.#n.renderCommandInvocation?.(`/${e.name}${i}`,r)}async#Q(e){if(e?.kind===`model-access-changed`){this.#E?.applyEffect({kind:`refresh-identity`}),this.#C=!0,await this.#ne();return}e!==void 0&&(this.#E?.applyEffect(e),this.#C=!0,this.#q(this.#O))}async#$(e,t,n,r){let i=await this.#X(e,{initialModelStep:r,title:t});this.#Z(e,n),this.#Y(i?.message),await this.#Q(i?.effect),this.#ee()}#ee(){let e=this.#_?.current().connection;e?.state!==`ready`||e.info===this.#O||(this.#O=e.info,this.#f!==void 0&&this.#n.renderAgentHeader?.({info:e.info,name:this.#r,serverUrl:this.#f}))}#te(e){let t=this.#n;if(t.logDisplayMode===void 0||t.setLogDisplayMode===void 0)return`/loglevel is not available in this session.`;if(e===``)return`Logs: ${t.logDisplayMode()}. Use /loglevel all|stderr|sandbox|none — logs stay buffered, so switching also hides or restores past lines.`;let n=parseLogDisplayMode(e);if(n===void 0)return`Unknown log level "${e}". Use all, stderr, sandbox, or none.`;if(n===t.logDisplayMode())return`Logs already set to ${n}.`;switch(t.setLogDisplayMode(n),n){case`none`:return`Logs hidden. Output stays buffered — /loglevel all restores it.`;case`stderr`:return`Showing stderr logs only.`;case`sandbox`:return`Showing sandbox logs only.`;case`all`:return`Showing all logs.`}}async#ne(){let e=this.#p;if(e===void 0)return;loadDevelopmentEnvironmentFiles(e);let t=this.#L(await this.#re());this.#q(t)}async#re(){try{return await this.#t?.info()}catch{return}}async#ie(){let e=this.#O,t=await this.#re();t!==void 0&&this.#L(t),(!this.#n.renderAgentHeader||t===void 0)&&this.#n.renderNotice?.(formatAgentUpdateNotice(e,t))}#ae(e){let t={name:e.data.name,description:e.data.description,state:`required`};e.data.authorization!==void 0&&(t.challenge=e.data.authorization),e.data.webhookUrl!==void 0&&(t.webhookUrl=e.data.webhookUrl),this.#M.set(e.data.name,t),this.#se(t)}#oe(e){let t=this.#M.get(e.data.name)??{name:e.data.name,description:``,state:e.data.outcome};t.state=e.data.outcome,e.data.reason!==void 0&&(t.reason=e.data.reason),this.#M.set(e.data.name,t),this.#N.delete(e.data.name),this.#se(t),this.#n.setConnectionAuthPendingCount?.(this.#N.size)}#se(e){let t={name:e.name,description:e.description,state:e.state};e.challenge!==void 0&&(t.challenge=e.challenge),e.reason!==void 0&&(t.reason=e.reason),this.#n.upsertConnectionAuth?.(t)}#ce(e){let t=e.data.callId;if(this.#j.has(t))return;let n=this.#t;if(!n)return;let r=new AbortController;this.#j.set(t,r),(async()=>{try{let i=n.session({sessionId:e.data.childSessionId,streamIndex:0}).stream({signal:r.signal});for await(let e of i)if(r.signal.aborted||(this.#de(t,e),isCurrentTurnBoundaryEvent(e)))break}catch(e){if(!isAbortLikeError(e)){let n=toErrorMessage(e),r=this.#A.get(t);if(r){let{key:e,step:i}=openCurrentSubagentSection(r);i.message=i.message?`${i.message}\n\nstream error: ${n}`:`stream error: ${n}`,i.finalized=!0,r.currentSectionKey=null,this.#n.upsertSubagentStep?.({callId:t,subagentName:r.name,sectionKey:e,reasoning:i.reasoning,message:i.message,finalized:!0})}}}finally{this.#j.delete(t)}})()}#le(e,t,n){let r=t.tools.get(n.childCallId),i=r??{toolName:n.toolName,input:n.input,status:n.status};if(r){let e={"approval-requested":0,executing:1,done:2,failed:2};e[n.status]>e[r.status]&&(r.status=n.status),r.input=n.input}else t.tools.set(n.childCallId,i);this.#n.markChildToolCallId?.(n.childCallId),this.#n.upsertSubagentTool?.({callId:e,subagentName:t.name,childCallId:n.childCallId,toolName:i.toolName,input:i.input,status:i.status})}#ue(e){let t=this.#A.get(e);if(t){for(let[n,r]of t.steps)r.finalized||(r.finalized=!0,this.#n.upsertSubagentStep?.({callId:e,subagentName:t.name,sectionKey:n,reasoning:r.reasoning,message:r.message,finalized:!0}));t.currentSectionKey=null}}#de(e,t){let n=this.#A.get(e);if(!n)return;let r=this.#n,emit=(t,i)=>{r.upsertSubagentStep?.({callId:e,subagentName:n.name,sectionKey:t,reasoning:i.reasoning,message:i.message,finalized:i.finalized})},finalizeCurrent=()=>{if(n.currentSectionKey===null)return;let e=n.steps.get(n.currentSectionKey);e&&(e.finalized=!0,emit(n.currentSectionKey,e)),n.currentSectionKey=null};switch(t.type){case`reasoning.appended`:{let{key:e,step:r}=openCurrentSubagentSection(n);r.reasoning+=t.data.reasoningDelta,emit(e,r);break}case`reasoning.completed`:break;case`message.appended`:{let{key:e,step:r}=openCurrentSubagentSection(n);r.message+=t.data.messageDelta,emit(e,r);break}case`message.completed`:{let{key:e,step:r}=openCurrentSubagentSection(n);t.data.message!==null&&r.message.length===0&&(r.message=t.data.message),r.finalized=!0,emit(e,r),n.currentSectionKey=null;break}case`step.completed`:finalizeCurrent();break;case`actions.requested`:finalizeCurrent();for(let r of t.data.actions)r.kind===`tool-call`&&this.#le(e,n,{childCallId:r.callId,toolName:r.toolName,input:r.input,status:`executing`});break;case`input.requested`:finalizeCurrent();for(let r of t.data.requests)r.action.kind===`tool-call`&&this.#le(e,n,{childCallId:r.action.callId,toolName:r.action.toolName,input:r.action.input,status:`approval-requested`});break;case`action.result`:{let i=t.data.result;if(i.kind!==`tool-result`)break;let a=n.tools.get(i.callId);if(!a)break;t.data.status===`failed`?(a.status=`failed`,a.errorText=formatActionResultError(t)):(a.status=`done`,a.output=i.output);let o={callId:e,subagentName:n.name,childCallId:i.callId,toolName:a.toolName,input:a.input,status:a.status};a.output!==void 0&&(o.output=a.output),a.errorText!==void 0&&(o.errorText=a.errorText),r.upsertSubagentTool?.(o);break}default:break}}};function createRenderer(e){return e.renderer?e.renderer:new TerminalRenderer({tools:e.tools,reasoning:e.reasoning,subagents:e.subagents,connectionAuth:e.connectionAuth,assistantResponseStats:e.assistantResponseStats,contextSize:e.contextSize,logs:e.logs,availablePromptCommands:e.availablePromptCommands,input:e.userInput,output:e.screen})}function formatAgentUpdateNotice(e,t){let n=e?.agent.model.id,r=t?.agent.model.id;return n!==void 0&&r!==void 0&&n!==r?`Agent updated: Model ${n} -> ${r}`:`Agent updated.`}async function*eveEventsToTUIStream(e){let{events:t,pendingInputRequests:n,subagentRuns:r,turnState:i,onSubagentCalled:a,onSubagentCompleted:o,onConnectionAuthRequired:s,onConnectionAuthCompleted:c,onTerminalFailure:l,failureOverride:u}=e,d=new Map,f=new Map,p=0,m=new Set,h=new Set,g=new Set,_=!1,v=!1,y;for await(let e of t)if(!(v&&isPostTurnVisibleEvent(e)))switch(e.type){case`session.started`:case`turn.started`:case`message.received`:break;case`step.started`:p+=1,yield{type:`step-start`};break;case`step.completed`:{let t=e;y=t.data.usage,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`step-finish`,usage:t.data.usage};break}case`message.appended`:{let t=e,n=textPartId(t.data.turnId,t.data.stepIndex),r=partStateFor(d,n),i=t.data.messageSoFar;if(r.completed){if(r.text.startsWith(i)||p<=r.completedEpoch)break;r.generation+=1,r.text=``,r.completed=!1}if(!i.startsWith(r.text)||i.length<=r.text.length)break;let a=i.slice(r.text.length);r.text=i,yield{type:`assistant-delta`,id:partGenerationId(n,r.generation),delta:a};break}case`message.completed`:{let t=textPartId(e.data.turnId,e.data.stepIndex),n=partStateFor(d,t),r=e.data.message;if(n.completed){if(r===null||r===n.text||p<=n.completedEpoch)break;n.generation+=1,n.text=r,n.completedEpoch=p,yield{type:`assistant-complete`,id:partGenerationId(t,n.generation),text:r};break}let i=partGenerationId(t,n.generation);if(r!==null){if(n.text.length===0)n.text=r,n.completed=!0,n.completedEpoch=p,yield{type:`assistant-complete`,id:i,text:r};else if(r.startsWith(n.text)){let e=r.slice(n.text.length);e.length>0&&(yield{type:`assistant-delta`,id:i,delta:e}),n.text=r,n.completed=!0,n.completedEpoch=p,yield{type:`assistant-complete`,id:i}}}else n.text.length>0&&(n.completed=!0,n.completedEpoch=p,yield{type:`assistant-complete`,id:i});break}case`reasoning.appended`:{let t=e,n=reasoningPartId(t.data.turnId,t.data.stepIndex),r=partStateFor(f,n),i=t.data.reasoningSoFar;if(r.completed){if(r.text.startsWith(i)||p<=r.completedEpoch)break;r.generation+=1,r.text=``,r.completed=!1}if(!i.startsWith(r.text)||i.length<=r.text.length)break;let a=i.slice(r.text.length);r.text=i,yield{type:`reasoning-delta`,id:partGenerationId(n,r.generation),delta:a};break}case`reasoning.completed`:{let t=reasoningPartId(e.data.turnId,e.data.stepIndex),n=partStateFor(f,t),r=e.data.reasoning;if(n.completed){if(r.length===0||r===n.text||n.text.startsWith(r)||p<=n.completedEpoch)break;n.generation+=1,n.text=r,n.completedEpoch=p;let e=partGenerationId(t,n.generation);yield{type:`reasoning-delta`,id:e,delta:r},yield{type:`reasoning-complete`,id:e};break}let i=partGenerationId(t,n.generation);if(n.text.length===0&&r.length>0)n.text=r,yield{type:`reasoning-delta`,id:i,delta:r};else if(r.length>0&&!r.startsWith(n.text))break;n.completed=!0,n.completedEpoch=p,yield{type:`reasoning-complete`,id:i};break}case`actions.requested`:{let t=e.data.actions.filter(e=>e.kind===`tool-call`);if(t.length===0)break;for(let e of t)m.has(e.callId)||(m.add(e.callId),yield{type:`tool-call`,toolCallId:e.callId,toolName:e.toolName,input:e.input});break}case`input.requested`:{let t=e.data.requests.filter(e=>e.action.kind===`tool-call`);if(t.length===0)break;for(let e of t){let t=e.action.callId;if(m.has(t)||(m.add(t),yield{type:`tool-call`,toolCallId:t,toolName:e.action.toolName,input:e.action.input}),!h.has(e.requestId)){if(h.add(e.requestId),n.set(e.requestId,e),isQuestionRequest(e)){upsertPendingQuestion(i,e);continue}upsertPendingApproval(i,e),yield{type:`tool-approval-request`,approvalId:e.requestId,toolCallId:t}}}break}case`action.result`:{let t=e;if(t.data.result.kind!==`tool-result`)break;let n=t.data.result.callId;if(!m.has(n))break;t.data.status===`failed`?yield{type:`tool-error`,toolCallId:n,errorText:formatActionResultError(t)}:yield{type:`tool-result`,toolCallId:n,output:t.data.result.output};break}case`step.failed`:case`turn.failed`:{let t=toFailureEvent(e,g,u);t&&(yield t);break}case`session.failed`:{i.sawSessionFailure=!0,l?.(e);let t=toFailureEvent(e,g,u);t&&(yield t),i.boundaryEvent=e.type,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`finish`,usage:y},_=!0;return}case`session.waiting`:case`session.completed`:i.boundaryEvent=e.type,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`finish`,usage:y},_=!0;return;case`turn.completed`:v=!0,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p);break;case`subagent.called`:{let t=e;if(!r.has(t.data.callId))r.set(t.data.callId,{name:t.data.name,steps:new Map,currentSectionKey:null,nextSectionKey:0,tools:new Map});else{let e=r.get(t.data.callId);e&&(e.name=t.data.name)}a?.(t);break}case`subagent.started`:case`subagent.event`:break;case`subagent.completed`:o?.(e.data.callId);break;case`authorization.required`:s?.(e);break;case`authorization.completed`:c?.(e);break;default:break}_||(yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`finish`,usage:y})}async function*errorOnlyTUIStream(e){yield{type:`error`,errorText:e.errorText},yield{type:`finish`}}function createTurnState(){return{pendingApprovals:[],pendingQuestions:[],sawSessionFailure:!1}}function upsertPendingApproval(e,t){let n=toAgentTUIToolApprovalRequest(t),r=e.pendingApprovals.findIndex(e=>e.approvalId===n.approvalId);r===-1?e.pendingApprovals.push(n):e.pendingApprovals[r]=n}function toAgentTUIToolApprovalRequest(e){return{approvalId:e.requestId,toolCallId:e.action.callId,toolName:e.action.toolName,input:e.action.input}}function upsertPendingQuestion(e,t){let n=e.pendingQuestions.findIndex(e=>e.requestId===t.requestId);n===-1?e.pendingQuestions.push(t):e.pendingQuestions[n]=t}function textPartId(e,t){return`text:${e}:${t}`}function reasoningPartId(e,t){return`reasoning:${e}:${t}`}function partStateFor(e,t){let n=e.get(t);return n===void 0&&(n={generation:0,text:``,completed:!1,completedEpoch:0},e.set(t,n)),n}function partGenerationId(e,t){return t===0?e:`${e}#${t}`}function*closeOpenParts(e,t,n){for(let[r,i]of e)i.completed||i.text.length===0||(i.completed=!0,i.completedEpoch=n,yield{type:t,id:partGenerationId(r,i.generation)})}function isPostTurnVisibleEvent(e){switch(e.type){case`actions.requested`:case`authorization.completed`:case`authorization.required`:case`input.requested`:case`message.appended`:case`message.completed`:case`reasoning.appended`:case`reasoning.completed`:case`result.completed`:case`step.completed`:case`step.failed`:case`step.started`:case`subagent.called`:case`subagent.completed`:case`subagent.event`:case`subagent.started`:case`turn.completed`:case`turn.failed`:return!0;default:return!1}}function formatActionResultError(e){if(e.data.error?.message)return e.data.error.message;let t=e.data.result.output;if(typeof t==`string`)return t;try{return JSON.stringify(t)}catch{return`Tool execution failed.`}}function toFailureEvent(e,t,n){let r=failureKey(e);if(t.has(r))return;t.add(r);let s=n?.(e),c={type:`error`,errorText:s??formatFailureMessage(e)};if(s!==void 0)return c;let l=formatFailureDetail(e);return l!==void 0&&(c.detail=l),c}function isQuestionRequest(e){return e.display===`select`||e.display===`text`?!0:e.display===`confirmation`?!1:e.options!==void 0&&e.options.length>0}function toAgentTUIInputQuestion(e){let t=e.display===`text`?`text`:e.display===`select`||e.options!==void 0&&e.options.length>0?`select`:`text`,n={requestId:e.requestId,prompt:e.prompt,display:t};return e.options!==void 0&&(n.options=e.options.map(e=>{let t={id:e.id,label:e.label};return e.description!==void 0&&(t.description=e.description),e.style!==void 0&&(t.style=e.style),t})),e.allowFreeform!==void 0&&(n.allowFreeform=e.allowFreeform),n}function openCurrentSubagentSection(e){e.currentSectionKey===null&&(e.currentSectionKey=e.nextSectionKey++,e.steps.set(e.currentSectionKey,{reasoning:``,message:``,finalized:!1}));let t=e.steps.get(e.currentSectionKey);if(!t)throw Error(`invariant: subagent section state missing for current key`);return{key:e.currentSectionKey,step:t}}export{EveTUIRunner,parsePromptCommand};
1
+ import{PROMPT_COMMANDS,formatPromptCommandHelp,parsePromptCommand}from"./prompt-commands.js";import{pickAgentHeaderTip}from"./agent-header.js";import{probeAgentInfo}from"./agent-info-probe.js";import{failureKey,formatFailureDetail,formatFailureMessage,formatGatewayAuthFailureNotice,isAbortLikeError,isGatewayAuthFailure,isInterruptedError}from"./errors.js";import{parseLogDisplayMode}from"./log-display-mode.js";import{createMcpConnectionStatusTracker}from"./mcp-connection-status.js";import{createRemoteConnectionController}from"./remote-connection.js";import{BOOT_DETECTIONS,CLI_MISSING_SETUP_ISSUE,LOGIN_SETUP_ISSUE,detectSetupIssues,formatSetupIssuesLine,orderedSetupIssues,resolveModelProviderState}from"./setup-issues.js";import{TerminalRenderer}from"./terminal-renderer.js";import{createVercelStatusTracker}from"./vercel-status.js";import{isCurrentTurnBoundaryEvent}from"#client/index.js";import{toErrorMessage}from"#shared/errors.js";import{getVercelAuthStatus}from"#setup/vercel-project.js";import{loadDevelopmentEnvironmentFiles}from"#cli/dev/environment.js";import{subscribeDevelopmentSandboxPrewarmLogs}from"#execution/sandbox/development-prewarm.js";import{createDevelopmentRuntimeArtifactSessionRefresher}from"#services/dev-client.js";import{devBootPhase}from"#internal/dev-boot-progress.js";function authIssueForStatus(e){if(e===`logged-out`)return LOGIN_SETUP_ISSUE;if(e===`cli-missing`)return CLI_MISSING_SETUP_ISSUE}var EveTUIRunner=class{#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;#u;#d;#f;#p;#m;#h;#g;#_;#v;#y;#b;#x=!1;#S=new AbortController;#C=!1;#w=[];#T;#E;#D;#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=createDevelopmentRuntimeArtifactSessionRefresher({serverUrl:t.serverUrl}))}async#L(){if(this.#f===void 0){this.#z(),await this.#q(void 0);return}let e;if(this.#_!==void 0){let t=await this.#_.check();t.state===`ready`&&(e=t.info)}else{let t=this.#t;if(t!==void 0)try{let n=await devBootPhase(`connecting to agent`,()=>probeAgentInfo({client:t}),this.#b);n.kind===`ready`&&(e=n.info)}catch{e=void 0}}this.#z();let t=this.#R(e);await this.#q(t)}#R(e){let t=this.#p===void 0?e:resolveModelProviderState(e,process.env);this.#k=t;let n=this.#f;if(n===void 0)return t;let r={name:this.#r,serverUrl:n};return t!==void 0&&(r.info=t),this.#p!==void 0&&(r.tip=this.#O),this.#n.renderAgentHeader?.(r),t}#z(){let e=this.#b;this.#b=void 0,e?.({type:`before-first-paint`})}async run(){try{await this.#B()}finally{this.#x=!0,this.#S.abort(),this.#H(),this.#I?.(),this.#I=void 0,this.#n.shutdown?.(),this.#E?.dispose(),this.#D?.dispose(),this.#_?.dispose()}}async#B(){let e=this.#r,r,i,a=!1,o=!1,s=this.#m;await this.#L(),this.#_?.current().connection.state===`auth-required`&&await this.#re({type:`extension`,name:`vc:login`,argument:``},e,{trigger:`startup`}),this.#Z(),this.#E?.refreshIdentity(),this.#D?.refresh();let c=this.#m===void 0?void 0:parsePromptCommand(this.#m);for(c?.type===`extension`&&c.name===`model`&&c.argument===``&&this.#p!==void 0&&this.#h!==void 0&&this.#n.setupFlow!==void 0&&(s=void 0,await this.#ie(e));;){if(!o){if(r==null){if(!this.#n.readPrompt){if(a)return;throw Error(`No prompt was provided and the renderer does not support prompt input.`)}let t={title:e};s!==void 0&&(t.initialDraft=s,s=void 0);try{r=await this.#U(t)}catch(e){if(isInterruptedError(e))return;throw e}if(r==null)return}let c=parsePromptCommand(r);if(c?.type===`exit`)return;if(c?.type===`new`){this.#V(),i=void 0,o=!1,r=void 0,this.#n.reset?.();continue}if(c?.type===`help`){this.#Q(formatPromptCommandHelp(this.#g)),i=void 0,o=!1,r=void 0;continue}if(c?.type===`loglevel`){this.#Q(this.#oe(c.argument)),i=void 0,o=!1,r=void 0;continue}if(c?.type===`extension`){try{await this.#re(c,e,{trigger:`command`})}catch(e){if(isInterruptedError(e))return;throw e}i=void 0,r=void 0,o=!1;continue}a=!0}let c=await this.#W({prompt:o?void 0:r,inputResponses:i}),l=r,u=!1;try{for(;;){await this.#n.renderStream(c,{title:e,submittedPrompt:l,continueSession:!!this.#n.readPrompt,tools:this.#i,reasoning:this.#a,subagents:this.#o,connectionAuth:this.#s,assistantResponseStats:this.#c,contextSize:this.#l});let t=c.turnState?.pendingApprovals??[],n=c.turnState?.pendingQuestions??[];if(t.length>0||n.length>0){let a=[];if(t.length>0){if(!this.#n.readToolApproval)throw Error(`Tool approval was requested, but the renderer does not support tool approval input.`);for(let n of t){let t=await this.#n.readToolApproval(n,{title:e});a.push({requestId:n.approvalId,optionId:t.approved?`approve`:`deny`}),this.#A.delete(n.approvalId)}}if(n.length>0){if(!this.#n.readInputQuestion)throw Error(`An interactive question was requested, but the renderer does not support input questions.`);for(let t of n){let n=toAgentTUIInputQuestion(t),r=await this.#n.readInputQuestion(n,{title:e});if(r===void 0)continue;let i={requestId:t.requestId};r.optionId!==void 0&&(i.optionId=r.optionId),r.text!==void 0&&(i.text=r.text),a.push(i),this.#A.delete(t.requestId)}}o=!0,i=a,r=void 0,u=!0;break}if(this.#de(c)){c=this.#G(),l=void 0;continue}c.turnState&&c.turnState.boundaryEvent===void 0&&(this.#F=!0);break}}catch(e){if(isInterruptedError(e))return;throw e}u||(o=!1,i=void 0,r=void 0,this.#F&&(this.#F=!1,this.#V(),this.#n.renderNotice?.(`Session ended — started a new session. Earlier context was cleared.`)))}}#V(){this.#H(),this.#j.clear(),this.#A.clear(),this.#N.clear(),this.#P.clear(),this.#n.setConnectionAuthPendingCount?.(0),this.#t&&(this.#e=this.#t.session()),this.#d?.clear()}#H(){for(let e of this.#M.values())e.abort();this.#M.clear()}async#U(e){if(!this.#n.readPrompt)return;let t=this.#n.readPrompt(e),n=this.#t,r=this.#d;if(n===void 0||r===void 0)return await t;let i=!1,a=!1,o,refresh=async()=>{if(!(i||a)){a=!0;try{this.#e=await r.refreshIdle({createSession:()=>n.session(),onRuntimeArtifactsChanged:()=>this.#le(),session:this.#e})}finally{a=!1}}},startRefresh=()=>{if(i||a)return;let e=refresh().finally(()=>{o===e&&(o=void 0)});o=e};startRefresh();let s=setInterval(()=>{startRefresh()},500);s.unref?.();try{return await t}finally{i=!0,clearInterval(s),await o}}async#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{let e=this.#t;e!==void 0&&this.#d!==void 0&&(this.#e=await this.#d.refresh({createSession:()=>e.session(),inputResponses:n.inputResponses,message:n.message,onRuntimeArtifactsChanged:()=>this.#le(),session:this.#e})),n.message!==void 0&&(n.inputResponses?.length??0)===0&&this.#n.flushDelayedDevBuildErrors?.(),r=await this.#e.send(n)}catch(e){if(isInterruptedError(e))throw e;return this.#_?.reportFailure(e),this.#F=!0,{events:errorOnlyTUIStream({errorText:this.#u(e)}),turnState:createTurnState()}}return this.#K(r,()=>t.abort())}#G(){let e=new AbortController;return this.#K(this.#e.stream({signal:e.signal}),()=>e.abort())}#K(e,t){let n=createTurnState();return{abort:t,events:eveEventsToTUIStream({events:e,pendingInputRequests:this.#A,subagentRuns:this.#j,turnState:n,onSubagentCalled:e=>this.#me(e),onSubagentCompleted:e=>this.#ge(e),onConnectionAuthRequired:e=>this.#ue(e),onConnectionAuthCompleted:e=>this.#fe(e),onTerminalFailure:()=>{this.#F=!0},failureOverride:this.#p===void 0?void 0:e=>isGatewayAuthFailure(e)?formatGatewayAuthFailureNotice(e):void 0}),turnState:n}}async#q(e){if(this.#p===void 0)return;let t={appRoot:this.#p,env:process.env};e!==void 0&&(t.info=e),this.#w=await detectSetupIssues(t,this.#v),this.#n.renderSetupWarning!==void 0&&(this.#J(),this.#Y())}#J(){let e=orderedSetupIssues(this.#w,this.#T);e.length>0?this.#n.renderSetupWarning?.(formatSetupIssuesLine(e)):this.#n.clearSetupWarning?.()}async#Y(){let e=this.#p;if(e===void 0)return;let t;try{t=await this.#y(e,{signal:this.#S.signal})}catch{return}this.#x||this.#C||(this.#T=authIssueForStatus(t),this.#J())}async#X(e){let t=this.#p;if(t===void 0||this.#n.renderSetupWarning===void 0)return;let n={appRoot:t,env:process.env};e!==void 0&&(n.info=e);try{this.#w=await detectSetupIssues(n,this.#v);let e=await this.#y(t,{signal:this.#S.signal});this.#T=authIssueForStatus(e)}catch{return}this.#x||this.#J()}#Z(){this.#p===void 0||this.#n.renderSandboxLog===void 0||this.#I===void 0&&(this.#I=subscribeDevelopmentSandboxPrewarmLogs({appRoot:this.#p,log:e=>this.#n.renderSandboxLog?.(e)}))}#Q(e){if(e!==void 0){if(this.#n.renderCommandResult!==void 0){this.#n.renderCommandResult(e);return}this.#n.renderNotice?.(e)}}async#$(e,t){let n=this.#h;if(n===void 0)return{message:`/${e.name} is not available in this session.`};let r={renderer:this.#n,title:t.title,initialModelStep:t.initialModelStep,remoteConnection:this.#_},i=this.#D?.current(),a=i!==void 0&&Object.keys(i).length>0?{...r,disabledConnectionReasons:i}:r;return t.keepSetupFlowOpen===!0?await n.handle(e,{...a,keepSetupFlowOpen:!0}):await n.handle(e,a)}#ee(e,t){if(t!==`startup`)return;let n=this.#_?.current().connection.state,r=n===`auth-failed`||n===`unavailable`?`failed`:void 0,i=e.argument.length===0?``:` ${e.argument}`;this.#n.renderCommandInvocation?.(`/${e.name}${i}`,r)}async#te(e){if(e?.kind===`connection-added`){this.#E?.applyEffect({kind:`refresh-identity`}),this.#C=!0,await this.#ne(),await this.#se();return}if(e?.kind===`model-access-changed`){this.#E?.applyEffect({kind:`refresh-identity`}),this.#C=!0,await this.#se();return}e!==void 0&&(this.#E?.applyEffect(e),this.#C=!0,this.#X(this.#k))}async#ne(){let e=this.#t,t=this.#d;e===void 0||t===void 0||(this.#e=await t.refreshAfterSourceChange({createSession:()=>e.session(),onRuntimeArtifactsChanged:()=>this.#le(),session:this.#e}))}async#re(e,t,n){let r=await this.#$(e,{initialModelStep:n.initialModelStep,keepSetupFlowOpen:n.keepSetupFlowOpen,title:t});this.#ee(e,n.trigger),this.#Q(r?.message),await this.#te(r?.effect),this.#ae()}async#ie(e){let t=this.#p;if(t===void 0)return;let authStatus=async()=>{try{return await this.#y(t,{signal:this.#S.signal})}catch{return}},n=await authStatus();if(n===`cli-missing`&&(await this.#re({type:`extension`,name:`vc:install`,argument:``},e,{trigger:`startup`,keepSetupFlowOpen:!0}),n=await authStatus(),n===`cli-missing`)){this.#n.setupFlow?.end();return}if(n===`logged-out`&&(await this.#re({type:`extension`,name:`vc:login`,argument:``},e,{trigger:`startup`,keepSetupFlowOpen:!0}),n=await authStatus(),n===`cli-missing`||n===`logged-out`)){this.#n.setupFlow?.end();return}await this.#re({type:`extension`,name:`model`,argument:``},e,{trigger:`startup`,initialModelStep:`provider`})}#ae(){let e=this.#_?.current().connection;e?.state!==`ready`||e.info===this.#k||(this.#k=e.info,this.#f!==void 0&&this.#n.renderAgentHeader?.({info:e.info,name:this.#r,serverUrl:this.#f}))}#oe(e){let t=this.#n;if(t.logDisplayMode===void 0||t.setLogDisplayMode===void 0)return`/loglevel is not available in this session.`;if(e===``)return`Logs: ${t.logDisplayMode()}. Use /loglevel all|stderr|sandbox|none — logs stay buffered, so switching also hides or restores past lines.`;let n=parseLogDisplayMode(e);if(n===void 0)return`Unknown log level "${e}". Use all, stderr, sandbox, or none.`;if(n===t.logDisplayMode())return`Logs already set to ${n}.`;switch(t.setLogDisplayMode(n),n){case`none`:return`Logs hidden. Output stays buffered — /loglevel all restores it.`;case`stderr`:return`Showing stderr logs only.`;case`sandbox`:return`Showing sandbox logs only.`;case`all`:return`Showing all logs.`}}async#se(){let e=this.#p;if(e===void 0)return;loadDevelopmentEnvironmentFiles(e);let t=this.#R(await this.#ce());this.#X(t)}async#ce(){let e=this.#t;if(e===void 0)return;let t=await probeAgentInfo({client:e});return t.kind===`ready`?t.info:void 0}async#le(){let e=this.#k,t=await this.#ce();t!==void 0&&this.#R(t),(!this.#n.renderAgentHeader||t===void 0)&&this.#n.renderNotice?.(formatAgentUpdateNotice(e,t))}#ue(e){let t={name:e.data.name,description:e.data.description,state:`required`};e.data.authorization!==void 0&&(t.challenge=e.data.authorization),e.data.webhookUrl!==void 0&&(t.webhookUrl=e.data.webhookUrl),this.#N.set(e.data.name,t),this.#pe(t)}#de(e){if(e.turnState?.boundaryEvent!==`session.waiting`)return!1;let t=!1;for(let e of this.#N.values())e.state!==`required`||e.webhookUrl===void 0||(e.state=`pending`,this.#P.add(e.name),this.#pe(e),t=!0);return t&&this.#n.setConnectionAuthPendingCount?.(this.#P.size),this.#P.size>0}#fe(e){let t=this.#N.get(e.data.name)??{name:e.data.name,description:``,state:e.data.outcome};t.state=e.data.outcome,e.data.reason!==void 0&&(t.reason=e.data.reason),this.#N.set(e.data.name,t),this.#P.delete(e.data.name),this.#pe(t),this.#n.setConnectionAuthPendingCount?.(this.#P.size)}#pe(e){let t={name:e.name,description:e.description,state:e.state};e.challenge!==void 0&&(t.challenge=e.challenge),e.reason!==void 0&&(t.reason=e.reason),this.#n.upsertConnectionAuth?.(t)}#me(e){let t=e.data.callId;if(this.#M.has(t))return;let n=this.#t;if(!n)return;let r=new AbortController;this.#M.set(t,r),(async()=>{try{let i=n.session({sessionId:e.data.childSessionId,streamIndex:0}).stream({signal:r.signal});for await(let e of i)if(r.signal.aborted||(this.#_e(t,e),isCurrentTurnBoundaryEvent(e)))break}catch(e){if(!isAbortLikeError(e)){let n=toErrorMessage(e),r=this.#j.get(t);if(r){let{key:e,step:i}=openCurrentSubagentSection(r);i.message=i.message?`${i.message}\n\nstream error: ${n}`:`stream error: ${n}`,i.finalized=!0,r.currentSectionKey=null,this.#n.upsertSubagentStep?.({callId:t,subagentName:r.name,sectionKey:e,reasoning:i.reasoning,message:i.message,finalized:!0})}}}finally{this.#M.delete(t)}})()}#he(e,t,n){let r=t.tools.get(n.childCallId),i=r??{toolName:n.toolName,input:n.input,status:n.status};if(r){let e={"approval-requested":0,executing:1,done:2,failed:2};e[n.status]>e[r.status]&&(r.status=n.status),r.input=n.input}else t.tools.set(n.childCallId,i);this.#n.markChildToolCallId?.(n.childCallId),this.#n.upsertSubagentTool?.({callId:e,subagentName:t.name,childCallId:n.childCallId,toolName:i.toolName,input:i.input,status:i.status})}#ge(e){let t=this.#j.get(e);if(t){for(let[n,r]of t.steps)r.finalized||(r.finalized=!0,this.#n.upsertSubagentStep?.({callId:e,subagentName:t.name,sectionKey:n,reasoning:r.reasoning,message:r.message,finalized:!0}));t.currentSectionKey=null}}#_e(e,t){let n=this.#j.get(e);if(!n)return;let r=this.#n,emit=(t,i)=>{r.upsertSubagentStep?.({callId:e,subagentName:n.name,sectionKey:t,reasoning:i.reasoning,message:i.message,finalized:i.finalized})},finalizeCurrent=()=>{if(n.currentSectionKey===null)return;let e=n.steps.get(n.currentSectionKey);e&&(e.finalized=!0,emit(n.currentSectionKey,e)),n.currentSectionKey=null};switch(t.type){case`reasoning.appended`:{let{key:e,step:r}=openCurrentSubagentSection(n);r.reasoning+=t.data.reasoningDelta,emit(e,r);break}case`reasoning.completed`:break;case`message.appended`:{let{key:e,step:r}=openCurrentSubagentSection(n);r.message+=t.data.messageDelta,emit(e,r);break}case`message.completed`:{let{key:e,step:r}=openCurrentSubagentSection(n);t.data.message!==null&&r.message.length===0&&(r.message=t.data.message),r.finalized=!0,emit(e,r),n.currentSectionKey=null;break}case`step.completed`:finalizeCurrent();break;case`actions.requested`:finalizeCurrent();for(let r of t.data.actions)r.kind===`tool-call`&&this.#he(e,n,{childCallId:r.callId,toolName:r.toolName,input:r.input,status:`executing`});break;case`input.requested`:finalizeCurrent();for(let r of t.data.requests)r.action.kind===`tool-call`&&this.#he(e,n,{childCallId:r.action.callId,toolName:r.action.toolName,input:r.action.input,status:`approval-requested`});break;case`action.result`:{let i=t.data.result;if(i.kind!==`tool-result`)break;let a=n.tools.get(i.callId);if(!a)break;t.data.status===`failed`?(a.status=`failed`,a.errorText=formatActionResultError(t)):(a.status=`done`,a.output=i.output);let o={callId:e,subagentName:n.name,childCallId:i.callId,toolName:a.toolName,input:a.input,status:a.status};a.output!==void 0&&(o.output=a.output),a.errorText!==void 0&&(o.errorText=a.errorText),r.upsertSubagentTool?.(o);break}default:break}}};function createRenderer(e){return e.renderer?e.renderer:new TerminalRenderer({tools:e.tools,reasoning:e.reasoning,subagents:e.subagents,connectionAuth:e.connectionAuth,assistantResponseStats:e.assistantResponseStats,contextSize:e.contextSize,logs:e.logs,availablePromptCommands:e.availablePromptCommands,input:e.userInput,output:e.screen})}function formatAgentUpdateNotice(e,t){let n=e?.agent.model.id,r=t?.agent.model.id;return n!==void 0&&r!==void 0&&n!==r?`Agent updated: Model ${n} -> ${r}`:`Agent updated.`}async function*eveEventsToTUIStream(e){let{events:t,pendingInputRequests:n,subagentRuns:r,turnState:i,onSubagentCalled:a,onSubagentCompleted:o,onConnectionAuthRequired:s,onConnectionAuthCompleted:c,onTerminalFailure:l,failureOverride:u}=e,d=new Map,f=new Map,p=0,m=new Set,h=new Set,g=new Set,_=!1,v=!1,y;for await(let e of t)if(!(v&&isPostTurnVisibleEvent(e)))switch(e.type){case`session.started`:case`turn.started`:case`message.received`:break;case`step.started`:p+=1,yield{type:`step-start`};break;case`step.completed`:{let t=e;y=t.data.usage,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`step-finish`,usage:t.data.usage};break}case`message.appended`:{let t=e,n=textPartId(t.data.turnId,t.data.stepIndex),r=partStateFor(d,n),i=t.data.messageSoFar;if(r.completed){if(r.text.startsWith(i)||p<=r.completedEpoch)break;r.generation+=1,r.text=``,r.completed=!1}if(!i.startsWith(r.text)||i.length<=r.text.length)break;let a=i.slice(r.text.length);r.text=i,yield{type:`assistant-delta`,id:partGenerationId(n,r.generation),delta:a};break}case`message.completed`:{let t=textPartId(e.data.turnId,e.data.stepIndex),n=partStateFor(d,t),r=e.data.message;if(n.completed){if(r===null||r===n.text||p<=n.completedEpoch)break;n.generation+=1,n.text=r,n.completedEpoch=p,yield{type:`assistant-complete`,id:partGenerationId(t,n.generation),text:r};break}let i=partGenerationId(t,n.generation);if(r!==null){if(n.text.length===0)n.text=r,n.completed=!0,n.completedEpoch=p,yield{type:`assistant-complete`,id:i,text:r};else if(r.startsWith(n.text)){let e=r.slice(n.text.length);e.length>0&&(yield{type:`assistant-delta`,id:i,delta:e}),n.text=r,n.completed=!0,n.completedEpoch=p,yield{type:`assistant-complete`,id:i}}}else n.text.length>0&&(n.completed=!0,n.completedEpoch=p,yield{type:`assistant-complete`,id:i});break}case`reasoning.appended`:{let t=e,n=reasoningPartId(t.data.turnId,t.data.stepIndex),r=partStateFor(f,n),i=t.data.reasoningSoFar;if(r.completed){if(r.text.startsWith(i)||p<=r.completedEpoch)break;r.generation+=1,r.text=``,r.completed=!1}if(!i.startsWith(r.text)||i.length<=r.text.length)break;let a=i.slice(r.text.length);r.text=i,yield{type:`reasoning-delta`,id:partGenerationId(n,r.generation),delta:a};break}case`reasoning.completed`:{let t=reasoningPartId(e.data.turnId,e.data.stepIndex),n=partStateFor(f,t),r=e.data.reasoning;if(n.completed){if(r.length===0||r===n.text||n.text.startsWith(r)||p<=n.completedEpoch)break;n.generation+=1,n.text=r,n.completedEpoch=p;let e=partGenerationId(t,n.generation);yield{type:`reasoning-delta`,id:e,delta:r},yield{type:`reasoning-complete`,id:e};break}let i=partGenerationId(t,n.generation);if(n.text.length===0&&r.length>0)n.text=r,yield{type:`reasoning-delta`,id:i,delta:r};else if(r.length>0&&!r.startsWith(n.text))break;n.completed=!0,n.completedEpoch=p,yield{type:`reasoning-complete`,id:i};break}case`actions.requested`:{let t=e.data.actions.filter(e=>e.kind===`tool-call`);if(t.length===0)break;for(let e of t)m.has(e.callId)||(m.add(e.callId),yield{type:`tool-call`,toolCallId:e.callId,toolName:e.toolName,input:e.input});break}case`input.requested`:{let t=e.data.requests.filter(e=>e.action.kind===`tool-call`);if(t.length===0)break;for(let e of t){let t=e.action.callId;if(m.has(t)||(m.add(t),yield{type:`tool-call`,toolCallId:t,toolName:e.action.toolName,input:e.action.input}),!h.has(e.requestId)){if(h.add(e.requestId),n.set(e.requestId,e),isQuestionRequest(e)){upsertPendingQuestion(i,e);continue}upsertPendingApproval(i,e),yield{type:`tool-approval-request`,approvalId:e.requestId,toolCallId:t}}}break}case`action.result`:{let t=e;if(t.data.result.kind!==`tool-result`)break;let n=t.data.result.callId;if(!m.has(n))break;t.data.status===`failed`?yield{type:`tool-error`,toolCallId:n,errorText:formatActionResultError(t)}:yield{type:`tool-result`,toolCallId:n,output:t.data.result.output};break}case`step.failed`:case`turn.failed`:{let t=toFailureEvent(e,g,u);t&&(yield t);break}case`session.failed`:{i.sawSessionFailure=!0,l?.(e);let t=toFailureEvent(e,g,u);t&&(yield t),i.boundaryEvent=e.type,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`finish`,usage:y},_=!0;return}case`session.waiting`:case`session.completed`:i.boundaryEvent=e.type,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`finish`,usage:y},_=!0;return;case`turn.completed`:v=!0,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p);break;case`subagent.called`:{let t=e;if(!r.has(t.data.callId))r.set(t.data.callId,{name:t.data.name,steps:new Map,currentSectionKey:null,nextSectionKey:0,tools:new Map});else{let e=r.get(t.data.callId);e&&(e.name=t.data.name)}a?.(t);break}case`subagent.started`:case`subagent.event`:break;case`subagent.completed`:o?.(e.data.callId);break;case`authorization.required`:s?.(e);break;case`authorization.completed`:c?.(e);break;default:break}_||(yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`finish`,usage:y})}async function*errorOnlyTUIStream(e){yield{type:`error`,errorText:e.errorText},yield{type:`finish`}}function createTurnState(){return{pendingApprovals:[],pendingQuestions:[],sawSessionFailure:!1}}function upsertPendingApproval(e,t){let n=toAgentTUIToolApprovalRequest(t),r=e.pendingApprovals.findIndex(e=>e.approvalId===n.approvalId);r===-1?e.pendingApprovals.push(n):e.pendingApprovals[r]=n}function toAgentTUIToolApprovalRequest(e){return{approvalId:e.requestId,toolCallId:e.action.callId,toolName:e.action.toolName,input:e.action.input}}function upsertPendingQuestion(e,t){let n=e.pendingQuestions.findIndex(e=>e.requestId===t.requestId);n===-1?e.pendingQuestions.push(t):e.pendingQuestions[n]=t}function textPartId(e,t){return`text:${e}:${t}`}function reasoningPartId(e,t){return`reasoning:${e}:${t}`}function partStateFor(e,t){let n=e.get(t);return n===void 0&&(n={generation:0,text:``,completed:!1,completedEpoch:0},e.set(t,n)),n}function partGenerationId(e,t){return t===0?e:`${e}#${t}`}function*closeOpenParts(e,t,n){for(let[r,i]of e)i.completed||i.text.length===0||(i.completed=!0,i.completedEpoch=n,yield{type:t,id:partGenerationId(r,i.generation)})}function isPostTurnVisibleEvent(e){switch(e.type){case`actions.requested`:case`authorization.completed`:case`authorization.required`:case`input.requested`:case`message.appended`:case`message.completed`:case`reasoning.appended`:case`reasoning.completed`:case`result.completed`:case`step.completed`:case`step.failed`:case`step.started`:case`subagent.called`:case`subagent.completed`:case`subagent.event`:case`subagent.started`:case`turn.completed`:case`turn.failed`:return!0;default:return!1}}function formatActionResultError(e){if(e.data.error?.message)return e.data.error.message;let t=e.data.result.output;if(typeof t==`string`)return t;try{return JSON.stringify(t)}catch{return`Tool execution failed.`}}function toFailureEvent(e,t,n){let r=failureKey(e);if(t.has(r))return;t.add(r);let i=n?.(e),c={type:`error`,errorText:i??formatFailureMessage(e)};if(i!==void 0)return c;let l=formatFailureDetail(e);return l!==void 0&&(c.detail=l),c}function isQuestionRequest(e){return e.display===`select`||e.display===`text`?!0:e.display===`confirmation`?!1:e.options!==void 0&&e.options.length>0}function toAgentTUIInputQuestion(e){let t=e.display===`text`?`text`:e.display===`select`||e.options!==void 0&&e.options.length>0?`select`:`text`,n={requestId:e.requestId,prompt:e.prompt,display:t};return e.options!==void 0&&(n.options=e.options.map(e=>{let t={id:e.id,label:e.label};return e.description!==void 0&&(t.description=e.description),e.style!==void 0&&(t.style=e.style),t})),e.allowFreeform!==void 0&&(n.allowFreeform=e.allowFreeform),n}function openCurrentSubagentSection(e){e.currentSectionKey===null&&(e.currentSectionKey=e.nextSectionKey++,e.steps.set(e.currentSectionKey,{reasoning:``,message:``,finalized:!1}));let t=e.steps.get(e.currentSectionKey);if(!t)throw Error(`invariant: subagent section state missing for current key`);return{key:e.currentSectionKey,step:t}}export{EveTUIRunner,parsePromptCommand};
@@ -1,4 +1,5 @@
1
1
  import { runChannelsFlow } from "#setup/flows/channels.js";
2
+ import { runConnectionsFlow } from "#setup/flows/connections.js";
2
3
  import { runDeployFlow } from "#setup/flows/deploy.js";
3
4
  import { runInstallVercelCliFlow } from "#setup/flows/install-vercel-cli.js";
4
5
  import { runLoginFlow } from "#setup/flows/login.js";
@@ -31,6 +32,10 @@ export declare const SETUP_FLOW_CONFIG: {
31
32
  title: string;
32
33
  indicator: "pulse";
33
34
  };
35
+ connect: {
36
+ title: string;
37
+ indicator: "pulse";
38
+ };
34
39
  deploy: {
35
40
  title: string;
36
41
  indicator: "spinner";
@@ -46,6 +51,7 @@ export interface TuiSetupCommandInput {
46
51
  renderer: TuiSetupCommandRenderer;
47
52
  /** Initial model-flow step authorized by the runner's boot evidence. */
48
53
  initialModelStep?: "provider";
54
+ disabledConnectionReasons?: Readonly<Record<string, string>>;
49
55
  /** Test seam; defaults to the real TUI-native prompter over `renderer`. */
50
56
  createPrompter?: (renderer: TuiPrompterRenderer) => Prompter;
51
57
  /** Test seam; defaults to the real setup flows. */
@@ -57,6 +63,7 @@ export interface TuiSetupFlows {
57
63
  runLoginFlow: typeof runLoginFlow;
58
64
  runModelFlow: typeof runModelFlow;
59
65
  runChannelsFlow: typeof runChannelsFlow;
66
+ runConnectionsFlow: typeof runConnectionsFlow;
60
67
  runDeployFlow: typeof runDeployFlow;
61
68
  }
62
69
  export interface TuiSetupCommandResult {
@@ -65,11 +72,13 @@ export interface TuiSetupCommandResult {
65
72
  preserveFlowDiagnostics: boolean;
66
73
  /** Status refresh required after the command settles. */
67
74
  effect?: VercelStatusEffect | {
75
+ kind: "connection-added";
76
+ } | {
68
77
  kind: "model-access-changed";
69
78
  };
70
79
  }
71
80
  /**
72
- * Runs one TUI setup command (/model, /channels, /deploy) over the
81
+ * Runs one TUI setup command (/model, /channels, /connect, /deploy) over the
73
82
  * shared setup flows, asking through the TUI's own bordered panel. Never throws:
74
83
  * every outcome — done, cancelled, failed — folds into the returned command
75
84
  * result. Ctrl-C or Esc on the working indicator (no question open) aborts the
@@ -1,2 +1,2 @@
1
- import{createTuiPrompter}from"./tui-prompter.js";import{runDeployFlow}from"#setup/flows/deploy.js";import{WizardCancelledError}from"#setup/step.js";import{runLoginFlow}from"#setup/flows/login.js";import{HumanActionRequiredError}from"#setup/human-action.js";import{runChannelsFlow}from"#setup/flows/channels.js";import{runInstallVercelCliFlow}from"#setup/flows/install-vercel-cli.js";import{runModelFlow}from"#setup/flows/model.js";import{runProviderFlow}from"#setup/flows/provider.js";import{openUrl}from"#setup/primitives/open-url.js";import{slackMessageDeepLink}from"#setup/slack-connect.js";const SETUP_FLOW_CONFIG={"vc:install":{title:`Install the Vercel CLI`,indicator:`pulse`},"vc:login":{title:`Log in to Vercel`,indicator:`pulse`},model:{title:`Configure the agent model`,indicator:`pulse`},channels:{title:`Agent channels`,indicator:`pulse`},deploy:{title:`Deploy to Vercel`,indicator:`spinner`}};function muteableRenderer(e,t){return{readSelect:n=>t()?Promise.resolve(void 0):e.readSelect(n),readEditableSelect:n=>t()?Promise.resolve(void 0):e.readEditableSelect(n),readProviderPicker:n=>t()?Promise.resolve(void 0):e.readProviderPicker(n),readText:n=>t()?Promise.resolve(void 0):e.readText(n),readAcknowledge:n=>t()?Promise.resolve():e.readAcknowledge(n),readChoice:n=>t()?{choice:Promise.resolve(void 0),close:()=>{}}:e.readChoice(n),setStatus:n=>{t()||e.setStatus(n)},renderLine:(n,r)=>{(!t()||r===`warning`||r===`error`)&&e.renderLine(n,r)},renderOutput:n=>{t()||e.renderOutput(n)}}}async function runTuiSetupCommand(t){let{command:r}=t,i=!1,a=new AbortController,o=muteableRenderer(t.renderer,()=>i),s=(t.createPrompter??createTuiPrompter)(o),c=t.renderer.waitForInterrupt(),l=Symbol(`interrupted`),u=executeSetupCommand(t,s,o,a.signal);try{let e=await Promise.race([u,c.promise.then(()=>l)]);return e===l?(i=!0,a.abort(new WizardCancelledError),{...await u,message:`/${r} interrupted.`,preserveFlowDiagnostics:!0}):e}finally{c.dispose(),t.renderer.setStatus(void 0)}}async function executeSetupCommand(e,i,l,u){let{command:d,appRoot:f}=e,p={runInstallVercelCliFlow,runLoginFlow,runModelFlow,runChannelsFlow,runDeployFlow,...e.flows};try{switch(d){case`vc:install`:return installVercelCliResultMessage(await p.runInstallVercelCliFlow({appRoot:f,prompter:i,signal:u}));case`vc:login`:return loginResultMessage(await p.runLoginFlow({appRoot:f,prompter:i,signal:u}));case`model`:{let pickProvider=e=>l.readProviderPicker(e),t={appRoot:f,prompter:i,signal:u,deps:{runProviderFlow:e=>runProviderFlow({...e,picker:pickProvider})}};e.initialModelStep!==void 0&&(t.initialStep=e.initialModelStep);let n=await p.runModelFlow(t);if(n.kind===`cancelled`)return{message:`/model cancelled.`,preserveFlowDiagnostics:!1};let r=[];n.modelMessage!==void 0&&r.push(n.modelMessage),n.providerOutcome!==void 0&&r.push(providerOutcomeMessage(n.providerOutcome));let a={message:r.join(`
2
- `),preserveFlowDiagnostics:!1};return n.providerOutcome!==void 0&&(a.effect={kind:`model-access-changed`}),a}case`channels`:{let e=await p.runChannelsFlow({appRoot:f,prompter:i,signal:u});switch(e.kind){case`failed`:return pendingChannelsResult(`Channel files changed, but /channels failed: ${e.message}`);case`cancelled`:return{message:`/channels cancelled.`,preserveFlowDiagnostics:!0};case`deploy-and-chat`:return await runDeployAndChat(p,{appRoot:f,prompter:i,signal:u},e.chat);case`done`:return e.addedChannels.length===0?{message:`No channels added.`,preserveFlowDiagnostics:!0}:{message:`Channels added: ${e.addedChannels.join(`, `)} — run /deploy to ship them.`,preserveFlowDiagnostics:!0,effect:{kind:`channels-added`}}}}case`deploy`:{let e=await p.runDeployFlow({appRoot:f,prompter:i,interactive:!0,signal:u});return e.kind===`cancelled`?{message:`/deploy cancelled.`,preserveFlowDiagnostics:!0}:e.kind===`needs-link`?{message:`Not linked to a Vercel project — run /model to connect one first.`,preserveFlowDiagnostics:!0}:{message:e.productionUrl===void 0?`Deployed.`:`Deployed: ${e.productionUrl}`,preserveFlowDiagnostics:!0,effect:{kind:`deployed`}}}}}catch(e){if(e instanceof WizardCancelledError)return{message:`/${d} cancelled.`,preserveFlowDiagnostics:d!==`model`};let t=vercelActionOutcome(e,d);return t===void 0?{message:`/${d} failed: ${e instanceof Error?e.message:String(e)}`,preserveFlowDiagnostics:!0}:t}}function vercelActionOutcome(e,t){if(!(e instanceof HumanActionRequiredError))return;let n=vercelActionMessage(e.action.kind,t);return n===void 0?void 0:{message:n,preserveFlowDiagnostics:!0}}function vercelActionMessage(e,t){switch(e){case`vercel-login`:return`You're not logged in to Vercel — run /vc:login, then retry /${t}.`;case`vercel-forbidden`:return`Vercel denied access to that team — run /vc:login to re-authenticate (for example to complete SSO), or pick a team you can access, then retry /${t}.`;case`vercel-cli-missing`:return`The Vercel CLI isn't installed — run /vc:install to install it, then retry /${t}.`;default:return}}async function runDeployAndChat(e,t,r){let i;try{i=await e.runDeployFlow({...t,interactive:!0})}catch(e){if(e instanceof WizardCancelledError)return pendingChannelsResult(`Channels added, but /deploy was cancelled. Run /deploy to ship them.`);let t=vercelActionOutcome(e,`deploy`);return pendingChannelsResult(t===void 0?`Channels added, but /deploy failed: ${e instanceof Error?e.message:String(e)}`:`Channels added. ${t.message}`)}if(i.kind===`cancelled`)return pendingChannelsResult(`Channels added, but /deploy was cancelled. Run /deploy to ship them.`);if(i.kind===`needs-link`)return pendingChannelsResult(`Channels added, but this directory is not linked to Vercel. Run /model, then /deploy.`);let a=i.productionUrl===void 0?`Deployed.`:`Deployed: ${i.productionUrl}`,o;if(r.chatUrl===void 0)o=`Message your agent in Slack to see it live.`;else{let e=slackMessageDeepLink(r.chatUrl);openUrl(e),o=`Chat with your agent in Slack: ${e}`}return{message:`${a}\n${o}`,preserveFlowDiagnostics:!0,effect:{kind:`deployed`}}}function installVercelCliResultMessage(e){switch(e.kind){case`cancelled`:return{message:`/vc:install cancelled.`,preserveFlowDiagnostics:!1};case`already`:return{message:`The Vercel CLI is already installed.`,preserveFlowDiagnostics:!1};case`failed`:return{message:"Couldn't install the Vercel CLI — install it manually with `npm i -g vercel@latest`.",preserveFlowDiagnostics:!0};case`installed`:return{message:`Installed the Vercel CLI. Run /vc:login next.`,preserveFlowDiagnostics:!1,effect:{kind:`refresh-identity`}}}}function loginResultMessage(e){switch(e.kind){case`cancelled`:return{message:`/vc:login cancelled.`,preserveFlowDiagnostics:!1};case`already`:return{message:`You're already logged in to Vercel.`,preserveFlowDiagnostics:!1};case`cli-missing`:return{message:`The Vercel CLI isn't installed — run /vc:install to install it, then retry /vc:login.`,preserveFlowDiagnostics:!0};case`failed`:return{message:`Vercel login didn't complete — run /vc:login to try again.`,preserveFlowDiagnostics:!0};case`logged-in`:return{message:`Logged in to Vercel.`,preserveFlowDiagnostics:!1,effect:{kind:`refresh-identity`}};case`unavailable`:return{message:`Couldn't reach Vercel — check your connection, then retry /vc:login.`,preserveFlowDiagnostics:!0}}}function pendingChannelsResult(e){return{message:e,preserveFlowDiagnostics:!0,effect:{kind:`channels-added`}}}function providerOutcomeMessage(e){let{credential:t,status:n}=e;return n.kind===`gateway-project`?t===void 0?`Project linked. No model credential found; set AI_GATEWAY_API_KEY in .env.local.`:`Project linked. Connected to AI Gateway via ${t}.`:n.kind===`gateway-key`?`Connected to AI Gateway via ${n.envKey} in ${n.envFile}.`:`Provider updated — no gateway credential detected; set AI_GATEWAY_API_KEY in .env.local.`}export{SETUP_FLOW_CONFIG,runTuiSetupCommand};
1
+ import{createTuiPrompter}from"./tui-prompter.js";import{runDeployFlow}from"#setup/flows/deploy.js";import{WizardCancelledError}from"#setup/step.js";import{runLoginFlow}from"#setup/flows/login.js";import{HumanActionRequiredError}from"#setup/human-action.js";import{runChannelsFlow}from"#setup/flows/channels.js";import{runConnectionsFlow}from"#setup/flows/connections.js";import{runInstallVercelCliFlow}from"#setup/flows/install-vercel-cli.js";import{runModelFlow}from"#setup/flows/model.js";import{runProviderFlow}from"#setup/flows/provider.js";import{openUrl}from"#setup/primitives/open-url.js";import{slackMessageDeepLink}from"#setup/slack-connect.js";const SETUP_FLOW_CONFIG={"vc:install":{title:`Install the Vercel CLI`,indicator:`pulse`},"vc:login":{title:`Log in to Vercel`,indicator:`pulse`},model:{title:`Configure the agent model`,indicator:`pulse`},channels:{title:`Agent channels`,indicator:`pulse`},connect:{title:`Agent connections`,indicator:`pulse`},deploy:{title:`Deploy to Vercel`,indicator:`spinner`}};function muteableRenderer(e,t){return{readSelect:n=>t()?Promise.resolve(void 0):e.readSelect(n),readEditableSelect:n=>t()?Promise.resolve(void 0):e.readEditableSelect(n),readProviderPicker:n=>t()?Promise.resolve(void 0):e.readProviderPicker(n),readText:n=>t()?Promise.resolve(void 0):e.readText(n),readAcknowledge:n=>t()?Promise.resolve():e.readAcknowledge(n),readChoice:n=>t()?{choice:Promise.resolve(void 0),close:()=>{}}:e.readChoice(n),setStatus:n=>{t()||e.setStatus(n)},renderLine:(n,r)=>{(!t()||r===`warning`||r===`error`)&&e.renderLine(n,r)},renderOutput:n=>{t()||e.renderOutput(n)}}}async function runTuiSetupCommand(t){let{command:r}=t,i=!1,a=new AbortController,o=muteableRenderer(t.renderer,()=>i),s=(t.createPrompter??createTuiPrompter)(o),c=t.renderer.waitForInterrupt(),l=Symbol(`interrupted`),u=executeSetupCommand(t,s,o,a.signal);try{let e=await Promise.race([u,c.promise.then(()=>l)]);return e===l?(i=!0,a.abort(new WizardCancelledError),{...await u,message:`/${r} interrupted.`,preserveFlowDiagnostics:!0}):e}finally{c.dispose(),t.renderer.setStatus(void 0)}}async function executeSetupCommand(e,i,u,d){let{command:f,appRoot:p}=e,m={runInstallVercelCliFlow,runLoginFlow,runModelFlow,runChannelsFlow,runConnectionsFlow,runDeployFlow,...e.flows};try{switch(f){case`vc:install`:return installVercelCliResultMessage(await m.runInstallVercelCliFlow({appRoot:p,prompter:i,signal:d}));case`vc:login`:return loginResultMessage(await m.runLoginFlow({appRoot:p,prompter:i,signal:d}));case`model`:{let pickProvider=e=>u.readProviderPicker(e),t={appRoot:p,prompter:i,signal:d,deps:{runProviderFlow:e=>runProviderFlow({...e,picker:pickProvider})}};e.initialModelStep!==void 0&&(t.initialStep=e.initialModelStep);let n=await m.runModelFlow(t);if(n.kind===`cancelled`)return{message:`/model cancelled.`,preserveFlowDiagnostics:!1};let r=[];n.modelMessage!==void 0&&r.push(n.modelMessage),n.providerOutcome!==void 0&&r.push(providerOutcomeMessage(n.providerOutcome));let a={message:r.join(`
2
+ `),preserveFlowDiagnostics:!1};return n.providerOutcome!==void 0&&(a.effect={kind:`model-access-changed`}),a}case`channels`:{let e=await m.runChannelsFlow({appRoot:p,prompter:i,signal:d});switch(e.kind){case`failed`:return pendingChannelsResult(`Channel files changed, but /channels failed: ${e.message}`);case`cancelled`:return{message:`/channels cancelled.`,preserveFlowDiagnostics:!0};case`deploy-and-chat`:return await runDeployAndChat(m,{appRoot:p,prompter:i,signal:d},e.chat);case`done`:return e.addedChannels.length===0?{message:`No channels added.`,preserveFlowDiagnostics:!0}:{message:`Channels added: ${e.addedChannels.join(`, `)} — run /deploy to ship them.`,preserveFlowDiagnostics:!0,effect:{kind:`channels-added`}}}}case`connect`:{let t=await m.runConnectionsFlow({appRoot:p,prompter:i,signal:d,disabledConnectionReasons:e.disabledConnectionReasons});switch(t.kind){case`cancelled`:return{message:`/connect cancelled.`,preserveFlowDiagnostics:!0,effect:{kind:`model-access-changed`}};case`failed`:return{message:t.addedConnections.length===0?`/connect failed: ${t.message}`:`Connection files changed, but /connect failed: ${t.message}`,preserveFlowDiagnostics:!0,effect:t.addedConnections.length===0?{kind:`model-access-changed`}:{kind:`connection-added`}};case`done`:return{message:t.addedConnections.length===0?`No connections added.`:`Connections added: ${t.addedConnections.join(`, `)}.`,preserveFlowDiagnostics:!0,effect:t.addedConnections.length===0?{kind:`model-access-changed`}:{kind:`connection-added`}}}}case`deploy`:{let e=await m.runDeployFlow({appRoot:p,prompter:i,interactive:!0,signal:d});return e.kind===`cancelled`?{message:`/deploy cancelled.`,preserveFlowDiagnostics:!0}:e.kind===`needs-link`?{message:`Not linked to a Vercel project — run /model to connect one first.`,preserveFlowDiagnostics:!0}:{message:e.productionUrl===void 0?`Deployed.`:`Deployed: ${e.productionUrl}`,preserveFlowDiagnostics:!0,effect:{kind:`deployed`}}}}}catch(e){if(e instanceof WizardCancelledError)return{message:`/${f} cancelled.`,preserveFlowDiagnostics:f!==`model`};let t=vercelActionOutcome(e,f);return t===void 0?{message:`/${f} failed: ${e instanceof Error?e.message:String(e)}`,preserveFlowDiagnostics:!0}:t}}function vercelActionOutcome(e,t){if(!(e instanceof HumanActionRequiredError))return;let n=vercelActionMessage(e.action.kind,t);return n===void 0?void 0:{message:n,preserveFlowDiagnostics:!0}}function vercelActionMessage(e,t){switch(e){case`vercel-login`:return`You're not logged in to Vercel — run /vc:login, then retry /${t}.`;case`vercel-forbidden`:return`Vercel denied access to that team — run /vc:login to re-authenticate (for example to complete SSO), or pick a team you can access, then retry /${t}.`;case`vercel-cli-missing`:return`The Vercel CLI isn't installed — run /vc:install to install it, then retry /${t}.`;default:return}}async function runDeployAndChat(e,t,r){let i;try{i=await e.runDeployFlow({...t,interactive:!0})}catch(e){if(e instanceof WizardCancelledError)return pendingChannelsResult(`Channels added, but /deploy was cancelled. Run /deploy to ship them.`);let t=vercelActionOutcome(e,`deploy`);return pendingChannelsResult(t===void 0?`Channels added, but /deploy failed: ${e instanceof Error?e.message:String(e)}`:`Channels added. ${t.message}`)}if(i.kind===`cancelled`)return pendingChannelsResult(`Channels added, but /deploy was cancelled. Run /deploy to ship them.`);if(i.kind===`needs-link`)return pendingChannelsResult(`Channels added, but this directory is not linked to Vercel. Run /model, then /deploy.`);let a=i.productionUrl===void 0?`Deployed.`:`Deployed: ${i.productionUrl}`,o;if(r.chatUrl===void 0)o=`Message your agent in Slack to see it live.`;else{let e=slackMessageDeepLink(r.chatUrl);openUrl(e),o=`Chat with your agent in Slack: ${e}`}return{message:`${a}\n${o}`,preserveFlowDiagnostics:!0,effect:{kind:`deployed`}}}function installVercelCliResultMessage(e){switch(e.kind){case`cancelled`:return{message:`/vc:install cancelled.`,preserveFlowDiagnostics:!1};case`already`:return{message:`The Vercel CLI is already installed.`,preserveFlowDiagnostics:!1};case`failed`:return{message:"Couldn't install the Vercel CLI — install it manually with `npm i -g vercel@latest`.",preserveFlowDiagnostics:!0};case`installed`:return{message:`Installed the Vercel CLI. Run /vc:login next.`,preserveFlowDiagnostics:!1,effect:{kind:`refresh-identity`}}}}function loginResultMessage(e){switch(e.kind){case`cancelled`:return{message:`/vc:login cancelled.`,preserveFlowDiagnostics:!1};case`already`:return{message:`You're already logged in to Vercel.`,preserveFlowDiagnostics:!1};case`cli-missing`:return{message:`The Vercel CLI isn't installed — run /vc:install to install it, then retry /vc:login.`,preserveFlowDiagnostics:!0};case`failed`:return{message:`Vercel login didn't complete — run /vc:login to try again.`,preserveFlowDiagnostics:!0};case`logged-in`:return{message:`Logged in to Vercel.`,preserveFlowDiagnostics:!1,effect:{kind:`refresh-identity`}};case`unavailable`:return{message:`Couldn't reach Vercel — check your connection, then retry /vc:login.`,preserveFlowDiagnostics:!0}}}function pendingChannelsResult(e){return{message:e,preserveFlowDiagnostics:!0,effect:{kind:`channels-added`}}}function providerOutcomeMessage(e){let{credential:t,status:n}=e;return n.kind===`gateway-project`?t===void 0?`Project linked. No model credential found; set AI_GATEWAY_API_KEY in .env.local.`:`Project linked. Connected to AI Gateway via ${t}.`:n.kind===`gateway-key`?`Connected to AI Gateway via ${n.envKey} in ${n.envFile}.`:`Provider updated — no gateway credential detected; set AI_GATEWAY_API_KEY in .env.local.`}export{SETUP_FLOW_CONFIG,runTuiSetupCommand};
@@ -13,6 +13,12 @@ export type SetupEditableSelectResult = {
13
13
  };
14
14
  /** Animation shown while a setup flow is between questions. */
15
15
  export type SetupFlowIndicator = "spinner" | "pulse";
16
+ /** Ephemeral setup status, with external user action distinct from background work. */
17
+ export type SetupFlowStatus = string | {
18
+ kind: "external-action";
19
+ text: string;
20
+ emphasis: string;
21
+ };
16
22
  interface SetupSelectRequestBase {
17
23
  message: string;
18
24
  options: readonly SetupPanelOption[];
@@ -27,6 +33,7 @@ interface SetupSearchAction extends SearchActionOption {
27
33
  }
28
34
  interface SetupSearchSelectRequest extends SetupSelectRequestBase {
29
35
  kind: "search";
36
+ layout?: "task-list";
30
37
  initialValue?: string;
31
38
  placeholder?: string;
32
39
  searchAction?: SetupSearchAction;
@@ -87,7 +94,7 @@ export interface SetupFlowRenderer {
87
94
  * whichever settles first wins.
88
95
  */
89
96
  readChoice(options: ChannelSetupChoiceOptions): ChannelSetupChoice;
90
- setStatus(text: string | undefined): void;
97
+ setStatus(status: SetupFlowStatus | undefined): void;
91
98
  renderLine(text: string, tone: "info" | "success" | "warning" | "error"): void;
92
99
  renderOutput(text: string): void;
93
100
  /**