eve 0.22.3 → 0.22.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/README.md +2 -0
- package/dist/src/chunks/{use-eve-agent-Cojyfr4X.js → use-eve-agent-CFBTHlPx.js} +18 -1
- package/dist/src/chunks/{use-eve-agent-D-S1TPCW.js → use-eve-agent-dEGV09g_.js} +18 -1
- package/dist/src/cli/commands/agent-instructions.d.ts +15 -0
- package/dist/src/cli/commands/agent-instructions.js +3 -1
- package/dist/src/cli/commands/agent-prompt/scaffold.md +3 -0
- package/dist/src/cli/commands/extension-build.d.ts +9 -0
- package/dist/src/cli/commands/extension-build.js +1 -0
- package/dist/src/cli/commands/extension-init.d.ts +25 -0
- package/dist/src/cli/commands/extension-init.js +1 -0
- package/dist/src/cli/commands/info.js +1 -1
- package/dist/src/cli/commands/init-git.js +1 -1
- package/dist/src/cli/commands/init-repl.js +1 -1
- package/dist/src/cli/commands/init.d.ts +2 -0
- package/dist/src/cli/commands/init.js +1 -1
- package/dist/src/cli/run.js +1 -1
- package/dist/src/client/agent-host.d.ts +4 -0
- package/dist/src/client/agent-host.js +1 -0
- package/dist/src/compiled/.vendor-stamp.json +4 -4
- package/dist/src/compiled/@workflow/core/global.d.ts +20 -0
- package/dist/src/compiled/@workflow/core/index.js +2 -2
- package/dist/src/compiled/@workflow/core/runtime/constants.d.ts +54 -0
- package/dist/src/compiled/@workflow/core/runtime/helpers.d.ts +11 -3
- package/dist/src/compiled/@workflow/core/runtime/run.d.ts +6 -2
- package/dist/src/compiled/@workflow/core/runtime/runs.d.ts +36 -2
- package/dist/src/compiled/@workflow/core/runtime/start.d.ts +28 -0
- package/dist/src/compiled/@workflow/core/runtime/step-executor.d.ts +23 -0
- package/dist/src/compiled/@workflow/core/runtime/step-latency.d.ts +131 -0
- package/dist/src/compiled/@workflow/core/runtime/step-ownership.d.ts +72 -0
- package/dist/src/compiled/@workflow/core/runtime/step-single-flight.d.ts +12 -0
- package/dist/src/compiled/@workflow/core/runtime/suspension-handler.d.ts +7 -0
- package/dist/src/compiled/@workflow/core/runtime.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/runtime.js +3 -3
- package/dist/src/compiled/@workflow/core/serialization-format.d.ts +1 -0
- package/dist/src/compiled/@workflow/core/telemetry/semantic-conventions.d.ts +40 -0
- package/dist/src/compiled/@workflow/core/telemetry.d.ts +8 -0
- package/dist/src/compiled/@workflow/core/version.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/workflow.js +1 -1
- package/dist/src/compiled/@workflow/world/analytics.d.ts +4 -4
- package/dist/src/compiled/@workflow/world/events.d.ts +142 -21
- package/dist/src/compiled/@workflow/world/hooks.d.ts +1 -24
- package/dist/src/compiled/@workflow/world/index.d.ts +3 -2
- package/dist/src/compiled/@workflow/world/queue.d.ts +10 -0
- package/dist/src/compiled/@workflow/world/ulid.d.ts +9 -0
- package/dist/src/compiled/@workflow/world-local/index.js +4 -4
- package/dist/src/compiled/@workflow/world-vercel/index.js +16 -16
- package/dist/src/compiled/_chunks/workflow/attribute-changes-ubiPfqvY.js +20 -0
- package/dist/src/compiled/_chunks/workflow/{dist-DJU_7R9s.js → dist-DnBjuNAZ.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/{functions-CnVBREsg.js → functions-BCMO8vbf.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/resume-hook-BkVkWg2r.js +1 -0
- package/dist/src/compiled/_chunks/workflow/run-B3N1kN9q.js +1 -0
- package/dist/src/compiled/_chunks/workflow/{sleep-phozDCW8.js → sleep-C2Bn-UUg.js} +1 -1
- package/dist/src/compiler/manifest.d.ts +4 -4
- package/dist/src/compiler/normalize-subagent.js +1 -1
- package/dist/src/compiler/remote-agent-node.d.ts +1 -1
- package/dist/src/compiler/remote-agent-node.js +1 -1
- package/dist/src/discover/filesystem.d.ts +2 -2
- package/dist/src/discover/filesystem.js +1 -1
- package/dist/src/discover/project.js +1 -1
- package/dist/src/harness/emission.d.ts +2 -4
- package/dist/src/harness/emission.js +1 -1
- package/dist/src/harness/inline-tool-authorization.d.ts +3 -0
- package/dist/src/harness/inline-tool-authorization.js +1 -0
- package/dist/src/harness/interruptible-stream.d.ts +5 -0
- package/dist/src/harness/interruptible-stream.js +1 -0
- package/dist/src/harness/model-call-error.js +1 -1
- package/dist/src/harness/ordered-stream-emitter.d.ts +17 -0
- package/dist/src/harness/ordered-stream-emitter.js +1 -0
- package/dist/src/harness/stream-actions.d.ts +1 -0
- package/dist/src/harness/stream-actions.js +1 -1
- package/dist/src/harness/subagent-depth.d.ts +1 -1
- package/dist/src/harness/subagent-depth.js +1 -1
- package/dist/src/harness/tool-loop.js +1 -1
- package/dist/src/internal/application/optional-package-install.js +2 -2
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/authored-module-loader.d.ts +1 -1
- package/dist/src/internal/nitro/host/build-application.js +1 -1
- package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
- package/dist/src/internal/workflow-bundle/eve-service-route-output.d.ts +1 -2
- package/dist/src/internal/workflow-bundle/eve-service-route-output.js +1 -54
- package/dist/src/internal/workflow-bundle/vercel-workflow-output.js +1 -1
- package/dist/src/packages/eve-catalog/src/index.js +1 -1
- package/dist/src/public/definitions/extension.d.ts +4 -4
- package/dist/src/public/definitions/remote-agent.d.ts +11 -2
- package/dist/src/public/index.d.ts +1 -1
- package/dist/src/public/models/openai/chatgpt/auth.d.ts +69 -0
- package/dist/src/public/models/openai/chatgpt/auth.js +1 -0
- package/dist/src/public/models/openai/chatgpt/model.d.ts +8 -0
- package/dist/src/public/models/openai/chatgpt/model.js +1 -0
- package/dist/src/public/models/openai/chatgpt/transport.d.ts +24 -0
- package/dist/src/public/models/openai/chatgpt/transport.js +1 -0
- package/dist/src/public/models/openai/chatgpt/unsigned-jwt.d.ts +5 -0
- package/dist/src/public/models/openai/chatgpt/unsigned-jwt.js +1 -0
- package/dist/src/public/models/openai/index.d.ts +30 -0
- package/dist/src/public/models/openai/index.js +1 -0
- package/dist/src/public/next/index.d.ts +38 -3
- package/dist/src/public/next/index.js +1 -1
- package/dist/src/public/next/server.d.ts +1 -0
- package/dist/src/public/next/server.js +2 -1
- package/dist/src/public/next/vercel-output-config.d.ts +12 -3
- package/dist/src/public/next/vercel-output-config.js +1 -1
- package/dist/src/public/nuxt/dev-server.js +1 -1
- package/dist/src/public/sveltekit/dev-server.js +1 -1
- package/dist/src/react/use-eve-agent.d.ts +8 -1
- package/dist/src/react/use-eve-agent.js +1 -1
- package/dist/src/runtime/resolve-agent-graph.js +1 -1
- package/dist/src/setup/scaffold/connections/catalog.js +1 -1
- package/dist/src/setup/scaffold/create/extension.d.ts +30 -0
- package/dist/src/setup/scaffold/create/extension.js +34 -0
- package/dist/src/setup/scaffold/create/project.d.ts +2 -0
- package/dist/src/setup/scaffold/create/project.js +2 -2
- package/dist/src/setup/scaffold/index.d.ts +1 -0
- package/dist/src/setup/scaffold/index.js +1 -1
- package/dist/src/shared/agent-definition.d.ts +1 -1
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-eve-agent.d.ts +8 -1
- package/dist/src/svelte/use-eve-agent.js +1 -1
- package/dist/src/vue/index.js +1 -1
- package/dist/src/vue/use-eve-agent.d.ts +8 -1
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/docs/agent-config.md +1 -1
- package/docs/channels/slack.mdx +6 -0
- package/docs/concepts/sessions-runs-and-streaming.md +1 -1
- package/docs/extensions.md +42 -13
- package/docs/guides/client/streaming.mdx +1 -1
- package/docs/guides/frontend/nextjs.mdx +32 -7
- package/docs/guides/frontend/overview.mdx +7 -1
- package/docs/guides/hooks.md +9 -0
- package/docs/guides/remote-agents.md +23 -8
- package/docs/meta.json +0 -1
- package/docs/reference/cli.md +56 -22
- package/docs/reference/typescript-api.md +17 -0
- package/docs/subagents.mdx +1 -1
- package/package.json +10 -5
- package/dist/src/compiled/_chunks/workflow/attribute-changes-BnKD8Y3m.js +0 -20
- package/dist/src/compiled/_chunks/workflow/resume-hook-DjPY9VGg.js +0 -1
- package/dist/src/compiled/_chunks/workflow/run-BSANnUPR.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# eve
|
|
2
2
|
|
|
3
|
+
## 0.22.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- c8f00aa: Add `experimental_chatgpt` under the new `eve/models/openai` subpath: it returns an AI SDK language model served through the local Codex login (`codex login`), billed to the ChatGPT subscription, and defaults to `gpt-5.6-sol`. Direct provider API request errors now also surface their upstream message when one is available.
|
|
8
|
+
- 640cd8e: Keep provider streams moving while durable event writes are in flight. eve now coalesces only adjacent queued text or reasoning appends behind an ordered writer, preserving event order while avoiding one durable round trip per provider delta.
|
|
9
|
+
- a5b43e7: Add `eve extension init` and `eve extension build` for scaffolding and building extension packages.
|
|
10
|
+
- a325195: `limits.maxSubagentDepth` now defaults to `1` instead of `3`. Agents that rely on deeper default delegation should set `limits: { maxSubagentDepth: 3 }` (or another value) explicitly.
|
|
11
|
+
- 4f86a21: Persist AI SDK approval-resume response messages in session history so approved local tool results survive later provider requests.
|
|
12
|
+
- 3577534: Update the bundled Workflow runtime dependencies to their latest 5.0 beta releases.
|
|
13
|
+
- bd780bd: Update the bundled Workflow runtime to `@workflow/core@5.0.0-beta.30` and align its world packages.
|
|
14
|
+
|
|
15
|
+
## 0.22.4
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- b5aedaf: The shared integrations catalog gains 33 curated MCP connections from the Vercel Connect preset directory (Airtable, Stripe, Sentry, Supabase, Zapier, and more) for the docs integrations gallery, and the connection scaffolder now skips gallery-only catalog entries, so the `eve connections add` picker is unchanged.
|
|
20
|
+
- edc93cc: Keep the mounted extensions guide out of the docs sidebar for now. The page stays at `/docs/extensions`, but the feature isn't surfaced in the nav while its API stabilizes.
|
|
21
|
+
- f00f084: Add named multi-agent routing to `withEve` and `useEveAgent`. Next.js apps can now configure multiple eve roots with `agents`, then target one from the frontend with `useEveAgent({ agent: "name" })`.
|
|
22
|
+
- f83d47d: `defineRemoteAgent` now accepts a function for `url`, resolved at runtime instead of baked at compile time. Return a `string` (or `Promise<string>`) from `() => process.env.MY_SERVICE_URL` to target an endpoint supplied by a runtime env var, known only once the deployment runs.
|
|
23
|
+
|
|
3
24
|
## 0.22.3
|
|
4
25
|
|
|
5
26
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -135,6 +135,8 @@ CLI commands:
|
|
|
135
135
|
- `eve build` — compile `.eve/` and build the host output
|
|
136
136
|
- `eve start` — serve the built `.output/` app
|
|
137
137
|
- `eve dev` — start the local runtime and REPL
|
|
138
|
+
- `eve extension init <name>` — create a new extension package
|
|
139
|
+
- `eve extension build` — build an extension package
|
|
138
140
|
|
|
139
141
|
## Deploying
|
|
140
142
|
|
|
@@ -1126,6 +1126,20 @@ function toTerminalStreamFailureError(event) {
|
|
|
1126
1126
|
return error;
|
|
1127
1127
|
}
|
|
1128
1128
|
|
|
1129
|
+
//#endregion
|
|
1130
|
+
//#region src/client/agent-host.ts
|
|
1131
|
+
const AGENT_NAME_PATTERN = /^[a-z0-9][a-z0-9_-]*$/;
|
|
1132
|
+
const EVE_NAMED_AGENT_ROUTE_PREFIX = "/eve/agents";
|
|
1133
|
+
function resolveEveAgentHost(input) {
|
|
1134
|
+
if (input.agent === void 0) return input.host ?? "";
|
|
1135
|
+
if (input.host !== void 0) throw new Error("useEveAgent cannot combine agent and host. Use one target option.");
|
|
1136
|
+
assertValidAgentName(input.agent);
|
|
1137
|
+
return `${EVE_NAMED_AGENT_ROUTE_PREFIX}/${input.agent}`;
|
|
1138
|
+
}
|
|
1139
|
+
function assertValidAgentName(name) {
|
|
1140
|
+
if (!AGENT_NAME_PATTERN.test(name)) throw new Error(`eve agent name ${JSON.stringify(name)} is invalid. Use lowercase letters, numbers, underscores, or hyphens, starting with a letter or number.`);
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1129
1143
|
//#endregion
|
|
1130
1144
|
//#region src/client/authorization-message-parts.ts
|
|
1131
1145
|
function createAuthorizationRequiredPart(event) {
|
|
@@ -1581,7 +1595,10 @@ function useEveAgent(options = {}) {
|
|
|
1581
1595
|
const store = new EveAgentStore({
|
|
1582
1596
|
auth: options.auth,
|
|
1583
1597
|
headers: options.headers,
|
|
1584
|
-
host:
|
|
1598
|
+
host: resolveEveAgentHost({
|
|
1599
|
+
agent: options.agent,
|
|
1600
|
+
host: options.host
|
|
1601
|
+
}),
|
|
1585
1602
|
initialEvents: options.initialEvents,
|
|
1586
1603
|
initialSession: options.initialSession,
|
|
1587
1604
|
maxReconnectAttempts: options.maxReconnectAttempts,
|
|
@@ -1126,6 +1126,20 @@ function toTerminalStreamFailureError(event) {
|
|
|
1126
1126
|
return error;
|
|
1127
1127
|
}
|
|
1128
1128
|
|
|
1129
|
+
//#endregion
|
|
1130
|
+
//#region src/client/agent-host.ts
|
|
1131
|
+
const AGENT_NAME_PATTERN = /^[a-z0-9][a-z0-9_-]*$/;
|
|
1132
|
+
const EVE_NAMED_AGENT_ROUTE_PREFIX = "/eve/agents";
|
|
1133
|
+
function resolveEveAgentHost(input) {
|
|
1134
|
+
if (input.agent === void 0) return input.host ?? "";
|
|
1135
|
+
if (input.host !== void 0) throw new Error("useEveAgent cannot combine agent and host. Use one target option.");
|
|
1136
|
+
assertValidAgentName(input.agent);
|
|
1137
|
+
return `${EVE_NAMED_AGENT_ROUTE_PREFIX}/${input.agent}`;
|
|
1138
|
+
}
|
|
1139
|
+
function assertValidAgentName(name) {
|
|
1140
|
+
if (!AGENT_NAME_PATTERN.test(name)) throw new Error(`eve agent name ${JSON.stringify(name)} is invalid. Use lowercase letters, numbers, underscores, or hyphens, starting with a letter or number.`);
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1129
1143
|
//#endregion
|
|
1130
1144
|
//#region src/client/authorization-message-parts.ts
|
|
1131
1145
|
function createAuthorizationRequiredPart(event) {
|
|
@@ -1630,7 +1644,10 @@ function useEveAgent(options = {}) {
|
|
|
1630
1644
|
const store = new EveAgentStore({
|
|
1631
1645
|
auth: options.auth,
|
|
1632
1646
|
headers: options.headers,
|
|
1633
|
-
host:
|
|
1647
|
+
host: resolveEveAgentHost({
|
|
1648
|
+
agent: options.agent,
|
|
1649
|
+
host: options.host
|
|
1650
|
+
}),
|
|
1634
1651
|
initialEvents: options.initialEvents,
|
|
1635
1652
|
initialSession: options.initialSession,
|
|
1636
1653
|
maxReconnectAttempts: options.maxReconnectAttempts,
|
|
@@ -17,3 +17,18 @@ export declare function initAgentDevHandoff(options: {
|
|
|
17
17
|
export declare function initAgentReplPrompt(options: {
|
|
18
18
|
devCommand: string;
|
|
19
19
|
}): string;
|
|
20
|
+
/**
|
|
21
|
+
* Pre-scaffold guide for a coding agent that ran `eve extension init` with no
|
|
22
|
+
* target. Mirrors agent bare-init: collect a package name, then re-run with it.
|
|
23
|
+
*/
|
|
24
|
+
export declare function initExtensionInstructions(): string;
|
|
25
|
+
/**
|
|
26
|
+
* Post-scaffold handoff after `eve extension init`. Same text for human and
|
|
27
|
+
* coding-agent launches: what was written and what to do next. Never assumes
|
|
28
|
+
* `eve dev`.
|
|
29
|
+
*/
|
|
30
|
+
export declare function initExtensionHandoff(options: {
|
|
31
|
+
packageManager: string;
|
|
32
|
+
packageName: string;
|
|
33
|
+
projectPath: string;
|
|
34
|
+
}): string;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import{readFileSync}from"node:fs";const SETUP_SECTIONS=[`intro-setup.md`,`collect-intent.md`,`vercel-connect.md`,`scaffold.md`,`build-and-verify.md`],HANDOFF_SECTIONS=[`intro-handoff.md`,`collect-intent.md`,`vercel-connect.md`,`build-and-verify.md`];function compose(t,n){let r=t.map(t=>readFileSync(new URL(`./agent-prompt/${t}`,import.meta.url),`utf8`).trim()).join(`
|
|
2
2
|
|
|
3
|
-
`).replaceAll(`{{devCommand}}`,()=>n.devCommand),{workingDirectory:i}=n;return i===void 0?r:r.replaceAll(`{{workingDirectory}}`,()=>i)}function initAgentInstructions(){return compose(SETUP_SECTIONS,{devCommand:`npx eve dev`})}function initAgentDevHandoff(e){return compose(HANDOFF_SECTIONS,{devCommand:e.devCommand,workingDirectory:e.projectPath})}function initAgentReplPrompt(e){return compose(HANDOFF_SECTIONS,{devCommand:e.devCommand,workingDirectory:`.`})}
|
|
3
|
+
`).replaceAll(`{{devCommand}}`,()=>n.devCommand),{workingDirectory:i}=n;return i===void 0?r:r.replaceAll(`{{workingDirectory}}`,()=>i)}function initAgentInstructions(){return compose(SETUP_SECTIONS,{devCommand:`npx eve dev`})}function initAgentDevHandoff(e){return compose(HANDOFF_SECTIONS,{devCommand:e.devCommand,workingDirectory:e.projectPath})}function initAgentReplPrompt(e){return compose(HANDOFF_SECTIONS,{devCommand:e.devCommand,workingDirectory:`.`})}function initExtensionInstructions(){return[`You are scaffolding an eve extension package (a reusable package of tools,`,`connections, skills, and hooks that a consuming agent mounts under`,`agent/extensions/).`,``,`Ask the user for a package directory name, then run:`,``,` npx eve@latest extension init <name>`,``,`That creates the package, installs dependencies, and initializes Git. It`,`prints what was set up and how to author, build, and mount the extension —`,`it does not start eve dev (extensions are not standalone agents).`,``,"Build with `eve extension build` (or the package `build` script)."].join(`
|
|
4
|
+
`)}function initExtensionHandoff(e){return[``,`What we set up:`,` - package.json with eve.extension → ./extension, peer+dev eve, and zod`,` - extension/extension.ts (config schema via defineExtension)`,` - build/prepare scripts → eve extension build`,``,`Next:`,` - Add tools, skills, hooks, or connections under extension/`,` (see AGENTS.md and node_modules/eve/docs/extensions.md)`,` - ${`${e.packageManager} run build`} # fills dist/ and package exports`,` - Mount from a consumer agent:`,` // agent/extensions/${e.packageName}.ts`,` import ext from "${e.packageName}";`,` export default ext({ apiKey: process.env.API_KEY });`,``,`Working directory: ${e.projectPath}`].join(`
|
|
5
|
+
`)}export{HANDOFF_SECTIONS,SETUP_SECTIONS,initAgentDevHandoff,initAgentInstructions,initAgentReplPrompt,initExtensionHandoff,initExtensionInstructions};
|
|
@@ -13,6 +13,9 @@ This creates the project, installs its dependencies, and initializes Git. Since
|
|
|
13
13
|
coding agent launched init, it prints a development handoff instead of starting
|
|
14
14
|
the interactive terminal UI.
|
|
15
15
|
|
|
16
|
+
If the user wants a reusable extension package instead of an agent, run
|
|
17
|
+
`npx eve@latest extension init <name>` and follow that command's next steps.
|
|
18
|
+
|
|
16
19
|
For an existing app, run `npx eve@latest init .` from its directory. This adds the
|
|
17
20
|
agent and missing dependencies while leaving the existing Git repository and app
|
|
18
21
|
scripts alone. If init cannot be used, install by hand with
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface ExtensionBuildCliLogger {
|
|
2
|
+
error(message: string): void;
|
|
3
|
+
log(message: string): void;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Builds the current package as an eve extension. Requires
|
|
7
|
+
* `package.json#eve.extension` pointing at the source root (e.g. `./extension`).
|
|
8
|
+
*/
|
|
9
|
+
export declare function runExtensionBuildCommand(logger: ExtensionBuildCliLogger, appRoot: string): Promise<void>;
|
|
@@ -0,0 +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{createLogger}from"#internal/logging.js";import{createCliTheme,renderCliTaggedLine}from"#cli/ui/output.js";import{buildExtensionPackage,tryReadExtensionBuildConfig}from"#internal/nitro/host/build-extension.js";var import_picocolors=__toESM(require_picocolors(),1);const buildLog=createLogger(`extension-build`);async function runExtensionBuildCommand(e,t){let n=await tryReadExtensionBuildConfig(t);if(n===null)throw Error('This package is not an eve extension. Add `"eve": { "extension": "./extension" }` to package.json, or run `eve build` for an agent app.');buildLog.debug(`building extension package`,{packageName:n.packageName,sourceRoot:n.sourceRoot});let r=await buildExtensionPackage(t,n),i=createCliTheme();e.log(renderCliTaggedLine(i,{message:`built extension ${import_picocolors.default.bold(n.packageName)} at ${r}`,tag:`build`,tone:`success`}))}export{runExtensionBuildCommand};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { isCodingAgentLaunch } from "#cli/agent-detection.js";
|
|
2
|
+
import { detectInvokingPackageManager, detectPackageManager } from "#setup/package-manager.js";
|
|
3
|
+
import { runPackageManagerInstall } from "#setup/primitives/index.js";
|
|
4
|
+
import { scaffoldExtensionProject } from "#setup/scaffold/index.js";
|
|
5
|
+
import { tryInitializeGit } from "./init-git.js";
|
|
6
|
+
export interface ExtensionInitCliLogger {
|
|
7
|
+
error(message: string): void;
|
|
8
|
+
log(message: string): void;
|
|
9
|
+
}
|
|
10
|
+
export interface ExtensionInitCommandDependencies {
|
|
11
|
+
detectInvokingPackageManager: typeof detectInvokingPackageManager;
|
|
12
|
+
detectPackageManager: typeof detectPackageManager;
|
|
13
|
+
isCodingAgentLaunch: typeof isCodingAgentLaunch;
|
|
14
|
+
now: () => number;
|
|
15
|
+
runPackageManagerInstall: typeof runPackageManagerInstall;
|
|
16
|
+
scaffoldExtensionProject: typeof scaffoldExtensionProject;
|
|
17
|
+
tryInitializeGit: typeof tryInitializeGit;
|
|
18
|
+
}
|
|
19
|
+
/** Same override env as agent `eve init` so CI can pin the eve package specifier. */
|
|
20
|
+
export declare const EVE_INIT_PACKAGE_SPEC_ENV = "EVE_INIT_PACKAGE_SPEC";
|
|
21
|
+
/**
|
|
22
|
+
* Creates a new eve extension package. Same install/git flow as agent `eve init`,
|
|
23
|
+
* but always create-only and prints next steps instead of starting `eve dev`.
|
|
24
|
+
*/
|
|
25
|
+
export declare function runExtensionInitCommand(logger: ExtensionInitCliLogger, parentDirectory: string, target: string | undefined, dependencies?: ExtensionInitCommandDependencies): Promise<void>;
|
|
@@ -0,0 +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{initExtensionHandoff,initExtensionInstructions}from"./agent-instructions.js";import{tryInitializeGit}from"./init-git.js";import{createLogger,isLogLevelEnabled}from"#internal/logging.js";import{basename,join,resolve}from"node:path";import{scaffoldExtensionProject}from"#setup/scaffold/index.js";import{mkdtemp,readdir,rename,rm,stat}from"node:fs/promises";import{performance}from"node:perf_hooks";import{isCodingAgentLaunch}from"#cli/agent-detection.js";import{EVE_WORDMARK}from"#cli/banner.js";import{formatElapsed}from"#cli/format-elapsed.js";import{startCliLiveRow}from"#cli/ui/live-row.js";import{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{runPackageManagerInstall}from"#setup/primitives/index.js";import{DEFAULT_EVE_PACKAGE_CONTRACT}from"#setup/scaffold/create/project.js";var import_picocolors=__toESM(require_picocolors(),1);const defaultDependencies={detectInvokingPackageManager,detectPackageManager,isCodingAgentLaunch,now:()=>performance.now(),runPackageManagerInstall,scaffoldExtensionProject,tryInitializeGit},ALLOWED_CREATE_IN_PLACE_ENTRIES=new Set([`.DS_Store`,`.git`,`.gitkeep`,`.hg`]),EVE_INIT_PACKAGE_SPEC_ENV=`EVE_INIT_PACKAGE_SPEC`,initLog=createLogger(`extension-init`);function isCurrentDirectoryTarget(e){return/^\.(?:[/\\]+\.?)*$/u.test(e.trim())}async function resolveTargetDirectory(e,t){let n=resolve(e,t);return(await stat(n).catch(()=>void 0))?.isDirectory()?n:void 0}async function assertCanScaffoldInPlace(e){let t=(await readdir(e)).filter(e=>!ALLOWED_CREATE_IN_PLACE_ENTRIES.has(e));if(t.length===0)return;let n=t.slice(0,5).join(`, `),r=t.length>5?`, and ${t.length-5} more`:``;throw Error(`Cannot create project in current directory because it is not empty. Found: ${n}${r}. Use an empty directory.`)}async function moveDirectoryContents(e,t){for(let n of await readdir(e))await rename(join(e,n),join(t,n))}function uniqueWorkspaceRootMutations(e){let t=new Map;for(let n of e){let e=`${n.kind}:${n.path}`,r=t.get(e);t.set(e,{...n,nodeEngineOverride:n.nodeEngineOverride??r?.nodeEngineOverride})}return[...t.values()]}function formatWorkspaceRootMutationWarning(e){let t=e.kind===`package-json`?`package.json`:`configuration`,n=e.nodeEngineOverride===void 0?``:` (${formatNodeEngineOverrideWarning(e.nodeEngineOverride)})`;return`Updated workspace root ${t} at ${e.path}${n}`}async function resolveScaffoldPackageManager(e,t){let n=await t.detectPackageManager(e);return n.source==="default"?t.detectInvokingPackageManager()??`pnpm`:n.kind}async function scaffoldExtension(e,t,n,r,i){let a=resolve(e),o=t===`.`,c=o?a:join(a,t);if(o)await assertCanScaffoldInPlace(c);else if(await pathExists(c))throw Error(`Cannot create project because "${c}" already exists.`);let u=await mkdtemp(join(a,`.eve-extension-init-`)),p=[];try{let e=o?basename(c):t,a=await r.scaffoldExtensionProject({projectName:e,evePackage:i,targetDirectory:u,workspaceProbeDirectory:c,packageManager:n,onWorkspaceRootMutation:e=>{p.push(e)}});return o?await moveDirectoryContents(a,c):await rename(a,c),{projectPath:c,workspaceRootMutations:uniqueWorkspaceRootMutations(p)}}finally{await rm(u,{recursive:!0,force:!0})}}function installProgressDetail(e,t){let n=t.text.trim();if(n===``||e!==`npm`)return n||void 0;let r=/^npm silly fetch manifest (.+)$/u.exec(n);if(r!==null)return`Resolving ${r[1]}`;let i=/^npm http fetch \S+ \S+ attempt (\d+) failed with (\S+)$/u.exec(n);if(i!==null)return`npm registry · attempt ${i[1]} failed: ${i[2]}`;if(t.stream===`stdout`||/^npm (?:error|warn)\b/u.test(n))return n}const NPM_NOISE_LINE=/^\s*npm (?:silly|verbose|http|timing)\b/u;function resolveInitEvePackageOverride(){let e=process.env[EVE_INIT_PACKAGE_SPEC_ENV]?.trim();if(!(e===void 0||e.length===0))return{nodeEngine:DEFAULT_EVE_PACKAGE_CONTRACT.nodeEngine,version:e}}async function runExtensionInitCommand(e,t,i,a=defaultDependencies){if(i===void 0&&await a.isCodingAgentLaunch()){e.log(initExtensionInstructions());return}let c=isLogLevelEnabled(`debug`),l=startCliLiveRow(e);l.update(`Preparing project`);let u,d,f=[],p,m,h;try{let n=i??`.`,r=isCurrentDirectoryTarget(n),o=r?await pathExists(join(resolve(t),`package.json`))?resolve(t):void 0:await resolveTargetDirectory(t,n),s=resolveInitEvePackageOverride();if(o!==void 0)throw Error("`eve extension init` creates a new extension package and cannot add to an existing project. Pass a new directory name, or run from an empty directory with `eve extension init .`.");l.update(`Creating extension`),initLog.debug(`creating extension`);let g=a.now(),_=r?`.`:parseProjectName(n),v=resolve(t);d=await resolveScaffoldPackageManager(_===`.`?v:join(v,_),a);let y=await scaffoldExtension(t,_,d,a,s);u=y.projectPath,f=y.workspaceRootMutations,p=a.now()-g,initLog.debug(`creating extension done`,{ms:p}),l.update(`Installing dependencies`,`${d} install`),initLog.debug(`installing dependencies with ${d}`);let b=a.now(),x=[],S=[],C=await a.runPackageManagerInstall(d,u,{bypassMinimumReleaseAge:!0,progressDetails:process.stdout.isTTY===!0&&!c,onOutput:e=>{e.text.trim()!==``&&(S.push(e.text),S.length>20&&S.shift(),NPM_NOISE_LINE.test(e.text)||x.push(e.text)),c&&initLog.debug(e.text);let t=installProgressDetail(d,e);t!==void 0&&l.update(`Installing dependencies`,t)}});if(m=a.now()-b,!C){initLog.debug(`dependency installation failed`,{ms:m}),l.stop();let t=x.length>0?x:S;for(let n of t)e.error(n);throw Error(`Failed to install dependencies in "${u}".`)}initLog.debug(`dependencies installed`,{ms:m}),l.update(`Initializing Git repository`),initLog.debug(`initializing git repository`),h=await a.tryInitializeGit(u)}finally{l.stop()}e.log(`${import_picocolors.default.green(`✓`)} Created an ${EVE_WORDMARK} extension in ${import_picocolors.default.bold(u)} ${import_picocolors.default.dim(`in ${formatElapsed(p)}`)}`);for(let t of f)e.log(import_picocolors.default.yellow(`⚠ ${formatWorkspaceRootMutationWarning(t)}`));e.log(`${import_picocolors.default.green(`✓`)} Installed dependencies ${import_picocolors.default.dim(`in ${formatElapsed(m)}`)}`),h.kind===`failed`?e.error(import_picocolors.default.yellow(`Git initialization failed: ${h.reason}`)):h.kind===`initialized`&&e.log(`${import_picocolors.default.green(`✓`)} Initialized Git repository`),e.log(initExtensionHandoff({packageManager:d,packageName:basename(u),projectPath:u}))}export{EVE_INIT_PACKAGE_SPEC_ENV,runExtensionInitCommand};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{createCliTheme,renderCliBanner,renderCliSection}from"#cli/ui/output.js";import{inspectApplication}from"#services/inspect-application.js";function buildApplicationInfoJson(e){let{application:t,compiledState:n,messaging:r}=e;return{appRoot:t.appRoot,agentRoot:n?.project.agentRoot??null,layout:n?.project.layout??null,status:n?.metadata.status??`unavailable`,diagnostics:n?{errors:n.metadata.discovery.summary.errors,warnings:n.metadata.discovery.summary.warnings}:null,model:n?.manifest.config.model.id??null,instructions:n?.manifest.instructions?.logicalPath??null,skills:(n?.manifest.skills??[]).map(e=>e.name),tools:(n?.manifest.tools??[]).map(e=>e.name),channels:(n?.manifest.channels??[]).map(e=>e.kind===`channel`?{name:e.name,kind:e.adapterKind??null,method:e.method,urlPath:e.urlPath}:{name:e.name,kind:`disabled`,method:null,urlPath:null}),messaging:{create:r.createSessionRoutePath,continue:r.continueSessionRoutePattern,stream:r.streamRoutePattern},artifacts:n?{compiledManifest:n.paths.compiledManifestPath,discoveryManifest:n.paths.discoveryManifestPath,diagnostics:n.paths.diagnosticsPath,moduleMap:n.paths.moduleMapPath,metadata:n.paths.compileMetadataPath}:null}}function pluralize(e,t){return`${e} ${t}${e===1?``:`s`}`}function formatDiscoverySummary(e,t){return`${pluralize(e,`error`)}, ${pluralize(t,`warning`)}`}function resolveCompileTone(e){switch(e){case`ready`:return`success`;case`failed`:return`danger`;default:return`warning`}}async function printApplicationInfo(i,a,o={}){let s=await inspectApplication(a);if(o.json){i.log(JSON.stringify(buildApplicationInfoJson(s),null,2));return}let c=s.compiledState,l=s.application,u=createCliTheme(),d=[{label:`App Root`,value:l.appRoot}],f=[{label:`Workflow Build`,value:l.workflowBuildDir},{label:`Output`,value:l.outputDir}],p=[];c===null?d.push({label:`Compile`,tone:`warning`,value:`unavailable`}):(d.push({label:`Agent Root`,value:c.project.agentRoot},{label:`Layout`,value:c.project.layout},{label:`Compile`,tone:resolveCompileTone(c.metadata.status),value:c.metadata.status},{label:`Diagnostics`,tone:c.metadata.discovery.summary.errors>0?`danger`:c.metadata.discovery.summary.warnings>0?`warning`:`success`,value:formatDiscoverySummary(c.metadata.discovery.summary.errors,c.metadata.discovery.summary.warnings)},{label:`Instructions`,value:c.manifest.instructions?.logicalPath??`none`},{label:`Skills`,value:pluralize(c.manifest.skills.length,`skill`)}),f.unshift({label:`Compiled Manifest`,value:c.paths.compiledManifestPath},{label:`Discovery Manifest`,value:c.paths.discoveryManifestPath},{label:`Diagnostics`,value:c.paths.diagnosticsPath},{label:`Module Map`,value:c.paths.moduleMapPath},{label:`Metadata`,value:c.paths.compileMetadataPath}),p.push(c.manifest.instructions===void 0?{label:`Instructions`,value:`No instructions prompt discovered.`}:{label:`Instructions`,value:c.manifest.instructions.logicalPath})),i.log([renderCliBanner(u,{subtitle:`Resolved application paths and the active message contract.`,title:`eve Info`}),``,renderCliSection(u,{rows:d,title:`Application`}),``,renderCliSection(u,{rows:f,title:`Artifacts`}),...c===null?[]:[``,renderCliSection(u,{rows:p,title:`Instructions`})],``,renderCliSection(u,{rows:[{label:`Workflow ID`,value:l.workflowId},{label:`Source Dir`,value:l.workflowSourceDir},{label:`Create`,tone:`info`,value:`POST ${s.messaging.createSessionRoutePath}`},{label:`Continue`,tone:`info`,value:`POST ${s.messaging.continueSessionRoutePattern}`},{label:`Stream`,tone:`info`,value:`GET ${s.messaging.streamRoutePattern}`}],title:`Messaging`})].join(`
|
|
2
2
|
`))}export{buildApplicationInfoJson,printApplicationInfo};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{join}from"node:path";import{
|
|
1
|
+
import{join}from"node:path";import{rm}from"node:fs/promises";import{execFile}from"node:child_process";import{promisify}from"node:util";const GIT_TIMEOUT_MS=5e3,runFile=promisify(execFile);async function commandSucceeds(e,t,n){try{let r={timeout:GIT_TIMEOUT_MS,windowsHide:!0};return n!==void 0&&(r.cwd=n),await runFile(e,[...t],r),!0}catch{return!1}}function isGitAvailable(){return commandSucceeds(`git`,[`--version`])}async function isInsideExistingRepository(e){return await commandSucceeds(`git`,[`rev-parse`,`--is-inside-work-tree`],e)||await commandSucceeds(`hg`,[`--cwd`,`.`,`root`],e)}function hasConfiguredDefaultBranch(e){return commandSucceeds(`git`,[`config`,`init.defaultBranch`],e)}async function runGit(e,t){await runFile(`git`,[...t],{cwd:e,timeout:GIT_TIMEOUT_MS,windowsHide:!0})}async function tryInitializeGit(n){if(!await isGitAvailable()||await isInsideExistingRepository(n))return{kind:`skipped`};let r=!1;try{return await runGit(n,[`init`]),r=!0,await hasConfiguredDefaultBranch(n)||await runGit(n,[`checkout`,`-b`,`main`]),await runGit(n,[`add`,`-A`]),await runGit(n,[`commit`,`-m`,`Initial commit from eve`]),{kind:`initialized`}}catch(i){return r&&await rm(join(n,`.git`),{recursive:!0,force:!0}).catch(()=>{}),{kind:`failed`,reason:i instanceof Error?i.message:String(i)}}}export{tryInitializeGit};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{hasInteractiveTerminal}from"./preconditions.js";import{constants}from"node:fs";import{delimiter,extname,join}from"node:path";import{createPrompter}from"#setup/prompter.js";import{
|
|
1
|
+
import{hasInteractiveTerminal}from"./preconditions.js";import{constants}from"node:fs";import{delimiter,extname,join}from"node:path";import{createPrompter}from"#setup/prompter.js";import{access,stat}from"node:fs/promises";import{spawn}from"node:child_process";const positional=e=>[e],CODING_AGENT_REPLS=[{command:`claude`,label:`Claude Code`,promptArgs:positional},{command:`codex`,label:`Codex`,promptArgs:positional},{command:`cursor-agent`,label:`Cursor`,promptArgs:positional},{command:`droid`,label:`Droid`,promptArgs:positional},{command:`gemini`,label:`Gemini CLI`,promptArgs:e=>[`-i`,e]},{command:`opencode`,label:`opencode`,promptArgs:e=>[`--prompt`,e]},{command:`pi`,label:`Pi`,promptArgs:positional}],WINDOWS_EXECUTABLE_EXTENSIONS=[`.COM`,`.EXE`,`.BAT`,`.CMD`],defaultDependencies={createPrompter,hasInteractiveTerminal,isCodingAgentReplAvailable};function executableNames(e){if(process.platform!==`win32`)return[e];let t=process.env.PATHEXT?.split(`;`).filter(Boolean);return(t&&t.length>0?t:WINDOWS_EXECUTABLE_EXTENSIONS).map(t=>`${e}${t}`)}async function isExecutable(e){try{return(await stat(e)).isFile()?(await access(e,constants.X_OK),!0):!1}catch{return!1}}async function resolveCodingAgentRepl(e){let t=process.env.PATH;if(t===void 0||t.length===0)return null;for(let r of t.split(delimiter))if(r.length!==0)for(let t of executableNames(e)){let e=join(r,t);if(await isExecutable(e))return e}return null}async function isCodingAgentReplAvailable(e){return await resolveCodingAgentRepl(e)!==null}function handoffOptions(e,t){return[{value:`eve-dev`,label:`Start eve dev`,focusHint:`talk to '${t}' in your terminal`},...e.map(e=>({value:e.command,label:`Open ${e.label}`,focusHint:`build '${t}' using ${e.label}`}))]}async function selectInitHandoff(e){let t={...defaultDependencies,...e.deps};if(!t.hasInteractiveTerminal())return`eve-dev`;let n=await Promise.all(CODING_AGENT_REPLS.map(({command:e})=>t.isCodingAgentReplAvailable(e))),r=CODING_AGENT_REPLS.filter((e,t)=>n[t]);return r.length===0?`eve-dev`:t.createPrompter().select({message:`How would you like to continue?`,options:handoffOptions(r,e.agentName),initialValue:`eve-dev`})}function codingAgentRepl(e){let t=CODING_AGENT_REPLS.find(t=>t.command===e);if(t===void 0)throw Error(`Unsupported coding-agent REPL "${e}".`);return t}function isDirectlySpawnable(e,t){if(t!==`win32`)return!0;let n=extname(e).toLowerCase();return n===`.exe`||n===`.com`}function replSpawnPlan(e,t,n,r=process.platform){return t!==null&&isDirectlySpawnable(t,r)?{file:t,args:codingAgentRepl(e).promptArgs(n),shell:!1,seeded:!0}:{file:e,args:[],shell:r===`win32`,seeded:!1}}async function spawnCodingAgentRepl(e){let t=e.resolvePath??resolveCodingAgentRepl,n=replSpawnPlan(e.command,await t(e.command),e.prompt);return n.seeded||e.onPromptUnseeded?.(e.prompt),new Promise(t=>{let r=spawn(n.file,n.args,{cwd:e.cwd,shell:n.shell,stdio:`inherit`}),i=!1,settle=e=>{i||(i=!0,t(e))};r.once(`error`,()=>settle(!1)),r.once(`close`,e=>settle(e===0))})}export{isCodingAgentReplAvailable,replSpawnPlan,resolveCodingAgentRepl,selectInitHandoff,spawnCodingAgentRepl};
|
|
@@ -38,5 +38,7 @@ export declare const EVE_INIT_PACKAGE_SPEC_ENV = "EVE_INIT_PACKAGE_SPEC";
|
|
|
38
38
|
* A coding agent that omits the target entirely gets the setup guide printed and
|
|
39
39
|
* nothing scaffolded, since a bare `eve init` means it has not yet chosen what to
|
|
40
40
|
* build.
|
|
41
|
+
*
|
|
42
|
+
* For extension packages, use `eve extension init` instead.
|
|
41
43
|
*/
|
|
42
44
|
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{initAgentDevHandoff,initAgentInstructions,initAgentReplPrompt}from"./agent-instructions.js";import{tryInitializeGit}from"./init-git.js";import{selectInitHandoff,spawnCodingAgentRepl}from"./init-repl.js";import{createLogger,isLogLevelEnabled}from"#internal/logging.js";import{basename,join,resolve}from"node:path";import{ensureChannel,scaffoldBaseProject}from"#setup/scaffold/index.js";import{mkdtemp,readdir,rename,rm,stat}from"node:fs/promises";import{performance}from"node:perf_hooks";import{isCodingAgentLaunch}from"#cli/agent-detection.js";import{EVE_WORDMARK}from"#cli/banner.js";import{formatElapsed}from"#cli/format-elapsed.js";import{startCliLiveRow}from"#cli/ui/live-row.js";import{
|
|
1
|
+
import{__toESM}from"../../_virtual/_rolldown/runtime.js";import{require_picocolors}from"../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js";import{initAgentDevHandoff,initAgentInstructions,initAgentReplPrompt}from"./agent-instructions.js";import{tryInitializeGit}from"./init-git.js";import{selectInitHandoff,spawnCodingAgentRepl}from"./init-repl.js";import{createLogger,isLogLevelEnabled}from"#internal/logging.js";import{basename,join,resolve}from"node:path";import{ensureChannel,scaffoldBaseProject}from"#setup/scaffold/index.js";import{mkdtemp,readdir,rename,rm,stat}from"node:fs/promises";import{performance}from"node:perf_hooks";import{isCodingAgentLaunch}from"#cli/agent-detection.js";import{EVE_WORDMARK}from"#cli/banner.js";import{formatElapsed}from"#cli/format-elapsed.js";import{startCliLiveRow}from"#cli/ui/live-row.js";import{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{DEFAULT_EVE_PACKAGE_CONTRACT}from"#setup/scaffold/create/project.js";import{DEFAULT_AGENT_MODEL_ID}from"#shared/default-agent-model.js";import{addAgentToProject}from"#setup/scaffold/create/add-to-project.js";import{WizardCancelledError}from"#setup/step.js";var import_picocolors=__toESM(require_picocolors(),1);const defaultDependencies={addAgentToProject,detectInvokingPackageManager,detectPackageManager,ensureChannel,isCodingAgentLaunch,now:()=>performance.now(),runPackageManagerInstall,scaffoldBaseProject,selectInitHandoff,spawnCodingAgentRepl,spawnPackageManager,tryInitializeGit},ALLOWED_CREATE_IN_PLACE_ENTRIES=new Set([`.DS_Store`,`.git`,`.gitkeep`,`.hg`]),EVE_INIT_PACKAGE_SPEC_ENV=`EVE_INIT_PACKAGE_SPEC`,initLog=createLogger(`init`);async function resolveTargetDirectory(e,t){let n=resolve(e,t);return(await stat(n).catch(()=>void 0))?.isDirectory()?n:void 0}function isCurrentDirectoryTarget(e){return/^\.(?:[/\\]+\.?)*$/u.test(e.trim())}async function assertCanScaffoldInPlace(e){let t=(await readdir(e)).filter(e=>!ALLOWED_CREATE_IN_PLACE_ENTRIES.has(e));if(t.length===0)return;let n=t.slice(0,5).join(`, `),r=t.length>5?`, and ${t.length-5} more`:``;throw Error(`Cannot create project in current directory because it is not empty. Found: ${n}${r}. Use an empty directory.`)}async function moveDirectoryContents(e,t){for(let n of await readdir(e))await rename(join(e,n),join(t,n))}function uniqueWorkspaceRootMutations(e){let t=new Map;for(let n of e){let e=`${n.kind}:${n.path}`,r=t.get(e);t.set(e,{...n,nodeEngineOverride:n.nodeEngineOverride??r?.nodeEngineOverride})}return[...t.values()]}function formatWorkspaceRootMutationWarning(e){let t=e.kind===`package-json`?`package.json`:`configuration`,n=e.nodeEngineOverride===void 0?``:` (${formatNodeEngineOverrideWarning(e.nodeEngineOverride)})`;return`Updated workspace root ${t} at ${e.path}${n}`}async function addToExistingProject(e,t,n,r){if(t.channelWebNextjs===!0)throw Error("`--channel-web-nextjs` is not supported when adding an agent to an existing project. Run `eve channels add web` from the project afterwards instead.");let i=await n.detectPackageManager(e),a=await n.addAgentToProject({projectRoot:e,model:DEFAULT_AGENT_MODEL_ID,packageManager:i.kind,evePackage:r});return{packageManager:i.kind,nodeEngineOverride:a.nodeEngineOverride}}async function resolveScaffoldPackageManager(e,t){let n=await t.detectPackageManager(e);return n.source==="default"?t.detectInvokingPackageManager()??`pnpm`:n.kind}async function scaffoldProject(e,t,n,r,i,a){let o=resolve(e),s=t===`.`,c=s?o:join(o,t);if(s)await assertCanScaffoldInPlace(c);else if(await pathExists(c))throw Error(`Cannot create project because "${c}" already exists.`);let l=await mkdtemp(join(o,`.eve-init-`)),p=[];try{let e={projectName:s?basename(c):t,model:DEFAULT_AGENT_MODEL_ID,evePackage:a,targetDirectory:l,workspaceProbeDirectory:c,packageManager:n,onWorkspaceRootMutation:e=>{p.push(e)}},o=await i.scaffoldBaseProject(e);return r.channelWebNextjs===!0&&await i.ensureChannel({projectRoot:o,kind:`web`,packageManager:n,workspaceProbeDirectory:c,configureVercelServices:!1,onWorkspaceRootMutation:e=>{p.push(e)}}),s?await moveDirectoryContents(o,c):await rename(o,c),{projectPath:c,workspaceRootMutations:uniqueWorkspaceRootMutations(p)}}finally{await rm(l,{recursive:!0,force:!0})}}function installProgressDetail(e,t){let n=t.text.trim();if(n===``||e!==`npm`)return n||void 0;let r=/^npm silly fetch manifest (.+)$/u.exec(n);if(r!==null)return`Resolving ${r[1]}`;let i=/^npm http fetch \S+ \S+ attempt (\d+) failed with (\S+)$/u.exec(n);if(i!==null)return`npm registry · attempt ${i[1]} failed: ${i[2]}`;if(t.stream===`stdout`||/^npm (?:error|warn)\b/u.test(n))return n}const NPM_NOISE_LINE=/^\s*npm (?:silly|verbose|http|timing)\b/u;async function runInitSteps(e){let{dependencies:t,logger:n,options:r,parentDirectory:i,target:a}=e,o=isLogLevelEnabled(`debug`),s=startCliLiveRow(n);s.update(`Preparing project`);try{let e=await t.isCodingAgentLaunch(),c=a??`.`,l=isCurrentDirectoryTarget(c),u=l?await pathExists(join(resolve(i),`package.json`))?resolve(i):void 0:await resolveTargetDirectory(i,c),p=resolveInitEvePackageOverride(),m=u===void 0?`creating agent`:`adding agent`;s.update(u===void 0?`Creating agent`:`Adding agent`),initLog.debug(m);let h=t.now(),g;if(u===void 0){let e=l?`.`:parseProjectName(c),n=resolve(i),a=await resolveScaffoldPackageManager(e===`.`?n:join(n,e),t),o=await scaffoldProject(i,e,a,r,t,p);g={kind:`created`,packageManager:a,projectPath:o.projectPath,workspaceRootMutations:o.workspaceRootMutations}}else{let e=await addToExistingProject(u,r,t,p);g=e.nodeEngineOverride===void 0?{kind:`added`,packageManager:e.packageManager,projectPath:u}:{kind:`added`,nodeEngineOverride:e.nodeEngineOverride,packageManager:e.packageManager,projectPath:u}}let _=t.now()-h;initLog.debug(`${m} done`,{ms:_}),s.update(`Installing dependencies`,`${g.packageManager} install`),initLog.debug(`installing dependencies with ${g.packageManager}`);let v=t.now(),y=[],b=[],x=await t.runPackageManagerInstall(g.packageManager,g.projectPath,{bypassMinimumReleaseAge:!0,progressDetails:process.stdout.isTTY===!0&&!o,onOutput:e=>{e.text.trim()!==``&&(b.push(e.text),b.length>20&&b.shift(),NPM_NOISE_LINE.test(e.text)||y.push(e.text)),o&&initLog.debug(e.text);let t=installProgressDetail(g.packageManager,e);t!==void 0&&s.update(`Installing dependencies`,t)}}),S=t.now()-v;if(!x){initLog.debug(`dependency installation failed`,{ms:S}),s.stop();let e=y.length>0?y:b;for(let t of e)n.error(t);throw Error(`Failed to install dependencies in "${g.projectPath}".`)}return initLog.debug(`dependencies installed`,{ms:S}),g.kind===`created`?(s.update(`Initializing Git repository`),initLog.debug(`initializing git repository`),{...g,agentElapsedMs:_,agentLaunched:e,gitResult:await t.tryInitializeGit(g.projectPath),installElapsedMs:S}):{...g,agentElapsedMs:_,agentLaunched:e,installElapsedMs:S}}finally{s.stop()}}async function runInitCommand(e,t,a,o,s=defaultDependencies){if(a===void 0&&await s.isCodingAgentLaunch()){e.log(initAgentInstructions());return}let c=await runInitSteps({dependencies:s,logger:e,options:o,parentDirectory:t,target:a});if(c.kind===`created`){e.log(`${import_picocolors.default.green(`✓`)} Created an ${EVE_WORDMARK} agent in ${import_picocolors.default.bold(c.projectPath)} ${import_picocolors.default.dim(`in ${formatElapsed(c.agentElapsedMs)}`)}`);for(let t of c.workspaceRootMutations)e.log(import_picocolors.default.yellow(`⚠ ${formatWorkspaceRootMutationWarning(t)}`))}else e.log(`${import_picocolors.default.green(`✓`)} Added an ${EVE_WORDMARK} agent to ${import_picocolors.default.bold(c.projectPath)} ${import_picocolors.default.dim(`in ${formatElapsed(c.agentElapsedMs)}`)}`),c.nodeEngineOverride!==void 0&&e.log(import_picocolors.default.yellow(`⚠ ${formatNodeEngineOverrideWarning(c.nodeEngineOverride)}`));e.log(`${import_picocolors.default.green(`✓`)} Installed dependencies ${import_picocolors.default.dim(`in ${formatElapsed(c.installElapsedMs)}`)}`),c.kind===`created`&&c.gitResult.kind===`failed`&&e.error(import_picocolors.default.yellow(`Git initialization failed: ${c.gitResult.reason}`));let l=[c.packageManager,...eveDevArguments(c.packageManager)].join(` `),d=initAgentDevHandoff({projectPath:c.projectPath,devCommand:l});if(c.agentLaunched){e.log(d);return}let f;try{f=await s.selectInitHandoff({agentName:basename(c.projectPath)})}catch(e){if(e instanceof WizardCancelledError)return;throw e}if(f!==`eve-dev`){if(e.log(import_picocolors.default.dim(`$ ${f}`)),!await s.spawnCodingAgentRepl({command:f,cwd:c.projectPath,prompt:initAgentReplPrompt({devCommand:l}),onPromptUnseeded:t=>{e.log(import_picocolors.default.yellow(`Could not seed ${f} automatically. Paste this prompt into it:`)),e.log(t)}}))throw Error(`Coding-agent REPL exited unsuccessfully in "${c.projectPath}".`);return}let p=c.kind===`created`,m=p?[...eveDevArguments(c.packageManager),`--input`,`/model`]:eveDevArguments(c.packageManager);if(e.log(import_picocolors.default.dim(p?`$ eve dev --input /model`:`$ eve dev`)),!await s.spawnPackageManager(c.packageManager,c.projectPath,m))throw Error(`Development server exited unsuccessfully in "${c.projectPath}".`)}function resolveInitEvePackageOverride(){let e=process.env[EVE_INIT_PACKAGE_SPEC_ENV]?.trim();if(!(e===void 0||e.length===0))return{nodeEngine:DEFAULT_EVE_PACKAGE_CONTRACT.nodeEngine,version:e}}export{EVE_INIT_PACKAGE_SPEC_ENV,runInitCommand};
|
package/dist/src/cli/run.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{createLogger}from"#internal/logging.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{createCliTheme,renderCliTaggedLine}from"#cli/ui/output.js";import{isCodingAgentLaunch}from"#cli/agent-detection.js";import{eveCliBanner}from"#cli/banner.js";import{startCliLiveRow}from"#cli/ui/live-row.js";import{devBootPhase}from"#internal/dev-boot-progress.js";import{Command,CommanderError,InvalidArgumentError}from"#compiled/commander/index.js";import{resolveApplicationRoot}from"#internal/application/paths.js";import{registerProjectCommands}from"#cli/commands/register-project-commands.js";import{resolveDevUiMode,resolveTuiDisplayOptions}from"#cli/dev/ui-options.js";import{parseDevelopmentHeaderOption,resolveDevelopmentUrlTarget}from"#cli/dev/url-target.js";import{LOG_DISPLAY_MODES,parseLogDisplayMode}from"#cli/dev/tui/log-display-mode.js";import{resolveTuiTitle}from"#cli/dev/tui/target.js";import{parseDevelopmentServerUrl}from"#cli/dev/url.js";const devBootLog=createLogger(`dev.boot`);function createDevBootProgressReporter(e){return t=>{switch(t.type){case`phase-started`:e?.update(`Building your agent`,t.phase),devBootLog.debug(t.phase);return;case`phase-finished`:devBootLog.debug(`${t.phase} finished`,{ms:t.elapsedMs});return;case`before-first-paint`:e?.stop();return;default:return t}}}async function loadBuildHost(){return(await import(`#internal/nitro/host.js`)).buildApplication}async function loadPrintApplicationInfo(){return(await import(`#cli/commands/info.js`)).printApplicationInfo}async function loadRunDevelopmentTui(){return(await import(`#cli/dev/tui/tui.js`)).runDevelopmentTui}async function loadRunEvalCommand(){return(await import(`#evals/cli/eval.js`)).runEvalCommand}async function loadStartHost(){return(await import(`#internal/nitro/host.js`)).createDevelopmentServer}const loadIsActiveDevelopmentServerForApp=async()=>(await import(`#internal/nitro/host.js`)).isActiveDevelopmentServerForApp;async function loadStartProductionHost(){return(await import(`#internal/nitro/host.js`)).startProductionServer}function shouldPrintCliBootBanner(e){return e.name()===`info`||e.name()===`dev`||e.name()===`init`}async function waitForShutdownSignal(e){await new Promise((t,n)=>{let r=!1,cleanup=()=>{process.off(`SIGINT`,handleSignal),process.off(`SIGTERM`,handleSignal)},handleSignal=()=>{r||(r=!0,cleanup(),e.close().then(t,n))};process.once(`SIGINT`,handleSignal),process.once(`SIGTERM`,handleSignal)})}async function waitForProductionServer(e){await Promise.race([e.wait(),waitForShutdownSignal({close:()=>e.close()})])}function parsePortOption(e){if(!/^-?\d+$/.test(e))throw new InvalidArgumentError(`Expected a numeric port, received "${e}".`);let t=Number(e);if(t<0||t>65535)throw new InvalidArgumentError(`Expected a port between 0 and 65535, received "${e}".`);return t}const DISPLAY_MODES=new Set([`full`,`collapsed`,`auto-collapsed`,`hidden`]),STATS_MODES=new Set([`tokens`,`tokensPerSecond`]);function parseDisplayMode(e){if(!DISPLAY_MODES.has(e))throw new InvalidArgumentError(`Expected one of ${[...DISPLAY_MODES].join(`, `)}, received "${e}".`);return e}function parseStatsMode(e){if(!STATS_MODES.has(e))throw new InvalidArgumentError(`Expected one of ${[...STATS_MODES].join(`, `)}, received "${e}".`);return e}function parseLogsMode(e){let t=parseLogDisplayMode(e);if(t===void 0)throw new InvalidArgumentError(`Expected one of ${LOG_DISPLAY_MODES.join(`, `)}, received "${e}".`);return t}function parseContextSizeOption(e){let t=Number(e);if(!Number.isFinite(t)||t<=0)throw new InvalidArgumentError(`Expected a positive number, received "${e}".`);return t}function hasInteractiveTerminal(){return!!(process.stdin.isTTY&&process.stdout.isTTY)}function createCliProgram(e,i){let c=resolveApplicationRoot(),p=resolveInstalledPackageInfo().version,m=new Command,g=createCliTheme();m.name(`eve`).description(`Build and run an eve application.`).version(p).showHelpAfterError().exitOverride().hook(`preAction`,(t,n)=>{shouldPrintCliBootBanner(n)&&e.log(eveCliBanner())}).configureOutput({writeErr:t=>{e.error(t.trimEnd())},writeOut:t=>{e.log(t.trimEnd())}});let _=m.command(`channels`).description(`Manage user-authored channels in the current project.`);
|
|
1
|
+
import{createLogger}from"#internal/logging.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{createCliTheme,renderCliTaggedLine}from"#cli/ui/output.js";import{isCodingAgentLaunch}from"#cli/agent-detection.js";import{eveCliBanner}from"#cli/banner.js";import{startCliLiveRow}from"#cli/ui/live-row.js";import{devBootPhase}from"#internal/dev-boot-progress.js";import{Command,CommanderError,InvalidArgumentError}from"#compiled/commander/index.js";import{resolveApplicationRoot}from"#internal/application/paths.js";import{registerProjectCommands}from"#cli/commands/register-project-commands.js";import{resolveDevUiMode,resolveTuiDisplayOptions}from"#cli/dev/ui-options.js";import{parseDevelopmentHeaderOption,resolveDevelopmentUrlTarget}from"#cli/dev/url-target.js";import{LOG_DISPLAY_MODES,parseLogDisplayMode}from"#cli/dev/tui/log-display-mode.js";import{resolveTuiTitle}from"#cli/dev/tui/target.js";import{parseDevelopmentServerUrl}from"#cli/dev/url.js";const devBootLog=createLogger(`dev.boot`);function createDevBootProgressReporter(e){return t=>{switch(t.type){case`phase-started`:e?.update(`Building your agent`,t.phase),devBootLog.debug(t.phase);return;case`phase-finished`:devBootLog.debug(`${t.phase} finished`,{ms:t.elapsedMs});return;case`before-first-paint`:e?.stop();return;default:return t}}}async function loadBuildHost(){return(await import(`#internal/nitro/host.js`)).buildApplication}async function loadPrintApplicationInfo(){return(await import(`#cli/commands/info.js`)).printApplicationInfo}async function loadRunDevelopmentTui(){return(await import(`#cli/dev/tui/tui.js`)).runDevelopmentTui}async function loadRunEvalCommand(){return(await import(`#evals/cli/eval.js`)).runEvalCommand}async function loadStartHost(){return(await import(`#internal/nitro/host.js`)).createDevelopmentServer}const loadIsActiveDevelopmentServerForApp=async()=>(await import(`#internal/nitro/host.js`)).isActiveDevelopmentServerForApp;async function loadStartProductionHost(){return(await import(`#internal/nitro/host.js`)).startProductionServer}function shouldPrintCliBootBanner(e){return e.name()===`info`||e.name()===`dev`||e.name()===`init`}async function waitForShutdownSignal(e){await new Promise((t,n)=>{let r=!1,cleanup=()=>{process.off(`SIGINT`,handleSignal),process.off(`SIGTERM`,handleSignal)},handleSignal=()=>{r||(r=!0,cleanup(),e.close().then(t,n))};process.once(`SIGINT`,handleSignal),process.once(`SIGTERM`,handleSignal)})}async function waitForProductionServer(e){await Promise.race([e.wait(),waitForShutdownSignal({close:()=>e.close()})])}function parsePortOption(e){if(!/^-?\d+$/.test(e))throw new InvalidArgumentError(`Expected a numeric port, received "${e}".`);let t=Number(e);if(t<0||t>65535)throw new InvalidArgumentError(`Expected a port between 0 and 65535, received "${e}".`);return t}const DISPLAY_MODES=new Set([`full`,`collapsed`,`auto-collapsed`,`hidden`]),STATS_MODES=new Set([`tokens`,`tokensPerSecond`]);function parseDisplayMode(e){if(!DISPLAY_MODES.has(e))throw new InvalidArgumentError(`Expected one of ${[...DISPLAY_MODES].join(`, `)}, received "${e}".`);return e}function parseStatsMode(e){if(!STATS_MODES.has(e))throw new InvalidArgumentError(`Expected one of ${[...STATS_MODES].join(`, `)}, received "${e}".`);return e}function parseLogsMode(e){let t=parseLogDisplayMode(e);if(t===void 0)throw new InvalidArgumentError(`Expected one of ${LOG_DISPLAY_MODES.join(`, `)}, received "${e}".`);return t}function parseContextSizeOption(e){let t=Number(e);if(!Number.isFinite(t)||t<=0)throw new InvalidArgumentError(`Expected a positive number, received "${e}".`);return t}function hasInteractiveTerminal(){return!!(process.stdin.isTTY&&process.stdout.isTTY)}function createCliProgram(e,i){let c=resolveApplicationRoot(),p=resolveInstalledPackageInfo().version,m=new Command,g=createCliTheme();m.name(`eve`).description(`Build and run an eve application.`).version(p).showHelpAfterError().exitOverride().hook(`preAction`,(t,n)=>{shouldPrintCliBootBanner(n)&&e.log(eveCliBanner())}).configureOutput({writeErr:t=>{e.error(t.trimEnd())},writeOut:t=>{e.log(t.trimEnd())}});let _=m.command(`channels`).description(`Manage user-authored channels in the current project.`);_.command(`add [kind]`).description(`Add channels interactively, or scaffold a channel kind (slack | web).`).option(`-f, --force`,`Overwrite existing channel files`).option(`-y, --yes`,`Assume yes for confirmations; requires an explicit channel kind`).action(async(t,n)=>{let{runChannelsAddCommand:r}=await import(`#cli/commands/channels.js`);await r(e,c,{kind:t,options:n})}),_.command(`list`).description(`List user-authored channels in the current project.`).option(`--json`,`Output as JSON`).action(async t=>{let{runChannelsListCommand:n}=await import(`#cli/commands/channels.js`);await n(e,c,t)});let v=m.command(`extension`).description(`Create and build reusable eve extension packages.`);return v.command(`init [target]`).description(`Create a new eve extension package.`).option(`-y, --yes`,`Accepted for compatibility; has no effect`).action(async(t,n)=>{n.yes&&e.error(`warning: --yes has no effect for eve extension init.`);let{runExtensionInitCommand:r}=await import(`#cli/commands/extension-init.js`);await r(e,c,t)}),v.command(`build`).description(`Build the current package as an eve extension.`).action(async()=>{let{loadDevelopmentEnvironmentFiles:t}=await import(`#cli/dev/environment.js`);t(c);let{runExtensionBuildCommand:n}=await import(`#cli/commands/extension-build.js`);await n(e,c)}),m.command(`init [target]`).description(`Create a new eve agent, or add one to an existing project directory.`).option(`--channel-web-nextjs`,`Add the Web Chat application (Next.js)`).option(`-y, --yes`,`Accepted for compatibility; has no effect`).action(async(t,n)=>{n.yes&&e.error(`warning: --yes has no effect for eve init.`);let{runInitCommand:r}=await import(`#cli/commands/init.js`);await r(e,c,t,{channelWebNextjs:n.channelWebNextjs})}),registerProjectCommands({program:m,logger:e,appRoot:c}),m.command(`build`).description(`Build the current eve application.`).action(async()=>{let{loadDevelopmentEnvironmentFiles:t}=await import(`#cli/dev/environment.js`);t(c);let n=await(i.buildHost??await loadBuildHost())(c);e.log(renderCliTaggedLine(g,{message:`built output at ${n}`,tag:`build`,tone:`success`}))}),m.command(`start`).description(`Start a built eve application.`).option(`--host <host>`,`Host interface to bind`).option(`--port <port>`,`Port to listen on (defaults to $PORT, then 3000)`,parsePortOption).action(async t=>{let{loadDevelopmentEnvironmentFiles:n}=await import(`#cli/dev/environment.js`);n(c);let a=await(i.startProductionHost??await loadStartProductionHost())(c,{host:t.host,port:t.port});e.log(renderCliTaggedLine(g,{message:`server listening at ${a.url}`,tag:`start`,tone:`success`})),await waitForProductionServer(a)}),m.command(`dev`).description(`Start the eve development server or connect to an existing URL.`).argument(`[url]`,`Connect to an existing server URL`,parseDevelopmentServerUrl).option(`--host <host>`,`Host interface to bind`).option(`--port <port>`,`Port to listen on (defaults to $PORT, then 2000)`,parsePortOption).option(`-u, --url <url>`,`Connect to an existing server URL`,parseDevelopmentServerUrl).option(`-H, --header <header>`,`Request header for a URL target, in "Name: value" form (repeatable)`,parseDevelopmentHeaderOption).option(`--no-ui`,`Start the server without an interactive UI`).option(`--name <name>`,`Title shown in the terminal UI (defaults to the app folder name)`).option(`--input <text>`,`Pre-fill the prompt input, or start onboarding with /model`).option(`--tools <mode>`,`How tool calls render: full | collapsed | auto-collapsed | hidden`,parseDisplayMode).option(`--reasoning <mode>`,`How reasoning renders: full | collapsed | auto-collapsed | hidden`,parseDisplayMode).option(`--subagents <mode>`,`How subagent sections render: full | collapsed | auto-collapsed | hidden`,parseDisplayMode).option(`--connection-auth <mode>`,`How connection authorization renders: full | collapsed | auto-collapsed | hidden`,parseDisplayMode).option(`--assistant-response-stats <mode>`,`Assistant header statistic: tokens | tokensPerSecond`,parseStatsMode).option(`--context-size <tokens>`,`Model context window size, shown as a usage percentage`,parseContextSizeOption).option(`--logs <mode>`,`Which server/agent logs to show: all | stderr | sandbox | none`,parseLogsMode).addHelpText(`after`,`
|
|
2
2
|
You can also pass a bare URL, for example: eve dev https://example.com
|
|
3
3
|
`).action(async(t,n)=>{let a=resolveDevelopmentUrlTarget(n,t),s=a?.serverUrl,u=hasInteractiveTerminal(),d=resolveDevUiMode({options:n,interactive:u});if(n.input!==void 0&&d===`headless`)throw new InvalidArgumentError(`--input requires the interactive UI.`);let f=!1;s!==void 0&&(f=await(i.isActiveDevelopmentServerForApp??await loadIsActiveDevelopmentServerForApp())({appRoot:c,serverUrl:s}));let runInteractiveUi=async(e,t)=>{let r=await devBootPhase(`loading interactive UI`,async()=>i.runDevelopmentTui??await loadRunDevelopmentTui(),t),o=resolveTuiDisplayOptions(n),l=s===void 0||f?{kind:`local`,serverUrl:e.serverUrl,workspaceRoot:e.appRoot??c}:{kind:`remote`,serverUrl:e.serverUrl,workspaceRoot:c},u=resolveTuiTitle({name:n.name,target:l});u!==void 0&&(o.name=u);let d={target:l,initialInput:n.input,onBootProgress:t,...o};a?.headers===void 0?await r(d):await r({...d,headers:a.headers})};if(s){let{loadDevelopmentEnvironmentFiles:t}=await import(`#cli/dev/environment.js`);if(t(c),e.log(`↗ ${f?`local`:`remote`} mode targeting ${g.info(new URL(s).host)}`),d===`headless`){e.log(renderCliTaggedLine(g,{message:`Interactive UI disabled because the current terminal is not a TTY.`,tag:`dev`,tone:`warning`}));return}e.log(``),await runInteractiveUi({serverUrl:s});return}d===`tui`&&e.log(``);let p=d===`tui`?startCliLiveRow(e):void 0,m=createDevBootProgressReporter(p);p?.update(`Building your agent`);let h=!1,_,closeServer=async()=>{h||_===void 0||(h=!0,await _.close())};try{_=(i.startHost??await loadStartHost())(c,{existing:d===`tui`?`attach-if-unconfigured`:`reject`,host:n.host,onBootProgress:m,port:n.port});let t=await _.start();if(d!==`tui`&&e.log(renderCliTaggedLine(g,{message:`server listening at ${t.url}`,tag:`dev`,tone:`success`})),d===`headless`)return n.ui!==!1&&!u&&e.log(renderCliTaggedLine(g,{message:`Interactive UI disabled because the current terminal is not a TTY.`,tag:`dev`,tone:`warning`})),await waitForShutdownSignal({close:closeServer});await runInteractiveUi({appRoot:t.appRoot,serverUrl:t.url},m)}finally{p?.stop(),await closeServer()}}),m.command(`info`).description(`Print resolved application information.`).option(`--json`,`Output as JSON`).action(async t=>{await(i.printApplicationInfo??await loadPrintApplicationInfo())(e,c,t)}),m.command(`eval`).description(`Run evals against an eve agent.`).argument(`[evalIds...]`,`Eval ids (or directory prefixes) to run (all discovered evals when omitted)`).option(`--url <url>`,`Remote agent URL (skip local host startup)`,parseDevelopmentServerUrl).option(`--tag <tag...>`,`Run only evals carrying a tag`).option(`--strict`,`Fail the exit code when any score falls below its threshold`).option(`--list`,`Print discovered evals without running them`).option(`--timeout <ms>`,`Per-eval timeout in milliseconds`).option(`--max-concurrency <n>`,`Max concurrent eval executions`).option(`--json`,`Output results as JSON`).option(`--junit <path>`,`Write JUnit XML results to a file`).option(`--skip-report`,`Skip eval-defined reporters (e.g. Braintrust)`).option(`--verbose`,`Stream per-eval t.log lines to stdout`).action(async(t,n)=>{await(i.runEvalCommand??await loadRunEvalCommand())(t,n,e)}),m}async function runCli(e=process.argv.slice(2),t=console,n={}){let r=createCliProgram(t,n),a=e.length===0?[`dev`]:e;try{await r.parseAsync(a,{from:`user`})}catch(e){if(e instanceof CommanderError){if(e.exitCode===0)return;let r=await(n.isCodingAgentLaunch??isCodingAgentLaunch)();if(a[0]===`init`&&r){let{initAgentInstructions:e}=await import(`#cli/commands/agent-instructions.js`);t.log(e())}throw Error(e.message)}throw e}}export{resolveDevUiMode,resolveTuiDisplayOptions,runCli};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const AGENT_NAME_PATTERN=/^[a-z0-9][a-z0-9_-]*$/;function resolveEveAgentHost(e){if(e.agent===void 0)return e.host??``;if(e.host!==void 0)throw Error(`useEveAgent cannot combine agent and host. Use one target option.`);return assertValidAgentName(e.agent),`/eve/agents/${e.agent}`}function assertValidAgentName(t){if(!AGENT_NAME_PATTERN.test(t))throw Error(`eve agent name ${JSON.stringify(t)} is invalid. Use lowercase letters, numbers, underscores, or hyphens, starting with a letter or number.`)}export{resolveEveAgentHost};
|
|
@@ -27,12 +27,12 @@
|
|
|
27
27
|
"@vercel/detect-agent": "1.2.3",
|
|
28
28
|
"@vercel/oidc": "3.5.0",
|
|
29
29
|
"@vercel/sandbox": "2.3.0",
|
|
30
|
-
"@workflow/core": "5.0.0-beta.
|
|
30
|
+
"@workflow/core": "5.0.0-beta.30",
|
|
31
31
|
"@workflow/errors": "5.0.0-beta.10",
|
|
32
32
|
"@workflow/serde": "5.0.0-beta.2",
|
|
33
|
-
"@workflow/world": "5.0.0-beta.
|
|
34
|
-
"@workflow/world-local": "5.0.0-beta.
|
|
35
|
-
"@workflow/world-vercel": "5.0.0-beta.
|
|
33
|
+
"@workflow/world": "5.0.0-beta.18",
|
|
34
|
+
"@workflow/world-local": "5.0.0-beta.26",
|
|
35
|
+
"@workflow/world-vercel": "5.0.0-beta.26",
|
|
36
36
|
"zod": "4.4.3",
|
|
37
37
|
"zod-validation-error": "5.0.0"
|
|
38
38
|
},
|
|
@@ -8,6 +8,26 @@ export interface StepInvocationQueueItem {
|
|
|
8
8
|
closureVars?: Record<string, Serializable>;
|
|
9
9
|
thisVal?: Serializable;
|
|
10
10
|
hasCreatedEvent?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Inline step ownership, derived from the step's LATEST `step_started`
|
|
13
|
+
* during replay: the queue message ID stamped by the invocation running
|
|
14
|
+
* the step inline, or undefined when the latest start was unstamped (a
|
|
15
|
+
* retry attempt driven by a queued step message, or an older runtime).
|
|
16
|
+
* Latest start wins — an unstamped bare start clears a previous stamp; an
|
|
17
|
+
* owner-recovery re-stamped start restores it.
|
|
18
|
+
*/
|
|
19
|
+
ownerMessageId?: string;
|
|
20
|
+
/**
|
|
21
|
+
* `createdAt` (ms) of the step's latest observed `step_started`. Anchors
|
|
22
|
+
* the ownership lease: `leaseRemaining = lastStartedAt + lease − now`.
|
|
23
|
+
*/
|
|
24
|
+
lastStartedAt?: number;
|
|
25
|
+
/**
|
|
26
|
+
* Whether a `step_retrying` was observed for this step. From that point
|
|
27
|
+
* the step is queue-owned (the delayed retry handoff or replay requeue),
|
|
28
|
+
* so inline ownership is permanently lapsed for this correlation ID.
|
|
29
|
+
*/
|
|
30
|
+
sawRetrying?: boolean;
|
|
11
31
|
}
|
|
12
32
|
export interface HookInvocationQueueItem {
|
|
13
33
|
type: 'hook';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{c as e,i as t}from"../../_chunks/workflow/dist-DpDDcpTl.js";import{
|
|
2
|
-
`)}`)}return await v(t,r.value)}}}async function C(e,n={}){let r=_.getStore(),
|
|
1
|
+
import{c as e,i as t}from"../../_chunks/workflow/dist-DpDDcpTl.js";import{An as n,C as r,Cn as i,Dn as a,En as o,Mn as s,R as c,T as l,Tn as u,fn as d,h as f,jn as p,mn as m,pn as h,t as g,z as _}from"../../_chunks/workflow/attribute-changes-ubiPfqvY.js";import"../../_chunks/workflow/dist-DnBjuNAZ.js";import{n as v}from"../../_chunks/workflow/resume-hook-BkVkWg2r.js";import{t as y}from"../../_chunks/workflow/sleep-C2Bn-UUg.js";function b(e){p(`createHook()`,`https://workflow-sdk.dev/docs/api-reference/workflow/create-hook`,b)}function x(e){p(`createWebhook()`,`https://workflow-sdk.dev/docs/api-reference/workflow/create-webhook`,x)}function S({schema:e}={}){function t(e){p(`defineHook().create()`,`https://workflow-sdk.dev/docs/api-reference/workflow/define-hook`,t)}return{create:t,async resume(t,n){if(!e?.[`~standard`])return await v(t,n);let r=e[`~standard`].validate(n);if(r instanceof Promise&&(r=await r),r.issues){let e=r.issues.map(e=>{let t=e.path?.map(e=>String(typeof e==`object`&&e?e.key:e)).join(`.`);return t?` at "${t}": ${e.message}`:` ${e.message}`});throw Error(`Hook payload did not match the defined schema:\n${e.join(`
|
|
2
|
+
`)}`)}return await v(t,r.value)}}}async function C(e,n={}){let r=_.getStore(),a=r?.workflowMetadata?.workflowRunId;if(!a)throw new t(`experimental_setAttributes() must be called from a 'use workflow' or 'use step' function. Calling it from plain host code is not supported.`);let o=g(e,n);if(o.length!==0){if(r.runReadyBarrier)try{await r.runReadyBarrier}catch{}await(await i()).events.create(a,{eventType:`attr_set`,specVersion:5,eventData:{changes:o,writer:{type:`step`,stepId:r.stepMetadata.stepId,attempt:r.stepMetadata.attempt},...n.allowReservedAttributes===!0?{allowReservedAttributes:!0}:{}}})}}function w(){let e=_.getStore();return e||n(`getStepMetadata()`,`https://workflow-sdk.dev/docs/api-reference/workflow/get-step-metadata`,w),e.stepMetadata}function T(){let e=_.getStore();return e||s(`getWorkflowMetadata()`,`https://workflow-sdk.dev/docs/api-reference/workflow/get-workflow-metadata`,T),e.workflowMetadata}function E(e={}){let t=_.getStore();t||s(`getWritable()`,`https://workflow-sdk.dev/docs/api-reference/workflow/get-writable`,E);let{namespace:n}=e,i=t.workflowMetadata.workflowRunId,p=c(i,n),g=t.writables??=new Map,v=g.get(p);if(v)return v.writable;let y=l(r(globalThis,t.ops,i,t.encryptionKey,!0,t.runReadyBarrier),t.encryptionKey),b=new f(i,p,t.runReadyBarrier),x=u();return t.ops.push(x.promise),o(y.readable,b,x).catch(()=>{}),a(y.writable,x),Object.defineProperty(y.writable,d,{value:p,writable:!1}),Object.defineProperty(y.writable,m,{value:i,writable:!1}),t.workflowDeploymentId&&Object.defineProperty(y.writable,h,{value:t.workflowDeploymentId,writable:!1}),g.set(p,{writable:y.writable,state:x}),y.writable}export{t as FatalError,e as RetryableError,b as createHook,x as createWebhook,S as defineHook,C as experimental_setAttributes,w as getStepMetadata,T as getWorkflowMetadata,E as getWritable,y as sleep};
|
|
@@ -130,6 +130,60 @@ export declare function isOptimisticInlineStartExplicitlyDisabled(): boolean;
|
|
|
130
130
|
* explicit `'0'` / `'false'` (case-insensitive).
|
|
131
131
|
*/
|
|
132
132
|
export declare function isTurboEnabled(): boolean;
|
|
133
|
+
/**
|
|
134
|
+
* Whether inline step ownership is enabled (default ON). When on, the lazy
|
|
135
|
+
* `step_started` that creates an inline step records the owning queue
|
|
136
|
+
* message ID, and wake replays that observe an actively-owned step enqueue a
|
|
137
|
+
* *delayed backstop* message instead of immediately requeueing it — fixing
|
|
138
|
+
* duplicate inline step execution when a hook/wait wakes a run mid-step
|
|
139
|
+
* (vercel/workflow#2780).
|
|
140
|
+
*
|
|
141
|
+
* `WORKFLOW_INLINE_OWNERSHIP=0` (or `false`) is the kill switch: dispatch
|
|
142
|
+
* reverts to the unconditional immediate requeue. Stamping is unaffected —
|
|
143
|
+
* the recorded ownerMessageId is inert data when the switch is off.
|
|
144
|
+
*/
|
|
145
|
+
export declare function isInlineOwnershipEnabled(): boolean;
|
|
146
|
+
/**
|
|
147
|
+
* Default inline-ownership lease, in seconds: how long after a step's latest
|
|
148
|
+
* (stamped) `step_started` a non-owner invocation assumes the owning
|
|
149
|
+
* invocation may still be alive. Within the lease, wake replays enqueue the
|
|
150
|
+
* step's backstop message with `delaySeconds = lease remaining` instead of
|
|
151
|
+
* immediately; past it, they enqueue immediately (today's behavior).
|
|
152
|
+
*
|
|
153
|
+
* Why a fixed 860 and not a value derived from the function's `maxDuration`:
|
|
154
|
+
* neither runtime nor build time can see the resolved value — builders emit
|
|
155
|
+
* `maxDuration: 'max'`, which the platform resolves per-plan at deploy, and
|
|
156
|
+
* no env var or request-context deadline API exposes the result. The bound
|
|
157
|
+
* comes from a platform rule instead: durations above 800s require explicit
|
|
158
|
+
* per-function numeric config, so a builder-emitted `'max'` resolves to at
|
|
159
|
+
* most 800s — 860s therefore dominates any workflow route's invocation
|
|
160
|
+
* lifetime plus scheduling slack. Revisit when that ceiling moves (the
|
|
161
|
+
* 30-minute duration beta becoming reachable via `'max'` would invalidate
|
|
162
|
+
* the bound). Worlds without an invocation kill bound (world-local,
|
|
163
|
+
* self-hosted) get no death proof from any constant — there the in-process
|
|
164
|
+
* single-flight layer (step-single-flight.ts) is what makes a backstop
|
|
165
|
+
* firing mid-step harmless.
|
|
166
|
+
*
|
|
167
|
+
* 860 also stays under the queue's 900s maximum delay (SQS cap), so a
|
|
168
|
+
* backstop's full lease remainder always fits in a single delayed message.
|
|
169
|
+
*
|
|
170
|
+
* Override via `WORKFLOW_INLINE_OWNERSHIP_LEASE_SECONDS` (clamped to
|
|
171
|
+
* 1..`MAX_INLINE_OWNERSHIP_LEASE_SECONDS`).
|
|
172
|
+
*/
|
|
173
|
+
export declare const INLINE_OWNERSHIP_LEASE_SECONDS = 860;
|
|
174
|
+
/**
|
|
175
|
+
* Upper bound for the lease env override. 900s is the queue's maximum
|
|
176
|
+
* per-message delay (SQS cap) — a longer lease would need delay chaining
|
|
177
|
+
* like long waits use; clamp instead so one delayed message always suffices.
|
|
178
|
+
*/
|
|
179
|
+
export declare const MAX_INLINE_OWNERSHIP_LEASE_SECONDS = 900;
|
|
180
|
+
/**
|
|
181
|
+
* Effective inline-ownership lease. Override via
|
|
182
|
+
* `WORKFLOW_INLINE_OWNERSHIP_LEASE_SECONDS` — e.g. raise it on self-hosted
|
|
183
|
+
* multi-instance worlds with long-running steps to widen the window in which
|
|
184
|
+
* a live owner is protected from a concurrent backstop execution.
|
|
185
|
+
*/
|
|
186
|
+
export declare function getInlineOwnershipLeaseSeconds(): number;
|
|
133
187
|
export declare const REPLAY_DIVERGENCE_MAX_RETRIES = 3;
|
|
134
188
|
/**
|
|
135
189
|
* Effective replay-divergence recovery budget. Override via
|
|
@@ -45,10 +45,18 @@ export interface HealthCheckOptions {
|
|
|
45
45
|
timeout?: number;
|
|
46
46
|
/** Deployment ID to send the health check to. Falls back to process.env.VERCEL_DEPLOYMENT_ID. */
|
|
47
47
|
deploymentId?: string;
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Queue namespace of the target deployment (e.g. `'eve'` for topics like
|
|
50
|
+
* `__eve_wkf_workflow_*`). Falls back to `WORKFLOW_QUEUE_NAMESPACE` in the
|
|
51
|
+
* calling process. Cross-context callers (e.g. the observability
|
|
52
|
+
* dashboard) must pass the target deployment's namespace explicitly —
|
|
53
|
+
* the env fallback resolves in the caller's process, and a message
|
|
54
|
+
* published to a mismatched topic has no consumer, so the check would
|
|
55
|
+
* always time out.
|
|
56
|
+
*/
|
|
50
57
|
namespace?: string;
|
|
51
|
-
}
|
|
58
|
+
}
|
|
59
|
+
export declare function healthCheck(world: World, endpoint: HealthCheckEndpoint, options?: HealthCheckOptions): Promise<HealthCheckResult>;
|
|
52
60
|
/**
|
|
53
61
|
* Loads workflow run events by iterating through all pages of paginated
|
|
54
62
|
* results. Events are returned in chronological (ascending) order for
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { WORKFLOW_DESERIALIZE, WORKFLOW_SERIALIZE } from '../_workflow-serde.js';
|
|
2
2
|
import { type WorkflowRunStatus } from '#compiled/@workflow/world/index.js';
|
|
3
|
-
import { type StopSleepOptions, type StopSleepResult } from './runs.js';
|
|
3
|
+
import { type CancelRunOptions, type StopSleepOptions, type StopSleepResult } from './runs.js';
|
|
4
4
|
/**
|
|
5
5
|
* A `ReadableStream` extended with workflow-specific helpers.
|
|
6
6
|
*/
|
|
@@ -72,8 +72,12 @@ export declare class Run<TResult> {
|
|
|
72
72
|
wakeUp(options?: StopSleepOptions): Promise<StopSleepResult>;
|
|
73
73
|
/**
|
|
74
74
|
* Cancels the workflow run.
|
|
75
|
+
*
|
|
76
|
+
* @param options - Optional cancellation settings. `cancelReason` records a
|
|
77
|
+
* free-text reason (max 512 chars) on the run_cancelled event, surfaced in
|
|
78
|
+
* the run detail view.
|
|
75
79
|
*/
|
|
76
|
-
cancel(): Promise<void>;
|
|
80
|
+
cancel(options?: CancelRunOptions): Promise<void>;
|
|
77
81
|
/**
|
|
78
82
|
* Whether the workflow run exists.
|
|
79
83
|
*/
|