eve 0.9.0 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/bin/eve.d.ts +5 -0
  3. package/bin/eve.js +16 -13
  4. package/dist/src/cli/agent-detection.d.ts +8 -0
  5. package/dist/src/cli/agent-detection.js +1 -0
  6. package/dist/src/cli/commands/agent-instructions.d.ts +7 -0
  7. package/dist/src/cli/commands/agent-instructions.js +1 -0
  8. package/dist/src/cli/commands/init-agent-handoff.md +12 -0
  9. package/dist/src/cli/commands/init-agent-instructions.md +16 -0
  10. package/dist/src/cli/commands/init-git.js +1 -1
  11. package/dist/src/cli/commands/init.d.ts +8 -1
  12. package/dist/src/cli/commands/init.js +1 -1
  13. package/dist/src/cli/dev/environment.js +1 -1
  14. package/dist/src/cli/dev/tui/blocks.d.ts +8 -0
  15. package/dist/src/cli/dev/tui/blocks.js +2 -2
  16. package/dist/src/cli/dev/tui/command-typeahead.js +1 -1
  17. package/dist/src/cli/dev/tui/prompt-commands.d.ts +1 -1
  18. package/dist/src/cli/dev/tui/prompt-commands.js +1 -1
  19. package/dist/src/cli/dev/tui/runner.d.ts +10 -0
  20. package/dist/src/cli/dev/tui/runner.js +1 -1
  21. package/dist/src/cli/dev/tui/setup-commands.d.ts +4 -0
  22. package/dist/src/cli/dev/tui/setup-commands.js +2 -2
  23. package/dist/src/cli/dev/tui/setup-issues.d.ts +15 -0
  24. package/dist/src/cli/dev/tui/setup-issues.js +1 -1
  25. package/dist/src/cli/dev/tui/terminal-renderer.d.ts +8 -2
  26. package/dist/src/cli/dev/tui/terminal-renderer.js +9 -6
  27. package/dist/src/cli/run.js +1 -1
  28. package/dist/src/compiled/.vendor-stamp.json +3 -1
  29. package/dist/src/compiled/@vercel/detect-agent/LICENSE +202 -0
  30. package/dist/src/compiled/@vercel/detect-agent/index.d.ts +20 -0
  31. package/dist/src/compiled/@vercel/detect-agent/index.js +1 -0
  32. package/dist/src/compiled/semver/LICENSE +15 -0
  33. package/dist/src/compiled/semver/index.d.ts +23 -0
  34. package/dist/src/compiled/semver/index.js +1 -0
  35. package/dist/src/execution/sandbox/bindings/docker-templates.js +1 -1
  36. package/dist/src/execution/sandbox/bindings/just-bash.js +1 -1
  37. package/dist/src/execution/sandbox/bindings/microsandbox-templates.js +1 -1
  38. package/dist/src/execution/sandbox/logging-session.js +2 -1
  39. package/dist/src/internal/application/compiled-artifacts.js +1 -1
  40. package/dist/src/internal/application/optional-package-install.js +1 -1
  41. package/dist/src/internal/application/package.js +1 -1
  42. package/dist/src/internal/application/paths.js +1 -1
  43. package/dist/src/internal/application/tsconfig-dependencies.js +1 -1
  44. package/dist/src/internal/authored-module-loader.js +2 -2
  45. package/dist/src/internal/bundler/nitro-rolldown.d.ts +3 -0
  46. package/dist/src/internal/bundler/nitro-rolldown.js +1 -1
  47. package/dist/src/internal/nitro/dev-runtime-artifacts.js +1 -1
  48. package/dist/src/internal/nitro/dev-runtime-source-snapshot-copy.js +1 -1
  49. package/dist/src/internal/nitro/dev-runtime-source-snapshot.js +1 -1
  50. package/dist/src/internal/nitro/host/dev-authored-source-watcher.js +1 -1
  51. package/dist/src/internal/nitro/host/dev-watcher-log.d.ts +3 -0
  52. package/dist/src/internal/nitro/host/dev-watcher-log.js +1 -1
  53. package/dist/src/internal/nitro/host/start-development-server.d.ts +1 -2
  54. package/dist/src/internal/nitro/host/start-development-server.js +2 -1
  55. package/dist/src/internal/nitro/host/start-production-server.js +2 -2
  56. package/dist/src/internal/process/pnpm.js +1 -1
  57. package/dist/src/internal/workflow-bundle/builder-support.js +2 -2
  58. package/dist/src/internal/workflow-bundle/dynamic-tool-transform.js +1 -1
  59. package/dist/src/internal/workflow-bundle/workflow-builders.js +1 -1
  60. package/dist/src/internal/workflow-bundle/workflow-transformer.js +3 -3
  61. package/dist/src/public/next/server.js +1 -1
  62. package/dist/src/setup/boxes/add-channels.d.ts +4 -6
  63. package/dist/src/setup/boxes/add-channels.js +1 -1
  64. package/dist/src/setup/boxes/apply-ai-gateway-credential.js +1 -1
  65. package/dist/src/setup/boxes/link-project.js +1 -1
  66. package/dist/src/setup/boxes/resolve-provisioning.js +1 -1
  67. package/dist/src/setup/boxes/scaffold.d.ts +2 -2
  68. package/dist/src/setup/boxes/scaffold.js +1 -1
  69. package/dist/src/setup/flows/channels.d.ts +2 -0
  70. package/dist/src/setup/flows/channels.js +1 -1
  71. package/dist/src/setup/flows/deploy.js +1 -1
  72. package/dist/src/setup/flows/install-vercel-cli.d.ts +42 -0
  73. package/dist/src/setup/flows/install-vercel-cli.js +1 -0
  74. package/dist/src/setup/flows/link.js +1 -1
  75. package/dist/src/setup/flows/login.d.ts +49 -0
  76. package/dist/src/setup/flows/login.js +1 -0
  77. package/dist/src/setup/flows/model.js +1 -1
  78. package/dist/src/setup/flows/vercel.d.ts +2 -0
  79. package/dist/src/setup/flows/vercel.js +1 -1
  80. package/dist/src/setup/node-engine.d.ts +31 -0
  81. package/dist/src/setup/node-engine.js +1 -0
  82. package/dist/src/setup/onboarding.d.ts +3 -2
  83. package/dist/src/setup/onboarding.js +1 -1
  84. package/dist/src/setup/primitives/coding-agent-env.d.ts +17 -0
  85. package/dist/src/setup/primitives/coding-agent-env.js +1 -0
  86. package/dist/src/setup/primitives/pm/pnpm.js +2 -2
  87. package/dist/src/setup/primitives/pm/run.d.ts +6 -0
  88. package/dist/src/setup/primitives/pm/run.js +1 -1
  89. package/dist/src/setup/primitives/run-vercel.d.ts +1 -1
  90. package/dist/src/setup/primitives/run-vercel.js +1 -1
  91. package/dist/src/setup/scaffold/create/add-to-project.d.ts +10 -5
  92. package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
  93. package/dist/src/setup/scaffold/create/project.d.ts +17 -4
  94. package/dist/src/setup/scaffold/create/project.js +9 -5
  95. package/dist/src/setup/scaffold/index.d.ts +1 -1
  96. package/dist/src/setup/scaffold/update/channels.d.ts +4 -2
  97. package/dist/src/setup/scaffold/update/channels.js +2 -2
  98. package/dist/src/setup/scaffold/update/package-json.d.ts +12 -1
  99. package/dist/src/setup/scaffold/update/package-json.js +1 -1
  100. package/dist/src/setup/scaffold/version-tokens.js +1 -1
  101. package/dist/src/setup/slack-connect-create.d.ts +41 -0
  102. package/dist/src/setup/slack-connect-create.js +1 -0
  103. package/dist/src/setup/slack-connect-lifecycle.d.ts +40 -11
  104. package/dist/src/setup/slack-connect-lifecycle.js +1 -1
  105. package/dist/src/setup/slack-connect.d.ts +25 -14
  106. package/dist/src/setup/slack-connect.js +1 -1
  107. package/dist/src/setup/slackbot.d.ts +12 -16
  108. package/dist/src/setup/slackbot.js +1 -1
  109. package/dist/src/setup/vercel-project.d.ts +25 -0
  110. package/dist/src/setup/vercel-project.js +1 -1
  111. package/dist/src/source-change/apply-model-name.d.ts +2 -2
  112. package/dist/src/source-change/apply-model-name.js +1 -1
  113. package/dist/src/source-change/static-source-change.js +1 -1
  114. package/docs/getting-started.mdx +7 -7
  115. package/docs/guides/dev-tui.md +3 -1
  116. package/docs/reference/cli.md +2 -0
  117. package/package.json +9 -7
package/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # eve
2
2
 
3
+ ## 0.9.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 7f3fbc5: The dev TUI gains a `/login` command that runs `vercel login` as a browser flow the panel waits on (with a Cancel action), mirroring the Slack Connect wait. Flows that need a Vercel account now route you to it: `/model`, `/channels` (including its Slack-provisioning and deploy continuations), and `/deploy` say "run /login" when you're logged out instead of dumping a raw error, the Slack channel row distinguishes logged-out (`/login`) from unlinked (`/model`) and is blocked even when the directory is already linked, and a "not logged in · /login" hint appears at startup. A scoped lookup denied with a 403 (for example a team that enforces SSO/SAML the session hasn't completed) is routed to `/login` to re-authenticate. A missing Vercel CLI is detected distinctly (never mislabeled "not logged in") and gets its own `/vc` command that installs it, so every diagnostic — not linked, not logged in, CLI missing — has a matching fix command and a startup hint. The startup hint is a live element that clears the moment its issue is resolved (run `/login` and the "not logged in" line disappears) instead of lingering stale in the transcript. The login probe is bounded and runs without the coding-agent environment markers (so a read-only check can't trigger a login flow), and a transient/network failure is reported as "couldn't reach Vercel" rather than sending you to `/login`.
8
+
9
+ The AI Gateway "Connect via a project" row now runs that prerequisite check before selection and stays disabled until the Vercel CLI is installed, the session is authenticated, and Vercel is reachable. "Use my own key" remains available.
10
+
11
+ - 7f3fbc5: `eve init` detects when an AI coding agent launched it. With no target, it asks the agent to collect the purpose, target, and Web Chat choice from the user; after scaffolding, it points the agent at the bundled docs, asks it to write the purpose into `agent/instructions.md`, and prints the interactive `eve dev` command for the user to run.
12
+ - 7f3fbc5: `eve dev` now advances to the next available local port when another process already owns port 3000, preventing the terminal UI from connecting to the wrong agent.
13
+ - 7f3fbc5: Slack channel setup now treats Vercel's completed browser verifier as the end of a new workspace setup and reads existing workspace state from the connector detail response, avoiding a second wait on the empty installations endpoint.
14
+ - 2a77e8d: Eve no longer declares `oxc-parser` as a direct runtime dependency. Model source edits now use the same Rolldown parser loaded from Nitro that workflow transforms already use.
15
+
16
+ ## 0.9.1
17
+
18
+ ### Patch Changes
19
+
20
+ - 79dcb7b: Update the AI SDK peer dependency range to accept `ai` versions starting at `7.0.0-beta.177`, and use that beta for workspace development installs.
21
+ - bd96d9c: Delay local dev rebuild errors in `eve dev` until the next user prompt unless all logs are enabled. A successful rebuild clears the delayed error so stale HMR failures are not shown after the agent builds cleanly.
22
+ - 9009664: `eve dev` now records its active process in `.eve/dev-process.pid` and refuses to start a second local server for the same agent while that process is still running. The duplicate-start message includes the command to stop the existing server.
23
+ - 9936fc8: Fail sandbox bootstrap immediately when a `sandbox.run` command exits with code 1, including the command plus full stdout and stderr in the error.
24
+ - 6d7a4e5: Scaffolded projects now select the lowest complete Node.js major supported by Eve's own `package.json` `engines.node` contract and pin that major (e.g. `24.x`). The CLI bootstrap validates the exact authored range and ships its runtime semver dependency, while `eve init` and Web Chat use the invoking Eve release's matching dependency version and engine contract.
25
+ - 6d7a4e5: Scaffolded agent projects now declare `@types/node` at the same major selected for `engines.node` and set `compilerOptions.types: ["node"]` in `tsconfig.json`. Agent code that touches `process` or Node built-ins now typechecks without exposing APIs from a newer Node major than the generated app declares.
26
+
3
27
  ## 0.9.0
4
28
 
5
29
  ### Minor Changes
package/bin/eve.d.ts CHANGED
@@ -46,6 +46,11 @@ export interface BootstrapDependencies extends BootstrapBuildDependencies {
46
46
  * Node.js version string used by tests to exercise the bin version guard.
47
47
  */
48
48
  nodeVersion?: string;
49
+
50
+ /**
51
+ * Node.js engine range used by tests to exercise non-default package contracts.
52
+ */
53
+ nodeEngineRequirement?: string;
49
54
  }
50
55
 
51
56
  /**
package/bin/eve.js CHANGED
@@ -5,9 +5,15 @@ import { access, readdir, realpath, stat } from "node:fs/promises";
5
5
  import { createRequire } from "node:module";
6
6
  import { dirname, resolve } from "node:path";
7
7
  import { fileURLToPath, pathToFileURL } from "node:url";
8
+ import semver from "semver";
8
9
 
9
10
  const require = createRequire(import.meta.url);
10
- const minimumNodeMajorVersion = 24;
11
+ const packageJson = require("../package.json");
12
+ const packageNodeEngine = packageJson.engines?.node;
13
+
14
+ if (typeof packageNodeEngine !== "string" || semver.validRange(packageNodeEngine) === null) {
15
+ throw new Error("eve package.json must declare a valid engines.node range.");
16
+ }
11
17
 
12
18
  function createBootstrapOptions(overrides = {}) {
13
19
  const packageRoot =
@@ -19,6 +25,7 @@ function createBootstrapOptions(overrides = {}) {
19
25
  packageRoot,
20
26
  postBuildScriptPaths: overrides.postBuildScriptPaths ?? [
21
27
  resolve(packageRoot, "scripts", "copy-compiled-assets.mjs"),
28
+ resolve(packageRoot, "scripts", "copy-runtime-assets.mjs"),
22
29
  resolve(packageRoot, "scripts", "copy-docs.mjs"),
23
30
  resolve(packageRoot, "scripts", "stamp-version-tokens.mjs"),
24
31
  ],
@@ -109,23 +116,19 @@ function inputTsconfigPath({ packageRoot }) {
109
116
  return resolve(packageRoot, "tsconfig.json");
110
117
  }
111
118
 
112
- function parseNodeMajorVersion(version) {
113
- const match = /^v?(\d+)/.exec(version);
114
- return match ? Number(match[1]) : undefined;
115
- }
116
-
117
- function assertSupportedNodeVersion(version = process.version) {
118
- const majorVersion = parseNodeMajorVersion(version);
119
-
120
- if (majorVersion !== undefined && majorVersion >= minimumNodeMajorVersion) {
119
+ function assertSupportedNodeVersion(version = process.version, requiredRange = packageNodeEngine) {
120
+ if (semver.validRange(requiredRange) === null) {
121
+ throw new Error(`Eve declares an invalid Node.js engine range: "${requiredRange}".`);
122
+ }
123
+ if (semver.satisfies(version, requiredRange)) {
121
124
  return;
122
125
  }
123
126
 
124
127
  throw new Error(
125
128
  [
126
- `Eve requires Node.js ${minimumNodeMajorVersion} or newer.`,
129
+ `Eve requires Node.js ${requiredRange}.`,
127
130
  `You are running ${version}.`,
128
- "Please upgrade Node.js and try again.",
131
+ "Please install a compatible Node.js version and try again.",
129
132
  ].join(" "),
130
133
  );
131
134
  }
@@ -230,7 +233,7 @@ export async function ensureBuiltCli(overrides = {}, dependencies = {}) {
230
233
  * Runs the compiled Eve CLI, building the workspace package on demand when needed.
231
234
  */
232
235
  export async function runEveCli(argv = process.argv.slice(2), overrides = {}, dependencies = {}) {
233
- assertSupportedNodeVersion(dependencies.nodeVersion);
236
+ assertSupportedNodeVersion(dependencies.nodeVersion, dependencies.nodeEngineRequirement);
234
237
 
235
238
  const cliEntrypointPath = await ensureBuiltCli(overrides, dependencies);
236
239
  const importModule = dependencies.importModule ?? ((specifier) => import(specifier));
@@ -0,0 +1,8 @@
1
+ export { CODING_AGENT_ENV_MARKERS } from "#setup/primitives/coding-agent-env.js";
2
+ /**
3
+ * Whether this CLI invocation was launched by an AI coding agent (Claude Code,
4
+ * Cursor, Codex, ...) rather than a human at a terminal. Wraps
5
+ * `@vercel/detect-agent` so the heuristic's source can change without touching
6
+ * callers.
7
+ */
8
+ export declare function isCodingAgentLaunch(): Promise<boolean>;
@@ -0,0 +1 @@
1
+ import{determineAgent}from"#compiled/@vercel/detect-agent/index.js";import{CODING_AGENT_ENV_MARKERS}from"#setup/primitives/coding-agent-env.js";async function isCodingAgentLaunch(){return(await determineAgent()).isAgent}export{CODING_AGENT_ENV_MARKERS,isCodingAgentLaunch};
@@ -0,0 +1,7 @@
1
+ export declare function initAgentInstructions(options: {
2
+ initCommand: string;
3
+ }): string;
4
+ export declare function initAgentDevHandoff(options: {
5
+ projectPath: string;
6
+ devCommand: string;
7
+ }): string;
@@ -0,0 +1 @@
1
+ import{readFileSync}from"node:fs";function readTemplate(t){return readFileSync(new URL(t,import.meta.url),`utf8`).trim()}function initAgentInstructions(e){return readTemplate(`./init-agent-instructions.md`).replace(`{{initCommand}}`,()=>e.initCommand)}function initAgentDevHandoff(e){return readTemplate(`./init-agent-handoff.md`).replaceAll(`{{projectPath}}`,()=>e.projectPath).replace(`{{devCommand}}`,()=>e.devCommand)}export{initAgentDevHandoff,initAgentInstructions};
@@ -0,0 +1,12 @@
1
+ Before editing the scaffold, read the relevant guide in
2
+ `{{projectPath}}/node_modules/eve/docs/`.
3
+
4
+ Then open `{{projectPath}}/agent/instructions.md` and replace the placeholder
5
+ with what the user said the agent should do (the purpose you collected). This
6
+ is the agent's always-on system prompt.
7
+
8
+ Do not start `eve dev` because it is interactive. Give the user this command to
9
+ run when they are ready:
10
+
11
+ cd {{projectPath}}
12
+ {{devCommand}}
@@ -0,0 +1,16 @@
1
+ # Set up an Eve agent
2
+
3
+ Ask the user these questions one at a time. Use the coding harness's prompt
4
+ tools when available. Do not guess.
5
+
6
+ 1. What should the agent do?
7
+ 2. Create a new project or add the agent to an existing directory?
8
+ For a new project, propose a name and ask the user to confirm it. For an
9
+ existing project, ask for the directory.
10
+ 3. For a new project, include Web Chat?
11
+
12
+ Then run:
13
+
14
+ {{initCommand}} <target>
15
+
16
+ Add `--channel-web-nextjs` if the user wants Web Chat.
@@ -1 +1 @@
1
- import{join}from"node:path";import{execSync}from"node:child_process";import{rmSync}from"node:fs";const GIT_TIMEOUT_MS=5e3;function isGitAvailable(){try{return execSync(`git --version`,{stdio:`ignore`,timeout:GIT_TIMEOUT_MS}),!0}catch{return!1}}function isInsideExistingRepository(e){try{return execSync(`git rev-parse --is-inside-work-tree`,{cwd:e,stdio:`ignore`,timeout:GIT_TIMEOUT_MS}),!0}catch{}try{return execSync(`hg --cwd . root`,{cwd:e,stdio:`ignore`,timeout:GIT_TIMEOUT_MS}),!0}catch{return!1}}function hasConfiguredDefaultBranch(e){try{return execSync(`git config init.defaultBranch`,{cwd:e,stdio:`ignore`,timeout:GIT_TIMEOUT_MS}),!0}catch{return!1}}function tryInitializeGit(n){if(!isGitAvailable()||isInsideExistingRepository(n))return{kind:`skipped`};let r=!1;try{return execSync(`git init`,{cwd:n,stdio:`ignore`,timeout:GIT_TIMEOUT_MS}),r=!0,hasConfiguredDefaultBranch(n)||execSync(`git checkout -b main`,{cwd:n,stdio:`ignore`,timeout:GIT_TIMEOUT_MS}),execSync(`git add -A`,{cwd:n,stdio:`ignore`,timeout:GIT_TIMEOUT_MS}),execSync(`git commit -m "Initial commit from Eve"`,{cwd:n,stdio:`ignore`,timeout:GIT_TIMEOUT_MS}),{kind:`initialized`}}catch(t){if(r)try{rmSync(join(n,`.git`),{recursive:!0,force:!0})}catch{}return{kind:`failed`,reason:t instanceof Error?t.message:String(t)}}}export{tryInitializeGit};
1
+ import{rmSync}from"node:fs";import{join}from"node:path";import{execSync}from"node:child_process";const GIT_TIMEOUT_MS=5e3;function isGitAvailable(){try{return execSync(`git --version`,{stdio:`ignore`,timeout:GIT_TIMEOUT_MS}),!0}catch{return!1}}function isInsideExistingRepository(e){try{return execSync(`git rev-parse --is-inside-work-tree`,{cwd:e,stdio:`ignore`,timeout:GIT_TIMEOUT_MS}),!0}catch{}try{return execSync(`hg --cwd . root`,{cwd:e,stdio:`ignore`,timeout:GIT_TIMEOUT_MS}),!0}catch{return!1}}function hasConfiguredDefaultBranch(e){try{return execSync(`git config init.defaultBranch`,{cwd:e,stdio:`ignore`,timeout:GIT_TIMEOUT_MS}),!0}catch{return!1}}function tryInitializeGit(n){if(!isGitAvailable()||isInsideExistingRepository(n))return{kind:`skipped`};let r=!1;try{return execSync(`git init`,{cwd:n,stdio:`ignore`,timeout:GIT_TIMEOUT_MS}),r=!0,hasConfiguredDefaultBranch(n)||execSync(`git checkout -b main`,{cwd:n,stdio:`ignore`,timeout:GIT_TIMEOUT_MS}),execSync(`git add -A`,{cwd:n,stdio:`ignore`,timeout:GIT_TIMEOUT_MS}),execSync(`git commit -m "Initial commit from Eve"`,{cwd:n,stdio:`ignore`,timeout:GIT_TIMEOUT_MS}),{kind:`initialized`}}catch(t){if(r)try{rmSync(join(n,`.git`),{recursive:!0,force:!0})}catch{}return{kind:`failed`,reason:t instanceof Error?t.message:String(t)}}}export{tryInitializeGit};
@@ -1,3 +1,4 @@
1
+ import { isCodingAgentLaunch } from "#cli/agent-detection.js";
1
2
  import { detectInvokingPackageManager, detectPackageManager } from "#setup/package-manager.js";
2
3
  import { runPackageManagerInstall, spawnPackageManager } from "#setup/primitives/index.js";
3
4
  import { addAgentToProject } from "#setup/scaffold/create/add-to-project.js";
@@ -16,6 +17,7 @@ export interface InitCommandDependencies {
16
17
  detectInvokingPackageManager: typeof detectInvokingPackageManager;
17
18
  detectPackageManager: typeof detectPackageManager;
18
19
  ensureChannel: typeof ensureChannel;
20
+ isCodingAgentLaunch: typeof isCodingAgentLaunch;
19
21
  runPackageManagerInstall: typeof runPackageManagerInstall;
20
22
  scaffoldBaseProject: typeof scaffoldBaseProject;
21
23
  spawnPackageManager: typeof spawnPackageManager;
@@ -25,5 +27,10 @@ export interface InitCommandDependencies {
25
27
  * Creates a new Eve agent (`target` is a project name), or adds one to an
26
28
  * existing project (`target` is a directory), without prompts or external
27
29
  * provisioning.
30
+ *
31
+ * Runs launched by a coding agent diverge twice: with no `target` they get the
32
+ * recipe for collecting one from the user instead of a scaffold under an
33
+ * invented name, and after scaffolding they get the dev command printed
34
+ * instead of spawned, since the dev TUI would wedge the launching agent.
28
35
  */
29
- export declare function runInitCommand(logger: InitCliLogger, parentDirectory: string, target: string, options: InitCommandOptions, dependencies?: InitCommandDependencies): Promise<void>;
36
+ export declare function runInitCommand(logger: InitCliLogger, parentDirectory: string, target: string | undefined, options: InitCommandOptions, dependencies?: InitCommandDependencies): Promise<void>;
@@ -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{tryInitializeGit}from"./init-git.js";import{join,resolve}from"node:path";import{ensureChannel,scaffoldBaseProject}from"#setup/scaffold/index.js";import{mkdtemp,rename,rm,stat}from"node:fs/promises";import{EVE_WORDMARK}from"#cli/banner.js";import{DEFAULT_AGENT_MODEL_ID}from"#shared/default-agent-model.js";import{SPINNER_FRAMES,SPINNER_FRAME_MS}from"#setup/cli/rail-log.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";var import_picocolors=__toESM(require_picocolors(),1);const defaultDependencies={addAgentToProject,detectInvokingPackageManager,detectPackageManager,ensureChannel,runPackageManagerInstall,scaffoldBaseProject,spawnPackageManager,tryInitializeGit};async function resolveTargetDirectory(e,t){let n=resolve(e,t);return(await stat(n).catch(()=>void 0))?.isDirectory()?n:void 0}async function addToExistingProject(e,t,n){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 r=await n.detectPackageManager(e);return await n.addAgentToProject({projectRoot:e,model:DEFAULT_AGENT_MODEL_ID,packageManager:r.kind}),r.kind}function resolveScaffoldPackageManager(e){return e.detectInvokingPackageManager()??`pnpm`}const EVE_INIT_PACKAGE_VERSION=`latest`;async function scaffoldProject(e,t,n,a,o){let u=resolve(e),d=join(u,t);if(await pathExists(d))throw Error(`Cannot create project because "${d}" already exists.`);let p=await mkdtemp(join(u,`.eve-init-`));try{let e=await o.scaffoldBaseProject({projectName:t,model:DEFAULT_AGENT_MODEL_ID,packageManager:n,targetDirectory:p,evePackageVersion:EVE_INIT_PACKAGE_VERSION});return a.channelWebNextjs===!0&&await o.ensureChannel({projectRoot:e,kind:`web`,packageManager:n,configureVercelServices:!1,webPackageVersions:{evePackageVersion:EVE_INIT_PACKAGE_VERSION}}),await rename(e,d),d}finally{await rm(p,{recursive:!0,force:!0})}}function startSpinner(e,t){if(process.stdout.isTTY!==!0)return e.log(t),{stop(){}};let row=e=>`${import_picocolors.default.green(e)} ${t}`;process.stdout.write(row(SPINNER_FRAMES[0]));let n=0,r=setInterval(()=>{n+=1;let e=SPINNER_FRAMES[n%SPINNER_FRAMES.length]??SPINNER_FRAMES[0];process.stdout.write(`\r\u001B[K${row(e)}`)},SPINNER_FRAME_MS);r.unref?.();let i=!1;return{stop(){i||(i=!0,clearInterval(r),process.stdout.write(`\r\x1B[K`))}}}async function runInitCommand(e,t,n,r,i=defaultDependencies){let a=await resolveTargetDirectory(t,n),o,s;a===void 0?(o=resolveScaffoldPackageManager(i),s=await scaffoldProject(t,parseProjectName(n),o,r,i),e.log(`${import_picocolors.default.green(`✓`)} Created an ${EVE_WORDMARK} agent in ${import_picocolors.default.bold(s)}`)):(o=await addToExistingProject(a,r,i),s=a,e.log(`${import_picocolors.default.green(`✓`)} Added an ${EVE_WORDMARK} agent to ${import_picocolors.default.bold(s)}`));let c=[],l=startSpinner(e,`Installing dependencies...`),u;try{u=await i.runPackageManagerInstall(o,s,{bypassMinimumReleaseAge:!0,onOutput:e=>c.push(e.text)})}finally{l.stop()}if(!u){for(let t of c)e.error(t);throw Error(`Failed to install dependencies in "${s}".`)}if(e.log(`${import_picocolors.default.green(`✓`)} Installed dependencies`),a===void 0){let t=i.tryInitializeGit(s);t.kind===`failed`&&e.error(import_picocolors.default.yellow(`Git initialization failed: ${t.reason}`))}let f=a===void 0,p=f?[...eveDevArguments(o),`--input`,`/model`]:eveDevArguments(o);if(e.log(import_picocolors.default.dim(f?`$ eve dev --input /model`:`$ eve dev`)),!await i.spawnPackageManager(o,s,p))throw Error(`Development server exited unsuccessfully in "${s}".`)}export{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}from"./agent-instructions.js";import{tryInitializeGit}from"./init-git.js";import{join,resolve}from"node:path";import{ensureChannel,scaffoldBaseProject}from"#setup/scaffold/index.js";import{mkdtemp,rename,rm,stat}from"node:fs/promises";import{isCodingAgentLaunch}from"#cli/agent-detection.js";import{EVE_WORDMARK}from"#cli/banner.js";import{DEFAULT_AGENT_MODEL_ID}from"#shared/default-agent-model.js";import{SPINNER_FRAMES,SPINNER_FRAME_MS}from"#setup/cli/rail-log.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";var import_picocolors=__toESM(require_picocolors(),1);const defaultDependencies={addAgentToProject,detectInvokingPackageManager,detectPackageManager,ensureChannel,isCodingAgentLaunch,runPackageManagerInstall,scaffoldBaseProject,spawnPackageManager,tryInitializeGit};async function resolveTargetDirectory(e,t){let n=resolve(e,t);return(await stat(n).catch(()=>void 0))?.isDirectory()?n:void 0}async function addToExistingProject(e,t,n){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 r=await n.detectPackageManager(e),i=await n.addAgentToProject({projectRoot:e,model:DEFAULT_AGENT_MODEL_ID,packageManager:r.kind});return{packageManager:r.kind,nodeEngineOverride:i.nodeEngineOverride}}function resolveScaffoldPackageManager(e){return e.detectInvokingPackageManager()??`pnpm`}const PACKAGE_RUNNERS={bun:`bunx`,npm:`npx`,pnpm:`pnpm dlx`,yarn:`yarn dlx`};function resolveInitCommand(e){let t=e.detectInvokingPackageManager();return t===void 0?`eve init`:`${PACKAGE_RUNNERS[t]} eve init`}async function scaffoldProject(e,t,n,r,i){let s=resolve(e),c=join(s,t);if(await pathExists(c))throw Error(`Cannot create project because "${c}" already exists.`);let f=await mkdtemp(join(s,`.eve-init-`));try{let e=await i.scaffoldBaseProject({projectName:t,model:DEFAULT_AGENT_MODEL_ID,packageManager:n,targetDirectory:f});return r.channelWebNextjs===!0&&await i.ensureChannel({projectRoot:e,kind:`web`,packageManager:n,configureVercelServices:!1}),await rename(e,c),c}finally{await rm(f,{recursive:!0,force:!0})}}function startSpinner(e,t){if(process.stdout.isTTY!==!0)return e.log(t),{stop(){}};let row=e=>`${import_picocolors.default.green(e)} ${t}`;process.stdout.write(row(SPINNER_FRAMES[0]));let n=0,r=setInterval(()=>{n+=1;let e=SPINNER_FRAMES[n%SPINNER_FRAMES.length]??SPINNER_FRAMES[0];process.stdout.write(`\r\u001B[K${row(e)}`)},SPINNER_FRAME_MS);r.unref?.();let i=!1;return{stop(){i||(i=!0,clearInterval(r),process.stdout.write(`\r\x1B[K`))}}}async function runInitCommand(e,t,i,a,o=defaultDependencies){let s=await o.isCodingAgentLaunch();if(i===void 0){if(s){e.log(initAgentInstructions({initCommand:resolveInitCommand(o)}));return}throw Error(`missing required argument 'target'`)}let c=await resolveTargetDirectory(t,i),l,u;if(c===void 0)l=resolveScaffoldPackageManager(o),u=await scaffoldProject(t,parseProjectName(i),l,a,o),e.log(`${import_picocolors.default.green(`✓`)} Created an ${EVE_WORDMARK} agent in ${import_picocolors.default.bold(u)}`);else{let t=await addToExistingProject(c,a,o);l=t.packageManager,u=c,e.log(`${import_picocolors.default.green(`✓`)} Added an ${EVE_WORDMARK} agent to ${import_picocolors.default.bold(u)}`),t.nodeEngineOverride!==void 0&&e.log(import_picocolors.default.yellow(`⚠ ${formatNodeEngineOverrideWarning(t.nodeEngineOverride)}`))}let d=[],f=startSpinner(e,`Installing dependencies...`),p;try{p=await o.runPackageManagerInstall(l,u,{bypassMinimumReleaseAge:!0,onOutput:e=>d.push(e.text)})}finally{f.stop()}if(!p){for(let t of d)e.error(t);throw Error(`Failed to install dependencies in "${u}".`)}if(e.log(`${import_picocolors.default.green(`✓`)} Installed dependencies`),c===void 0){let t=o.tryInitializeGit(u);t.kind===`failed`&&e.error(import_picocolors.default.yellow(`Git initialization failed: ${t.reason}`))}if(s){e.log(initAgentDevHandoff({projectPath:u,devCommand:[l,...eveDevArguments(l)].join(` `)}));return}let m=c===void 0,h=m?[...eveDevArguments(l),`--input`,`/model`]:eveDevArguments(l);if(e.log(import_picocolors.default.dim(m?`$ eve dev --input /model`:`$ eve dev`)),!await o.spawnPackageManager(l,u,h))throw Error(`Development server exited unsuccessfully in "${u}".`)}export{runInitCommand};
@@ -1 +1 @@
1
- import{join,resolve}from"node:path";import{readFileSync}from"node:fs";import{parseEnv}from"node:util";import{isObject}from"#shared/guards.js";const DEVELOPMENT_ENV_FILE_NAMES=[`.env.development.local`,`.env.local`,`.env.development`,`.env`];function isMissingEnvironmentFileError(e){return isObject(e)&&e.code===`ENOENT`}const developmentEnvironmentLoaders=new Map;function getDevelopmentEnvironmentFilePaths(n){let r=resolve(n);return DEVELOPMENT_ENV_FILE_NAMES.map(t=>join(r,t))}function loadDevelopmentEnvironmentFiles(e){getDevelopmentEnvironmentLoader(e).reload()}function getDevelopmentEnvironmentLoader(e){let n=resolve(e),r=developmentEnvironmentLoaders.get(n);if(r!==void 0)return r;let i=createDevelopmentEnvironmentLoader(n);return developmentEnvironmentLoaders.set(n,i),i}function createDevelopmentEnvironmentLoader(e){let t=new Set(Object.keys(process.env)),n=new Map;return{reload(){let r=readDevelopmentEnvironmentValues(e);for(let[e,i]of n)r.has(e)||t.has(e)||(process.env[e]===i&&delete process.env[e],n.delete(e));for(let[e,i]of r)t.has(e)||(process.env[e]=i,n.set(e,i))}}}function readDevelopmentEnvironmentValues(t){let i=new Map;for(let o of[...DEVELOPMENT_ENV_FILE_NAMES].reverse())try{let a=parseEnv(readFileSync(join(t,o),`utf8`));for(let[e,t]of Object.entries(a))t!==void 0&&i.set(e,t)}catch(e){if(!isMissingEnvironmentFileError(e))throw e}return i}export{DEVELOPMENT_ENV_FILE_NAMES,getDevelopmentEnvironmentFilePaths,loadDevelopmentEnvironmentFiles};
1
+ import{readFileSync}from"node:fs";import{join,resolve}from"node:path";import{parseEnv}from"node:util";import{isObject}from"#shared/guards.js";const DEVELOPMENT_ENV_FILE_NAMES=[`.env.development.local`,`.env.local`,`.env.development`,`.env`];function isMissingEnvironmentFileError(e){return isObject(e)&&e.code===`ENOENT`}const developmentEnvironmentLoaders=new Map;function getDevelopmentEnvironmentFilePaths(e){let r=resolve(e);return DEVELOPMENT_ENV_FILE_NAMES.map(e=>join(r,e))}function loadDevelopmentEnvironmentFiles(e){getDevelopmentEnvironmentLoader(e).reload()}function getDevelopmentEnvironmentLoader(e){let t=resolve(e),r=developmentEnvironmentLoaders.get(t);if(r!==void 0)return r;let i=createDevelopmentEnvironmentLoader(t);return developmentEnvironmentLoaders.set(t,i),i}function createDevelopmentEnvironmentLoader(e){let t=new Set(Object.keys(process.env)),n=new Map;return{reload(){let r=readDevelopmentEnvironmentValues(e);for(let[e,i]of n)r.has(e)||t.has(e)||(process.env[e]===i&&delete process.env[e],n.delete(e));for(let[e,i]of r)t.has(e)||(process.env[e]=i,n.set(e,i))}}}function readDevelopmentEnvironmentValues(n){let i=new Map;for(let o of[...DEVELOPMENT_ENV_FILE_NAMES].reverse())try{let a=parseEnv(readFileSync(join(n,o),`utf8`));for(let[e,t]of Object.entries(a))t!==void 0&&i.set(e,t)}catch(e){if(!isMissingEnvironmentFileError(e))throw e}return i}export{DEVELOPMENT_ENV_FILE_NAMES,getDevelopmentEnvironmentFilePaths,loadDevelopmentEnvironmentFiles};
@@ -70,3 +70,11 @@ export interface RenderBlockContext {
70
70
  * to `width` visible columns.
71
71
  */
72
72
  export declare function renderBlockLines(block: Block, width: number, theme: Theme, context: RenderBlockContext): string[];
73
+ /**
74
+ * The setup attention line (`⚠ 1 setup issue: … · /model`): yellow glyph, body
75
+ * at full intensity, slash commands painted blue so the fix reads as actionable
76
+ * — clearly a system surface, not chat content. Exported so the live footer can
77
+ * render the same line as a clearable element (it disappears once the issue is
78
+ * resolved), not just committed scrollback.
79
+ */
80
+ export declare function renderAttentionRows(body: string, width: number, theme: Theme): string[];
@@ -1,8 +1,8 @@
1
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
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
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 renderWarning(e,t,n){let r=n.colors.yellow(n.glyph.warning);return wrap(e.body??``,t-2).map((e,t)=>`${t===0?r:` `} ${paintCommands(e,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;return[`${n.cyan(t.glyph.user)} ${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(`
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;return[`${n.cyan(t.glyph.user)} ${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
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
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
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{renderBlockLines};
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 +1 @@
1
- import{sliceVisible,visibleLength}from"./terminal-text.js";function typeaheadFor(e,t,n){let r=matchingCommands(e,t),i=n===void 0?void 0:n.matches[n.selectedIndex],a=i===void 0?-1:r.indexOf(i);return{query:t,matches:r,selectedIndex:a>=0?a:0,dismissed:n!==void 0&&n.dismissed&&n.query===t}}function matchingCommands(e,t){if(!t.startsWith(`/`)||/\s/.test(t))return[];let n=t.slice(1);return e.filter(e=>[e.name,...e.aliases].some(e=>e.startsWith(n)))}function isTypeaheadOpen(e){return e.matches.length>0&&!e.dismissed}function moveTypeaheadSelection(e,t){let n=e.matches.length;if(n===0)return e;let r=(e.selectedIndex+t+n)%n;return{...e,selectedIndex:r}}function dismissTypeahead(e){return e.dismissed?e:{...e,dismissed:!0}}function selectedTypeaheadCommand(e){return e.matches[e.selectedIndex]}function typeaheadCompletion(e){return`/${e.name}${e.takesArgument?` `:``}`}function inlineCommandHint(e){if(e.dismissed||e.matches.length!==1)return;let t=e.matches[0],n=e.query.startsWith(`/`)?e.query.slice(1):e.query;if([t.name,...t.aliases].includes(n))return t.argumentHint??``}function renderCommandSuggestions(n,r,i){let a=r.colors,o=n.matches.length,s=Math.min(o,8),c=Math.max(0,Math.min(n.selectedIndex-Math.floor(s/2),o-s)),l=Math.min(c+s,o),u=n.matches.slice(c,l),invocation=e=>{let t=e.aliases.map(e=>` (/${e})`).join(``);return`/${e.name}${t}`},d=Math.max(...u.map(e=>invocation(e).length))+2;return u.map((e,t)=>{let i=c+t===n.selectedIndex,o=i?a.cyan(r.glyph.prompt):` `,s=i?a.blue(`/${e.name}`):`/${e.name}`,l=invocation(e).slice(`/${e.name}`.length),u=` `.repeat(d-invocation(e).length);return`${o} ${s}${a.dim(l)}${u}${a.dim(e.description)}`}).map(n=>visibleLength(n)>i?sliceVisible(n,i):n)}export{dismissTypeahead,inlineCommandHint,isTypeaheadOpen,moveTypeaheadSelection,renderCommandSuggestions,selectedTypeaheadCommand,typeaheadCompletion,typeaheadFor};
1
+ import{sliceVisible,visibleLength}from"./terminal-text.js";function typeaheadFor(e,t,n){let r=matchingCommands(e,t),i=n===void 0?void 0:n.matches[n.selectedIndex],a=i===void 0?-1:r.indexOf(i);return{query:t,matches:r,selectedIndex:a>=0?a:0,dismissed:n!==void 0&&n.dismissed&&n.query===t}}function matchingCommands(e,t){if(!t.startsWith(`/`)||/\s/.test(t))return[];let n=t.slice(1);return e.filter(e=>[e.name,...e.aliases].some(e=>e.startsWith(n)))}function isTypeaheadOpen(e){return e.matches.length>0&&!e.dismissed}function moveTypeaheadSelection(e,t){let n=e.matches.length;if(n===0)return e;let r=(e.selectedIndex+t+n)%n;return{...e,selectedIndex:r}}function dismissTypeahead(e){return e.dismissed?e:{...e,dismissed:!0}}function selectedTypeaheadCommand(e){return e.matches[e.selectedIndex]}function typeaheadCompletion(e){return`/${e.name}${e.takesArgument?` `:``}`}function inlineCommandHint(e){if(e.dismissed||e.matches.length!==1)return;let t=e.matches[0],n=e.query.startsWith(`/`)?e.query.slice(1):e.query;if([t.name,...t.aliases].includes(n))return t.argumentHint??``}function renderCommandSuggestions(n,r,i){let a=r.colors,o=n.matches.length,s=Math.min(o,10),c=Math.max(0,Math.min(n.selectedIndex-Math.floor(s/2),o-s)),l=Math.min(c+s,o),u=n.matches.slice(c,l),invocation=e=>{let t=e.aliases.map(e=>` (/${e})`).join(``);return`/${e.name}${t}`},d=Math.max(...u.map(e=>invocation(e).length))+2;return u.map((e,t)=>{let i=c+t===n.selectedIndex,o=i?a.cyan(r.glyph.prompt):` `,s=i?a.blue(`/${e.name}`):`/${e.name}`,l=invocation(e).slice(`/${e.name}`.length),u=` `.repeat(d-invocation(e).length);return`${o} ${s}${a.dim(l)}${u}${a.dim(e.description)}`}).map(n=>visibleLength(n)>i?sliceVisible(n,i):n)}export{dismissTypeahead,inlineCommandHint,isTypeaheadOpen,moveTypeaheadSelection,renderCommandSuggestions,selectedTypeaheadCommand,typeaheadCompletion,typeaheadFor};
@@ -1,4 +1,4 @@
1
- export type PromptCommandExtensionName = "model" | "channels" | "deploy";
1
+ export type PromptCommandExtensionName = "model" | "channels" | "deploy" | "login" | "vc";
2
2
  /** The slash commands the prompt accepts. */
3
3
  export type PromptCommand = {
4
4
  type: "new";
@@ -1,2 +1,2 @@
1
- const PROMPT_COMMANDS=[{name:`help`,aliases:[],description:`Show available commands`,takesArgument:!1,build:()=>({type:`help`})},{name:`new`,aliases:[],description:`Start a fresh session`,takesArgument:!1,build:()=>({type:`new`})},{name:`model`,aliases:[],description:`Configure the agent's model and provider`,argumentHint:`[provider/model]`,takesArgument:!0,build:e=>({type:`extension`,name:`model`,argument:e})},{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})},{name:`channels`,aliases:[],description:`Add chat channels to the agent`,takesArgument:!1,build:()=>({type:`extension`,name:`channels`,argument:``})},{name:`deploy`,aliases:[],description:`Deploy the agent to Vercel`,takesArgument:!1,build:()=>({type:`extension`,name:`deploy`,argument:``})},{name:`exit`,aliases:[`quit`],description:`Quit the TUI`,takesArgument:!1,build:()=>({type:`exit`})}];function parsePromptCommand(t){let n=t.trim();if(!n.startsWith(`/`))return null;for(let t of PROMPT_COMMANDS)for(let e of[t.name,...t.aliases]){let r=`/${e}`;if(n===r)return t.build(``);if(t.takesArgument&&n.startsWith(`${r} `))return t.build(n.slice(r.length).trim())}return null}function isPromptControlCommand(e){return parsePromptCommand(e)!==null}function formatPromptCommandHelp(){let t=PROMPT_COMMANDS.map(e=>{let t=e.argumentHint===void 0?``:` ${e.argumentHint}`,n=e.aliases.map(e=>` (/${e})`).join(``);return{invocation:`/${e.name}${t}${n}`,description:e.description}}),n=Math.max(...t.map(e=>e.invocation.length))+2;return t.map(e=>e.invocation.padEnd(n)+e.description).join(`
1
+ const PROMPT_COMMANDS=[{name:`help`,aliases:[],description:`Show available commands`,takesArgument:!1,build:()=>({type:`help`})},{name:`new`,aliases:[],description:`Start a fresh session`,takesArgument:!1,build:()=>({type:`new`})},{name:`vc`,aliases:[],description:`Install the Vercel CLI`,takesArgument:!1,build:()=>({type:`extension`,name:`vc`,argument:``})},{name:`login`,aliases:[],description:`Log in to Vercel`,takesArgument:!1,build:()=>({type:`extension`,name:`login`,argument:``})},{name:`model`,aliases:[],description:`Configure the agent's model and provider`,argumentHint:`[provider/model]`,takesArgument:!0,build:e=>({type:`extension`,name:`model`,argument:e})},{name:`loglevel`,aliases:[],description:`Show or hide captured stdout/stderr/sandbox logs`,argumentHint:`[all|stderr|sandbox|none]`,takesArgument:!0,build:e=>({type:`loglevel`,argument:e})},{name:`channels`,aliases:[],description:`Add chat channels to the agent`,takesArgument:!1,build:()=>({type:`extension`,name:`channels`,argument:``})},{name:`deploy`,aliases:[],description:`Deploy the agent to Vercel`,takesArgument:!1,build:()=>({type:`extension`,name:`deploy`,argument:``})},{name:`exit`,aliases:[`quit`],description:`Quit the TUI`,takesArgument:!1,build:()=>({type:`exit`})}];function parsePromptCommand(t){let n=t.trim();if(!n.startsWith(`/`))return null;for(let t of PROMPT_COMMANDS)for(let e of[t.name,...t.aliases]){let r=`/${e}`;if(n===r)return t.build(``);if(t.takesArgument&&n.startsWith(`${r} `))return t.build(n.slice(r.length).trim())}return null}function isPromptControlCommand(e){return parsePromptCommand(e)!==null}function formatPromptCommandHelp(){let t=PROMPT_COMMANDS.map(e=>{let t=e.argumentHint===void 0?``:` ${e.argumentHint}`,n=e.aliases.map(e=>` (/${e})`).join(``);return{invocation:`/${e.name}${t}${n}`,description:e.description}}),n=Math.max(...t.map(e=>e.invocation.length))+2;return t.map(e=>e.invocation.padEnd(n)+e.description).join(`
2
2
  `)}export{PROMPT_COMMANDS,formatPromptCommandHelp,isPromptControlCommand,parsePromptCommand};
@@ -6,6 +6,7 @@ import type { AssistantResponseStatsMode, LogDisplayMode, TerminalPartDisplayMod
6
6
  import { type TerminalInput, type TerminalOutput } from "./terminal-renderer.js";
7
7
  import { type VercelStatusEffect, type VercelStatusSnapshot } from "./vercel-status.js";
8
8
  import type { detectProjectIdentity } from "#setup/project-resolution.js";
9
+ import { getVercelAuthStatus } from "#setup/vercel-project.js";
9
10
  export { parsePromptCommand, type PromptCommand } from "./prompt-commands.js";
10
11
  export type AgentTUIStreamResult = {
11
12
  events: AsyncIterable<AgentTUIStreamEvent> | ReadableStream<AgentTUIStreamEvent>;
@@ -137,6 +138,8 @@ export type AgentTUIRenderer = {
137
138
  */
138
139
  renderSandboxLog?(text: string): void;
139
140
  renderSetupWarning?(text: string): void;
141
+ /** Clears the setup attention line once its issue is resolved. */
142
+ clearSetupWarning?(): void;
140
143
  renderCommandResult?(text: string): void;
141
144
  readonly setupFlow?: SetupFlowRenderer;
142
145
  readPrompt?(options?: AgentTUISessionOptions): Promise<string | undefined>;
@@ -189,6 +192,11 @@ export type AgentTUIRenderer = {
189
192
  * positions. Used by the `/loglevel` command.
190
193
  */
191
194
  setLogDisplayMode?(mode: LogDisplayMode): void;
195
+ /**
196
+ * Commits any delayed local dev build errors immediately before dispatching
197
+ * a user prompt. Renderers without process-log capture ignore it.
198
+ */
199
+ flushDelayedDevBuildErrors?(): void;
192
200
  /**
193
201
  * Sets the workspace-scoped Vercel segment of the persistent bottom
194
202
  * status line: linked project identity and the session's pending-deploy
@@ -266,6 +274,8 @@ export type EveTUIRunnerOptions = TuiDisplayOptions & {
266
274
  bootDetections?: readonly BootDetection[];
267
275
  /** Test seam for the status line's Vercel link probe; defaults to the real one. */
268
276
  detectProjectIdentity?: typeof detectProjectIdentity;
277
+ /** Test seam for the off-critical-path boot login probe; defaults to the real one. */
278
+ getVercelAuthStatus?: typeof getVercelAuthStatus;
269
279
  };
270
280
  export declare class EveTUIRunner {
271
281
  #private;
@@ -1 +1 @@
1
- import{pickAgentHeaderTip}from"./agent-header.js";import{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{BOOT_DETECTIONS,detectSetupIssues,formatSetupIssuesLine}from"./setup-issues.js";import{TerminalRenderer}from"./terminal-renderer.js";import{createVercelStatusTracker}from"./vercel-status.js";import{toErrorMessage}from"#shared/errors.js";import{isCurrentTurnBoundaryEvent}from"#client/index.js";import{subscribeDevelopmentSandboxPrewarmLogs}from"#execution/sandbox/development-prewarm.js";import{createDevelopmentRuntimeArtifactSessionRefresher}from"#services/dev-client.js";var EveTUIRunner=class{#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;#u;#d;#f;#p;#m;#h;#g;#_;#v=pickAgentHeaderTip();#y;#b=new Map;#x=new Map;#S=new Map;#C=new Map;#w=new Set;#T=!1;#E;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.#_=createVercelStatusTracker(t)}e.promptCommandHandler!==void 0&&(this.#h=e.promptCommandHandler),this.#g=e.bootDetections??BOOT_DETECTIONS,e.serverUrl!==void 0&&(this.#f=e.serverUrl,this.#d=createDevelopmentRuntimeArtifactSessionRefresher({serverUrl:e.serverUrl}))}async#D(){let e=this.#f;if(e===void 0){await this.#M(void 0);return}let t;try{t=await this.#t?.info()}catch{t=void 0}this.#y=t;let n={name:this.#r,serverUrl:e};t!==void 0&&(n.info=t),this.#p!==void 0&&(n.tip=this.#v),this.#n.renderAgentHeader?.(n),await this.#M(t)}async run(){try{await this.#O()}finally{this.#E?.(),this.#E=void 0,this.#n.shutdown?.(),this.#_?.dispose()}}async#O(){let e=this.#r,r,i,a=!1,o=!1,s=this.#m;for(await this.#D(),this.#N(),this.#_?.refreshIdentity();;){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.#A(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.#k(),i=void 0,o=!1,r=void 0,this.#n.reset?.();continue}if(c?.type===`help`){this.#P(formatPromptCommandHelp()),i=void 0,o=!1,r=void 0;continue}if(c?.type===`loglevel`){this.#P(this.#F(c.argument)),i=void 0,o=!1,r=void 0;continue}if(c?.type===`extension`){try{let t=this.#h===void 0?{message:`/${c.name} is not available in this session.`}:await this.#h.handle(c,{renderer:this.#n,title:e});t?.message!==void 0&&this.#P(t.message),t?.vercelEffect!==void 0&&this.#_?.applyEffect(t.vercelEffect)}catch(e){if(isInterruptedError(e))return;throw e}i=void 0,r=void 0,o=!1;continue}a=!0}let c=await this.#j({prompt:o?void 0:r,inputResponses:i});try{await this.#n.renderStream(c,{title:e,submittedPrompt:r,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.#b.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.#b.delete(t.requestId)}}o=!0,i=a,r=void 0;continue}c.turnState&&c.turnState.boundaryEvent===void 0&&(this.#T=!0)}catch(e){if(isInterruptedError(e))return;throw e}o=!1,i=void 0,r=void 0,this.#T&&(this.#T=!1,this.#k(),this.#n.renderNotice?.(`Session ended — started a new session. Earlier context was cleared.`))}}#k(){for(let e of this.#S.values())e.abort();this.#S.clear(),this.#x.clear(),this.#b.clear(),this.#C.clear(),this.#w.clear(),this.#t&&(this.#e=this.#t.session()),this.#d?.clear()}async#A(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.#I(),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#j(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.#I(),session:this.#e})),r=await this.#e.send(n)}catch(e){if(isInterruptedError(e))throw e;return this.#T=!0,{events:errorOnlyTUIStream({errorText:this.#u(e)}),turnState:createTurnState()}}let i=createTurnState();return{abort:()=>t.abort(),events:eveEventsToTUIStream({events:r,pendingInputRequests:this.#b,subagentRuns:this.#x,turnState:i,onSubagentCalled:e=>this.#B(e),onSubagentCompleted:e=>this.#H(e),onConnectionAuthRequired:e=>this.#L(e),onConnectionAuthCompleted:e=>this.#R(e),onTerminalFailure:()=>{this.#T=!0},failureOverride:this.#p===void 0?void 0:e=>isGatewayAuthFailure(e)?formatGatewayAuthFailureNotice(e):void 0}),turnState:i}}async#M(e){if(this.#p===void 0||this.#n.renderSetupWarning===void 0)return;let t={appRoot:this.#p,env:process.env};e!==void 0&&(t.info=e);let n=await detectSetupIssues(t,this.#g);n.length!==0&&this.#n.renderSetupWarning(formatSetupIssuesLine(n))}#N(){this.#p===void 0||this.#n.renderSandboxLog===void 0||this.#E===void 0&&(this.#E=subscribeDevelopmentSandboxPrewarmLogs({appRoot:this.#p,log:e=>this.#n.renderSandboxLog?.(e)}))}#P(e){if(this.#n.renderCommandResult!==void 0){this.#n.renderCommandResult(e);return}this.#n.renderNotice?.(e)}#F(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#I(){let e=this.#y,t;try{t=await this.#t?.info()}catch{t=void 0}if(t!==void 0&&(this.#y=t,this.#f!==void 0)){let e={info:t,name:this.#r,serverUrl:this.#f};this.#p!==void 0&&(e.tip=this.#v),this.#n.renderAgentHeader?.(e)}(!this.#n.renderAgentHeader||t===void 0)&&this.#n.renderNotice?.(formatAgentUpdateNotice(e,t))}#L(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.#C.set(e.data.name,t),this.#z(t)}#R(e){let t=this.#C.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.#C.set(e.data.name,t),this.#w.delete(e.data.name),this.#z(t),this.#n.setConnectionAuthPendingCount?.(this.#w.size)}#z(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)}#B(e){let t=e.data.callId;if(this.#S.has(t))return;let n=this.#t;if(!n)return;let r=new AbortController;this.#S.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.#U(t,e),isCurrentTurnBoundaryEvent(e)))break}catch(e){if(!isAbortLikeError(e)){let n=toErrorMessage(e),r=this.#x.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.#S.delete(t)}})()}#V(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})}#H(e){let t=this.#x.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}}#U(e,t){let n=this.#x.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.#V(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.#V(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,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,_=new Set,v=!1,y=!1,b;for await(let e of t)if(!(y&&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;b=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,n=t.actions.filter(e=>e.kind===`tool-call`);if(n.length===0)break;let r=toolBatchKey(`actions.requested`,t.turnId,t.stepIndex,n);if(g.has(r)){for(let e of n)m.has(e.callId)||h.add(e.callId);break}g.add(r);for(let e of n)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,r=t.requests.filter(e=>e.action.kind===`tool-call`);if(r.length===0)break;let a=inputRequestBatchKey(t.turnId,t.stepIndex,r);if(g.has(a)){for(let e of r)m.has(e.action.callId)||h.add(e.action.callId);break}g.add(a);for(let e of r){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}),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(h.has(n)||!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,_,u);t&&(yield t);break}case`session.failed`:{i.sawSessionFailure=!0,l?.(e);let t=toFailureEvent(e,_,u);t&&(yield t),i.boundaryEvent=e.type,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`finish`,usage:b},v=!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:b},v=!0;return;case`turn.completed`:y=!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}v||(yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`finish`,usage:b})}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 toolBatchKey(e,t,n,r){return`${e}:${t}:${String(n)}:${stableStringify(r.map(e=>({input:e.input,toolName:e.toolName})))}`}function inputRequestBatchKey(e,t,n){return toolBatchKey(`input.requested`,e,t,n.map(e=>({input:e.action.input,toolName:e.action.toolName})))}function stableStringify(e){return JSON.stringify(toStableJson(e))??`undefined`}function toStableJson(e,t=new WeakSet){if(typeof e!=`object`||!e)return e;if(t.has(e))return`[Circular]`;if(t.add(e),Array.isArray(e))return e.map(e=>toStableJson(e,t));let n=e,r={};for(let e of Object.keys(n).sort())r[e]=toStableJson(n[e],t);return r}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 o=failureKey(e);if(t.has(o))return;t.add(o);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{pickAgentHeaderTip}from"./agent-header.js";import{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{BOOT_DETECTIONS,CLI_MISSING_SETUP_ISSUE,LOGIN_SETUP_ISSUE,detectSetupIssues,formatSetupIssuesLine}from"./setup-issues.js";import{TerminalRenderer}from"./terminal-renderer.js";import{createVercelStatusTracker}from"./vercel-status.js";import{toErrorMessage}from"#shared/errors.js";import{isCurrentTurnBoundaryEvent}from"#client/index.js";import{subscribeDevelopmentSandboxPrewarmLogs}from"#execution/sandbox/development-prewarm.js";import{createDevelopmentRuntimeArtifactSessionRefresher}from"#services/dev-client.js";import{getVercelAuthStatus}from"#setup/vercel-project.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=!1;#y=new AbortController;#b=!1;#x=[];#S;#C;#w=pickAgentHeaderTip();#T;#E=new Map;#D=new Map;#O=new Map;#k=new Map;#A=new Set;#j=!1;#M;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.#C=createVercelStatusTracker(t)}e.promptCommandHandler!==void 0&&(this.#h=e.promptCommandHandler),this.#g=e.bootDetections??BOOT_DETECTIONS,this.#_=e.getVercelAuthStatus??getVercelAuthStatus,e.serverUrl!==void 0&&(this.#f=e.serverUrl,this.#d=createDevelopmentRuntimeArtifactSessionRefresher({serverUrl:e.serverUrl}))}async#N(){let e=this.#f;if(e===void 0){await this.#R(void 0);return}let t;try{t=await this.#t?.info()}catch{t=void 0}this.#T=t;let n={name:this.#r,serverUrl:e};t!==void 0&&(n.info=t),this.#p!==void 0&&(n.tip=this.#w),this.#n.renderAgentHeader?.(n),await this.#R(t)}async run(){try{await this.#P()}finally{this.#v=!0,this.#y.abort(),this.#M?.(),this.#M=void 0,this.#n.shutdown?.(),this.#C?.dispose()}}async#P(){let e=this.#r,r,i,a=!1,o=!1,s=this.#m;for(await this.#N(),this.#H(),this.#C?.refreshIdentity();;){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.#I(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.#F(),i=void 0,o=!1,r=void 0,this.#n.reset?.();continue}if(c?.type===`help`){this.#U(formatPromptCommandHelp()),i=void 0,o=!1,r=void 0;continue}if(c?.type===`loglevel`){this.#U(this.#W(c.argument)),i=void 0,o=!1,r=void 0;continue}if(c?.type===`extension`){try{let t=this.#h===void 0?{message:`/${c.name} is not available in this session.`}:await this.#h.handle(c,{renderer:this.#n,title:e});t?.message!==void 0&&this.#U(t.message),t?.vercelEffect!==void 0&&(this.#C?.applyEffect(t.vercelEffect),this.#b=!0,this.#V())}catch(e){if(isInterruptedError(e))return;throw e}i=void 0,r=void 0,o=!1;continue}a=!0}let c=await this.#L({prompt:o?void 0:r,inputResponses:i});try{await this.#n.renderStream(c,{title:e,submittedPrompt:r,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.#E.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.#E.delete(t.requestId)}}o=!0,i=a,r=void 0;continue}c.turnState&&c.turnState.boundaryEvent===void 0&&(this.#j=!0)}catch(e){if(isInterruptedError(e))return;throw e}o=!1,i=void 0,r=void 0,this.#j&&(this.#j=!1,this.#F(),this.#n.renderNotice?.(`Session ended — started a new session. Earlier context was cleared.`))}}#F(){for(let e of this.#O.values())e.abort();this.#O.clear(),this.#D.clear(),this.#E.clear(),this.#k.clear(),this.#A.clear(),this.#t&&(this.#e=this.#t.session()),this.#d?.clear()}async#I(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.#G(),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#L(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.#G(),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.#j=!0,{events:errorOnlyTUIStream({errorText:this.#u(e)}),turnState:createTurnState()}}let i=createTurnState();return{abort:()=>t.abort(),events:eveEventsToTUIStream({events:r,pendingInputRequests:this.#E,subagentRuns:this.#D,turnState:i,onSubagentCalled:e=>this.#Y(e),onSubagentCompleted:e=>this.#Z(e),onConnectionAuthRequired:e=>this.#K(e),onConnectionAuthCompleted:e=>this.#q(e),onTerminalFailure:()=>{this.#j=!0},failureOverride:this.#p===void 0?void 0:e=>isGatewayAuthFailure(e)?formatGatewayAuthFailureNotice(e):void 0}),turnState:i}}async#R(e){if(this.#p===void 0||this.#n.renderSetupWarning===void 0)return;let t={appRoot:this.#p,env:process.env};e!==void 0&&(t.info=e),this.#x=await detectSetupIssues(t,this.#g),this.#z(),this.#B()}#z(){let e=[...this.#x,...this.#S?[this.#S]:[]];e.length>0?this.#n.renderSetupWarning?.(formatSetupIssuesLine(e)):this.#n.clearSetupWarning?.()}async#B(){let e=this.#p;if(e===void 0)return;let t;try{t=await this.#_(e,{signal:this.#y.signal})}catch{return}this.#v||this.#b||(this.#S=authIssueForStatus(t),this.#z())}async#V(){let e=this.#p;if(e===void 0||this.#n.renderSetupWarning===void 0)return;let t={appRoot:e,env:process.env};this.#T!==void 0&&(t.info=this.#T);try{this.#x=await detectSetupIssues(t,this.#g);let n=await this.#_(e,{signal:this.#y.signal});this.#S=authIssueForStatus(n)}catch{return}this.#v||this.#z()}#H(){this.#p===void 0||this.#n.renderSandboxLog===void 0||this.#M===void 0&&(this.#M=subscribeDevelopmentSandboxPrewarmLogs({appRoot:this.#p,log:e=>this.#n.renderSandboxLog?.(e)}))}#U(e){if(this.#n.renderCommandResult!==void 0){this.#n.renderCommandResult(e);return}this.#n.renderNotice?.(e)}#W(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#G(){let e=this.#T,t;try{t=await this.#t?.info()}catch{t=void 0}if(t!==void 0&&(this.#T=t,this.#f!==void 0)){let e={info:t,name:this.#r,serverUrl:this.#f};this.#p!==void 0&&(e.tip=this.#w),this.#n.renderAgentHeader?.(e)}(!this.#n.renderAgentHeader||t===void 0)&&this.#n.renderNotice?.(formatAgentUpdateNotice(e,t))}#K(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.#k.set(e.data.name,t),this.#J(t)}#q(e){let t=this.#k.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.#k.set(e.data.name,t),this.#A.delete(e.data.name),this.#J(t),this.#n.setConnectionAuthPendingCount?.(this.#A.size)}#J(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)}#Y(e){let t=e.data.callId;if(this.#O.has(t))return;let n=this.#t;if(!n)return;let r=new AbortController;this.#O.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.#Q(t,e),isCurrentTurnBoundaryEvent(e)))break}catch(e){if(!isAbortLikeError(e)){let n=toErrorMessage(e),r=this.#D.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.#O.delete(t)}})()}#X(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})}#Z(e){let t=this.#D.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}}#Q(e,t){let n=this.#D.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.#X(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.#X(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,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,_=new Set,v=!1,y=!1,b;for await(let e of t)if(!(y&&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;b=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,n=t.actions.filter(e=>e.kind===`tool-call`);if(n.length===0)break;let r=toolBatchKey(`actions.requested`,t.turnId,t.stepIndex,n);if(g.has(r)){for(let e of n)m.has(e.callId)||h.add(e.callId);break}g.add(r);for(let e of n)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,r=t.requests.filter(e=>e.action.kind===`tool-call`);if(r.length===0)break;let a=inputRequestBatchKey(t.turnId,t.stepIndex,r);if(g.has(a)){for(let e of r)m.has(e.action.callId)||h.add(e.action.callId);break}g.add(a);for(let e of r){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}),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(h.has(n)||!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,_,u);t&&(yield t);break}case`session.failed`:{i.sawSessionFailure=!0,l?.(e);let t=toFailureEvent(e,_,u);t&&(yield t),i.boundaryEvent=e.type,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`finish`,usage:b},v=!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:b},v=!0;return;case`turn.completed`:y=!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}v||(yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`finish`,usage:b})}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 toolBatchKey(e,t,n,r){return`${e}:${t}:${String(n)}:${stableStringify(r.map(e=>({input:e.input,toolName:e.toolName})))}`}function inputRequestBatchKey(e,t,n){return toolBatchKey(`input.requested`,e,t,n.map(e=>({input:e.action.input,toolName:e.action.toolName})))}function stableStringify(e){return JSON.stringify(toStableJson(e))??`undefined`}function toStableJson(e,t=new WeakSet){if(typeof e!=`object`||!e)return e;if(t.has(e))return`[Circular]`;if(t.add(e),Array.isArray(e))return e.map(e=>toStableJson(e,t));let n=e,r={};for(let e of Object.keys(n).sort())r[e]=toStableJson(n[e],t);return r}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 o=failureKey(e);if(t.has(o))return;t.add(o);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,5 +1,7 @@
1
1
  import { runChannelsFlow } from "#setup/flows/channels.js";
2
2
  import { runDeployFlow } from "#setup/flows/deploy.js";
3
+ import { runInstallVercelCliFlow } from "#setup/flows/install-vercel-cli.js";
4
+ import { runLoginFlow } from "#setup/flows/login.js";
3
5
  import { runModelFlow } from "#setup/flows/model.js";
4
6
  import type { Prompter } from "#setup/prompter.js";
5
7
  import { type TuiPrompterRenderer } from "./tui-prompter.js";
@@ -30,6 +32,8 @@ export interface TuiSetupCommandInput {
30
32
  }
31
33
  /** The flow entry points the commands dispatch to, injectable for tests. */
32
34
  export interface TuiSetupFlows {
35
+ runInstallVercelCliFlow: typeof runInstallVercelCliFlow;
36
+ runLoginFlow: typeof runLoginFlow;
33
37
  runModelFlow: typeof runModelFlow;
34
38
  runChannelsFlow: typeof runChannelsFlow;
35
39
  runDeployFlow: typeof runDeployFlow;
@@ -1,2 +1,2 @@
1
- import{createTuiPrompter}from"./tui-prompter.js";import{runDeployFlow}from"#setup/flows/deploy.js";import{runChannelsFlow}from"#setup/flows/channels.js";import{runModelFlow}from"#setup/flows/model.js";import{openUrl}from"#setup/primitives/open-url.js";import{slackMessageDeepLink}from"#setup/slack-connect.js";import{WizardCancelledError}from"#setup/step.js";const SETUP_FLOW_TITLES={model:`Configure the agent model`,channels:`Agent channels`,deploy:`Deploy to Vercel`};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),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:n}=t,r=!1,i=new AbortController,a=(t.createPrompter??createTuiPrompter)(muteableRenderer(t.renderer,()=>r)),o=t.renderer.waitForInterrupt(),s=Symbol(`interrupted`),c=executeSetupCommand(t,a,i.signal);try{let e=await Promise.race([c,o.promise.then(()=>s)]);if(e!==s)return e;r=!0,i.abort(new WizardCancelledError);let t=await c,a={message:`/${n} interrupted.`,preserveFlowDiagnostics:!0};return t.vercelEffect!==void 0&&(a.vercelEffect=t.vercelEffect),a}finally{o.dispose(),t.renderer.setStatus(void 0)}}async function executeSetupCommand(e,i,a){let{command:o,appRoot:s}=e,c={runModelFlow,runChannelsFlow,runDeployFlow,...e.flows};try{switch(o){case`model`:{let e=await c.runModelFlow({appRoot:s,prompter:i,signal:a});if(e.kind===`cancelled`)return{message:`/model cancelled.`,preserveFlowDiagnostics:!1};let t=[];e.modelMessage!==void 0&&t.push(e.modelMessage),e.providerOutcome!==void 0&&t.push(providerOutcomeMessage(e.providerOutcome));let n={message:t.join(`
2
- `),preserveFlowDiagnostics:!1};return e.providerOutcome!==void 0&&(n.vercelEffect={kind:`refresh-identity`}),n}case`channels`:{let e=await c.runChannelsFlow({appRoot:s,prompter:i,signal:a});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(c,{appRoot:s,prompter:i,signal:a},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,vercelEffect:{kind:`channels-added`}}}}case`deploy`:{let e=await c.runDeployFlow({appRoot:s,prompter:i,interactive:!0,signal:a});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,vercelEffect:{kind:`deployed`}}}}}catch(e){return e instanceof WizardCancelledError?{message:`/${o} cancelled.`,preserveFlowDiagnostics:o!==`model`}:{message:`/${o} failed: ${e instanceof Error?e.message:String(e)}`,preserveFlowDiagnostics:!0}}}async function runDeployAndChat(e,t,n){let r;try{r=await e.runDeployFlow({...t,interactive:!0})}catch(e){return e instanceof WizardCancelledError?pendingChannelsResult(`Channels added, but /deploy was cancelled. Run /deploy to ship them.`):pendingChannelsResult(`Channels added, but /deploy failed: ${e instanceof Error?e.message:String(e)}`)}if(r.kind===`cancelled`)return pendingChannelsResult(`Channels added, but /deploy was cancelled. Run /deploy to ship them.`);if(r.kind===`needs-link`)return pendingChannelsResult(`Channels added, but this directory is not linked to Vercel. Run /model, then /deploy.`);let o=r.productionUrl===void 0?`Deployed.`:`Deployed: ${r.productionUrl}`,s;if(n.chatUrl===void 0)s=`Message your agent in Slack to see it live.`;else{let e=slackMessageDeepLink(n.chatUrl);openUrl(e),s=`Chat with your agent in Slack: ${e}`}return{message:`${o}\n${s}`,preserveFlowDiagnostics:!0,vercelEffect:{kind:`deployed`}}}function pendingChannelsResult(e){return{message:e,preserveFlowDiagnostics:!0,vercelEffect:{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_TITLES,runTuiSetupCommand};
1
+ import{createTuiPrompter}from"./tui-prompter.js";import{runDeployFlow}from"#setup/flows/deploy.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{runLoginFlow}from"#setup/flows/login.js";import{runModelFlow}from"#setup/flows/model.js";import{openUrl}from"#setup/primitives/open-url.js";import{slackMessageDeepLink}from"#setup/slack-connect.js";import{WizardCancelledError}from"#setup/step.js";const SETUP_FLOW_TITLES={vc:`Install the Vercel CLI`,login:`Log in to Vercel`,model:`Configure the agent model`,channels:`Agent channels`,deploy:`Deploy to Vercel`};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),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:n}=t,r=!1,i=new AbortController,a=(t.createPrompter??createTuiPrompter)(muteableRenderer(t.renderer,()=>r)),o=t.renderer.waitForInterrupt(),s=Symbol(`interrupted`),c=executeSetupCommand(t,a,i.signal);try{let e=await Promise.race([c,o.promise.then(()=>s)]);if(e!==s)return e;r=!0,i.abort(new WizardCancelledError);let t=await c,a={message:`/${n} interrupted.`,preserveFlowDiagnostics:!0};return t.vercelEffect!==void 0&&(a.vercelEffect=t.vercelEffect),a}finally{o.dispose(),t.renderer.setStatus(void 0)}}async function executeSetupCommand(e,n,s){let{command:c,appRoot:l}=e,u={runInstallVercelCliFlow,runLoginFlow,runModelFlow,runChannelsFlow,runDeployFlow,...e.flows};try{switch(c){case`vc`:return installVercelCliResultMessage(await u.runInstallVercelCliFlow({appRoot:l,prompter:n,signal:s}));case`login`:return loginResultMessage(await u.runLoginFlow({appRoot:l,prompter:n,signal:s}));case`model`:{let e=await u.runModelFlow({appRoot:l,prompter:n,signal:s});if(e.kind===`cancelled`)return{message:`/model cancelled.`,preserveFlowDiagnostics:!1};let t=[];e.modelMessage!==void 0&&t.push(e.modelMessage),e.providerOutcome!==void 0&&t.push(providerOutcomeMessage(e.providerOutcome));let r={message:t.join(`
2
+ `),preserveFlowDiagnostics:!1};return e.providerOutcome!==void 0&&(r.vercelEffect={kind:`refresh-identity`}),r}case`channels`:{let e=await u.runChannelsFlow({appRoot:l,prompter:n,signal:s});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(u,{appRoot:l,prompter:n,signal:s},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,vercelEffect:{kind:`channels-added`}}}}case`deploy`:{let e=await u.runDeployFlow({appRoot:l,prompter:n,interactive:!0,signal:s});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,vercelEffect:{kind:`deployed`}}}}}catch(e){if(e instanceof WizardCancelledError)return{message:`/${c} cancelled.`,preserveFlowDiagnostics:c!==`model`};let t=vercelActionOutcome(e,c);return t===void 0?{message:`/${c} failed: ${e instanceof Error?e.message:String(e)}`,preserveFlowDiagnostics:!0}:t}}function vercelActionOutcome(e,t){if(!(e instanceof HumanActionRequiredError))return;let r=vercelActionMessage(e.action.kind,t);return r===void 0?void 0:{message:r,preserveFlowDiagnostics:!0}}function vercelActionMessage(e,t){switch(e){case`vercel-login`:return`You're not logged in to Vercel — run /login, then retry /${t}.`;case`vercel-forbidden`:return`Vercel denied access to that team — run /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 to install it, then retry /${t}.`;default:return}}async function runDeployAndChat(e,t,n){let r;try{r=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(r.kind===`cancelled`)return pendingChannelsResult(`Channels added, but /deploy was cancelled. Run /deploy to ship them.`);if(r.kind===`needs-link`)return pendingChannelsResult(`Channels added, but this directory is not linked to Vercel. Run /model, then /deploy.`);let i=r.productionUrl===void 0?`Deployed.`:`Deployed: ${r.productionUrl}`,a;if(n.chatUrl===void 0)a=`Message your agent in Slack to see it live.`;else{let e=slackMessageDeepLink(n.chatUrl);openUrl(e),a=`Chat with your agent in Slack: ${e}`}return{message:`${i}\n${a}`,preserveFlowDiagnostics:!0,vercelEffect:{kind:`deployed`}}}function installVercelCliResultMessage(e){switch(e.kind){case`cancelled`:return{message:`/vc 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 /login next.`,preserveFlowDiagnostics:!1,vercelEffect:{kind:`refresh-identity`}}}}function loginResultMessage(e){switch(e.kind){case`cancelled`:return{message:`/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 to install it, then retry /login.`,preserveFlowDiagnostics:!0};case`failed`:return{message:`Vercel login didn't complete — run /login to try again.`,preserveFlowDiagnostics:!0};case`logged-in`:return{message:`Logged in to Vercel.`,preserveFlowDiagnostics:!1,vercelEffect:{kind:`refresh-identity`}};case`unavailable`:return{message:`Couldn't reach Vercel — check your connection, then retry /login.`,preserveFlowDiagnostics:!0}}}function pendingChannelsResult(e){return{message:e,preserveFlowDiagnostics:!0,vercelEffect:{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_TITLES,runTuiSetupCommand};
@@ -26,6 +26,21 @@ export interface BootDetection {
26
26
  }
27
27
  /** The built-in boot detections, run in order. */
28
28
  export declare const BOOT_DETECTIONS: readonly BootDetection[];
29
+ /**
30
+ * The logged-out hint. Deliberately not a {@link BootDetection}: confirming
31
+ * Vercel login is a `vercel whoami` subprocess, too costly for the cheap,
32
+ * local detections that run between the header and the first prompt. The
33
+ * runner probes it off the critical path and renders this issue only when the
34
+ * probe resolves logged-out.
35
+ */
36
+ export declare const LOGIN_SETUP_ISSUE: SetupIssue;
37
+ /**
38
+ * The CLI-missing hint, surfaced by the same off-critical-path probe as
39
+ * {@link LOGIN_SETUP_ISSUE}. When the `vercel` binary is absent the probe
40
+ * reports this instead of the login hint, so the diagnostic points at its fix
41
+ * command (`/vc`) rather than a logged-out state the probe can't determine.
42
+ */
43
+ export declare const CLI_MISSING_SETUP_ISSUE: SetupIssue;
29
44
  /**
30
45
  * Runs the boot detections and aggregates their issues. Each detection is
31
46
  * individually guarded: one that throws contributes nothing and never blocks
@@ -1 +1 @@
1
- import{join}from"node:path";import{pathExists}from"#setup/path-exists.js";const BOOT_DETECTIONS=[{id:`model-provider`,async detect({appRoot:n,env:r,info:i}){return i?.agent.model.routing?.kind===`external`||r.AI_GATEWAY_API_KEY||r.VERCEL_OIDC_TOKEN?[]:await pathExists(join(n,`.vercel`,`project.json`))?[{label:`AI Gateway credentials missing`,command:`/model`}]:[{label:`model provider not linked`,command:`/model`}]}}];async function detectSetupIssues(e,t=BOOT_DETECTIONS){return(await Promise.all(t.map(async t=>{try{return await t.detect(e)}catch{return[]}}))).flat()}function formatSetupIssuesLine(e){let t=e.length===1?`setup issue`:`setup issues`,n=e.map(e=>`${e.label} · ${e.command}`).join(`, `);return`${e.length} ${t}: ${n}`}export{BOOT_DETECTIONS,detectSetupIssues,formatSetupIssuesLine};
1
+ import{join}from"node:path";import{pathExists}from"#setup/path-exists.js";const BOOT_DETECTIONS=[{id:`model-provider`,async detect({appRoot:n,env:r,info:i}){return i?.agent.model.routing?.kind===`external`||r.AI_GATEWAY_API_KEY||r.VERCEL_OIDC_TOKEN?[]:await pathExists(join(n,`.vercel`,`project.json`))?[{label:`AI Gateway credentials missing`,command:`/model`}]:[{label:`model provider not linked`,command:`/model`}]}}],LOGIN_SETUP_ISSUE={label:`not logged in`,command:`/login`},CLI_MISSING_SETUP_ISSUE={label:`Vercel CLI not found`,command:`/vc`};async function detectSetupIssues(e,t=BOOT_DETECTIONS){return(await Promise.all(t.map(async t=>{try{return await t.detect(e)}catch{return[]}}))).flat()}function formatSetupIssuesLine(e){let t=e.length===1?`setup issue`:`setup issues`,n=e.map(e=>`${e.label} · ${e.command}`).join(`, `);return`${e.length} ${t}: ${n}`}export{BOOT_DETECTIONS,CLI_MISSING_SETUP_ISSUE,LOGIN_SETUP_ISSUE,detectSetupIssues,formatSetupIssuesLine};
@@ -72,10 +72,15 @@ export declare class TerminalRenderer implements AgentTUIRenderer {
72
72
  renderNotice(text: string): void;
73
73
  renderSandboxLog(text: string): void;
74
74
  /**
75
- * Commits the boot-time setup attention line (yellow `⚠`, commands blue),
76
- * shown once after the agent header when boot detection finds issues.
75
+ * Sets the setup attention line (yellow `⚠`, commands blue) as a live footer
76
+ * element above the prompt. Unlike committed scrollback, it can be cleared:
77
+ * once the underlying issue is fixed (e.g. `/login` succeeds) the runner calls
78
+ * {@link clearSetupWarning} and the line disappears rather than lingering
79
+ * stale in the transcript.
77
80
  */
78
81
  renderSetupWarning(text: string): void;
82
+ /** Removes the setup attention line once its issue is resolved. */
83
+ clearSetupWarning(): void;
79
84
  /**
80
85
  * Commits one command's outcome under its invocation with the elbow
81
86
  * connector (` ⎿ /model cancelled.`), Claude Code's sub-result grammar.
@@ -92,4 +97,5 @@ export declare class TerminalRenderer implements AgentTUIRenderer {
92
97
  * positions.
93
98
  */
94
99
  setLogDisplayMode(mode: LogDisplayMode): void;
100
+ flushDelayedDevBuildErrors(): void;
95
101
  }