Skip to content

feat(eve): convert standalone agents to workspaces - #3349

Draft
OwenKephart wants to merge 2 commits into
mainfrom
init-standalone-workspace-migration
Draft

OwenKephart wants to merge 2 commits into
mainfrom
init-standalone-workspace-migration

Conversation

@OwenKephart

@OwenKephart OwenKephart commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Standalone eve projects currently reject eve init <name>, so authors cannot grow a single-agent project into a workspace through the CLI. This adds an explicit conversion flow that moves the existing agent and evals into agents/<project-name>/ and adds the requested agent, with confirmation by default and --yes for non-interactive use. Generated Web Chat projects retain their root app and are rewired to the moved agent; custom Next.js apps and Vercel service graphs stop before writing and explain the manual migration boundary.

Validation

  • pnpm fmt
  • pnpm lint (passes with pre-existing workspace warnings)
  • pnpm --filter eve exec tsc --noEmit --pretty false
  • pnpm --filter eve exec vitest run --config vitest.integration.config.ts src/cli/commands/migrate/standalone.integration.test.ts src/cli/commands/init.integration.test.ts (72 passed)
  • pnpm --filter eve exec vitest run --config vitest.unit.config.ts src/cli/run.test.ts (67 passed)
  • pnpm guard:invariants
  • pnpm docs:check
  • git diff --check

Checklist

  • This change was requested or approved by a maintainer
  • I ran the relevant checks from CONTRIBUTING.md
  • I added tests and documentation where relevant
  • I added a changeset if this touches the published eve package
  • DCO sign-off passes for every commit (git commit --signoff)

Signed-off-by: owenkephart <owen.kephart@vercel.com>
@vercel

vercel Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
eve-docs Ready Ready Preview, v0 Sep 14, 2026 7:48pm UTC
eve-docs-4759 Ready Ready Preview, v0 Sep 14, 2026 7:48pm UTC
1 Skipped Deployment
Project Deployment Actions Updated
eve-pkg Skipped Skipped v0 Sep 14, 2026 7:48pm UTC


const oldRoot = join(root, "agents", oldName);
await mkdir(oldRoot, { recursive: true });
await moveIfPresent(root, oldName, "agent");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Preserve flat standalone agents

findEveProjectContext also classifies flat roots containing agent.ts, instructions.md, tools/, and similar entries as standalone. This path only renames a root agent/ directory, so converting a valid flat project leaves the original files at the workspace root. Once agents/<new> exists, project resolution selects the workspace and the original agent disappears from dev, build, and deploy. Detect the flat layout and move its complete agent surface into agents/${oldName}, or reject it before the first write.

const oldRoot = join(root, "agents", oldName);
await mkdir(oldRoot, { recursive: true });
await moveIfPresent(root, oldName, "agent");
await moveIfPresent(root, oldName, "evals");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Preserve app-scoped local state

The original agent's app root changes from root to agents/${oldName}, but its .eve/ state stays at root. The converted agent therefore starts with a new .eve/.workflow-data store and can no longer resume its existing local sessions; traces, logs, eval artifacts, and dev runtime generations are stranded too. Migrate the app-scoped state needed under the new app root, or stop with explicit guidance instead of reporting a complete conversion.

`Cannot convert this standalone eve project because ${tsconfigPath} is not a generated eve TypeScript configuration.`,
);
}
const packageUpdated = packageSource

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Make package imports workspace-safe

These two literal replacements leave any additional import target rooted in ./agent or ./evals pointing at a removed path. They also make the root #* map resolve to the original member for every nested agent, so a later #tools/foo import from agents/research resolves to agents/${oldName}/agent/tools/foo. Please provide member-correct import resolution, or reject package configurations that cannot be migrated safely before moving files.

"Cannot convert this standalone eve project because agents/ already exists. Complete the migration manually to avoid overwriting an existing workspace.",
);
}
if (entries.has("vercel.ts") || entries.has("vercel.json")) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Preserve the original agent's public route

For a plain standalone project, this conversion changes the root build into an inferred workspace build. The old agent then moves from /eve/v1/* to /${oldName}/eve/v1/*, breaking existing clients and webhooks on the next deployment. The preflight only blocks authored service graphs, and the confirmation mentions filesystem moves but not this API break. Preserve a compatibility route for the original agent, or block automatic conversion when that compatibility cannot be guaranteed.

const GENERATED_WEB_CHAT_NEXT_CONFIG =
'import type { NextConfig } from "next";\nimport { withEve } from "eve/next";\n\nconst nextConfig: NextConfig = {};\n\nexport default withEve(nextConfig);\n';

interface StandaloneMigrationOptions {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Reject init options this path ignores

The caller passes the full InitCommandOptions, but this narrowed type drops agents and channelWebNextjs. As a result, eve init research --agents=a,b --yes converts the project and creates only research, while --channel-web-nextjs converts without adding Web Chat. The existing project and workspace paths reject these incompatible combinations. Include them in migration preflight and fail before confirmation or mutation, rather than silently changing the requested operation.

@vercel
vercel Bot temporarily deployed to Preview – eve-pkg September 14, 2026 19:45 Inactive
@OwenKephart
OwenKephart force-pushed the init-standalone-workspace-migration branch from b358bae to 71ea0a9 Compare September 14, 2026 19:45
@vercel
vercel Bot temporarily deployed to Preview – eve-pkg September 14, 2026 19:45 Inactive
Signed-off-by: owenkephart <owen.kephart@vercel.com>
}
const choice = await dependencies.createPrompter().select<"convert" | "cancel">({
message: "Convert this eve project to an agents workspace?",
description: `The existing agent will move to agents/${oldName}/ and ${name} will be added.`,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
description: `The existing agent will move to agents/${oldName}/ and ${name} will be added.`,
description:
`The existing agent will move to agents/${oldName}/ and ${name} will be added. ` +
`Its public route changes from /eve/v1/* to /eve/agents/${oldName}/eve/v1/*, ` +
`so update any external clients, webhooks, or channel callbacks that target the old path.`,

Confirmation prompt for converting a standalone eve project to a workspace omits that the existing agent's public HTTP route changes from /eve/v1/* to /eve/agents/<oldName>/eve/v1/*, so users can't make an informed decision and existing clients/webhooks silently break.

Fix on Vercel

await rename(join(root, path), join(root, "agents", oldName, path));
} catch (error) {
if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Standalone→workspace migration moves agent/ and evals/ but not the app-scoped .eve/ state directory, orphaning durable local workflow runs/schedules, traces, logs, and provider settings after the agent's appRoot changes.

Fix on Vercel

import { prepareWebChatMigration, type WebChatMigration } from "./web-chat.js";
import type { InitCliLogger } from "../init-agent-workspace.js";
import { hasInteractiveTerminal } from "../preconditions.js";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The standalone-migration path silently ignores --agents and --channel-web-nextjs, so eve init <name> --agents=... on a standalone project drops the extra agents and the web-channel flag without any error.

Fix on Vercel

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant