eve 0.44.0 → 0.44.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/dist/src/chunks/{use-eve-agent-C0SG1Ttk.js → use-eve-agent-BsLJiIbc.js} +224 -62
- package/dist/src/chunks/{use-eve-agent-D71oDil7.js → use-eve-agent-DpUEwS23.js} +222 -62
- package/dist/src/cli/commands/extension-init.js +1 -1
- package/dist/src/cli/commands/init.js +1 -1
- package/dist/src/cli/dev/tui/setup-commands.js +1 -1
- package/dist/src/client/eve-agent-store-helpers.d.ts +12 -0
- package/dist/src/client/eve-agent-store-helpers.js +2 -0
- package/dist/src/client/eve-agent-store.d.ts +8 -6
- package/dist/src/client/eve-agent-store.js +1 -2
- package/dist/src/client/ndjson.d.ts +3 -1
- package/dist/src/client/ndjson.js +3 -3
- package/dist/src/client/open-stream.d.ts +3 -0
- package/dist/src/client/open-stream.js +1 -1
- package/dist/src/context/build-dynamic-tools.js +1 -1
- package/dist/src/context/dynamic-tool-lifecycle.d.ts +5 -1
- package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
- package/dist/src/context/keys.d.ts +4 -2
- package/dist/src/context/keys.js +1 -1
- package/dist/src/execution/cancel-descendant-turns-step.js +1 -1
- package/dist/src/execution/dispatch-turn-step.js +1 -1
- package/dist/src/execution/eve-workflow-attributes.d.ts +3 -0
- package/dist/src/execution/eve-workflow-attributes.js +1 -1
- package/dist/src/execution/pending-turn-state.d.ts +9 -0
- package/dist/src/execution/pending-turn-state.js +1 -0
- package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
- package/dist/src/execution/tasks/parent/tool-execution.js +1 -1
- package/dist/src/execution/turn-workflow.js +1 -1
- package/dist/src/execution/workflow-steps.js +1 -1
- package/dist/src/harness/channel-delivery-instrumentation.js +1 -1
- package/dist/src/harness/instrumentation/content-policy.d.ts +6 -0
- package/dist/src/harness/instrumentation/content-policy.js +1 -0
- package/dist/src/harness/instrumentation/lifecycle.d.ts +2 -0
- package/dist/src/harness/instrumentation/runtime-context.js +1 -1
- package/dist/src/harness/runtime-actions.js +1 -1
- package/dist/src/harness/tool-loop.js +2 -2
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/workflow-bundle/dynamic-remote-agent-transform.js +2 -2
- package/dist/src/internal/workflow-bundle/dynamic-tool-transform.d.ts +4 -4
- package/dist/src/internal/workflow-bundle/dynamic-tool-transform.js +3 -4
- package/dist/src/internal/workflow-bundle/stable-module-id.d.ts +6 -0
- package/dist/src/internal/workflow-bundle/stable-module-id.js +1 -0
- package/dist/src/packages/eve-catalog/src/index.js +1 -1
- package/dist/src/public/channels/eve.js +3 -3
- package/dist/src/public/tools/approval/approval-helpers.js +1 -1
- package/dist/src/react/use-eve-agent.d.ts +10 -1
- package/dist/src/react/use-eve-agent.js +1 -1
- package/dist/src/runtime/attributes/emit.d.ts +1 -1
- package/dist/src/runtime/attributes/normalize.d.ts +1 -1
- package/dist/src/runtime/attributes/normalize.js +1 -1
- package/dist/src/runtime/framework-tools/connection-search-dynamic.js +2 -2
- package/dist/src/runtime/framework-tools/subagent/local.js +1 -1
- package/dist/src/runtime/sessions/runtime-context-keys.js +1 -1
- package/dist/src/setup/integrations/linq/connect.js +1 -1
- package/dist/src/setup/primitives/pm/npm.js +1 -1
- package/dist/src/setup/primitives/pm/pnpm.js +5 -9
- package/dist/src/setup/primitives/pm/types.d.ts +0 -2
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/setup/scaffold/create/web-template.d.ts +9 -4
- package/dist/src/setup/scaffold/create/web-template.js +296 -73
- package/dist/src/shared/durable-dynamic-tool-callbacks.d.ts +43 -19
- package/dist/src/shared/durable-dynamic-tool-callbacks.js +1 -1
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-eve-agent.d.ts +4 -0
- package/dist/src/svelte/use-eve-agent.js +1 -1
- package/dist/src/tasks/delivery-context.d.ts +9 -0
- package/dist/src/tasks/delivery-context.js +5 -2
- package/dist/src/vue/index.js +1 -1
- package/dist/src/vue/use-eve-agent.d.ts +4 -0
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/docs/concepts/sessions-runs-and-streaming.md +1 -1
- package/docs/guides/dynamic-capabilities.md +10 -2
- package/docs/guides/frontend/nextjs.mdx +23 -0
- package/docs/guides/frontend/overview.mdx +24 -9
- package/docs/guides/frontend/use-eve-agent-svelte.mdx +9 -9
- package/docs/guides/frontend/use-eve-agent-vue.mdx +9 -9
- package/docs/tools/overview.mdx +5 -4
- package/package.json +1 -1
|
@@ -527,14 +527,14 @@ function isStreamDisconnectError(error) {
|
|
|
527
527
|
const errorCode = "code" in error && typeof error.code === "string" ? error.code : void 0;
|
|
528
528
|
return error.name === "AbortError" || error.message === "terminated" || errorCode === "UND_ERR_SOCKET" || error instanceof TypeError && /^(?:failed to fetch|fetch failed)$/i.test(error.message) || /abort|cancel|disconnect|premature close|socket|terminated/i.test(error.message);
|
|
529
529
|
}
|
|
530
|
-
async function* readNdjsonStream(body) {
|
|
530
|
+
async function* readNdjsonStream(body, options) {
|
|
531
531
|
const reader = body.getReader();
|
|
532
532
|
const decoder = new TextDecoder();
|
|
533
533
|
let buffer = "";
|
|
534
534
|
let reachedEof = false;
|
|
535
535
|
try {
|
|
536
536
|
while (true) {
|
|
537
|
-
const result = await reader
|
|
537
|
+
const result = await readWithIdleTimeout(reader, options?.idleTimeoutMs);
|
|
538
538
|
if (result.done) {
|
|
539
539
|
reachedEof = true;
|
|
540
540
|
buffer += decoder.decode();
|
|
@@ -556,6 +556,17 @@ async function* readNdjsonStream(body) {
|
|
|
556
556
|
reader.releaseLock();
|
|
557
557
|
}
|
|
558
558
|
}
|
|
559
|
+
async function readWithIdleTimeout(reader, idleTimeoutMs) {
|
|
560
|
+
if (idleTimeoutMs === void 0) return await reader.read();
|
|
561
|
+
let timeout;
|
|
562
|
+
try {
|
|
563
|
+
return await Promise.race([reader.read(), new Promise((_resolve, reject) => {
|
|
564
|
+
timeout = setTimeout(() => reject(new DOMException("Session stream was idle.", "AbortError")), idleTimeoutMs);
|
|
565
|
+
})]);
|
|
566
|
+
} finally {
|
|
567
|
+
if (timeout !== void 0) clearTimeout(timeout);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
559
570
|
|
|
560
571
|
//#endregion
|
|
561
572
|
//#region src/client/url.ts
|
|
@@ -600,6 +611,7 @@ function formatSearch(searchParams) {
|
|
|
600
611
|
|
|
601
612
|
//#endregion
|
|
602
613
|
//#region src/client/open-stream.ts
|
|
614
|
+
const DEFAULT_STREAM_READ_IDLE_TIMEOUT_MS = 15e3;
|
|
603
615
|
const DEFAULT_STREAM_RECONNECT_POLICY = {
|
|
604
616
|
retryableErrorStatuses: /* @__PURE__ */ new Set([
|
|
605
617
|
404,
|
|
@@ -672,17 +684,17 @@ async function* followStreamIterable(input) {
|
|
|
672
684
|
if (input.follow === false && tailIndex === void 0) {
|
|
673
685
|
tailIndex = connection.tailIndex;
|
|
674
686
|
if (tailIndex === void 0) {
|
|
675
|
-
|
|
687
|
+
connection.close();
|
|
676
688
|
throw new Error(`stream({ follow: false }) requires the server to report the ${EVE_STREAM_TAIL_INDEX_HEADER} header. The agent may be running an older eve version.`);
|
|
677
689
|
}
|
|
678
690
|
}
|
|
679
691
|
if (tailIndex !== void 0 && startIndex > tailIndex) {
|
|
680
|
-
|
|
692
|
+
connection.close();
|
|
681
693
|
return;
|
|
682
694
|
}
|
|
683
695
|
let deliveredEvent = false;
|
|
684
696
|
try {
|
|
685
|
-
for await (const event of readNdjsonStream(connection.body)) {
|
|
697
|
+
for await (const event of readNdjsonStream(connection.body, { idleTimeoutMs: input.streamReadIdleTimeoutMs ?? DEFAULT_STREAM_READ_IDLE_TIMEOUT_MS })) {
|
|
686
698
|
startIndex += 1;
|
|
687
699
|
deliveredEvent = true;
|
|
688
700
|
reconnectDelayMs = idleRetryPolicy.baseDelayMs;
|
|
@@ -692,6 +704,8 @@ async function* followStreamIterable(input) {
|
|
|
692
704
|
}
|
|
693
705
|
} catch (error) {
|
|
694
706
|
if (!isStreamDisconnectError(error)) throw error;
|
|
707
|
+
} finally {
|
|
708
|
+
connection.close();
|
|
695
709
|
}
|
|
696
710
|
if (input.signal?.aborted || input.startIndex < 0 || idleRetryPolicy.maxAttempts === 0) return;
|
|
697
711
|
if (input.keepAlive !== true && !deliveredEvent && !initialConnection && (idleReconnects += 1) >= idleRetryPolicy.maxAttempts) return;
|
|
@@ -714,13 +728,15 @@ async function openStreamBody(input) {
|
|
|
714
728
|
for (let attempt = 0; attempt < openRetryPolicy.maxAttempts; attempt += 1) {
|
|
715
729
|
const url = createClientUrl(input.host, createEveSessionStreamRoutePath(input.sessionId), Object.keys(searchParams).length > 0 ? searchParams : void 0);
|
|
716
730
|
const headers = await input.resolveHeaders();
|
|
731
|
+
const connectionController = new AbortController();
|
|
732
|
+
const signal = input.signal ? AbortSignal.any([input.signal, connectionController.signal]) : connectionController.signal;
|
|
717
733
|
let response;
|
|
718
734
|
try {
|
|
719
735
|
response = await fetch(url, {
|
|
720
736
|
cache: "no-store",
|
|
721
737
|
headers,
|
|
722
738
|
redirect: input.redirect,
|
|
723
|
-
signal
|
|
739
|
+
signal
|
|
724
740
|
});
|
|
725
741
|
} catch (error) {
|
|
726
742
|
if (input.signal?.aborted || !isStreamDisconnectError(error) || attempt === openRetryPolicy.maxAttempts - 1) throw error;
|
|
@@ -732,6 +748,7 @@ async function openStreamBody(input) {
|
|
|
732
748
|
if (!response.body) throw new ClientError(response.status, "Response body is null.", response.headers);
|
|
733
749
|
return {
|
|
734
750
|
body: response.body,
|
|
751
|
+
close: () => connectionController.abort(),
|
|
735
752
|
tailIndex: parseTailIndexHeader(response.headers)
|
|
736
753
|
};
|
|
737
754
|
}
|
|
@@ -1317,6 +1334,51 @@ function createEventDeduper() {
|
|
|
1317
1334
|
};
|
|
1318
1335
|
}
|
|
1319
1336
|
|
|
1337
|
+
//#endregion
|
|
1338
|
+
//#region src/client/eve-agent-store-helpers.ts
|
|
1339
|
+
function isSettledSessionTail(events) {
|
|
1340
|
+
const tail = events.at(-1);
|
|
1341
|
+
return tail !== void 0 && isCurrentTurnBoundaryEvent(tail) && (tail.type !== "session.waiting" || collectPendingAuthorizations(events).size === 0);
|
|
1342
|
+
}
|
|
1343
|
+
function collectPendingAuthorizations(events) {
|
|
1344
|
+
const pending = /* @__PURE__ */ new Set();
|
|
1345
|
+
for (const event of events) updatePendingAuthorizations(pending, event);
|
|
1346
|
+
return pending;
|
|
1347
|
+
}
|
|
1348
|
+
function updatePendingAuthorizations(pending, event) {
|
|
1349
|
+
if (event.type === "authorization.required" && event.data.webhookUrl !== void 0) pending.add(event.data.name);
|
|
1350
|
+
else if (event.type === "authorization.completed") pending.delete(event.data.name);
|
|
1351
|
+
}
|
|
1352
|
+
function assertExclusiveTurnInput(input) {
|
|
1353
|
+
if (input.message !== void 0 === (input.inputResponses !== void 0)) throw new Error("A turn requires exactly one of message or inputResponses.");
|
|
1354
|
+
}
|
|
1355
|
+
let submissionSequence = 0;
|
|
1356
|
+
function createSubmissionId() {
|
|
1357
|
+
const randomUUID = globalThis.crypto?.randomUUID;
|
|
1358
|
+
if (randomUUID !== void 0) return randomUUID.call(globalThis.crypto);
|
|
1359
|
+
submissionSequence += 1;
|
|
1360
|
+
return `submission_${submissionSequence.toString()}`;
|
|
1361
|
+
}
|
|
1362
|
+
function createAbortSignal(first, second) {
|
|
1363
|
+
return first ? AbortSignal.any([first, second]) : second;
|
|
1364
|
+
}
|
|
1365
|
+
function summarizeUserContent(message) {
|
|
1366
|
+
if (typeof message === "string") return message;
|
|
1367
|
+
const parts = [];
|
|
1368
|
+
for (const part of message) if (part.type === "text") parts.push(part.text);
|
|
1369
|
+
else if (part.type === "file") parts.push(part.filename ? `[file: ${part.filename}]` : "[file]");
|
|
1370
|
+
return parts.join("\n");
|
|
1371
|
+
}
|
|
1372
|
+
function isAbortError(error) {
|
|
1373
|
+
return error instanceof Error && error.name === "AbortError";
|
|
1374
|
+
}
|
|
1375
|
+
function toTerminalStreamFailureError(event) {
|
|
1376
|
+
if (event.type !== "session.failed") return void 0;
|
|
1377
|
+
const error = new Error(event.data.message);
|
|
1378
|
+
error.name = event.data.code;
|
|
1379
|
+
return error;
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1320
1382
|
//#endregion
|
|
1321
1383
|
//#region src/client/eve-agent-store.ts
|
|
1322
1384
|
const detachStore = Symbol("detachEveAgentStore");
|
|
@@ -1332,8 +1394,9 @@ var EveAgentStore = class {
|
|
|
1332
1394
|
#data;
|
|
1333
1395
|
#error;
|
|
1334
1396
|
#events;
|
|
1335
|
-
#
|
|
1397
|
+
#pendingMessageSubmissions = [];
|
|
1336
1398
|
#projectionEvents;
|
|
1399
|
+
#resumePromise;
|
|
1337
1400
|
#session;
|
|
1338
1401
|
#snapshot;
|
|
1339
1402
|
#status = "ready";
|
|
@@ -1367,10 +1430,17 @@ var EveAgentStore = class {
|
|
|
1367
1430
|
};
|
|
1368
1431
|
}
|
|
1369
1432
|
async send(input) {
|
|
1370
|
-
if (this.#
|
|
1433
|
+
if (this.#activeTurn !== void 0) return await this.#sendFollowUp(this.#activeTurn, input);
|
|
1371
1434
|
const response = Promise.withResolvers();
|
|
1435
|
+
const completion = Promise.withResolvers();
|
|
1372
1436
|
const turn = {
|
|
1373
1437
|
abortController: new AbortController(),
|
|
1438
|
+
acceptedFollowUps: 0,
|
|
1439
|
+
cancel: () => turn.acceptedFollowUps > 0 && this.#session !== void 0 ? this.#session.cancel() : response.promise.then((messageResponse) => messageResponse === void 0 ? { status: "no_active_turn" } : messageResponse.cancel()),
|
|
1440
|
+
completion: completion.promise,
|
|
1441
|
+
followUpDispatches: /* @__PURE__ */ new Set(),
|
|
1442
|
+
receivedFollowUps: 0,
|
|
1443
|
+
resolveCompletion: completion.resolve,
|
|
1374
1444
|
response: response.promise,
|
|
1375
1445
|
resolveResponse: response.resolve
|
|
1376
1446
|
};
|
|
@@ -1392,21 +1462,13 @@ var EveAgentStore = class {
|
|
|
1392
1462
|
const response = await this.#dispatchTurn(turnInput);
|
|
1393
1463
|
if (!this.#isActiveTurn(turn)) return;
|
|
1394
1464
|
turn.resolveResponse(response);
|
|
1395
|
-
let sawEvent = false;
|
|
1396
1465
|
for await (const event of response) {
|
|
1397
1466
|
if (!this.#isActiveTurn(turn)) return;
|
|
1398
|
-
|
|
1399
|
-
sawEvent = true;
|
|
1400
|
-
this.#status = "streaming";
|
|
1401
|
-
}
|
|
1402
|
-
if (!this.#seenEvents.admit(event)) continue;
|
|
1403
|
-
this.#events = [...this.#events, event];
|
|
1404
|
-
this.#applyServerEvent(event);
|
|
1405
|
-
this.#callbacks.onEvent?.(event);
|
|
1406
|
-
this.#applyTerminalStreamFailure(event);
|
|
1407
|
-
this.#publish();
|
|
1467
|
+
this.#acceptServerEvent(event);
|
|
1408
1468
|
}
|
|
1409
1469
|
if (!this.#isActiveTurn(turn)) return;
|
|
1470
|
+
await this.#followSteeredTurns(turn);
|
|
1471
|
+
if (!this.#isActiveTurn(turn)) return;
|
|
1410
1472
|
this.#status = this.#error === void 0 ? "ready" : "error";
|
|
1411
1473
|
} catch (error) {
|
|
1412
1474
|
if (!this.#isActiveTurn(turn)) return;
|
|
@@ -1426,13 +1488,89 @@ var EveAgentStore = class {
|
|
|
1426
1488
|
this.#callbacks.onSessionChange?.(this.#session?.state);
|
|
1427
1489
|
this.#publish();
|
|
1428
1490
|
this.#callbacks.onFinish?.(this.#snapshot);
|
|
1491
|
+
turn.resolveCompletion();
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1494
|
+
}
|
|
1495
|
+
resume() {
|
|
1496
|
+
if (this.#resumePromise !== void 0) return this.#resumePromise;
|
|
1497
|
+
const promise = this.#resume();
|
|
1498
|
+
this.#resumePromise = promise;
|
|
1499
|
+
const clear = () => {
|
|
1500
|
+
if (this.#resumePromise === promise) this.#resumePromise = void 0;
|
|
1501
|
+
};
|
|
1502
|
+
promise.then(clear, clear);
|
|
1503
|
+
return promise;
|
|
1504
|
+
}
|
|
1505
|
+
async #resume() {
|
|
1506
|
+
if (this.#status === "streaming" || this.#status === "submitted") throw new Error("eve session is already processing a turn.");
|
|
1507
|
+
if (this.#session === void 0) throw new Error("An eve session is required before resuming.");
|
|
1508
|
+
const response = Promise.withResolvers();
|
|
1509
|
+
const completion = Promise.withResolvers();
|
|
1510
|
+
const session = this.#session;
|
|
1511
|
+
const turn = {
|
|
1512
|
+
abortController: new AbortController(),
|
|
1513
|
+
acceptedFollowUps: 0,
|
|
1514
|
+
cancel: () => session.cancel(),
|
|
1515
|
+
completion: completion.promise,
|
|
1516
|
+
followUpDispatches: /* @__PURE__ */ new Set(),
|
|
1517
|
+
receivedFollowUps: 0,
|
|
1518
|
+
resolveCompletion: completion.resolve,
|
|
1519
|
+
response: response.promise,
|
|
1520
|
+
resolveResponse: response.resolve
|
|
1521
|
+
};
|
|
1522
|
+
this.#activeTurn = turn;
|
|
1523
|
+
turn.resolveResponse(void 0);
|
|
1524
|
+
this.#error = void 0;
|
|
1525
|
+
this.#status = "submitted";
|
|
1526
|
+
this.#publish();
|
|
1527
|
+
try {
|
|
1528
|
+
const replayed = [];
|
|
1529
|
+
for await (const event of session.stream({
|
|
1530
|
+
follow: false,
|
|
1531
|
+
signal: turn.abortController.signal,
|
|
1532
|
+
startIndex: 0
|
|
1533
|
+
})) {
|
|
1534
|
+
if (!this.#isActiveTurn(turn)) return;
|
|
1535
|
+
replayed.push(event);
|
|
1536
|
+
this.#acceptServerEvent(event, false);
|
|
1537
|
+
}
|
|
1538
|
+
if (!this.#isActiveTurn(turn)) return;
|
|
1539
|
+
this.#publish();
|
|
1540
|
+
if (!isSettledSessionTail(replayed)) {
|
|
1541
|
+
const pendingAuthorizations = collectPendingAuthorizations(replayed);
|
|
1542
|
+
for await (const event of session.stream({ signal: turn.abortController.signal })) {
|
|
1543
|
+
if (!this.#isActiveTurn(turn)) return;
|
|
1544
|
+
this.#acceptServerEvent(event);
|
|
1545
|
+
updatePendingAuthorizations(pendingAuthorizations, event);
|
|
1546
|
+
if (isCurrentTurnBoundaryEvent(event) && (event.type !== "session.waiting" || pendingAuthorizations.size === 0)) break;
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
await this.#followSteeredTurns(turn);
|
|
1550
|
+
if (this.#isActiveTurn(turn)) this.#status = this.#error === void 0 ? "ready" : "error";
|
|
1551
|
+
} catch (error) {
|
|
1552
|
+
if (!this.#isActiveTurn(turn)) return;
|
|
1553
|
+
if (isAbortError(error)) this.#status = "ready";
|
|
1554
|
+
else {
|
|
1555
|
+
this.#error = toError(error);
|
|
1556
|
+
this.#status = "error";
|
|
1557
|
+
this.#callbacks.onError?.(this.#error);
|
|
1558
|
+
}
|
|
1559
|
+
} finally {
|
|
1560
|
+
if (this.#isActiveTurn(turn)) {
|
|
1561
|
+
turn.resolveResponse(void 0);
|
|
1562
|
+
this.#activeTurn = void 0;
|
|
1563
|
+
this.#callbacks.onSessionChange?.(session.state);
|
|
1564
|
+
this.#publish();
|
|
1565
|
+
this.#callbacks.onFinish?.(this.#snapshot);
|
|
1566
|
+
turn.resolveCompletion();
|
|
1429
1567
|
}
|
|
1430
1568
|
}
|
|
1431
1569
|
}
|
|
1432
1570
|
cancel() {
|
|
1433
1571
|
const turn = this.#activeTurn;
|
|
1434
1572
|
if (turn === void 0) return Promise.resolve({ status: "no_active_turn" });
|
|
1435
|
-
return turn.
|
|
1573
|
+
return turn.cancel();
|
|
1436
1574
|
}
|
|
1437
1575
|
[detachStore]() {
|
|
1438
1576
|
this.#activeTurn?.abortController.abort();
|
|
@@ -1441,11 +1579,12 @@ var EveAgentStore = class {
|
|
|
1441
1579
|
const turn = this.#activeTurn;
|
|
1442
1580
|
this.#activeTurn = void 0;
|
|
1443
1581
|
turn?.resolveResponse(void 0);
|
|
1582
|
+
turn?.resolveCompletion();
|
|
1444
1583
|
turn?.abortController.abort();
|
|
1445
1584
|
if (!this.#externalSession) this.#session = void 0;
|
|
1446
1585
|
this.#events = [];
|
|
1447
1586
|
this.#seenEvents = createEventDeduper();
|
|
1448
|
-
this.#
|
|
1587
|
+
this.#pendingMessageSubmissions = [];
|
|
1449
1588
|
this.#projectionEvents = [];
|
|
1450
1589
|
this.#data = this.#reducer.initial();
|
|
1451
1590
|
this.#error = void 0;
|
|
@@ -1453,6 +1592,47 @@ var EveAgentStore = class {
|
|
|
1453
1592
|
this.#callbacks.onSessionChange?.(this.#session?.state);
|
|
1454
1593
|
this.#publish();
|
|
1455
1594
|
}
|
|
1595
|
+
async #sendFollowUp(turn, input) {
|
|
1596
|
+
if (input.message === void 0 || input.turnPolicy !== "steer") throw new Error("eve session is already processing a turn. Send a message with turnPolicy: \"steer\" to replace it.");
|
|
1597
|
+
const preparedInput = await this.#callbacks.prepareSend?.(input) ?? input;
|
|
1598
|
+
assertExclusiveTurnInput(preparedInput);
|
|
1599
|
+
if (preparedInput.message === void 0 || preparedInput.turnPolicy !== "steer") throw new Error("An in-flight follow-up requires a message with turnPolicy: \"steer\".");
|
|
1600
|
+
if (!this.#isActiveTurn(turn)) return await this.send(preparedInput);
|
|
1601
|
+
const submissionId = this.#projectOptimisticMessage(preparedInput);
|
|
1602
|
+
this.#publish();
|
|
1603
|
+
let dispatch;
|
|
1604
|
+
dispatch = (async () => {
|
|
1605
|
+
try {
|
|
1606
|
+
await turn.response;
|
|
1607
|
+
if (!this.#isActiveTurn(turn) || this.#session === void 0) throw new Error("The active eve turn ended before the follow-up could be sent.");
|
|
1608
|
+
const { message, ...options } = preparedInput;
|
|
1609
|
+
await this.#session.send(message, options);
|
|
1610
|
+
turn.acceptedFollowUps += 1;
|
|
1611
|
+
} catch (error) {
|
|
1612
|
+
this.#failPendingMessageSubmission(toError(error), submissionId);
|
|
1613
|
+
this.#publish();
|
|
1614
|
+
throw error;
|
|
1615
|
+
} finally {
|
|
1616
|
+
turn.followUpDispatches.delete(dispatch);
|
|
1617
|
+
}
|
|
1618
|
+
})();
|
|
1619
|
+
turn.followUpDispatches.add(dispatch);
|
|
1620
|
+
await dispatch;
|
|
1621
|
+
await turn.completion;
|
|
1622
|
+
}
|
|
1623
|
+
async #followSteeredTurns(turn) {
|
|
1624
|
+
while (turn.followUpDispatches.size > 0) await Promise.allSettled(turn.followUpDispatches);
|
|
1625
|
+
if (turn.receivedFollowUps >= turn.acceptedFollowUps || this.#session === void 0) return;
|
|
1626
|
+
for await (const event of this.#session.stream({ signal: turn.abortController.signal })) {
|
|
1627
|
+
if (!this.#isActiveTurn(turn)) return;
|
|
1628
|
+
if (event.type === "message.received") turn.receivedFollowUps += 1;
|
|
1629
|
+
this.#acceptServerEvent(event);
|
|
1630
|
+
if (isCurrentTurnBoundaryEvent(event)) {
|
|
1631
|
+
while (turn.followUpDispatches.size > 0) await Promise.allSettled(turn.followUpDispatches);
|
|
1632
|
+
if (turn.receivedFollowUps >= turn.acceptedFollowUps) return;
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1456
1636
|
async #createFirstTurn(input) {
|
|
1457
1637
|
if (this.#client === void 0) throw new Error("An external eve session is required before sending.");
|
|
1458
1638
|
if (input.message === void 0) throw new Error("Cannot answer an input request before the session starts.");
|
|
@@ -1485,7 +1665,7 @@ var EveAgentStore = class {
|
|
|
1485
1665
|
id,
|
|
1486
1666
|
message: summarizeUserContent(input.message)
|
|
1487
1667
|
};
|
|
1488
|
-
this.#
|
|
1668
|
+
this.#pendingMessageSubmissions = [...this.#pendingMessageSubmissions, pending];
|
|
1489
1669
|
this.#appendProjectionEvent({
|
|
1490
1670
|
data: {
|
|
1491
1671
|
createdAt: pending.createdAt,
|
|
@@ -1494,6 +1674,7 @@ var EveAgentStore = class {
|
|
|
1494
1674
|
},
|
|
1495
1675
|
type: "client.message.submitted"
|
|
1496
1676
|
});
|
|
1677
|
+
return id;
|
|
1497
1678
|
}
|
|
1498
1679
|
#projectInputResponses(input) {
|
|
1499
1680
|
if (input.inputResponses === void 0 || input.inputResponses.length === 0) return;
|
|
@@ -1505,10 +1686,20 @@ var EveAgentStore = class {
|
|
|
1505
1686
|
type: "client.input.responded"
|
|
1506
1687
|
});
|
|
1507
1688
|
}
|
|
1689
|
+
#acceptServerEvent(event, publish = true) {
|
|
1690
|
+
if (!this.#seenEvents.admit(event)) return;
|
|
1691
|
+
this.#events = [...this.#events, event];
|
|
1692
|
+
this.#applyServerEvent(event);
|
|
1693
|
+
this.#callbacks.onEvent?.(event);
|
|
1694
|
+
this.#status = "streaming";
|
|
1695
|
+
this.#applyTerminalStreamFailure(event);
|
|
1696
|
+
if (publish) this.#publish();
|
|
1697
|
+
}
|
|
1508
1698
|
#applyServerEvent(event) {
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1699
|
+
const pendingSubmission = this.#pendingMessageSubmissions[0];
|
|
1700
|
+
if (event.type === "message.received" && pendingSubmission !== void 0) {
|
|
1701
|
+
const submissionId = pendingSubmission.id;
|
|
1702
|
+
this.#pendingMessageSubmissions = this.#pendingMessageSubmissions.slice(1);
|
|
1512
1703
|
this.#replaceProjectionEvent((candidate) => candidate.type === "client.message.submitted" && candidate.data.submissionId === submissionId, event);
|
|
1513
1704
|
return;
|
|
1514
1705
|
}
|
|
@@ -1524,10 +1715,10 @@ var EveAgentStore = class {
|
|
|
1524
1715
|
this.#callbacks.onError?.(error);
|
|
1525
1716
|
}
|
|
1526
1717
|
}
|
|
1527
|
-
#failPendingMessageSubmission(error) {
|
|
1528
|
-
const pending = this.#
|
|
1718
|
+
#failPendingMessageSubmission(error, submissionId) {
|
|
1719
|
+
const pending = submissionId === void 0 ? this.#pendingMessageSubmissions[0] : this.#pendingMessageSubmissions.find((candidate) => candidate.id === submissionId);
|
|
1529
1720
|
if (pending === void 0) return;
|
|
1530
|
-
this.#
|
|
1721
|
+
this.#pendingMessageSubmissions = this.#pendingMessageSubmissions.filter((candidate) => candidate.id !== pending.id);
|
|
1531
1722
|
this.#replaceProjectionEvent((event) => event.type === "client.message.submitted" && event.data.submissionId === pending.id, {
|
|
1532
1723
|
data: {
|
|
1533
1724
|
createdAt: pending.createdAt,
|
|
@@ -1576,40 +1767,6 @@ var EveAgentStore = class {
|
|
|
1576
1767
|
function detachEveAgentStore(store) {
|
|
1577
1768
|
store[detachStore]();
|
|
1578
1769
|
}
|
|
1579
|
-
function assertExclusiveTurnInput(input) {
|
|
1580
|
-
if (input.message !== void 0 === (input.inputResponses !== void 0)) throw new Error("A turn requires exactly one of message or inputResponses.");
|
|
1581
|
-
}
|
|
1582
|
-
let submissionSequence = 0;
|
|
1583
|
-
function createSubmissionId() {
|
|
1584
|
-
const randomUUID = globalThis.crypto?.randomUUID;
|
|
1585
|
-
if (randomUUID !== void 0) return randomUUID.call(globalThis.crypto);
|
|
1586
|
-
submissionSequence += 1;
|
|
1587
|
-
return `submission_${submissionSequence.toString()}`;
|
|
1588
|
-
}
|
|
1589
|
-
function createAbortSignal(first, second) {
|
|
1590
|
-
return first ? AbortSignal.any([first, second]) : second;
|
|
1591
|
-
}
|
|
1592
|
-
function summarizeUserContent(message) {
|
|
1593
|
-
if (typeof message === "string") return message;
|
|
1594
|
-
const parts = [];
|
|
1595
|
-
for (const part of message) {
|
|
1596
|
-
if (part.type === "text") {
|
|
1597
|
-
parts.push(part.text);
|
|
1598
|
-
continue;
|
|
1599
|
-
}
|
|
1600
|
-
if (part.type === "file") parts.push(part.filename ? `[file: ${part.filename}]` : "[file]");
|
|
1601
|
-
}
|
|
1602
|
-
return parts.join("\n");
|
|
1603
|
-
}
|
|
1604
|
-
function isAbortError(error) {
|
|
1605
|
-
return error instanceof Error && error.name === "AbortError";
|
|
1606
|
-
}
|
|
1607
|
-
function toTerminalStreamFailureError(event) {
|
|
1608
|
-
if (event.type !== "session.failed") return;
|
|
1609
|
-
const error = new Error(event.data.message);
|
|
1610
|
-
error.name = event.data.code;
|
|
1611
|
-
return error;
|
|
1612
|
-
}
|
|
1613
1770
|
|
|
1614
1771
|
//#endregion
|
|
1615
1772
|
//#region src/client/agent-host.ts
|
|
@@ -2189,6 +2346,7 @@ function optimisticUserMessageId(submissionId) {
|
|
|
2189
2346
|
//#endregion
|
|
2190
2347
|
//#region src/vue/use-eve-agent.ts
|
|
2191
2348
|
function useEveAgent(options = {}) {
|
|
2349
|
+
if (options.resume && options.initialSession === void 0 && options.session === void 0) throw new Error("useEveAgent({ resume: true }) requires initialSession or session.");
|
|
2192
2350
|
const reducer = options.reducer ?? defaultMessageReducer();
|
|
2193
2351
|
const store = new EveAgentStore({
|
|
2194
2352
|
auth: options.auth,
|
|
@@ -2215,6 +2373,7 @@ function useEveAgent(options = {}) {
|
|
|
2215
2373
|
const unsubscribe = store.subscribe(() => {
|
|
2216
2374
|
snapshot.value = store.snapshot;
|
|
2217
2375
|
});
|
|
2376
|
+
if (options.resume) store.resume();
|
|
2218
2377
|
onScopeDispose(() => {
|
|
2219
2378
|
unsubscribe();
|
|
2220
2379
|
detachEveAgentStore(store);
|
|
@@ -2230,6 +2389,7 @@ function useEveAgent(options = {}) {
|
|
|
2230
2389
|
...options,
|
|
2231
2390
|
inputResponses
|
|
2232
2391
|
}),
|
|
2392
|
+
resume: () => store.resume(),
|
|
2233
2393
|
send: (message, options) => store.send({
|
|
2234
2394
|
...options,
|
|
2235
2395
|
message
|
|
@@ -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{initExtensionHandoff,initExtensionInstructions}from"./agent-instructions.js";import{tryInitializeGit}from"./init-git.js";import{mkdtemp,readdir,rename,rm,stat}from"node:fs/promises";import{createLogger,isLogLevelEnabled}from"#internal/logging.js";import{basename,join,resolve}from"node:path";import{scaffoldExtensionProject}from"#setup/scaffold/index.js";import{packageManagerInstallFailureMessage,packageManagerInstallSucceeded,runPackageManagerInstall}from"#setup/primitives/index.js";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{blockingCreateInPlaceEntries}from"#setup/scaffold/create-in-place.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},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=blockingCreateInPlaceEntries(await readdir(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 o=resolve(e),l=t===`.`,u=l?o:join(o,t);if(l)await assertCanScaffoldInPlace(u);else if(await pathExists(u))throw Error(`Cannot create project because "${u}" already exists.`);let d=await mkdtemp(join(o,`.eve-extension-init-`)),p=[];try{let e=l?basename(u):t,a=await r.scaffoldExtensionProject({projectName:e,evePackage:i,targetDirectory:d,workspaceProbeDirectory:u,packageManager:n,onWorkspaceRootMutation:e=>{p.push(e)}});return l?await moveDirectoryContents(a,u):await rename(a,u),{projectPath:u,workspaceRootMutations:uniqueWorkspaceRootMutations(p)}}finally{await rm(d,{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 o=isLogLevelEnabled(`debug`),s=startCliLiveRow(e);s.update(`Preparing project`);let c,l,u=[],p,m,h;try{let n=i??`.`,r=isCurrentDirectoryTarget(n),d=r?await pathExists(join(resolve(t),`package.json`))?resolve(t):void 0:await resolveTargetDirectory(t,n),f=resolveInitEvePackageOverride();if(d!==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 .`.");s.update(`Creating extension`),initLog.debug(`creating extension`);let g=a.now(),_=r?`.`:parseProjectName(n),v=resolve(t);l=await resolveScaffoldPackageManager(_===`.`?v:join(v,_),a);let y=await scaffoldExtension(t,_,l,a,f);c=y.projectPath,u=y.workspaceRootMutations,p=a.now()-g,initLog.debug(`creating extension done`,{ms:p}),s.update(`Installing dependencies`,`${l} install`),initLog.debug(`installing dependencies with ${l}`);let b=a.now(),x=[],S=[],C=await a.runPackageManagerInstall(l,c,{
|
|
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{mkdtemp,readdir,rename,rm,stat}from"node:fs/promises";import{createLogger,isLogLevelEnabled}from"#internal/logging.js";import{basename,join,resolve}from"node:path";import{scaffoldExtensionProject}from"#setup/scaffold/index.js";import{packageManagerInstallFailureMessage,packageManagerInstallSucceeded,runPackageManagerInstall}from"#setup/primitives/index.js";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{blockingCreateInPlaceEntries}from"#setup/scaffold/create-in-place.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},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=blockingCreateInPlaceEntries(await readdir(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 o=resolve(e),l=t===`.`,u=l?o:join(o,t);if(l)await assertCanScaffoldInPlace(u);else if(await pathExists(u))throw Error(`Cannot create project because "${u}" already exists.`);let d=await mkdtemp(join(o,`.eve-extension-init-`)),p=[];try{let e=l?basename(u):t,a=await r.scaffoldExtensionProject({projectName:e,evePackage:i,targetDirectory:d,workspaceProbeDirectory:u,packageManager:n,onWorkspaceRootMutation:e=>{p.push(e)}});return l?await moveDirectoryContents(a,u):await rename(a,u),{projectPath:u,workspaceRootMutations:uniqueWorkspaceRootMutations(p)}}finally{await rm(d,{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 o=isLogLevelEnabled(`debug`),s=startCliLiveRow(e);s.update(`Preparing project`);let c,l,u=[],p,m,h;try{let n=i??`.`,r=isCurrentDirectoryTarget(n),d=r?await pathExists(join(resolve(t),`package.json`))?resolve(t):void 0:await resolveTargetDirectory(t,n),f=resolveInitEvePackageOverride();if(d!==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 .`.");s.update(`Creating extension`),initLog.debug(`creating extension`);let g=a.now(),_=r?`.`:parseProjectName(n),v=resolve(t);l=await resolveScaffoldPackageManager(_===`.`?v:join(v,_),a);let y=await scaffoldExtension(t,_,l,a,f);c=y.projectPath,u=y.workspaceRootMutations,p=a.now()-g,initLog.debug(`creating extension done`,{ms:p}),s.update(`Installing dependencies`,`${l} install`),initLog.debug(`installing dependencies with ${l}`);let b=a.now(),x=[],S=[],C=await a.runPackageManagerInstall(l,c,{progressDetails:process.stdout.isTTY===!0&&!o,onOutput:e=>{e.text.trim()!==``&&(S.push(e.text),S.length>20&&S.shift(),NPM_NOISE_LINE.test(e.text)||x.push(e.text)),o&&initLog.debug(e.text);let t=installProgressDetail(l,e);t!==void 0&&s.update(`Installing dependencies`,t)}});if(m=a.now()-b,!packageManagerInstallSucceeded(C)){initLog.debug(`dependency installation failed`,{ms:m}),s.stop();let t=x.length>0?x:S;for(let n of t)e.error(n);if(t.length===0){let t=packageManagerInstallFailureMessage(C);t!==void 0&&e.error(t)}throw Error(`Failed to install dependencies in "${c}".`)}initLog.debug(`dependencies installed`,{ms:m}),s.update(`Initializing Git repository`),initLog.debug(`initializing git repository`),h=await a.tryInitializeGit(c)}finally{s.stop()}e.log(`${import_picocolors.default.green(`✓`)} Created an ${EVE_WORDMARK} extension in ${import_picocolors.default.bold(c)} ${import_picocolors.default.dim(`in ${formatElapsed(p)}`)}`);for(let t of u)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:l,packageName:basename(c),projectPath:c}))}export{EVE_INIT_PACKAGE_SPEC_ENV,runExtensionInitCommand};
|
|
@@ -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,initAgentReadySummary,initAgentReplPrompt}from"./agent-instructions.js";import{tryInitializeGit}from"./init-git.js";import{confirmInitInNonEmptyDirectory}from"./init-confirm.js";import{cleanupFreshInitTarget,workspaceFailureNote}from"./init-recovery.js";import{selectInitHandoff,spawnCodingAgentRepl}from"./init-repl.js";import{resolveInitTarget}from"./init-target.js";import{mkdtemp,readdir,rename,rm}from"node:fs/promises";import{createLogger,isLogLevelEnabled}from"#internal/logging.js";import{basename,join,relative,resolve}from"node:path";import{DEFAULT_AGENT_MODEL_ID}from"#shared/default-agent-model.js";import{ensureChannel,scaffoldBaseProject}from"#setup/scaffold/index.js";import{eveDevArguments,packageManagerInstallFailureMessage,packageManagerInstallSucceeded,resultSucceeded,runPackageManagerInstall,spawnPackageManager}from"#setup/primitives/index.js";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{DEFAULT_EVE_PACKAGE_CONTRACT}from"#setup/scaffold/create/project.js";import{addAgentToProject}from"#setup/scaffold/create/add-to-project.js";import{WizardCancelledError}from"#setup/step.js";import{validateModelSlug}from"#setup/flows/model-source-change.js";import{isPackageManagerWorkspaceMember}from"#setup/scaffold/workspace-root.js";var import_picocolors=__toESM(require_picocolors(),1);const defaultDependencies={addAgentToProject,confirmInitInNonEmptyDirectory,detectInvokingPackageManager,detectPackageManager,ensureChannel,isCodingAgentLaunch,now:()=>performance.now(),runPackageManagerInstall,scaffoldBaseProject,selectInitHandoff,spawnCodingAgentRepl,spawnPackageManager,tryInitializeGit,validateModelSlug},EVE_INIT_PACKAGE_SPEC_ENV=`EVE_INIT_PACKAGE_SPEC`,initLog=createLogger(`init`);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}`}function initDevArguments(e){let t=[...eveDevArguments(e)];return e===`pnpm`?[`--config.minimum-release-age=0`,...t]:t}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 add channel/web` from the project afterwards instead.");if(t.model!==void 0){let r=await n.validateModelSlug(e,t.model);if(r!==null)throw Error(r)}let i=await n.detectPackageManager(e),a=await n.addAgentToProject({projectRoot:e,model:t.model??DEFAULT_AGENT_MODEL_ID,reasoning:t.reasoning,packageManager:i.kind,evePackage:r});return{configurationFilesChanged:a.configurationFilesChanged,dependenciesAdded:a.dependenciesAdded,filesWritten:a.filesWritten,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,o,s){let c=resolve(e,`..`),l=!n&&await pathExists(e)&&(await readdir(e)).length===0;if(!n&&await pathExists(e)&&!l)throw Error(`Cannot create project because "${e}" already exists.`);let u=n&&s?void 0:await mkdtemp(join(c,`.eve-init-`)),d=[];try{let c=u??e;if(i.model!==void 0){let e=await a.validateModelSlug(c,i.model);if(e!==null)throw Error(e)}let f={projectName:u===void 0?`.`:n?basename(e):t,model:i.model??DEFAULT_AGENT_MODEL_ID,reasoning:i.reasoning,evePackage:o,targetDirectory:c,overwriteExisting:s,workspaceProbeDirectory:e,packageManager:r,onWorkspaceRootMutation:e=>{d.push(e)}},p=await a.scaffoldBaseProject(f);return i.channelWebNextjs===!0&&await a.ensureChannel({projectRoot:p,kind:`web`,packageManager:r,force:s,workspaceProbeDirectory:e,configureVercelServices:!1,onWorkspaceRootMutation:e=>{d.push(e)}}),u!==void 0&&(n||l?await moveDirectoryContents(p,e):await rename(p,e)),{projectPath:e,workspaceRootMutations:uniqueWorkspaceRootMutations(d)}}finally{u!==void 0&&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 reportExistingProjectChanges(e,t){e.log(`Updated existing project:`);for(let n of t.filesWritten)e.log(` Created ${relative(t.projectPath,n).replaceAll(`\\`,`/`)}`);t.dependenciesAdded.length>0&&e.log(` Added dependencies: ${t.dependenciesAdded.join(`, `)}`);for(let n of t.configurationFilesChanged)e.log(` Updated ${n}`);t.nodeEngineOverride!==void 0&&e.log(import_picocolors.default.yellow(` ⚠ ${formatNodeEngineOverrideWarning(t.nodeEngineOverride)}`))}async function runInitSteps(e){let{dependencies:t,logger:n,options:r,parentDirectory:i,target:a}=e,o=isLogLevelEnabled(`debug`),l=await t.isCodingAgentLaunch(),u=await resolveInitTarget({parentDirectory:i,target:a}),f=resolveInitEvePackageOverride(),p=startCliLiveRow(n);p.update(`Preparing project`);try{let e=u.kind===`fresh`?`creating agent`:`adding agent`;p.update(u.kind===`fresh`?`Creating agent`:`Adding agent`),initLog.debug(e);let i=t.now(),a;if(u.kind===`fresh`){let e=await resolveScaffoldPackageManager(u.projectPath,t),n=isPackageManagerWorkspaceMember(e,u.projectPath),i;try{i=await scaffoldProject(u.projectPath,u.projectName,u.createInPlace,e,r,t,f,u.overwriteExisting)}catch(e){if(u.failurePolicy===`clear`){let t=await cleanupFreshInitTarget(u.projectPath,u.failurePolicy,u.preservedEntries),r=e instanceof Error?e.message:String(e),i=t?`eve restored "${u.projectPath}" to its original state.`:`eve could not completely clean "${u.projectPath}".`;throw Error(`${r}\n\n${i}${workspaceFailureNote(n)}`)}if(u.failurePolicy===`remove`&&n){let t=e instanceof Error?e.message:String(e);throw Error(`${t}${workspaceFailureNote(!0)}`)}throw e}a={failurePolicy:u.failurePolicy,kind:`created`,packageManager:e,preservedTargetEntries:u.preservedEntries,projectPath:i.projectPath,retryCommand:`eve init ${u.projectPath}`,workspaceMember:n,workspaceRootMutations:i.workspaceRootMutations}}else{let e=await addToExistingProject(u.projectPath,r,t,f);a=e.nodeEngineOverride===void 0?{configurationFilesChanged:e.configurationFilesChanged,dependenciesAdded:e.dependenciesAdded,failurePolicy:`preserve`,filesWritten:e.filesWritten,kind:`added`,packageManager:e.packageManager,projectPath:u.projectPath}:{configurationFilesChanged:e.configurationFilesChanged,dependenciesAdded:e.dependenciesAdded,failurePolicy:`preserve`,filesWritten:e.filesWritten,kind:`added`,nodeEngineOverride:e.nodeEngineOverride,packageManager:e.packageManager,projectPath:u.projectPath}}let d=t.now()-i;initLog.debug(`${e} done`,{ms:d}),a.kind===`added`&&(p.stop(),reportExistingProjectChanges(n,a),p=startCliLiveRow(n)),p.update(`Installing dependencies`,`${a.packageManager} install`),initLog.debug(`installing dependencies with ${a.packageManager}`);let m=t.now(),h=[],g=[],_=await t.runPackageManagerInstall(a.packageManager,a.projectPath,{bypassMinimumReleaseAge:!0,progressDetails:process.stdout.isTTY===!0&&!o,onOutput:e=>{e.text.trim()!==``&&(g.push(e.text),g.length>20&&g.shift(),NPM_NOISE_LINE.test(e.text)||h.push(e.text)),o&&initLog.debug(e.text);let t=installProgressDetail(a.packageManager,e);t!==void 0&&p.update(`Installing dependencies`,t)}}),v=t.now()-m;if(!packageManagerInstallSucceeded(_)){initLog.debug(`dependency installation failed`,{ms:v}),p.stop();let e=h.length>0?h:g;for(let t of e)n.error(t);if(e.length===0){let e=packageManagerInstallFailureMessage(_);e!==void 0&&n.error(e)}if(a.failurePolicy!==`preserve`){if(await cleanupFreshInitTarget(a.projectPath,a.failurePolicy,a.preservedTargetEntries)){let e=a.failurePolicy===`remove`?`eve removed the incomplete project at "${a.projectPath}".`:`eve restored "${a.projectPath}" to its original state.`,t=a.workspaceMember||a.workspaceRootMutations.length>0;throw Error(`Failed to install dependencies.\n\n${e}\n\nResolve the package-manager error above, then retry:\n ${a.retryCommand}${workspaceFailureNote(t)}`)}let e=a.workspaceMember||a.workspaceRootMutations.length>0;throw Error(`Failed to install dependencies, and eve could not completely clean "${a.projectPath}".\n\nResolve the package-manager error above, then install dependencies with ${a.packageManager} in that directory. Or clean the target manually before rerunning eve init.${workspaceFailureNote(e)}`)}throw Error(`The eve agent was added, but dependency installation failed.\n\nResolve the package-manager error above, then install dependencies with ${a.packageManager} in "${a.projectPath}".\n\nDo not rerun eve init; the agent is already configured.`)}return initLog.debug(`dependencies installed`,{ms:v}),a.kind===`created`?(p.update(`Initializing Git repository`),initLog.debug(`initializing git repository`),{...a,agentElapsedMs:d,agentLaunched:l,gitResult:await t.tryInitializeGit(a.projectPath),installElapsedMs:v}):{...a,agentElapsedMs:d,agentLaunched:l,installElapsedMs:v}}finally{p.stop()}}async function runInitCommand(e,t,a,o,s=defaultDependencies){let c;try{c=await runInitSteps({dependencies:s,logger:e,options:o,parentDirectory:t,target:a})}catch(e){if(e instanceof WizardCancelledError)return;throw e}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)}`)}`);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 during ${c.gitResult.stage}: ${c.gitResult.reason}`)),c.gitResult.stage===`commit`&&e.error(import_picocolors.default.yellow(`The eve agent was created successfully. Git repository metadata and staged files were preserved at "${c.projectPath}"; the initial commit is optional.\n\nTo create it later, configure Git identity and run:\n git -C ${JSON.stringify(c.projectPath)} commit -m "Initial commit from eve"`)));let l=initDevArguments(c.packageManager),u=[c.packageManager,...l].join(` `),d=initAgentDevHandoff({projectPath:c.projectPath,devCommand:u});if(c.agentLaunched){e.log(initAgentReadySummary(o.model,c.projectPath)),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===`exit`)return;if(f!==`eve-dev`){if(e.log(import_picocolors.default.dim(`$ ${f}`)),!await s.spawnCodingAgentRepl({command:f,cwd:c.projectPath,prompt:initAgentReplPrompt({devCommand:u}),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?[...l,`--input`,`/model`]:l;if(e.log(import_picocolors.default.dim(p?`$ eve dev --input /model`:`$ eve dev`)),!resultSucceeded(await s.spawnPackageManager(c.packageManager,c.projectPath,m)))throw Error(`Development server exited unsuccessfully in "${c.projectPath}".`)}function resolveInitEvePackageOverride(){let e=process.env[EVE_INIT_PACKAGE_SPEC_ENV]?.trim();if(!(e===void 0||e.length===0))return{nodeEngine:DEFAULT_EVE_PACKAGE_CONTRACT.nodeEngine,version:e}}export{EVE_INIT_PACKAGE_SPEC_ENV,runInitCommand};
|
|
1
|
+
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,initAgentReadySummary,initAgentReplPrompt}from"./agent-instructions.js";import{tryInitializeGit}from"./init-git.js";import{confirmInitInNonEmptyDirectory}from"./init-confirm.js";import{cleanupFreshInitTarget,workspaceFailureNote}from"./init-recovery.js";import{selectInitHandoff,spawnCodingAgentRepl}from"./init-repl.js";import{resolveInitTarget}from"./init-target.js";import{mkdtemp,readdir,rename,rm}from"node:fs/promises";import{createLogger,isLogLevelEnabled}from"#internal/logging.js";import{basename,join,relative,resolve}from"node:path";import{DEFAULT_AGENT_MODEL_ID}from"#shared/default-agent-model.js";import{ensureChannel,scaffoldBaseProject}from"#setup/scaffold/index.js";import{eveDevArguments,packageManagerInstallFailureMessage,packageManagerInstallSucceeded,resultSucceeded,runPackageManagerInstall,spawnPackageManager}from"#setup/primitives/index.js";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{DEFAULT_EVE_PACKAGE_CONTRACT}from"#setup/scaffold/create/project.js";import{addAgentToProject}from"#setup/scaffold/create/add-to-project.js";import{WizardCancelledError}from"#setup/step.js";import{validateModelSlug}from"#setup/flows/model-source-change.js";import{isPackageManagerWorkspaceMember}from"#setup/scaffold/workspace-root.js";var import_picocolors=__toESM(require_picocolors(),1);const defaultDependencies={addAgentToProject,confirmInitInNonEmptyDirectory,detectInvokingPackageManager,detectPackageManager,ensureChannel,isCodingAgentLaunch,now:()=>performance.now(),runPackageManagerInstall,scaffoldBaseProject,selectInitHandoff,spawnCodingAgentRepl,spawnPackageManager,tryInitializeGit,validateModelSlug},EVE_INIT_PACKAGE_SPEC_ENV=`EVE_INIT_PACKAGE_SPEC`,initLog=createLogger(`init`);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 add channel/web` from the project afterwards instead.");if(t.model!==void 0){let r=await n.validateModelSlug(e,t.model);if(r!==null)throw Error(r)}let i=await n.detectPackageManager(e),a=await n.addAgentToProject({projectRoot:e,model:t.model??DEFAULT_AGENT_MODEL_ID,reasoning:t.reasoning,packageManager:i.kind,evePackage:r});return{configurationFilesChanged:a.configurationFilesChanged,dependenciesAdded:a.dependenciesAdded,filesWritten:a.filesWritten,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,o,s){let c=resolve(e,`..`),l=!n&&await pathExists(e)&&(await readdir(e)).length===0;if(!n&&await pathExists(e)&&!l)throw Error(`Cannot create project because "${e}" already exists.`);let u=n&&s?void 0:await mkdtemp(join(c,`.eve-init-`)),d=[];try{let c=u??e;if(i.model!==void 0){let e=await a.validateModelSlug(c,i.model);if(e!==null)throw Error(e)}let f={projectName:u===void 0?`.`:n?basename(e):t,model:i.model??DEFAULT_AGENT_MODEL_ID,reasoning:i.reasoning,evePackage:o,targetDirectory:c,overwriteExisting:s,workspaceProbeDirectory:e,packageManager:r,onWorkspaceRootMutation:e=>{d.push(e)}},p=await a.scaffoldBaseProject(f);return i.channelWebNextjs===!0&&await a.ensureChannel({projectRoot:p,kind:`web`,packageManager:r,force:s,workspaceProbeDirectory:e,configureVercelServices:!1,onWorkspaceRootMutation:e=>{d.push(e)}}),u!==void 0&&(n||l?await moveDirectoryContents(p,e):await rename(p,e)),{projectPath:e,workspaceRootMutations:uniqueWorkspaceRootMutations(d)}}finally{u!==void 0&&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 reportExistingProjectChanges(e,t){e.log(`Updated existing project:`);for(let n of t.filesWritten)e.log(` Created ${relative(t.projectPath,n).replaceAll(`\\`,`/`)}`);t.dependenciesAdded.length>0&&e.log(` Added dependencies: ${t.dependenciesAdded.join(`, `)}`);for(let n of t.configurationFilesChanged)e.log(` Updated ${n}`);t.nodeEngineOverride!==void 0&&e.log(import_picocolors.default.yellow(` ⚠ ${formatNodeEngineOverrideWarning(t.nodeEngineOverride)}`))}async function runInitSteps(e){let{dependencies:t,logger:n,options:r,parentDirectory:i,target:a}=e,o=isLogLevelEnabled(`debug`),l=await t.isCodingAgentLaunch(),u=await resolveInitTarget({parentDirectory:i,target:a}),f=resolveInitEvePackageOverride(),p=startCliLiveRow(n);p.update(`Preparing project`);try{let e=u.kind===`fresh`?`creating agent`:`adding agent`;p.update(u.kind===`fresh`?`Creating agent`:`Adding agent`),initLog.debug(e);let i=t.now(),a;if(u.kind===`fresh`){let e=await resolveScaffoldPackageManager(u.projectPath,t),n=isPackageManagerWorkspaceMember(e,u.projectPath),i;try{i=await scaffoldProject(u.projectPath,u.projectName,u.createInPlace,e,r,t,f,u.overwriteExisting)}catch(e){if(u.failurePolicy===`clear`){let t=await cleanupFreshInitTarget(u.projectPath,u.failurePolicy,u.preservedEntries),r=e instanceof Error?e.message:String(e),i=t?`eve restored "${u.projectPath}" to its original state.`:`eve could not completely clean "${u.projectPath}".`;throw Error(`${r}\n\n${i}${workspaceFailureNote(n)}`)}if(u.failurePolicy===`remove`&&n){let t=e instanceof Error?e.message:String(e);throw Error(`${t}${workspaceFailureNote(!0)}`)}throw e}a={failurePolicy:u.failurePolicy,kind:`created`,packageManager:e,preservedTargetEntries:u.preservedEntries,projectPath:i.projectPath,retryCommand:`eve init ${u.projectPath}`,workspaceMember:n,workspaceRootMutations:i.workspaceRootMutations}}else{let e=await addToExistingProject(u.projectPath,r,t,f);a=e.nodeEngineOverride===void 0?{configurationFilesChanged:e.configurationFilesChanged,dependenciesAdded:e.dependenciesAdded,failurePolicy:`preserve`,filesWritten:e.filesWritten,kind:`added`,packageManager:e.packageManager,projectPath:u.projectPath}:{configurationFilesChanged:e.configurationFilesChanged,dependenciesAdded:e.dependenciesAdded,failurePolicy:`preserve`,filesWritten:e.filesWritten,kind:`added`,nodeEngineOverride:e.nodeEngineOverride,packageManager:e.packageManager,projectPath:u.projectPath}}let d=t.now()-i;initLog.debug(`${e} done`,{ms:d}),a.kind===`added`&&(p.stop(),reportExistingProjectChanges(n,a),p=startCliLiveRow(n)),p.update(`Installing dependencies`,`${a.packageManager} install`),initLog.debug(`installing dependencies with ${a.packageManager}`);let m=t.now(),h=[],g=[],_=await t.runPackageManagerInstall(a.packageManager,a.projectPath,{progressDetails:process.stdout.isTTY===!0&&!o,onOutput:e=>{e.text.trim()!==``&&(g.push(e.text),g.length>20&&g.shift(),NPM_NOISE_LINE.test(e.text)||h.push(e.text)),o&&initLog.debug(e.text);let t=installProgressDetail(a.packageManager,e);t!==void 0&&p.update(`Installing dependencies`,t)}}),v=t.now()-m;if(!packageManagerInstallSucceeded(_)){initLog.debug(`dependency installation failed`,{ms:v}),p.stop();let e=h.length>0?h:g;for(let t of e)n.error(t);if(e.length===0){let e=packageManagerInstallFailureMessage(_);e!==void 0&&n.error(e)}if(a.failurePolicy!==`preserve`){if(await cleanupFreshInitTarget(a.projectPath,a.failurePolicy,a.preservedTargetEntries)){let e=a.failurePolicy===`remove`?`eve removed the incomplete project at "${a.projectPath}".`:`eve restored "${a.projectPath}" to its original state.`,t=a.workspaceMember||a.workspaceRootMutations.length>0;throw Error(`Failed to install dependencies.\n\n${e}\n\nResolve the package-manager error above, then retry:\n ${a.retryCommand}${workspaceFailureNote(t)}`)}let e=a.workspaceMember||a.workspaceRootMutations.length>0;throw Error(`Failed to install dependencies, and eve could not completely clean "${a.projectPath}".\n\nResolve the package-manager error above, then install dependencies with ${a.packageManager} in that directory. Or clean the target manually before rerunning eve init.${workspaceFailureNote(e)}`)}throw Error(`The eve agent was added, but dependency installation failed.\n\nResolve the package-manager error above, then install dependencies with ${a.packageManager} in "${a.projectPath}".\n\nDo not rerun eve init; the agent is already configured.`)}return initLog.debug(`dependencies installed`,{ms:v}),a.kind===`created`?(p.update(`Initializing Git repository`),initLog.debug(`initializing git repository`),{...a,agentElapsedMs:d,agentLaunched:l,gitResult:await t.tryInitializeGit(a.projectPath),installElapsedMs:v}):{...a,agentElapsedMs:d,agentLaunched:l,installElapsedMs:v}}finally{p.stop()}}async function runInitCommand(e,t,a,o,s=defaultDependencies){let c;try{c=await runInitSteps({dependencies:s,logger:e,options:o,parentDirectory:t,target:a})}catch(e){if(e instanceof WizardCancelledError)return;throw e}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)}`)}`);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 during ${c.gitResult.stage}: ${c.gitResult.reason}`)),c.gitResult.stage===`commit`&&e.error(import_picocolors.default.yellow(`The eve agent was created successfully. Git repository metadata and staged files were preserved at "${c.projectPath}"; the initial commit is optional.\n\nTo create it later, configure Git identity and run:\n git -C ${JSON.stringify(c.projectPath)} commit -m "Initial commit from eve"`)));let l=[...eveDevArguments(c.packageManager)],u=[c.packageManager,...l].join(` `),d=initAgentDevHandoff({projectPath:c.projectPath,devCommand:u});if(c.agentLaunched){e.log(initAgentReadySummary(o.model,c.projectPath)),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===`exit`)return;if(f!==`eve-dev`){if(e.log(import_picocolors.default.dim(`$ ${f}`)),!await s.spawnCodingAgentRepl({command:f,cwd:c.projectPath,prompt:initAgentReplPrompt({devCommand:u}),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?[...l,`--input`,`/model`]:l;if(e.log(import_picocolors.default.dim(p?`$ eve dev --input /model`:`$ eve dev`)),!resultSucceeded(await s.spawnPackageManager(c.packageManager,c.projectPath,m)))throw Error(`Development server exited unsuccessfully in "${c.projectPath}".`)}function resolveInitEvePackageOverride(){let e=process.env[EVE_INIT_PACKAGE_SPEC_ENV]?.trim();if(!(e===void 0||e.length===0))return{nodeEngine:DEFAULT_EVE_PACKAGE_CONTRACT.nodeEngine,version:e}}export{EVE_INIT_PACKAGE_SPEC_ENV,runInitCommand};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import{createTuiPrompter}from"./tui-prompter.js";import{runDeployFlow}from"#setup/flows/deploy.js";import{WizardCancelledError}from"#setup/step.js";import{runLoginFlow}from"#setup/flows/login.js";import{HumanActionRequiredError}from"#setup/human-action.js";import{runInstallVercelCliFlow}from"#setup/flows/install-vercel-cli.js";import{runModelFlow}from"#setup/flows/model.js";import{runProviderFlow}from"#setup/flows/provider.js";import{RegistryFlowFailedError,runRegistryFlow}from"#setup/flows/registry.js";const SETUP_FLOW_CONFIG={"vc:install":{title:`Install the Vercel CLI`,indicator:`pulse`},"vc:login":{title:`Log in to Vercel`,indicator:`pulse`},model:{title:`Configure the agent model`,indicator:`pulse`},add:{title:`Add to your agent`,indicator:`pulse`},deploy:{title:`Deploy to Vercel`,indicator:`spinner`}};function joinedTitles(e){return e.length===0?``:e.length===1?e[0]:e.length===2?`${e[0]} and ${e[1]}`:`${e.slice(0,-1).join(`, `)}, and ${e.at(-1)}`}function registryResultMessage(e){let t=[`Added ${joinedTitles(e.items.map(e=>e.title))}`];for(let n of e.items){if(n.facts.length===0&&n.output.length===0)continue;t.push(``,n.title);let e=Math.max(0,...n.facts.map(e=>e.label.length));for(let r of n.facts)t.push(` ${r.label.padEnd(e)} ${r.value}`);for(let e of n.output)t.push(` ${e}`)}return t.join(`
|
|
2
2
|
`)}function muteableRenderer(e,t,n){return{readSelect:n=>t()?Promise.resolve(void 0):e.readSelect(n),readEditableSelect:n=>t()?Promise.resolve(void 0):e.readEditableSelect(n),readProviderPicker:n=>t()?Promise.resolve(void 0):e.readProviderPicker(n),readModelEditor:n=>t()?Promise.resolve(void 0):e.readModelEditor(n),readText:n=>t()?Promise.resolve(void 0):e.readText(n),readAcknowledge:n=>t()?Promise.resolve():e.readAcknowledge(n),readChoice:n=>t()?{choice:Promise.resolve(void 0),close:()=>{}}:e.readChoice(n),setStatus:n=>{t()||e.setStatus(n)},renderLine:(n,r)=>{(!t()||r===`warning`||r===`error`)&&e.renderLine(n,r)},replaceContent:n=>{t()||e.replaceContent?.(n)},renderOutput:n=>{t()||e.renderOutput(n)},withInheritedStdio:t=>e.withInheritedStdio(t),withExclusiveTerminal:e=>n?.(e)??e()}}async function runTuiSetupCommand(t){let{command:r}=t,i=!1,a=new AbortController,o=muteableRenderer(t.renderer,()=>i,t.withExclusiveTerminal),s=(t.createPrompter??createTuiPrompter)(o),c=t.renderer.waitForInterrupt(),l=Symbol(`interrupted`),u=executeSetupCommand(t,s,o,a.signal);try{let e=await Promise.race([u,c.promise.then(()=>l)]);return e===l?(i=!0,a.abort(new WizardCancelledError),{...await u,message:`/${r} interrupted.`,tone:`error`,preserveFlowDiagnostics:!0}):e}finally{c.dispose(),t.renderer.setStatus(void 0)}}async function executeSetupCommand(e,i,u,d){let{command:f,appRoot:p}=e,m={runInstallVercelCliFlow,runLoginFlow,runModelFlow,runRegistryFlow,runDeployFlow,...e.flows};try{switch(f){case`vc:install`:return installVercelCliResultMessage(await m.runInstallVercelCliFlow({appRoot:p,prompter:i,signal:d}));case`vc:login`:return loginResultMessage(await m.runLoginFlow({appRoot:p,prompter:i,signal:d}));case`model`:{let pickProvider=e=>u.readProviderPicker(e),t={appRoot:p,prompter:i,signal:d,chatGptAccountLabel:e.chatGptAccountLabel,deps:{pickModelSettings:e=>u.readModelEditor(e),runProviderFlow:e=>runProviderFlow({...e,picker:pickProvider})}};e.initialModelStep!==void 0&&(t.initialStep=e.initialModelStep),t.withExclusiveTerminal=t=>u.withInheritedStdio(()=>e.withExclusiveTerminal?.(t)??t());let n=await m.runModelFlow(t);if(n.kind===`cancelled`)return{message:n.discardedDraft===!0?`/model dismissed. Drafted changes were discarded; Done commits them.`:`/model dismissed.`,preserveFlowDiagnostics:!1};let r=[];n.modelMessage!==void 0&&r.push(n.modelMessage),n.providerSelection!==void 0&&r.push(providerSelectionMessage(n.providerSelection));let a={message:r.join(`
|
|
3
|
-
`),preserveFlowDiagnostics:!1};return n.accessChanged&&(a.effect={kind:`model-access-changed`}),a}case`add`:{let e=await m.runRegistryFlow({appRoot:p,prompter:i,signal:d});if(e.kind===`cancelled`)return{message:`/add dismissed.`,preserveFlowDiagnostics:!0};let t={message:e.addedItems.length>0?registryResultMessage(e):`No registry items added.`,preserveFlowDiagnostics:!0};return e.addedItems.length>0&&(t.tone=`success`),e.deployed===`production`&&(t.effect={kind:`deployed`}),t}case`deploy`:{let e=await m.runDeployFlow({appRoot:p,prompter:i,interactive:!0,signal:d});return e.kind===`cancelled`?{message:`/deploy dismissed.`,preserveFlowDiagnostics:!0}:e.kind===`needs-link`?{message:`Not linked to a Vercel project — run /model to connect one first.`,preserveFlowDiagnostics:!0}:e.kind===`local-model`?{message:`ChatGPT subscription models are local-only. Switch to an AI Gateway or server-authenticated model before deploying.`,preserveFlowDiagnostics:!0}:{message:e.productionUrl===void 0?`Deployed.`:`Deployed: ${e.productionUrl}`,preserveFlowDiagnostics:!0,effect:{kind:`deployed`}}}}}catch(e){if(e instanceof RegistryFlowFailedError){let t=e.completed;return{message:`${registryResultMessage(t)}\n\n${e.message}`,tone:`error`,preserveFlowDiagnostics:!0}}if(e instanceof WizardCancelledError)return{message:`/${f} dismissed.`,preserveFlowDiagnostics:f!==`model`};let
|
|
3
|
+
`),preserveFlowDiagnostics:!1};return n.accessChanged&&(a.effect={kind:`model-access-changed`}),a}case`add`:{let e=await m.runRegistryFlow({appRoot:p,prompter:i,signal:d});if(e.kind===`cancelled`)return{message:`/add dismissed.`,preserveFlowDiagnostics:!0};let t={message:e.addedItems.length>0?registryResultMessage(e):`No registry items added.`,preserveFlowDiagnostics:!0};return e.addedItems.length>0&&(t.tone=`success`),e.deployed===`production`&&(t.effect={kind:`deployed`}),t}case`deploy`:{let e=await m.runDeployFlow({appRoot:p,prompter:i,interactive:!0,signal:d});return e.kind===`cancelled`?{message:`/deploy dismissed.`,preserveFlowDiagnostics:!0}:e.kind===`needs-link`?{message:`Not linked to a Vercel project — run /model to connect one first.`,preserveFlowDiagnostics:!0}:e.kind===`local-model`?{message:`ChatGPT subscription models are local-only. Switch to an AI Gateway or server-authenticated model before deploying.`,preserveFlowDiagnostics:!0}:{message:e.productionUrl===void 0?`Deployed.`:`Deployed: ${e.productionUrl}`,preserveFlowDiagnostics:!0,effect:{kind:`deployed`}}}}}catch(e){let t=await vercelCliUpgradeOutcome(e instanceof RegistryFlowFailedError?e.cause:e,f,m,{appRoot:p,prompter:i,signal:d});if(t!==void 0)return t;if(e instanceof RegistryFlowFailedError){let t=e.completed;return{message:`${registryResultMessage(t)}\n\n${e.message}`,tone:`error`,preserveFlowDiagnostics:!0}}if(e instanceof WizardCancelledError)return{message:`/${f} dismissed.`,preserveFlowDiagnostics:f!==`model`};let r=vercelActionOutcome(e,f);return r===void 0?{message:`/${f} failed: ${e instanceof Error?e.message:String(e)}`,tone:`error`,preserveFlowDiagnostics:!0}:r}}async function vercelCliUpgradeOutcome(e,t,n,r){if(!(e instanceof HumanActionRequiredError)||e.action.kind!==`vercel-cli-upgrade`)return;let a;try{a=await r.prompter.select({message:`Your Vercel CLI needs an update to continue setup. Upgrade now?`,options:[{value:`upgrade`,label:`Upgrade Vercel CLI`,description:`Run the Vercel CLI's native upgrader`},{value:`later`,label:`Not now`}],initialValue:`upgrade`})}catch{a=`later`}if(a===`later`)return{message:`The Vercel CLI needs an update — run \`vercel upgrade\`, then retry /${t}.`,preserveFlowDiagnostics:!0};let o;try{o=await n.runInstallVercelCliFlow({appRoot:r.appRoot,prompter:r.prompter,signal:r.signal,upgrade:!0})}catch(e){return{message:vercelCliUpgradeFailureMessage(t,errorMessage(e)),preserveFlowDiagnostics:!0}}switch(o.kind){case`installed`:return{message:`Upgraded the Vercel CLI. Retry /${t}.`,preserveFlowDiagnostics:!1};case`failed`:return{message:vercelCliUpgradeFailureMessage(t,o.reason),preserveFlowDiagnostics:!0};case`cancelled`:return{message:`Vercel CLI upgrade cancelled — run \`vercel upgrade\`, then retry /${t}.`,preserveFlowDiagnostics:!0};case`already`:return{message:`The Vercel CLI is already up to date. Retry /${t}.`,preserveFlowDiagnostics:!1}}}function errorMessage(e){let t=(e instanceof Error?e.message:String(e)).replace(/\s+/gu,` `).trim();return t.length<=240?t:`${t.slice(0,239)}…`}function vercelCliUpgradeFailureMessage(e,t){return`Couldn't upgrade the Vercel CLI${t===void 0||t===``?``:` (${t})`} — run \`vercel upgrade\`, then retry /${e}.`}function vercelActionOutcome(e,t){if(!(e instanceof HumanActionRequiredError))return;let n=vercelActionMessage(e.action.kind,t);return n===void 0?void 0:{message:n,preserveFlowDiagnostics:!0}}function vercelActionMessage(e,t){switch(e){case`vercel-login`:return`You're not logged in to Vercel — run /vc:login, then retry /${t}.`;case`vercel-forbidden`:return`Vercel denied access to that team — run /vc:login to re-authenticate (for example to complete SSO), or pick a team you can access, then retry /${t}.`;case`vercel-cli-missing`:return`The Vercel CLI isn't installed — run /vc:install to install it, then retry /${t}.`;case`vercel-cli-upgrade`:return`The Vercel CLI needs an update — run \`vercel upgrade\`, then retry /${t}.`;default:return}}function installVercelCliResultMessage(e){switch(e.kind){case`cancelled`:return{message:`/vc:install dismissed.`,preserveFlowDiagnostics:!1};case`already`:return{message:`The Vercel CLI is already installed.`,preserveFlowDiagnostics:!1};case`failed`:return{message:"Couldn't install the Vercel CLI — install it manually with `npm i -g vercel@latest`.",preserveFlowDiagnostics:!0};case`installed`:return{message:`Installed the Vercel CLI. Run /vc:login next.`,preserveFlowDiagnostics:!1,effect:{kind:`refresh-identity`}}}}function loginResultMessage(e){switch(e.kind){case`cancelled`:return{message:`/vc:login dismissed.`,preserveFlowDiagnostics:!1};case`already`:return{message:`You're already logged in to Vercel.`,preserveFlowDiagnostics:!1};case`cli-missing`:return{message:`The Vercel CLI isn't installed — run /vc:install to install it, then retry /vc:login.`,preserveFlowDiagnostics:!0};case`failed`:return{message:`Vercel login didn't complete — run /vc:login to try again.`,preserveFlowDiagnostics:!0};case`logged-in`:return{message:`Logged in to Vercel.`,preserveFlowDiagnostics:!1,effect:{kind:`refresh-identity`}};case`unavailable`:return{message:`Couldn't reach Vercel — check your connection, then retry /vc:login.`,preserveFlowDiagnostics:!0}}}function providerSelectionMessage(e){return e===`chatgpt`?`ChatGPT subscription selected.`:e===`ai-gateway-project`?`AI Gateway via Project selected.`:`AI Gateway via API key selected.`}export{SETUP_FLOW_CONFIG,runTuiSetupCommand};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SendTurnPayload } from "#client/types.js";
|
|
2
|
+
import { type MessageStreamEvent } from "#protocol/message.js";
|
|
3
|
+
import type { UserContent } from "ai";
|
|
4
|
+
export declare function isSettledSessionTail(events: readonly MessageStreamEvent[]): boolean;
|
|
5
|
+
export declare function collectPendingAuthorizations(events: readonly MessageStreamEvent[]): Set<string>;
|
|
6
|
+
export declare function updatePendingAuthorizations(pending: Set<string>, event: MessageStreamEvent): void;
|
|
7
|
+
export declare function assertExclusiveTurnInput(input: SendTurnPayload): void;
|
|
8
|
+
export declare function createSubmissionId(): string;
|
|
9
|
+
export declare function createAbortSignal(first: AbortSignal | undefined, second: AbortSignal): AbortSignal;
|
|
10
|
+
export declare function summarizeUserContent(message: string | UserContent): string;
|
|
11
|
+
export declare function isAbortError(error: unknown): boolean;
|
|
12
|
+
export declare function toTerminalStreamFailureError(event: MessageStreamEvent): Error | undefined;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{isCurrentTurnBoundaryEvent}from"#protocol/message.js";function isSettledSessionTail(t){let n=t.at(-1);return n!==void 0&&isCurrentTurnBoundaryEvent(n)&&(n.type!==`session.waiting`||collectPendingAuthorizations(t).size===0)}function collectPendingAuthorizations(e){let t=new Set;for(let n of e)updatePendingAuthorizations(t,n);return t}function updatePendingAuthorizations(e,t){t.type===`authorization.required`&&t.data.webhookUrl!==void 0?e.add(t.data.name):t.type===`authorization.completed`&&e.delete(t.data.name)}function assertExclusiveTurnInput(e){if(e.message!==void 0==(e.inputResponses!==void 0))throw Error(`A turn requires exactly one of message or inputResponses.`)}let submissionSequence=0;function createSubmissionId(){let e=globalThis.crypto?.randomUUID;return e===void 0?(submissionSequence+=1,`submission_${submissionSequence.toString()}`):e.call(globalThis.crypto)}function createAbortSignal(e,t){return e?AbortSignal.any([e,t]):t}function summarizeUserContent(e){if(typeof e==`string`)return e;let t=[];for(let n of e)n.type===`text`?t.push(n.text):n.type===`file`&&t.push(n.filename?`[file: ${n.filename}]`:`[file]`);return t.join(`
|
|
2
|
+
`)}function isAbortError(e){return e instanceof Error&&e.name===`AbortError`}function toTerminalStreamFailureError(e){if(e.type!==`session.failed`)return;let t=Error(e.data.message);return t.name=e.data.code,t}export{assertExclusiveTurnInput,collectPendingAuthorizations,createAbortSignal,createSubmissionId,isAbortError,isSettledSessionTail,summarizeUserContent,toTerminalStreamFailureError,updatePendingAuthorizations};
|