eve 0.9.3 → 0.9.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 +14 -0
- package/bin/eve.d.ts +9 -0
- package/bin/eve.js +78 -7
- package/dist/src/cli/commands/init.d.ts +2 -4
- package/dist/src/cli/commands/init.js +1 -1
- package/dist/src/execution/sandbox/logging-session.js +2 -2
- package/dist/src/execution/sandbox/read-file-tool.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/docs/getting-started.mdx +7 -29
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# eve
|
|
2
2
|
|
|
3
|
+
## 0.9.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 7c45498: Allow `eve init` with no target, `eve init .`, and `eve init ./` to scaffold a full agent in the current empty directory. Existing package directories still use the add-agent flow.
|
|
8
|
+
|
|
9
|
+
## 0.9.4
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 285386b: Limit sandbox bootstrap failure stdout and stderr in thrown errors so large install logs cannot inflate workflow memory usage.
|
|
14
|
+
- 3e9b8d9: Allow `write_file` to overwrite an existing empty file after it has been successfully read with `read_file`.
|
|
15
|
+
- aa1f593: Vendor semver for the Eve CLI bootstrap so production installs no longer need semver as a runtime dependency.
|
|
16
|
+
|
|
3
17
|
## 0.9.3
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
package/bin/eve.d.ts
CHANGED
|
@@ -39,7 +39,16 @@ export interface BootstrapCliModule {
|
|
|
39
39
|
runCli(argv?: string[]): Promise<void>;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
export interface BootstrapSemverModule {
|
|
43
|
+
default: {
|
|
44
|
+
validRange(range: string | undefined): string | null;
|
|
45
|
+
satisfies(version: string, range: string): boolean;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
42
49
|
export interface BootstrapDependencies extends BootstrapBuildDependencies {
|
|
50
|
+
importBootstrapModule?: (specifier: string) => Promise<BootstrapSemverModule>;
|
|
51
|
+
|
|
43
52
|
importModule?: (specifier: string) => Promise<BootstrapCliModule>;
|
|
44
53
|
|
|
45
54
|
/**
|
package/bin/eve.js
CHANGED
|
@@ -5,19 +5,19 @@ 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";
|
|
9
8
|
|
|
10
9
|
const require = createRequire(import.meta.url);
|
|
11
10
|
const packageJson = require("../package.json");
|
|
12
11
|
const packageNodeEngine = packageJson.engines?.node;
|
|
12
|
+
const bootstrapPackageRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
13
|
+
let semverPromise;
|
|
13
14
|
|
|
14
|
-
if (typeof packageNodeEngine !== "string"
|
|
15
|
+
if (typeof packageNodeEngine !== "string") {
|
|
15
16
|
throw new Error("eve package.json must declare a valid engines.node range.");
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
function createBootstrapOptions(overrides = {}) {
|
|
19
|
-
const packageRoot =
|
|
20
|
-
overrides.packageRoot ?? resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
20
|
+
const packageRoot = overrides.packageRoot ?? bootstrapPackageRoot;
|
|
21
21
|
|
|
22
22
|
return {
|
|
23
23
|
cliEntrypointPath:
|
|
@@ -116,7 +116,72 @@ function inputTsconfigPath({ packageRoot }) {
|
|
|
116
116
|
return resolve(packageRoot, "tsconfig.json");
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
function
|
|
119
|
+
function vendorCompiledScriptPath({ packageRoot }) {
|
|
120
|
+
return resolve(packageRoot, "scripts", "vendor-compiled.mjs");
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function generatedSemverPath({ packageRoot }) {
|
|
124
|
+
return resolve(packageRoot, ".generated", "compiled", "semver", "index.js");
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
async function canBuildVendoredSemver({ exists, packageRoot }) {
|
|
128
|
+
return await exists(vendorCompiledScriptPath({ packageRoot }));
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function isModuleNotFoundError(error) {
|
|
132
|
+
return typeof error === "object" && error !== null && error.code === "ERR_MODULE_NOT_FOUND";
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
async function loadVendoredSemver(options, dependencies = {}) {
|
|
136
|
+
semverPromise ??= (async () => {
|
|
137
|
+
const exists = dependencies.exists ?? fileExists;
|
|
138
|
+
const executeCommand = dependencies.runCommand ?? runCommand;
|
|
139
|
+
const importModule = dependencies.importBootstrapModule ?? ((specifier) => import(specifier));
|
|
140
|
+
|
|
141
|
+
try {
|
|
142
|
+
const module = await importModule("#compiled/semver/index.js");
|
|
143
|
+
return module.default;
|
|
144
|
+
} catch (error) {
|
|
145
|
+
if (
|
|
146
|
+
!isModuleNotFoundError(error) ||
|
|
147
|
+
!(await canBuildVendoredSemver({ exists, packageRoot: options.packageRoot }))
|
|
148
|
+
) {
|
|
149
|
+
throw error;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const scriptPath = vendorCompiledScriptPath({
|
|
154
|
+
packageRoot: options.packageRoot,
|
|
155
|
+
});
|
|
156
|
+
const semverPath = generatedSemverPath({
|
|
157
|
+
packageRoot: options.packageRoot,
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
if (!(await exists(semverPath))) {
|
|
161
|
+
await executeCommand(process.execPath, [scriptPath], {
|
|
162
|
+
cwd: options.packageRoot,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (!(await exists(semverPath))) {
|
|
167
|
+
throw new Error(`Building Eve's vendored dependencies did not produce ${semverPath}.`);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const module = await importModule(pathToFileURL(semverPath).href);
|
|
171
|
+
return module.default;
|
|
172
|
+
})();
|
|
173
|
+
|
|
174
|
+
return semverPromise;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
async function assertSupportedNodeVersion(
|
|
178
|
+
version = process.version,
|
|
179
|
+
requiredRange = packageNodeEngine,
|
|
180
|
+
options = createBootstrapOptions(),
|
|
181
|
+
dependencies = {},
|
|
182
|
+
) {
|
|
183
|
+
const semver = await loadVendoredSemver(options, dependencies);
|
|
184
|
+
|
|
120
185
|
if (semver.validRange(requiredRange) === null) {
|
|
121
186
|
throw new Error(`Eve declares an invalid Node.js engine range: "${requiredRange}".`);
|
|
122
187
|
}
|
|
@@ -233,9 +298,15 @@ export async function ensureBuiltCli(overrides = {}, dependencies = {}) {
|
|
|
233
298
|
* Runs the compiled Eve CLI, building the workspace package on demand when needed.
|
|
234
299
|
*/
|
|
235
300
|
export async function runEveCli(argv = process.argv.slice(2), overrides = {}, dependencies = {}) {
|
|
236
|
-
|
|
301
|
+
const options = createBootstrapOptions(overrides);
|
|
302
|
+
await assertSupportedNodeVersion(
|
|
303
|
+
dependencies.nodeVersion,
|
|
304
|
+
dependencies.nodeEngineRequirement,
|
|
305
|
+
options,
|
|
306
|
+
dependencies,
|
|
307
|
+
);
|
|
237
308
|
|
|
238
|
-
const cliEntrypointPath = await ensureBuiltCli(
|
|
309
|
+
const cliEntrypointPath = await ensureBuiltCli(options, dependencies);
|
|
239
310
|
const importModule = dependencies.importModule ?? ((specifier) => import(specifier));
|
|
240
311
|
const cliModule = await importModule(pathToFileURL(cliEntrypointPath).href);
|
|
241
312
|
|
|
@@ -28,9 +28,7 @@ export interface InitCommandDependencies {
|
|
|
28
28
|
* existing project (`target` is a directory), without prompts or external
|
|
29
29
|
* provisioning.
|
|
30
30
|
*
|
|
31
|
-
* Runs launched by a coding agent
|
|
32
|
-
*
|
|
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.
|
|
31
|
+
* Runs launched by a coding agent get the dev command printed instead of
|
|
32
|
+
* spawned after scaffolding, since the dev TUI would wedge the launching agent.
|
|
35
33
|
*/
|
|
36
34
|
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
|
|
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}from"./agent-instructions.js";import{tryInitializeGit}from"./init-git.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{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},ALLOWED_CREATE_IN_PLACE_ENTRIES=new Set([`.DS_Store`,`.git`,`.gitkeep`,`.hg`]);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))}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`}async function scaffoldProject(e,t,n,r,o){let s=resolve(e),l=t===`.`,f=l?s:join(s,t);if(l)await assertCanScaffoldInPlace(f);else if(await pathExists(f))throw Error(`Cannot create project because "${f}" already exists.`);let p=await mkdtemp(join(s,`.eve-init-`));try{let e=l?basename(f):t,a=await o.scaffoldBaseProject({projectName:e,model:DEFAULT_AGENT_MODEL_ID,packageManager:n,targetDirectory:p});return r.channelWebNextjs===!0&&await o.ensureChannel({projectRoot:a,kind:`web`,packageManager:n,configureVercelServices:!1}),l?await moveDirectoryContents(a,f):await rename(a,f),f}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,r,i,o=defaultDependencies){let s=await o.isCodingAgentLaunch(),c=r??`.`,l=isCurrentDirectoryTarget(c),u=l?await pathExists(join(resolve(t),`package.json`))?resolve(t):void 0:await resolveTargetDirectory(t,c),d,f,p;if(u===void 0)d=resolveScaffoldPackageManager(o),f=await scaffoldProject(t,l?`.`:parseProjectName(c),d,i,o),p=!0,e.log(`${import_picocolors.default.green(`✓`)} Created an ${EVE_WORDMARK} agent in ${import_picocolors.default.bold(f)}`);else{let t=await addToExistingProject(u,i,o);d=t.packageManager,f=u,p=!1,e.log(`${import_picocolors.default.green(`✓`)} Added an ${EVE_WORDMARK} agent to ${import_picocolors.default.bold(f)}`),t.nodeEngineOverride!==void 0&&e.log(import_picocolors.default.yellow(`⚠ ${formatNodeEngineOverrideWarning(t.nodeEngineOverride)}`))}let m=[],h=startSpinner(e,`Installing dependencies...`),g;try{g=await o.runPackageManagerInstall(d,f,{bypassMinimumReleaseAge:!0,onOutput:e=>m.push(e.text)})}finally{h.stop()}if(!g){for(let t of m)e.error(t);throw Error(`Failed to install dependencies in "${f}".`)}if(e.log(`${import_picocolors.default.green(`✓`)} Installed dependencies`),p){let t=o.tryInitializeGit(f);t.kind===`failed`&&e.error(import_picocolors.default.yellow(`Git initialization failed: ${t.reason}`))}if(s){e.log(initAgentDevHandoff({projectPath:f,devCommand:[d,...eveDevArguments(d)].join(` `)}));return}let _=p?[...eveDevArguments(d),`--input`,`/model`]:eveDevArguments(d);if(e.log(import_picocolors.default.dim(p?`$ eve dev --input /model`:`$ eve dev`)),!await o.spawnPackageManager(d,f,_))throw Error(`Development server exited unsuccessfully in "${f}".`)}export{runInitCommand};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
function createLoggingSandboxSession(e){let{log:t,session:n}=e;return{...n,async run(e){t?.(`bootstrap run: ${formatCommand(e.command)}`);let r=await n.run(e);if(r.exitCode===1)throw Error(formatBootstrapRunFailure(e.command,r));return r},async spawn(e){return t?.(`bootstrap spawn: ${formatCommand(e.command)}`),await n.spawn(e)},async setNetworkPolicy(e){return t?.(`bootstrap set network policy: ${formatNetworkPolicy(e)}`),await n.setNetworkPolicy(e)},async writeFile(e){return t?.(`bootstrap write file: ${e.path}`),await n.writeFile(e)},async writeBinaryFile(e){return t?.(`bootstrap write binary file: ${e.path} (${e.content.byteLength} bytes)`),await n.writeBinaryFile(e)},async writeTextFile(e){return t?.(`bootstrap write text file: ${e.path} (${e.content.length} chars)`),await n.writeTextFile(e)},async removePath(e){return t?.(`bootstrap remove path: ${e.path}`),await n.removePath(e)}}}function formatBootstrapRunFailure(e,t){return[`Sandbox bootstrap failed because sandbox.run command exited with code 1:`,e,``,`stdout:`,t.stdout,``,`stderr:`,t.stderr].join(`
|
|
2
|
-
`)}function formatCommand(e){return truncateOneLine(e)}function formatNetworkPolicy(e){return truncateOneLine(typeof e==`string`?e:JSON.stringify(e))}function truncateOneLine(e){let t=e.replaceAll(/\s+/g,` `).trim();return t.length<=240?t:`${t.slice(0,239)}…`}export{createLoggingSandboxSession};
|
|
1
|
+
import{truncateTail}from"#execution/sandbox/truncate-output.js";function createLoggingSandboxSession(e){let{log:t,session:n}=e;return{...n,async run(e){t?.(`bootstrap run: ${formatCommand(e.command)}`);let r=await n.run(e);if(r.exitCode===1)throw Error(formatBootstrapRunFailure(e.command,r));return r},async spawn(e){return t?.(`bootstrap spawn: ${formatCommand(e.command)}`),await n.spawn(e)},async setNetworkPolicy(e){return t?.(`bootstrap set network policy: ${formatNetworkPolicy(e)}`),await n.setNetworkPolicy(e)},async writeFile(e){return t?.(`bootstrap write file: ${e.path}`),await n.writeFile(e)},async writeBinaryFile(e){return t?.(`bootstrap write binary file: ${e.path} (${e.content.byteLength} bytes)`),await n.writeBinaryFile(e)},async writeTextFile(e){return t?.(`bootstrap write text file: ${e.path} (${e.content.length} chars)`),await n.writeTextFile(e)},async removePath(e){return t?.(`bootstrap remove path: ${e.path}`),await n.removePath(e)}}}function formatBootstrapRunFailure(e,t){return[`Sandbox bootstrap failed because sandbox.run command exited with code 1:`,e,``,`stdout:`,formatCapturedOutput(`stdout`,t.stdout),``,`stderr:`,formatCapturedOutput(`stderr`,t.stderr)].join(`
|
|
2
|
+
`)}function formatCapturedOutput(t,n){let r=truncateTail(n);return r.truncated?`[${t} truncated: showing last ${r.outputLines} of ${r.totalLines} lines]\n${r.output}`:r.output}function formatCommand(e){return truncateOneLine(e)}function formatNetworkPolicy(e){return truncateOneLine(typeof e==`string`?e:JSON.stringify(e))}function truncateOneLine(e){let t=e.replaceAll(/\s+/g,` `).trim();return t.length<=240?t:`${t.slice(0,239)}…`}export{createLoggingSandboxSession};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import{loadContext}from"#context/container.js";import{buildReadFileTargetKey,createReadFileStamp,normalizeModelPath,setReadFileStamp}from"#runtime/framework-tools/file-state.js";import{MAX_OUTPUT_BYTES,capLineLength}from"#execution/sandbox/truncate-output.js";import{validateAbsoluteFilePath}from"#execution/sandbox/require-sandbox.js";async function executeReadFileOnSandbox(r,i){let{filePath:a,offset:o,limit:s}=i;validateAbsoluteFilePath(a);let c=normalizeModelPath(a),l=o??1,u=s??2e3;if(l<1)throw Error(`offset must be >= 1. Received: ${l}.`);let d=await r.readTextFile({path:a});if(d===null)throw Error(`File not found: ${a}. Verify the path exists and is accessible in the sandbox.`);if(d.includes(`\0`))throw Error(`File "${a}" contains NUL bytes and appears to be a binary file. read_file only supports text files.`);let f=d.split(`
|
|
2
|
-
`),p=f.length>0&&f[f.length-1]===``?f.length-1:f.length;if(p===0){if(l>1)throw Error(`offset ${l} is past the end of the file (0 lines). Use the default offset to read an empty file.`)
|
|
2
|
+
`),p=f.length>0&&f[f.length-1]===``?f.length-1:f.length;if(p===0){if(l>1)throw Error(`offset ${l} is past the end of the file (0 lines). Use the default offset to read an empty file.`)}else if(l>p)throw Error(`offset ${l} is past the end of the file (${p} lines).`);let m=createReadFileStamp({content:d,filePath:c}),h=buildReadFileTargetKey(c);if(setReadFileStamp(loadContext(),h,m),p===0)return{content:``,path:c,totalLines:0,truncated:!1};let g=l-1,_=Math.min(g+u,p),v=f.slice(g,_),y=[],b=0,x=!1;for(let e=0;e<v.length;e++){let t=`${l+e}: ${capLineLength(v[e]??``)}`,n=Buffer.byteLength(t,`utf8`)+1;if(b+n>MAX_OUTPUT_BYTES&&y.length>0){x=!0;break}y.push(t),b+=n}let S=y.join(`
|
|
3
3
|
`),C=l+y.length-1;return C<p||x?{content:S,nextOffset:C+1,path:c,totalLines:p,truncated:!0}:{content:S,path:c,totalLines:p,truncated:!1}}export{executeReadFileOnSandbox};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createRequire}from"node:module";import{existsSync,readFileSync,realpathSync}from"node:fs";import{basename,dirname,join}from"node:path";import{EVE_PACKAGE_NAME}from"#internal/package-name.js";import{fileURLToPath}from"node:url";let cachedPackageInfo;const BUNDLED_FALLBACK_PACKAGE_VERSION=`0.9.
|
|
1
|
+
import{createRequire}from"node:module";import{existsSync,readFileSync,realpathSync}from"node:fs";import{basename,dirname,join}from"node:path";import{EVE_PACKAGE_NAME}from"#internal/package-name.js";import{fileURLToPath}from"node:url";let cachedPackageInfo;const BUNDLED_FALLBACK_PACKAGE_VERSION=`0.9.5`,WORKFLOW_MODULE_ALIASES={"workflow/api":`src/compiled/@workflow/core/runtime.js`,"workflow/errors":`src/compiled/@workflow/errors/index.js`,"workflow/internal/private":`src/compiled/@workflow/core/private.js`,"workflow/runtime":`src/compiled/@workflow/core/runtime.js`};function resolveFallbackPackageVersion(){return BUNDLED_FALLBACK_PACKAGE_VERSION.startsWith(`__`)?`0.0.0`:BUNDLED_FALLBACK_PACKAGE_VERSION}const FALLBACK_PACKAGE_INFO={name:EVE_PACKAGE_NAME,version:resolveFallbackPackageVersion()};function resolveCurrentModulePath(){return typeof __filename==`string`?__filename:resolveCurrentModulePathFromStack()}function resolveCurrentModulePathFromStack(){let e=Error.prepareStackTrace;try{Error.prepareStackTrace=(e,t)=>t;let e=Error().stack?.[0]?.getFileName();if(typeof e!=`string`||e.length===0)throw Error(`Failed to resolve the current module path from the stack trace.`);return e.startsWith(`file:`)?fileURLToPath(e):e}finally{Error.prepareStackTrace=e}}const require=createRequire(resolveCurrentModulePath());function isBuildOutputPackageRoot(e){return basename(e)===`dist`&&existsSync(join(dirname(e),`package.json`))}function resolvePackageBuildRoot(){let e=dirname(realpathSync(resolveCurrentModulePath()));for(;;){if(isBuildOutputPackageRoot(e))return e;let t=dirname(e);if(t===e)return null;e=t}}function findNearestPackageRoot(e){let n=e;for(;;){if(existsSync(join(n,`package.json`))&&!isBuildOutputPackageRoot(n))return n;let r=dirname(n);if(r===n)throw Error(`Failed to resolve package root from "${e}".`);n=r}}function resolvePackageRoot(){return findNearestPackageRoot(dirname(realpathSync(resolveCurrentModulePath())))}function tryResolvePackageRoot(){try{return resolvePackageRoot()}catch{return}}function rewriteSourceFilePathForBuild(e){return e.replace(/\.[cm]?tsx?$/,`.js`)}function resolvePackageSourceFilePath(e){let t=resolvePackageBuildRoot();return t===null?join(resolvePackageRoot(),e):join(t,rewriteSourceFilePathForBuild(e))}function resolvePackageSourceDirectoryPath(e){let t=resolvePackageBuildRoot();return join(t===null?resolvePackageRoot():t,e)}function resolvePackageDependencyPath(e){return require.resolve(e)}function resolvePackageCompiledFilePath(e){let t=resolvePackageBuildRoot();return t===null?join(resolvePackageRoot(),`.generated`,`compiled`,e.replace(/^src\/compiled\//,``)):join(t,e)}function normalizeInstalledPackageInfo(e){let t=e;if(!(typeof t.name!=`string`||typeof t.version!=`string`))return{name:t.name,version:t.version}}function tryReadInstalledPackageInfo(e,t){let r=normalizeInstalledPackageInfo(JSON.parse(readFileSync(e,`utf8`)));if(r?.name===t)return r}function resolveInstalledPackageInfo(){if(cachedPackageInfo)return cachedPackageInfo;let e=tryResolvePackageRoot(),t=e===void 0?void 0:tryReadInstalledPackageInfo(join(e,`package.json`),EVE_PACKAGE_NAME);if(t)return cachedPackageInfo=t,cachedPackageInfo;try{let e=tryReadInstalledPackageInfo(require.resolve(`${EVE_PACKAGE_NAME}/package.json`),EVE_PACKAGE_NAME);if(e)return cachedPackageInfo=e,cachedPackageInfo}catch{}return cachedPackageInfo={...FALLBACK_PACKAGE_INFO},cachedPackageInfo}function resolveWorkflowModulePath(e){if(e===`workflow`)return resolvePackageSourceFilePath(`src/internal/workflow/index.ts`);if(e===`workflow/internal/builtins`)return resolvePackageSourceFilePath(`src/internal/workflow/builtins.ts`);let t=WORKFLOW_MODULE_ALIASES[e];return t===void 0?require.resolve(e):resolvePackageCompiledFilePath(t)}export{resolveInstalledPackageInfo,resolvePackageDependencyPath,resolvePackageRoot,resolvePackageSourceDirectoryPath,resolvePackageSourceFilePath,resolveWorkflowModulePath};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{getPackageManagerStrategy}from"../../primitives/pm/index.js";import{pinnedNodeEngineMajor}from"../../node-engine.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{basename,join,resolve}from"node:path";import{mkdir,readdir,stat}from"node:fs/promises";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,ALLOWED_CREATE_IN_PLACE_ENTRIES=new Set([`.DS_Store`,`.git`,`.gitkeep`,`.hg`]),DEFAULT_AI_PACKAGE_VERSION=`7.0.0-beta.178`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.2.2`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.9.
|
|
1
|
+
import{getPackageManagerStrategy}from"../../primitives/pm/index.js";import{pinnedNodeEngineMajor}from"../../node-engine.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{basename,join,resolve}from"node:path";import{mkdir,readdir,stat}from"node:fs/promises";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,ALLOWED_CREATE_IN_PLACE_ENTRIES=new Set([`.DS_Store`,`.git`,`.gitkeep`,`.hg`]),DEFAULT_AI_PACKAGE_VERSION=`7.0.0-beta.178`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.2.2`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.9.5`,nodeEngine:`>=24`};function resolveEvePackageContract(e=DEFAULT_EVE_PACKAGE_CONTRACT){return{version:resolveVersionToken(`evePackage.version`,e.version),nodeEngine:resolveVersionToken(`evePackage.nodeEngine`,e.nodeEngine)}}function modelProviderSlug(e){let t=(e.split(`/`)[0]??``).replaceAll(/[^A-Za-z0-9._-]/gu,``);return t.length>0?t:`anthropic`}function byokProviderEnvVar(e){let t=modelProviderSlug(e).toUpperCase().replaceAll(/[^A-Z0-9]/gu,`_`);return`${/^[0-9]/.test(t)?`_`:``}${t}_API_KEY`}function agentTemplateFiles(e){return{"agent/agent.ts":BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function renderTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_MODEL__`,t.model).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(t.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(t.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(t.eveVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,t.aiPackageVersion).replaceAll(`__EVE_INIT_CONNECT_VERSION__`,t.connectPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,t.zodPackageVersion).replaceAll(`__EVE_INIT_TSGO_VERSION__`,t.tsgoPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,t.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,t.nodeEngine)}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}const BASE_AGENT_TEMPLATE=`import { defineAgent } from "eve";
|
|
2
2
|
|
|
3
3
|
export default defineAgent({
|
|
4
4
|
model: "__EVE_INIT_MODEL__",
|
package/docs/getting-started.mdx
CHANGED
|
@@ -24,9 +24,9 @@ You also need a model credential. Set the provider or gateway key your model str
|
|
|
24
24
|
|
|
25
25
|
## Manual installation
|
|
26
26
|
|
|
27
|
-
The quick start uses `eve init` for a guided scaffold.
|
|
27
|
+
The quick start uses `eve init` for a guided scaffold. Run `npx eve@latest init <name>` from a parent directory, or create an empty directory first and run `eve init`, `eve init .`, or `eve init ./` inside it to run the same full scaffold there, including `package.json`. To add Eve to a non-empty existing app, use `npx eve@latest init .`: that add-agent flow requires a `package.json` and no existing `agent/` files yet, and Eve adds the missing `eve`, `ai`, and `zod` dependencies for you. Eve also ensures a compatible Node engine (for example `24.x`) is present; if an existing range is too narrow for the release, Eve updates it and warns you. Either way the final handoff runs the `eve dev` binary through the package manager, not the project’s own `dev` script.
|
|
28
28
|
|
|
29
|
-
To wire Eve
|
|
29
|
+
To wire Eve in by hand, declare a compatible Node runtime in `package.json`:
|
|
30
30
|
|
|
31
31
|
```json
|
|
32
32
|
{
|
|
@@ -36,7 +36,7 @@ To wire Eve into an existing app yourself instead, make sure the app declares a
|
|
|
36
36
|
}
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
Then
|
|
39
|
+
Then install Eve and author the two files the runtime needs:
|
|
40
40
|
|
|
41
41
|
```bash
|
|
42
42
|
npm install eve@latest
|
|
@@ -127,29 +127,7 @@ Attach to the session stream:
|
|
|
127
127
|
curl http://127.0.0.1:3000/eve/v1/session/<sessionId>/stream
|
|
128
128
|
```
|
|
129
129
|
|
|
130
|
-
The stream is NDJSON
|
|
131
|
-
|
|
132
|
-
- `session.started`
|
|
133
|
-
- `turn.started`
|
|
134
|
-
- `message.received`
|
|
135
|
-
- `step.started`
|
|
136
|
-
- `actions.requested`
|
|
137
|
-
- `action.result`
|
|
138
|
-
- `subagent.called`
|
|
139
|
-
- `subagent.completed`
|
|
140
|
-
- `reasoning.appended`
|
|
141
|
-
- `reasoning.completed`
|
|
142
|
-
- `message.appended`
|
|
143
|
-
- `message.completed`
|
|
144
|
-
- `step.completed`
|
|
145
|
-
- `turn.completed`
|
|
146
|
-
- `session.waiting`
|
|
147
|
-
- `session.completed`
|
|
148
|
-
- `session.failed`
|
|
149
|
-
|
|
150
|
-
`reasoning.appended` and `message.appended` are optional live-streaming events. Clients that can't surface incremental output can ignore them and rely on `reasoning.completed` and `message.completed`.
|
|
151
|
-
|
|
152
|
-
`message.completed.data.finishReason` tells you whether assistant text is interim tool-call narration or a terminal reply, and `step.completed.data.usage` carries token usage. When a parent delegates to a subagent, `subagent.called.data.childSessionId` gives you the child session id, so you can subscribe to that child stream and watch the delegated work.
|
|
130
|
+
The stream is NDJSON, one lifecycle event per line. See [Sessions, runs & streaming](./concepts/sessions-runs-and-streaming) for the full list of events and what each one carries.
|
|
153
131
|
|
|
154
132
|
## Send a follow-up message
|
|
155
133
|
|
|
@@ -168,8 +146,8 @@ See [Sessions, runs & streaming](./concepts/sessions-runs-and-streaming) for the
|
|
|
168
146
|
If a coding agent (Claude Code, Cursor, and the like) is doing the setup, hand it this prompt:
|
|
169
147
|
|
|
170
148
|
<CopyPrompt text="Set up an Eve agent for the user. Ask one question at a time. Use your prompt tools when available and do not guess. First ask what the agent should do. Then ask whether to create a new project or add it to an existing directory. For a new project, propose a name and ask the user to confirm it, then ask whether it should include Web Chat. Run `npx eve@latest init <target>`, adding `--channel-web-nextjs` if the user wants Web Chat. After scaffolding, read the relevant guide in `<project>/node_modules/eve/docs/`, replace the placeholder in `<project>/agent/instructions.md` with the purpose the user gave you, and do not start `eve dev` because it is interactive. Give the user the exact dev command printed by init.">
|
|
171
|
-
Set up an Eve agent by asking what it should do, whether to create a new project
|
|
172
|
-
|
|
149
|
+
Set up an Eve agent by asking what it should do, whether to create a new project, scaffold the
|
|
150
|
+
current empty directory, or add Eve to an existing app, and whether a new project should include Web Chat, one question at a time.
|
|
173
151
|
Run `npx eve@latest init <target>`, read the bundled docs, fill in agent/instructions.md, and give
|
|
174
152
|
the user the dev command instead of starting the interactive server.
|
|
175
153
|
</CopyPrompt>
|
|
@@ -178,7 +156,7 @@ Once `eve` is a dependency, the full docs are bundled in the package, so the age
|
|
|
178
156
|
|
|
179
157
|
- Docs: `node_modules/eve/docs/`
|
|
180
158
|
|
|
181
|
-
`eve init
|
|
159
|
+
`eve init [name]` creates the base agent; `eve init`, `eve init .`, and `eve init ./` do the same in the current empty directory; `eve init .` adds one to a non-empty existing app. Add `--channel-web-nextjs` for Web Chat, or run
|
|
182
160
|
`eve channels add slack` later from an interactive terminal.
|
|
183
161
|
|
|
184
162
|
## What to read next
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eve",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.5",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Filesystem-first framework for durable backend AI agents that run anywhere.",
|
|
6
6
|
"keywords": [
|
|
@@ -264,8 +264,7 @@
|
|
|
264
264
|
"access": "public"
|
|
265
265
|
},
|
|
266
266
|
"dependencies": {
|
|
267
|
-
"nitro": "3.0.260610-beta"
|
|
268
|
-
"semver": "7.8.4"
|
|
267
|
+
"nitro": "3.0.260610-beta"
|
|
269
268
|
},
|
|
270
269
|
"devDependencies": {
|
|
271
270
|
"@ai-sdk/anthropic": "4.0.0-beta.67",
|
|
@@ -306,6 +305,7 @@
|
|
|
306
305
|
"picocolors": "1.1.1",
|
|
307
306
|
"react": "19.2.6",
|
|
308
307
|
"react-test-renderer": "19.2.6",
|
|
308
|
+
"semver": "7.8.4",
|
|
309
309
|
"svelte": "^5.0.0",
|
|
310
310
|
"turndown": "7.2.4",
|
|
311
311
|
"vite": "^8.0.0",
|