@cydm/pie 1.0.18 → 1.0.20
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/dist/builtin/extensions/ask-user/index.js +3 -3
- package/dist/builtin/extensions/plan-mode/index.js +3 -3
- package/dist/builtin/extensions/subagent/index.js +4 -4
- package/dist/builtin/extensions/todo/index.js +3 -3
- package/dist/chunks/{chunk-VE2HDCNB.js → chunk-L5BJNCNG.js} +1 -1
- package/dist/chunks/{chunk-G4GV2CRT.js → chunk-NHR6EBM2.js} +775 -181
- package/dist/chunks/{chunk-5DA2D3K2.js → chunk-VESPMEDG.js} +317 -0
- package/dist/chunks/{chunk-MHFUWY7I.js → chunk-ZYOTRKU7.js} +3 -2
- package/dist/chunks/{src-6WPNVGT2.js → src-2FHZO63Y.js} +2 -2
- package/dist/chunks/{test-stream-ZSKNLUEJ.js → test-stream-UW74PA6T.js} +1 -1
- package/dist/cli.js +749 -232
- package/package.json +4 -3
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
|
|
3
3
|
import {
|
|
4
|
+
VERSION,
|
|
4
5
|
createCliHostCapabilities,
|
|
5
6
|
createCliWebResearchHealthStore,
|
|
6
7
|
getAgentDir,
|
|
@@ -14,11 +15,12 @@ import {
|
|
|
14
15
|
getSettingsPath,
|
|
15
16
|
getThemesDir,
|
|
16
17
|
migrateConfigFromAgentDir
|
|
17
|
-
} from "./chunks/chunk-
|
|
18
|
+
} from "./chunks/chunk-ZYOTRKU7.js";
|
|
18
19
|
import {
|
|
19
20
|
AGENTS_CONTEXT_FILE_NAME,
|
|
20
21
|
AgentSessionController,
|
|
21
22
|
BUILTIN_TOOL_CAPABILITY_METADATA,
|
|
23
|
+
FileSessionStore,
|
|
22
24
|
SessionTraceSnapshotWriter,
|
|
23
25
|
abortExecutionState,
|
|
24
26
|
attachAgentEventsToSessionTrace,
|
|
@@ -31,6 +33,7 @@ import {
|
|
|
31
33
|
createEmptyExecutionState,
|
|
32
34
|
createExecutionStateFromTodos,
|
|
33
35
|
createExecutionStateStore,
|
|
36
|
+
createFileObservationState,
|
|
34
37
|
createPolicyEnforcedTools,
|
|
35
38
|
createReadFileUnderstandingHandler,
|
|
36
39
|
createSessionManager,
|
|
@@ -44,6 +47,7 @@ import {
|
|
|
44
47
|
evaluateTodoClosureAfterFailedTurn,
|
|
45
48
|
findFirstKeptEntryId,
|
|
46
49
|
formatSkillSummariesForPrompt,
|
|
50
|
+
generateEntryId,
|
|
47
51
|
getAutoCompactTokenLimit,
|
|
48
52
|
hasInteractionHandler,
|
|
49
53
|
maybeAdvanceTodoExecutionState,
|
|
@@ -55,8 +59,8 @@ import {
|
|
|
55
59
|
selectToolsForRuntimePolicy,
|
|
56
60
|
shouldPreserveExecutionStateForUserText,
|
|
57
61
|
supersedeExecutionState
|
|
58
|
-
} from "./chunks/chunk-
|
|
59
|
-
import "./chunks/chunk-
|
|
62
|
+
} from "./chunks/chunk-NHR6EBM2.js";
|
|
63
|
+
import "./chunks/chunk-L5BJNCNG.js";
|
|
60
64
|
import {
|
|
61
65
|
Deref,
|
|
62
66
|
Errors,
|
|
@@ -90,7 +94,7 @@ import {
|
|
|
90
94
|
setLogger,
|
|
91
95
|
sortToolModelCandidatesByCapability,
|
|
92
96
|
type_exports
|
|
93
|
-
} from "./chunks/chunk-
|
|
97
|
+
} from "./chunks/chunk-VESPMEDG.js";
|
|
94
98
|
import {
|
|
95
99
|
resolveCliProjectRoot
|
|
96
100
|
} from "./chunks/chunk-NTYHFBUA.js";
|
|
@@ -1220,12 +1224,12 @@ var require_supports_color = __commonJS({
|
|
|
1220
1224
|
"use strict";
|
|
1221
1225
|
var os6 = __require("os");
|
|
1222
1226
|
var tty = __require("tty");
|
|
1223
|
-
var
|
|
1227
|
+
var hasFlag2 = require_has_flag();
|
|
1224
1228
|
var { env } = process;
|
|
1225
1229
|
var forceColor;
|
|
1226
|
-
if (
|
|
1230
|
+
if (hasFlag2("no-color") || hasFlag2("no-colors") || hasFlag2("color=false") || hasFlag2("color=never")) {
|
|
1227
1231
|
forceColor = 0;
|
|
1228
|
-
} else if (
|
|
1232
|
+
} else if (hasFlag2("color") || hasFlag2("colors") || hasFlag2("color=true") || hasFlag2("color=always")) {
|
|
1229
1233
|
forceColor = 1;
|
|
1230
1234
|
}
|
|
1231
1235
|
if ("FORCE_COLOR" in env) {
|
|
@@ -1252,10 +1256,10 @@ var require_supports_color = __commonJS({
|
|
|
1252
1256
|
if (forceColor === 0) {
|
|
1253
1257
|
return 0;
|
|
1254
1258
|
}
|
|
1255
|
-
if (
|
|
1259
|
+
if (hasFlag2("color=16m") || hasFlag2("color=full") || hasFlag2("color=truecolor")) {
|
|
1256
1260
|
return 3;
|
|
1257
1261
|
}
|
|
1258
|
-
if (
|
|
1262
|
+
if (hasFlag2("color=256")) {
|
|
1259
1263
|
return 2;
|
|
1260
1264
|
}
|
|
1261
1265
|
if (haveStream && !streamIsTTY && forceColor === void 0) {
|
|
@@ -14067,7 +14071,7 @@ var require_http = __commonJS({
|
|
|
14067
14071
|
return joined;
|
|
14068
14072
|
}
|
|
14069
14073
|
function http(hljs) {
|
|
14070
|
-
const
|
|
14074
|
+
const VERSION2 = "HTTP/(2|1\\.[01])";
|
|
14071
14075
|
const HEADER_NAME = /[A-Za-z][A-Za-z0-9-]*/;
|
|
14072
14076
|
const HEADER = {
|
|
14073
14077
|
className: "attribute",
|
|
@@ -14100,12 +14104,12 @@ var require_http = __commonJS({
|
|
|
14100
14104
|
contains: [
|
|
14101
14105
|
// response
|
|
14102
14106
|
{
|
|
14103
|
-
begin: "^(?=" +
|
|
14107
|
+
begin: "^(?=" + VERSION2 + " \\d{3})",
|
|
14104
14108
|
end: /$/,
|
|
14105
14109
|
contains: [
|
|
14106
14110
|
{
|
|
14107
14111
|
className: "meta",
|
|
14108
|
-
begin:
|
|
14112
|
+
begin: VERSION2
|
|
14109
14113
|
},
|
|
14110
14114
|
{
|
|
14111
14115
|
className: "number",
|
|
@@ -14120,7 +14124,7 @@ var require_http = __commonJS({
|
|
|
14120
14124
|
},
|
|
14121
14125
|
// request
|
|
14122
14126
|
{
|
|
14123
|
-
begin: "(?=^[A-Z]+ (.*?) " +
|
|
14127
|
+
begin: "(?=^[A-Z]+ (.*?) " + VERSION2 + "$)",
|
|
14124
14128
|
end: /$/,
|
|
14125
14129
|
contains: [
|
|
14126
14130
|
{
|
|
@@ -14132,7 +14136,7 @@ var require_http = __commonJS({
|
|
|
14132
14136
|
},
|
|
14133
14137
|
{
|
|
14134
14138
|
className: "meta",
|
|
14135
|
-
begin:
|
|
14139
|
+
begin: VERSION2
|
|
14136
14140
|
},
|
|
14137
14141
|
{
|
|
14138
14142
|
className: "keyword",
|
|
@@ -43942,7 +43946,7 @@ var require_dist = __commonJS({
|
|
|
43942
43946
|
});
|
|
43943
43947
|
|
|
43944
43948
|
// src/cli.ts
|
|
43945
|
-
import * as
|
|
43949
|
+
import * as fs26 from "fs";
|
|
43946
43950
|
import * as path26 from "path";
|
|
43947
43951
|
|
|
43948
43952
|
// src/cli-args.ts
|
|
@@ -45480,6 +45484,356 @@ function parseModelsCommandArgs(args) {
|
|
|
45480
45484
|
return parsed;
|
|
45481
45485
|
}
|
|
45482
45486
|
|
|
45487
|
+
// src/commands/sessions.ts
|
|
45488
|
+
import fs6 from "node:fs";
|
|
45489
|
+
async function runSessionsCommand(args) {
|
|
45490
|
+
const command = args[0] || "help";
|
|
45491
|
+
const rest = args.slice(1);
|
|
45492
|
+
try {
|
|
45493
|
+
if (command === "list") {
|
|
45494
|
+
await listSessions(rest);
|
|
45495
|
+
return;
|
|
45496
|
+
}
|
|
45497
|
+
if (command === "read") {
|
|
45498
|
+
await readSession(rest);
|
|
45499
|
+
return;
|
|
45500
|
+
}
|
|
45501
|
+
if (command === "rename") {
|
|
45502
|
+
await renameSession(rest);
|
|
45503
|
+
return;
|
|
45504
|
+
}
|
|
45505
|
+
if (command === "rewind") {
|
|
45506
|
+
await rewindSession(rest);
|
|
45507
|
+
return;
|
|
45508
|
+
}
|
|
45509
|
+
if (command === "fork") {
|
|
45510
|
+
await forkSession(rest);
|
|
45511
|
+
return;
|
|
45512
|
+
}
|
|
45513
|
+
if (command === "help" || command === "--help" || command === "-h") {
|
|
45514
|
+
printSessionsUsage();
|
|
45515
|
+
return;
|
|
45516
|
+
}
|
|
45517
|
+
throw new Error(`Unknown sessions command: ${command}`);
|
|
45518
|
+
} catch (error) {
|
|
45519
|
+
if (hasFlag(args, "--json")) {
|
|
45520
|
+
console.log(JSON.stringify({ ok: false, error: error instanceof Error ? error.message : String(error) }));
|
|
45521
|
+
} else {
|
|
45522
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
45523
|
+
}
|
|
45524
|
+
process.exitCode = 1;
|
|
45525
|
+
}
|
|
45526
|
+
}
|
|
45527
|
+
async function listSessions(args) {
|
|
45528
|
+
const json = hasFlag(args, "--json");
|
|
45529
|
+
const limit = numericFlag(args, "--limit", 50);
|
|
45530
|
+
const cwd = stringFlag(args, "--cwd");
|
|
45531
|
+
const cursor = stringFlag(args, "--cursor");
|
|
45532
|
+
const store = new FileSessionStore(getSessionsDir());
|
|
45533
|
+
const cursorState = decodeListCursor(cursor);
|
|
45534
|
+
const queryKey = listCursorQueryKey({ cwd });
|
|
45535
|
+
const after = cursorState.q === queryKey ? cursorState.after : void 0;
|
|
45536
|
+
const page = await store.listMetadataPage({
|
|
45537
|
+
limit,
|
|
45538
|
+
after,
|
|
45539
|
+
filter: (metadata) => !cwd || cwdMatches(typeof metadata.cwd === "string" ? metadata.cwd : void 0, cwd)
|
|
45540
|
+
});
|
|
45541
|
+
const sessions = page.metadata.map(sessionSummary);
|
|
45542
|
+
const hasMore = page.hasMore;
|
|
45543
|
+
const lastSession = sessions.at(-1);
|
|
45544
|
+
const nextCursor = hasMore && lastSession ? encodeListCursor({ v: 2, q: queryKey, after: { updatedAt: lastSession.updatedAt, id: lastSession.id } }) : void 0;
|
|
45545
|
+
if (json) {
|
|
45546
|
+
console.log(JSON.stringify({ ok: true, sessions, hasMore, nextCursor }, null, 2));
|
|
45547
|
+
return;
|
|
45548
|
+
}
|
|
45549
|
+
if (sessions.length === 0) {
|
|
45550
|
+
console.log("No sessions.");
|
|
45551
|
+
return;
|
|
45552
|
+
}
|
|
45553
|
+
for (const session of sessions) {
|
|
45554
|
+
console.log(`${session.id} ${session.name} ${new Date(session.updatedAt).toISOString()}${session.cwd ? ` ${session.cwd}` : ""}`);
|
|
45555
|
+
}
|
|
45556
|
+
}
|
|
45557
|
+
async function readSession(args) {
|
|
45558
|
+
const json = hasFlag(args, "--json");
|
|
45559
|
+
const sessionId = positionalArgs(args, /* @__PURE__ */ new Set(["--limit", "--before"]))[0];
|
|
45560
|
+
if (!sessionId) throw new Error("Usage: pie sessions read <sessionId> [--json] [--limit <n>] [--before <cursor>]");
|
|
45561
|
+
const limit = numericFlag(args, "--limit", 200);
|
|
45562
|
+
const before = stringFlag(args, "--before");
|
|
45563
|
+
const store = new FileSessionStore(getSessionsDir());
|
|
45564
|
+
const data = await store.load(sessionId);
|
|
45565
|
+
if (!data) throw new Error(`Session not found: ${sessionId}`);
|
|
45566
|
+
const events = activeTranscriptEvents(activePathEntries(data));
|
|
45567
|
+
const end = resolveBeforeCursor(events, before);
|
|
45568
|
+
const start = Math.max(0, end - limit);
|
|
45569
|
+
const page = events.slice(start, end);
|
|
45570
|
+
const response = {
|
|
45571
|
+
ok: true,
|
|
45572
|
+
session: sessionSummary(data.metadata),
|
|
45573
|
+
currentHead: data.metadata.activeEntryId,
|
|
45574
|
+
activeEntryId: data.metadata.activeEntryId,
|
|
45575
|
+
events: page,
|
|
45576
|
+
hasMoreBefore: start > 0,
|
|
45577
|
+
nextBefore: start > 0 ? String(start) : void 0
|
|
45578
|
+
};
|
|
45579
|
+
if (json) {
|
|
45580
|
+
console.log(JSON.stringify(response, null, 2));
|
|
45581
|
+
return;
|
|
45582
|
+
}
|
|
45583
|
+
console.log(`${response.session.id}: ${response.session.name}`);
|
|
45584
|
+
for (const entry of page) {
|
|
45585
|
+
console.log(`${entry.logicalSeq} ${entry.type}${entry.role ? `:${entry.role}` : ""} ${entry.content ?? ""}`);
|
|
45586
|
+
}
|
|
45587
|
+
}
|
|
45588
|
+
async function renameSession(args) {
|
|
45589
|
+
const json = hasFlag(args, "--json");
|
|
45590
|
+
const cwd = stringFlag(args, "--cwd");
|
|
45591
|
+
const positionals = positionalArgs(args, /* @__PURE__ */ new Set(["--cwd"]));
|
|
45592
|
+
const sessionId = positionals[0];
|
|
45593
|
+
const name = positionals.slice(1).join(" ").trim();
|
|
45594
|
+
if (!sessionId || !name) throw new Error("Usage: pie sessions rename <sessionId> <name> [--json] [--cwd <path>]");
|
|
45595
|
+
const store = new FileSessionStore(getSessionsDir());
|
|
45596
|
+
const data = await store.load(sessionId);
|
|
45597
|
+
if (!data) throw new Error(`Session not found: ${sessionId}`);
|
|
45598
|
+
await store.save(sessionId, data.entries, { ...data.metadata, name, ...cwd ? { cwd } : {}, updatedAt: Date.now() });
|
|
45599
|
+
const updated = await store.getMetadata(sessionId);
|
|
45600
|
+
if (!updated) throw new Error(`Session not found after rename: ${sessionId}`);
|
|
45601
|
+
const response = { ok: true, session: sessionSummary(updated) };
|
|
45602
|
+
if (json) {
|
|
45603
|
+
console.log(JSON.stringify(response, null, 2));
|
|
45604
|
+
return;
|
|
45605
|
+
}
|
|
45606
|
+
console.log(`Renamed ${sessionId} to "${name}".`);
|
|
45607
|
+
}
|
|
45608
|
+
async function rewindSession(args) {
|
|
45609
|
+
const json = hasFlag(args, "--json");
|
|
45610
|
+
const sessionId = positionalArgs(args, /* @__PURE__ */ new Set(["--to"]))[0];
|
|
45611
|
+
const entryId = stringFlag(args, "--to");
|
|
45612
|
+
if (!sessionId || !entryId) throw new Error("Usage: pie sessions rewind <sessionId> --to <entryId> [--json]");
|
|
45613
|
+
const store = new FileSessionStore(getSessionsDir());
|
|
45614
|
+
const data = await store.load(sessionId);
|
|
45615
|
+
if (!data) throw new Error(`Session not found: ${sessionId}`);
|
|
45616
|
+
if (!data.entries.some((entry) => entry.id === entryId)) throw new Error(`Entry not found: ${entryId}`);
|
|
45617
|
+
await store.save(sessionId, data.entries, { ...data.metadata, activeEntryId: entryId, updatedAt: Date.now() });
|
|
45618
|
+
const updated = await store.getMetadata(sessionId);
|
|
45619
|
+
if (!updated) throw new Error(`Session not found after rewind: ${sessionId}`);
|
|
45620
|
+
const response = {
|
|
45621
|
+
ok: true,
|
|
45622
|
+
session: sessionSummary(updated),
|
|
45623
|
+
activeEntryId: entryId,
|
|
45624
|
+
currentHead: entryId
|
|
45625
|
+
};
|
|
45626
|
+
if (json) {
|
|
45627
|
+
console.log(JSON.stringify(response, null, 2));
|
|
45628
|
+
return;
|
|
45629
|
+
}
|
|
45630
|
+
console.log(`Rewound ${sessionId} to ${entryId}.`);
|
|
45631
|
+
}
|
|
45632
|
+
async function forkSession(args) {
|
|
45633
|
+
const json = hasFlag(args, "--json");
|
|
45634
|
+
const sourceSessionId = positionalArgs(args, /* @__PURE__ */ new Set(["--from", "--target", "--name", "--cwd"]))[0];
|
|
45635
|
+
const sourceEntryId = stringFlag(args, "--from");
|
|
45636
|
+
const targetSessionId = stringFlag(args, "--target");
|
|
45637
|
+
const name = stringFlag(args, "--name");
|
|
45638
|
+
const cwd = stringFlag(args, "--cwd");
|
|
45639
|
+
if (!sourceSessionId || !sourceEntryId || !targetSessionId || !name) {
|
|
45640
|
+
throw new Error("Usage: pie sessions fork <sessionId> --from <entryId> --target <newSessionId> --name <name> [--cwd <path>] [--json]");
|
|
45641
|
+
}
|
|
45642
|
+
const store = new FileSessionStore(getSessionsDir());
|
|
45643
|
+
const source = await store.load(sourceSessionId);
|
|
45644
|
+
if (!source) throw new Error(`Session not found: ${sourceSessionId}`);
|
|
45645
|
+
if (await store.exists(targetSessionId)) throw new Error(`Target session already exists: ${targetSessionId}`);
|
|
45646
|
+
const pathEntries = pathToEntry(source, sourceEntryId);
|
|
45647
|
+
if (pathEntries.length === 0 || pathEntries[pathEntries.length - 1]?.id !== sourceEntryId) {
|
|
45648
|
+
throw new Error(`Entry not found: ${sourceEntryId}`);
|
|
45649
|
+
}
|
|
45650
|
+
const now = Date.now();
|
|
45651
|
+
const idMap = /* @__PURE__ */ new Map();
|
|
45652
|
+
for (const entry of pathEntries) idMap.set(entry.id, generateEntryId());
|
|
45653
|
+
const forkedEntries = pathEntries.map((entry) => {
|
|
45654
|
+
const nextId = idMap.get(entry.id);
|
|
45655
|
+
if (!nextId) throw new Error(`Failed to map entry: ${entry.id}`);
|
|
45656
|
+
const parentId = entry.parentId ? idMap.get(entry.parentId) ?? null : null;
|
|
45657
|
+
return {
|
|
45658
|
+
...cloneJson(entry),
|
|
45659
|
+
id: nextId,
|
|
45660
|
+
parentId,
|
|
45661
|
+
timestamp: entry.timestamp
|
|
45662
|
+
};
|
|
45663
|
+
});
|
|
45664
|
+
const activeEntryId = idMap.get(sourceEntryId) ?? null;
|
|
45665
|
+
await store.save(targetSessionId, forkedEntries, {
|
|
45666
|
+
name,
|
|
45667
|
+
createdAt: now,
|
|
45668
|
+
updatedAt: now,
|
|
45669
|
+
activeEntryId,
|
|
45670
|
+
cwd: cwd ?? source.metadata.cwd,
|
|
45671
|
+
sourceSessionId,
|
|
45672
|
+
sourceEntryId,
|
|
45673
|
+
sourceActiveEntryId: source.metadata.activeEntryId ?? void 0,
|
|
45674
|
+
forkBaseEntryId: activeEntryId ?? void 0
|
|
45675
|
+
});
|
|
45676
|
+
const updated = await store.getMetadata(targetSessionId);
|
|
45677
|
+
if (!updated) throw new Error(`Session not found after fork: ${targetSessionId}`);
|
|
45678
|
+
const response = {
|
|
45679
|
+
ok: true,
|
|
45680
|
+
session: sessionSummary(updated),
|
|
45681
|
+
sourceSessionId,
|
|
45682
|
+
sourceEntryId,
|
|
45683
|
+
sourceActiveEntryId: source.metadata.activeEntryId,
|
|
45684
|
+
forkBaseEntryId: activeEntryId,
|
|
45685
|
+
activeEntryId,
|
|
45686
|
+
currentHead: activeEntryId
|
|
45687
|
+
};
|
|
45688
|
+
if (json) {
|
|
45689
|
+
console.log(JSON.stringify(response, null, 2));
|
|
45690
|
+
return;
|
|
45691
|
+
}
|
|
45692
|
+
console.log(`Forked ${sourceSessionId} at ${sourceEntryId} into ${targetSessionId}.`);
|
|
45693
|
+
}
|
|
45694
|
+
function printSessionsUsage() {
|
|
45695
|
+
console.log(`Usage:
|
|
45696
|
+
pie sessions list [--json] [--limit <n>] [--cursor <cursor>] [--cwd <path>]
|
|
45697
|
+
pie sessions read <sessionId> [--json] [--limit <n>] [--before <cursor>]
|
|
45698
|
+
pie sessions rename <sessionId> <name> [--json] [--cwd <path>]
|
|
45699
|
+
pie sessions rewind <sessionId> --to <entryId> [--json]
|
|
45700
|
+
pie sessions fork <sessionId> --from <entryId> --target <newSessionId> --name <name> [--cwd <path>] [--json]`);
|
|
45701
|
+
}
|
|
45702
|
+
function hasFlag(args, flag) {
|
|
45703
|
+
return args.includes(flag);
|
|
45704
|
+
}
|
|
45705
|
+
function stringFlag(args, flag) {
|
|
45706
|
+
const index = args.indexOf(flag);
|
|
45707
|
+
if (index < 0) return void 0;
|
|
45708
|
+
const value = args[index + 1];
|
|
45709
|
+
return value && !value.startsWith("-") ? value : void 0;
|
|
45710
|
+
}
|
|
45711
|
+
function numericFlag(args, flag, fallback) {
|
|
45712
|
+
const value = stringFlag(args, flag);
|
|
45713
|
+
if (!value) return fallback;
|
|
45714
|
+
const parsed = Number(value);
|
|
45715
|
+
return Number.isFinite(parsed) && parsed >= 0 ? parsed : fallback;
|
|
45716
|
+
}
|
|
45717
|
+
function positionalArgs(args, valueFlags) {
|
|
45718
|
+
const result = [];
|
|
45719
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
45720
|
+
const arg = args[index];
|
|
45721
|
+
if (arg.startsWith("--")) {
|
|
45722
|
+
if (valueFlags.has(arg)) index += 1;
|
|
45723
|
+
continue;
|
|
45724
|
+
}
|
|
45725
|
+
result.push(arg);
|
|
45726
|
+
}
|
|
45727
|
+
return result;
|
|
45728
|
+
}
|
|
45729
|
+
function sessionSummary(metadata) {
|
|
45730
|
+
return {
|
|
45731
|
+
id: metadata.id,
|
|
45732
|
+
name: metadata.name,
|
|
45733
|
+
createdAt: metadata.createdAt,
|
|
45734
|
+
updatedAt: metadata.updatedAt,
|
|
45735
|
+
cwd: typeof metadata.cwd === "string" ? metadata.cwd : void 0,
|
|
45736
|
+
entryCount: metadata.entryCount,
|
|
45737
|
+
messageCount: metadata.messageCount,
|
|
45738
|
+
activeEntryId: metadata.activeEntryId,
|
|
45739
|
+
rootEntryId: metadata.rootEntryId,
|
|
45740
|
+
sourceSessionId: typeof metadata.sourceSessionId === "string" ? metadata.sourceSessionId : void 0,
|
|
45741
|
+
sourceEntryId: typeof metadata.sourceEntryId === "string" ? metadata.sourceEntryId : void 0,
|
|
45742
|
+
sourceActiveEntryId: typeof metadata.sourceActiveEntryId === "string" ? metadata.sourceActiveEntryId : void 0,
|
|
45743
|
+
forkBaseEntryId: typeof metadata.forkBaseEntryId === "string" ? metadata.forkBaseEntryId : void 0
|
|
45744
|
+
};
|
|
45745
|
+
}
|
|
45746
|
+
function cwdMatches(sessionCwd, requestedCwd) {
|
|
45747
|
+
if (!sessionCwd) return false;
|
|
45748
|
+
if (sessionCwd === requestedCwd) return true;
|
|
45749
|
+
return realpathOrInput(sessionCwd) === realpathOrInput(requestedCwd);
|
|
45750
|
+
}
|
|
45751
|
+
function realpathOrInput(value) {
|
|
45752
|
+
try {
|
|
45753
|
+
return fs6.realpathSync.native(value);
|
|
45754
|
+
} catch {
|
|
45755
|
+
return value;
|
|
45756
|
+
}
|
|
45757
|
+
}
|
|
45758
|
+
function activeTranscriptEvents(entries) {
|
|
45759
|
+
return entries.map((entry, index) => {
|
|
45760
|
+
const role = isRecord2(entry.message) && typeof entry.message.role === "string" ? entry.message.role : void 0;
|
|
45761
|
+
return {
|
|
45762
|
+
logicalSeq: index + 1,
|
|
45763
|
+
checkpointId: entry.id,
|
|
45764
|
+
entryId: entry.id,
|
|
45765
|
+
id: entry.id,
|
|
45766
|
+
type: entry.type,
|
|
45767
|
+
timestamp: entry.timestamp,
|
|
45768
|
+
occurredAt: entry.timestamp,
|
|
45769
|
+
role,
|
|
45770
|
+
content: textFromMessage(entry.message),
|
|
45771
|
+
message: entry.message ? cloneJson(entry.message) : void 0
|
|
45772
|
+
};
|
|
45773
|
+
});
|
|
45774
|
+
}
|
|
45775
|
+
function activePathEntries(data) {
|
|
45776
|
+
const activeEntryId = data.metadata.activeEntryId;
|
|
45777
|
+
if (!activeEntryId) return [];
|
|
45778
|
+
return pathToEntry(data, activeEntryId);
|
|
45779
|
+
}
|
|
45780
|
+
function pathToEntry(data, entryId) {
|
|
45781
|
+
const byId = new Map(data.entries.map((entry) => [entry.id, entry]));
|
|
45782
|
+
const path27 = [];
|
|
45783
|
+
let current = entryId;
|
|
45784
|
+
while (current) {
|
|
45785
|
+
const entry = byId.get(current);
|
|
45786
|
+
if (!entry) return [];
|
|
45787
|
+
path27.unshift(entry);
|
|
45788
|
+
current = entry.parentId;
|
|
45789
|
+
}
|
|
45790
|
+
return path27;
|
|
45791
|
+
}
|
|
45792
|
+
function resolveBeforeCursor(events, cursor) {
|
|
45793
|
+
if (!cursor) return events.length;
|
|
45794
|
+
const numeric = Number(cursor);
|
|
45795
|
+
if (Number.isInteger(numeric) && numeric >= 0) {
|
|
45796
|
+
return Math.max(0, Math.min(events.length, numeric));
|
|
45797
|
+
}
|
|
45798
|
+
const index = events.findIndex((event) => event.entryId === cursor || event.checkpointId === cursor);
|
|
45799
|
+
return index >= 0 ? index : events.length;
|
|
45800
|
+
}
|
|
45801
|
+
function cloneJson(value) {
|
|
45802
|
+
return JSON.parse(JSON.stringify(value));
|
|
45803
|
+
}
|
|
45804
|
+
function listCursorQueryKey(input) {
|
|
45805
|
+
return JSON.stringify({ cwd: input.cwd ? realpathOrInput(input.cwd) : "" });
|
|
45806
|
+
}
|
|
45807
|
+
function encodeListCursor(state) {
|
|
45808
|
+
return `list:${Buffer.from(JSON.stringify(state), "utf8").toString("base64url")}`;
|
|
45809
|
+
}
|
|
45810
|
+
function decodeListCursor(cursor) {
|
|
45811
|
+
if (!cursor?.startsWith("list:")) return { v: 2 };
|
|
45812
|
+
try {
|
|
45813
|
+
const parsed = JSON.parse(Buffer.from(cursor.slice("list:".length), "base64url").toString("utf8"));
|
|
45814
|
+
if (!isRecord2(parsed) || parsed.v !== 2) return { v: 2 };
|
|
45815
|
+
const after = isRecord2(parsed.after) && typeof parsed.after.id === "string" && typeof parsed.after.updatedAt === "number" && Number.isFinite(parsed.after.updatedAt) ? { id: parsed.after.id, updatedAt: parsed.after.updatedAt } : void 0;
|
|
45816
|
+
return {
|
|
45817
|
+
v: 2,
|
|
45818
|
+
q: typeof parsed.q === "string" ? parsed.q : void 0,
|
|
45819
|
+
...after ? { after } : {}
|
|
45820
|
+
};
|
|
45821
|
+
} catch {
|
|
45822
|
+
return { v: 2 };
|
|
45823
|
+
}
|
|
45824
|
+
}
|
|
45825
|
+
function textFromMessage(message) {
|
|
45826
|
+
if (!isRecord2(message)) return void 0;
|
|
45827
|
+
const content = message.content;
|
|
45828
|
+
if (typeof content === "string") return content;
|
|
45829
|
+
if (!Array.isArray(content)) return void 0;
|
|
45830
|
+
const text = content.map((block) => isRecord2(block) && block.type === "text" && typeof block.text === "string" ? block.text : "").filter(Boolean).join("\n").trim();
|
|
45831
|
+
return text || void 0;
|
|
45832
|
+
}
|
|
45833
|
+
function isRecord2(value) {
|
|
45834
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
45835
|
+
}
|
|
45836
|
+
|
|
45483
45837
|
// ../../packages/tui/src/fuzzy.ts
|
|
45484
45838
|
function fuzzyMatch(query, text) {
|
|
45485
45839
|
const queryLower = query.toLowerCase();
|
|
@@ -47030,7 +47384,7 @@ var KillRing = class {
|
|
|
47030
47384
|
};
|
|
47031
47385
|
|
|
47032
47386
|
// ../../packages/tui/src/tui.ts
|
|
47033
|
-
import * as
|
|
47387
|
+
import * as fs7 from "node:fs";
|
|
47034
47388
|
import * as os2 from "node:os";
|
|
47035
47389
|
import * as path5 from "node:path";
|
|
47036
47390
|
|
|
@@ -47709,10 +48063,10 @@ var TUI = class extends Container {
|
|
|
47709
48063
|
const logRedraw = (reason) => {
|
|
47710
48064
|
if (!debugRedraw) return;
|
|
47711
48065
|
const logPath = path5.join(os2.homedir(), ".pie", "logs", "pie-cli.log");
|
|
47712
|
-
|
|
48066
|
+
fs7.mkdirSync(path5.dirname(logPath), { recursive: true });
|
|
47713
48067
|
const msg = `[${(/* @__PURE__ */ new Date()).toISOString()}] [DEBUG] [ui] fullRender: ${reason} (prev=${this.previousLines.length}, new=${newLines.length}, height=${height})
|
|
47714
48068
|
`;
|
|
47715
|
-
|
|
48069
|
+
fs7.appendFileSync(logPath, msg);
|
|
47716
48070
|
};
|
|
47717
48071
|
if (this.previousLines.length === 0 && !widthChanged) {
|
|
47718
48072
|
logRedraw("first render");
|
|
@@ -47815,8 +48169,8 @@ var TUI = class extends Container {
|
|
|
47815
48169
|
...newLines.map((l, idx) => `[${idx}] (w=${visibleWidth(l)}) ${l}`),
|
|
47816
48170
|
""
|
|
47817
48171
|
].join("\n");
|
|
47818
|
-
|
|
47819
|
-
|
|
48172
|
+
fs7.mkdirSync(path5.dirname(crashLogPath), { recursive: true });
|
|
48173
|
+
fs7.writeFileSync(crashLogPath, crashData);
|
|
47820
48174
|
this.stop();
|
|
47821
48175
|
const errorMsg = [
|
|
47822
48176
|
`Rendered line ${i} exceeds terminal width (${visibleWidth(line)} > ${width}).`,
|
|
@@ -47846,7 +48200,7 @@ var TUI = class extends Container {
|
|
|
47846
48200
|
buffer += "\x1B[?2026l";
|
|
47847
48201
|
if (process.env.PIE_TUI_DEBUG === "1") {
|
|
47848
48202
|
const debugDir = "/tmp/tui";
|
|
47849
|
-
|
|
48203
|
+
fs7.mkdirSync(debugDir, { recursive: true });
|
|
47850
48204
|
const debugPath = path5.join(debugDir, `render-${Date.now()}-${Math.random().toString(36).slice(2)}.log`);
|
|
47851
48205
|
const debugData = [
|
|
47852
48206
|
`firstChanged: ${firstChanged}`,
|
|
@@ -47870,7 +48224,7 @@ var TUI = class extends Container {
|
|
|
47870
48224
|
"=== buffer ===",
|
|
47871
48225
|
JSON.stringify(buffer)
|
|
47872
48226
|
].join("\n");
|
|
47873
|
-
|
|
48227
|
+
fs7.writeFileSync(debugPath, debugData);
|
|
47874
48228
|
}
|
|
47875
48229
|
this.terminal.write(buffer);
|
|
47876
48230
|
this.cursorRow = Math.max(0, newLines.length - 1);
|
|
@@ -52045,7 +52399,7 @@ var StdinBuffer = class extends EventEmitter {
|
|
|
52045
52399
|
};
|
|
52046
52400
|
|
|
52047
52401
|
// ../../packages/tui/src/terminal.ts
|
|
52048
|
-
import * as
|
|
52402
|
+
import * as fs8 from "node:fs";
|
|
52049
52403
|
import koffi from "koffi";
|
|
52050
52404
|
var ProcessTerminal = class {
|
|
52051
52405
|
wasRaw = false;
|
|
@@ -52206,7 +52560,7 @@ var ProcessTerminal = class {
|
|
|
52206
52560
|
process.stdout.write(data);
|
|
52207
52561
|
if (this.writeLogPath) {
|
|
52208
52562
|
try {
|
|
52209
|
-
|
|
52563
|
+
fs8.appendFileSync(this.writeLogPath, data, { encoding: "utf8" });
|
|
52210
52564
|
} catch {
|
|
52211
52565
|
}
|
|
52212
52566
|
}
|
|
@@ -52378,7 +52732,7 @@ var KeybindingsManager = class _KeybindingsManager {
|
|
|
52378
52732
|
};
|
|
52379
52733
|
|
|
52380
52734
|
// src/project-knowledge.ts
|
|
52381
|
-
import
|
|
52735
|
+
import fs9 from "node:fs";
|
|
52382
52736
|
import path6 from "node:path";
|
|
52383
52737
|
function collectAncestorAgentsFiles(cwd) {
|
|
52384
52738
|
const resolvedCwd = path6.resolve(cwd || process.cwd());
|
|
@@ -52398,13 +52752,13 @@ function collectAncestorAgentsFiles(cwd) {
|
|
|
52398
52752
|
}
|
|
52399
52753
|
const files = [];
|
|
52400
52754
|
for (const candidate of candidates) {
|
|
52401
|
-
if (!
|
|
52755
|
+
if (!fs9.existsSync(candidate)) {
|
|
52402
52756
|
continue;
|
|
52403
52757
|
}
|
|
52404
52758
|
try {
|
|
52405
52759
|
files.push({
|
|
52406
52760
|
path: path6.relative(resolvedCwd, candidate) || AGENTS_CONTEXT_FILE_NAME,
|
|
52407
|
-
content:
|
|
52761
|
+
content: fs9.readFileSync(candidate, "utf-8")
|
|
52408
52762
|
});
|
|
52409
52763
|
} catch {
|
|
52410
52764
|
}
|
|
@@ -52442,7 +52796,7 @@ function buildCliFileAccessOptions(params) {
|
|
|
52442
52796
|
}
|
|
52443
52797
|
|
|
52444
52798
|
// src/theme/theme.ts
|
|
52445
|
-
import * as
|
|
52799
|
+
import * as fs10 from "node:fs";
|
|
52446
52800
|
import * as path8 from "node:path";
|
|
52447
52801
|
|
|
52448
52802
|
// ../../node_modules/@sinclair/typebox/build/esm/compiler/compiler.mjs
|
|
@@ -53333,8 +53687,8 @@ function getBuiltinThemes() {
|
|
|
53333
53687
|
const darkPath = path8.join(themesDir, "dark.json");
|
|
53334
53688
|
const lightPath = path8.join(themesDir, "light.json");
|
|
53335
53689
|
BUILTIN_THEMES = {
|
|
53336
|
-
dark: JSON.parse(
|
|
53337
|
-
light: JSON.parse(
|
|
53690
|
+
dark: JSON.parse(fs10.readFileSync(darkPath, "utf-8")),
|
|
53691
|
+
light: JSON.parse(fs10.readFileSync(lightPath, "utf-8"))
|
|
53338
53692
|
};
|
|
53339
53693
|
}
|
|
53340
53694
|
return BUILTIN_THEMES;
|
|
@@ -53342,8 +53696,8 @@ function getBuiltinThemes() {
|
|
|
53342
53696
|
function getAvailableThemes() {
|
|
53343
53697
|
const themes = new Set(Object.keys(getBuiltinThemes()));
|
|
53344
53698
|
const customThemesDir = getCustomThemesDir();
|
|
53345
|
-
if (
|
|
53346
|
-
const files =
|
|
53699
|
+
if (fs10.existsSync(customThemesDir)) {
|
|
53700
|
+
const files = fs10.readdirSync(customThemesDir);
|
|
53347
53701
|
for (const file of files) {
|
|
53348
53702
|
if (file.endsWith(".json")) {
|
|
53349
53703
|
themes.add(file.slice(0, -5));
|
|
@@ -53404,7 +53758,7 @@ function loadThemeJson(name) {
|
|
|
53404
53758
|
}
|
|
53405
53759
|
const registeredTheme = registeredThemes.get(name);
|
|
53406
53760
|
if (registeredTheme?.sourcePath) {
|
|
53407
|
-
const content2 =
|
|
53761
|
+
const content2 = fs10.readFileSync(registeredTheme.sourcePath, "utf-8");
|
|
53408
53762
|
return parseThemeJsonContent(registeredTheme.sourcePath, content2);
|
|
53409
53763
|
}
|
|
53410
53764
|
if (registeredTheme) {
|
|
@@ -53412,10 +53766,10 @@ function loadThemeJson(name) {
|
|
|
53412
53766
|
}
|
|
53413
53767
|
const customThemesDir = getCustomThemesDir();
|
|
53414
53768
|
const themePath = path8.join(customThemesDir, `${name}.json`);
|
|
53415
|
-
if (!
|
|
53769
|
+
if (!fs10.existsSync(themePath)) {
|
|
53416
53770
|
throw new Error(`Theme not found: ${name}`);
|
|
53417
53771
|
}
|
|
53418
|
-
const content =
|
|
53772
|
+
const content = fs10.readFileSync(themePath, "utf-8");
|
|
53419
53773
|
return parseThemeJsonContent(name, content);
|
|
53420
53774
|
}
|
|
53421
53775
|
function createTheme(themeJson, mode, sourcePath) {
|
|
@@ -53529,11 +53883,11 @@ function startThemeWatcher() {
|
|
|
53529
53883
|
}
|
|
53530
53884
|
const customThemesDir = getCustomThemesDir();
|
|
53531
53885
|
const themeFile = path8.join(customThemesDir, `${currentThemeName}.json`);
|
|
53532
|
-
if (!
|
|
53886
|
+
if (!fs10.existsSync(themeFile)) {
|
|
53533
53887
|
return;
|
|
53534
53888
|
}
|
|
53535
53889
|
try {
|
|
53536
|
-
themeWatcher =
|
|
53890
|
+
themeWatcher = fs10.watch(themeFile, (eventType) => {
|
|
53537
53891
|
if (eventType === "change") {
|
|
53538
53892
|
setTimeout(() => {
|
|
53539
53893
|
try {
|
|
@@ -53546,7 +53900,7 @@ function startThemeWatcher() {
|
|
|
53546
53900
|
}, 100);
|
|
53547
53901
|
} else if (eventType === "rename") {
|
|
53548
53902
|
setTimeout(() => {
|
|
53549
|
-
if (!
|
|
53903
|
+
if (!fs10.existsSync(themeFile)) {
|
|
53550
53904
|
currentThemeName = "dark";
|
|
53551
53905
|
setGlobalTheme(loadTheme("dark"));
|
|
53552
53906
|
if (themeWatcher) {
|
|
@@ -53717,7 +54071,7 @@ function getEditorTheme() {
|
|
|
53717
54071
|
}
|
|
53718
54072
|
|
|
53719
54073
|
// src/skills/loader.ts
|
|
53720
|
-
import * as
|
|
54074
|
+
import * as fs11 from "fs";
|
|
53721
54075
|
import * as path9 from "path";
|
|
53722
54076
|
function parseSkillDescription(content) {
|
|
53723
54077
|
const frontmatterMatch = content.match(/^---\n[\s\S]*?description:\s*["']?(.+?)["']?(?:\n|$)/m);
|
|
@@ -53736,18 +54090,18 @@ function parseSkillDescription(content) {
|
|
|
53736
54090
|
function loadSkillsFromDir(dir, source) {
|
|
53737
54091
|
const skills = [];
|
|
53738
54092
|
const diagnostics = [];
|
|
53739
|
-
if (!
|
|
54093
|
+
if (!fs11.existsSync(dir)) {
|
|
53740
54094
|
return { skills, diagnostics };
|
|
53741
54095
|
}
|
|
53742
|
-
const entries =
|
|
54096
|
+
const entries = fs11.readdirSync(dir, { withFileTypes: true });
|
|
53743
54097
|
for (const entry of entries) {
|
|
53744
54098
|
if (entry.name.startsWith(".")) continue;
|
|
53745
54099
|
const fullPath = path9.join(dir, entry.name);
|
|
53746
54100
|
if (entry.isDirectory()) {
|
|
53747
54101
|
const skillMdPath = path9.join(fullPath, "SKILL.md");
|
|
53748
|
-
if (
|
|
54102
|
+
if (fs11.existsSync(skillMdPath)) {
|
|
53749
54103
|
try {
|
|
53750
|
-
const content =
|
|
54104
|
+
const content = fs11.readFileSync(skillMdPath, "utf-8");
|
|
53751
54105
|
const description = parseSkillDescription(content);
|
|
53752
54106
|
skills.push({
|
|
53753
54107
|
name: entry.name,
|
|
@@ -53768,7 +54122,7 @@ function loadSkillsFromDir(dir, source) {
|
|
|
53768
54122
|
} else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
53769
54123
|
const name = entry.name.slice(0, -3);
|
|
53770
54124
|
try {
|
|
53771
|
-
const content =
|
|
54125
|
+
const content = fs11.readFileSync(fullPath, "utf-8");
|
|
53772
54126
|
const description = parseSkillDescription(content);
|
|
53773
54127
|
skills.push({
|
|
53774
54128
|
name,
|
|
@@ -53965,7 +54319,7 @@ function validateSkillName(name) {
|
|
|
53965
54319
|
|
|
53966
54320
|
// src/capabilities/read-file-understanding.ts
|
|
53967
54321
|
import * as path18 from "node:path";
|
|
53968
|
-
import * as
|
|
54322
|
+
import * as fs19 from "node:fs/promises";
|
|
53969
54323
|
|
|
53970
54324
|
// src/core/provider-capabilities.ts
|
|
53971
54325
|
var PLATFORM_DISPLAY_NAMES = {
|
|
@@ -53991,7 +54345,7 @@ function getProviderDisplayName(platform2) {
|
|
|
53991
54345
|
}
|
|
53992
54346
|
|
|
53993
54347
|
// src/files/adapters/kimi-adapter.ts
|
|
53994
|
-
import * as
|
|
54348
|
+
import * as fs12 from "node:fs";
|
|
53995
54349
|
import * as path10 from "node:path";
|
|
53996
54350
|
|
|
53997
54351
|
// src/files/errors.ts
|
|
@@ -54132,14 +54486,14 @@ var KimiFileAdapter = class {
|
|
|
54132
54486
|
const fileName = options.sourceName || path10.basename(filePath);
|
|
54133
54487
|
const mimeType = options.mimeType || this.guessMimeType(fileName);
|
|
54134
54488
|
const purpose = this.detectPurpose(filePath, options.purpose, mimeType);
|
|
54135
|
-
const stats =
|
|
54489
|
+
const stats = fs12.statSync(filePath);
|
|
54136
54490
|
if (stats.size > this.capabilities.maxFileSize) {
|
|
54137
54491
|
throw new FileManagerError(
|
|
54138
54492
|
"FILE_TOO_LARGE" /* FILE_TOO_LARGE */,
|
|
54139
54493
|
`File size ${(stats.size / 1024 / 1024).toFixed(1)}MB exceeds Kimi limit of 100MB`
|
|
54140
54494
|
);
|
|
54141
54495
|
}
|
|
54142
|
-
const fileBuffer =
|
|
54496
|
+
const fileBuffer = fs12.readFileSync(filePath);
|
|
54143
54497
|
const file = new File([fileBuffer], fileName, { type: mimeType });
|
|
54144
54498
|
const formData = new FormData();
|
|
54145
54499
|
formData.append("file", file);
|
|
@@ -54353,7 +54707,7 @@ var KimiFileAdapter = class {
|
|
|
54353
54707
|
};
|
|
54354
54708
|
|
|
54355
54709
|
// src/files/adapters/gemini-adapter.ts
|
|
54356
|
-
import * as
|
|
54710
|
+
import * as fs13 from "node:fs";
|
|
54357
54711
|
import * as path11 from "node:path";
|
|
54358
54712
|
import { Readable } from "node:stream";
|
|
54359
54713
|
var GeminiFileAdapter = class {
|
|
@@ -54411,7 +54765,7 @@ var GeminiFileAdapter = class {
|
|
|
54411
54765
|
// Upload
|
|
54412
54766
|
// ============================================================================
|
|
54413
54767
|
async upload(filePath, options = {}) {
|
|
54414
|
-
const stats =
|
|
54768
|
+
const stats = fs13.statSync(filePath);
|
|
54415
54769
|
if (stats.size > this.capabilities.maxFileSize) {
|
|
54416
54770
|
throw new FileManagerError(
|
|
54417
54771
|
"FILE_TOO_LARGE" /* FILE_TOO_LARGE */,
|
|
@@ -54450,7 +54804,7 @@ var GeminiFileAdapter = class {
|
|
|
54450
54804
|
"No upload URL received"
|
|
54451
54805
|
);
|
|
54452
54806
|
}
|
|
54453
|
-
const fileStream = Readable.toWeb(
|
|
54807
|
+
const fileStream = Readable.toWeb(fs13.createReadStream(filePath));
|
|
54454
54808
|
const uploadResponse = await fetch(uploadUrl, {
|
|
54455
54809
|
method: "POST",
|
|
54456
54810
|
headers: {
|
|
@@ -54654,7 +55008,7 @@ var GeminiFileAdapter = class {
|
|
|
54654
55008
|
};
|
|
54655
55009
|
|
|
54656
55010
|
// src/files/adapters/openai-compatible-files-adapter.ts
|
|
54657
|
-
import * as
|
|
55011
|
+
import * as fs14 from "node:fs";
|
|
54658
55012
|
import * as path12 from "node:path";
|
|
54659
55013
|
var OpenAICompatibleFilesAdapter = class {
|
|
54660
55014
|
constructor(apiKey, baseUrl, extraHeaders = {}) {
|
|
@@ -54683,14 +55037,14 @@ var OpenAICompatibleFilesAdapter = class {
|
|
|
54683
55037
|
async upload(filePath, options = {}) {
|
|
54684
55038
|
const fileName = options.sourceName || path12.basename(filePath);
|
|
54685
55039
|
const mimeType = options.mimeType || guessMimeType(fileName);
|
|
54686
|
-
const stats =
|
|
55040
|
+
const stats = fs14.statSync(filePath);
|
|
54687
55041
|
if (stats.size > this.capabilities.maxFileSize) {
|
|
54688
55042
|
throw new FileManagerError(
|
|
54689
55043
|
"FILE_TOO_LARGE" /* FILE_TOO_LARGE */,
|
|
54690
55044
|
`File size ${(stats.size / 1024 / 1024).toFixed(1)}MB exceeds OpenAI-compatible Files limit of ${this.capabilities.maxFileSize / 1024 / 1024}MB`
|
|
54691
55045
|
);
|
|
54692
55046
|
}
|
|
54693
|
-
const file = new File([
|
|
55047
|
+
const file = new File([fs14.readFileSync(filePath)], fileName, { type: mimeType });
|
|
54694
55048
|
const formData = new FormData();
|
|
54695
55049
|
formData.append("file", file);
|
|
54696
55050
|
formData.append("purpose", options.purpose && options.purpose !== "auto" ? options.purpose : "file-extract");
|
|
@@ -54823,12 +55177,12 @@ function guessMimeType(filename) {
|
|
|
54823
55177
|
}
|
|
54824
55178
|
|
|
54825
55179
|
// src/files/file-manager.ts
|
|
54826
|
-
import * as
|
|
55180
|
+
import * as fs18 from "node:fs";
|
|
54827
55181
|
import * as path17 from "node:path";
|
|
54828
55182
|
import * as crypto2 from "node:crypto";
|
|
54829
55183
|
|
|
54830
55184
|
// src/files/file-cache.ts
|
|
54831
|
-
import * as
|
|
55185
|
+
import * as fs15 from "node:fs";
|
|
54832
55186
|
import * as path14 from "node:path";
|
|
54833
55187
|
import * as crypto from "node:crypto";
|
|
54834
55188
|
|
|
@@ -54989,22 +55343,22 @@ var FileCache = class _FileCache {
|
|
|
54989
55343
|
// Directory Management
|
|
54990
55344
|
// ============================================================================
|
|
54991
55345
|
ensureDirectories() {
|
|
54992
|
-
if (!
|
|
54993
|
-
|
|
55346
|
+
if (!fs15.existsSync(this.baseDir)) {
|
|
55347
|
+
fs15.mkdirSync(this.baseDir, { recursive: true });
|
|
54994
55348
|
}
|
|
54995
|
-
if (!
|
|
54996
|
-
|
|
55349
|
+
if (!fs15.existsSync(this.dataDir)) {
|
|
55350
|
+
fs15.mkdirSync(this.dataDir, { recursive: true });
|
|
54997
55351
|
}
|
|
54998
55352
|
}
|
|
54999
55353
|
// ============================================================================
|
|
55000
55354
|
// Index Management
|
|
55001
55355
|
// ============================================================================
|
|
55002
55356
|
loadIndex() {
|
|
55003
|
-
if (!
|
|
55357
|
+
if (!fs15.existsSync(this.indexPath)) {
|
|
55004
55358
|
return { version: CACHE_VERSION, files: {}, pathHints: {} };
|
|
55005
55359
|
}
|
|
55006
55360
|
try {
|
|
55007
|
-
const data = JSON.parse(
|
|
55361
|
+
const data = JSON.parse(fs15.readFileSync(this.indexPath, "utf-8"));
|
|
55008
55362
|
if (data.version !== CACHE_VERSION) {
|
|
55009
55363
|
cacheLogger.warn(`Index version mismatch: ${data.version} vs ${CACHE_VERSION}`);
|
|
55010
55364
|
}
|
|
@@ -55020,7 +55374,7 @@ var FileCache = class _FileCache {
|
|
|
55020
55374
|
}
|
|
55021
55375
|
saveIndex() {
|
|
55022
55376
|
try {
|
|
55023
|
-
|
|
55377
|
+
fs15.writeFileSync(this.indexPath, JSON.stringify(this.index, null, 2));
|
|
55024
55378
|
} catch (err) {
|
|
55025
55379
|
cacheLogger.error(" Failed to save index:", err);
|
|
55026
55380
|
throw err;
|
|
@@ -55032,7 +55386,7 @@ var FileCache = class _FileCache {
|
|
|
55032
55386
|
async computeHash(filePath) {
|
|
55033
55387
|
return new Promise((resolve4, reject) => {
|
|
55034
55388
|
const hash = crypto.createHash("sha256");
|
|
55035
|
-
const stream =
|
|
55389
|
+
const stream = fs15.createReadStream(filePath);
|
|
55036
55390
|
stream.on("data", (chunk) => hash.update(chunk));
|
|
55037
55391
|
stream.on("end", () => resolve4(hash.digest("hex")));
|
|
55038
55392
|
stream.on("error", reject);
|
|
@@ -55047,8 +55401,8 @@ var FileCache = class _FileCache {
|
|
|
55047
55401
|
getStoragePath(hash) {
|
|
55048
55402
|
const subdir = hash.slice(0, 2);
|
|
55049
55403
|
const fullDir = path14.join(this.dataDir, subdir);
|
|
55050
|
-
if (!
|
|
55051
|
-
|
|
55404
|
+
if (!fs15.existsSync(fullDir)) {
|
|
55405
|
+
fs15.mkdirSync(fullDir, { recursive: true });
|
|
55052
55406
|
}
|
|
55053
55407
|
return path14.join(fullDir, hash);
|
|
55054
55408
|
}
|
|
@@ -55060,11 +55414,11 @@ var FileCache = class _FileCache {
|
|
|
55060
55414
|
const hash = await this.computeHash(sourcePath);
|
|
55061
55415
|
const storagePath = this.getStoragePath(hash);
|
|
55062
55416
|
this.rememberPathHint(sourcePath, hash, name);
|
|
55063
|
-
if (
|
|
55417
|
+
if (fs15.existsSync(storagePath)) {
|
|
55064
55418
|
return { hash, localPath: storagePath };
|
|
55065
55419
|
}
|
|
55066
|
-
|
|
55067
|
-
const stat2 =
|
|
55420
|
+
fs15.copyFileSync(sourcePath, storagePath);
|
|
55421
|
+
const stat2 = fs15.statSync(storagePath);
|
|
55068
55422
|
this.index.files[hash] = {
|
|
55069
55423
|
hash,
|
|
55070
55424
|
name,
|
|
@@ -55081,10 +55435,10 @@ var FileCache = class _FileCache {
|
|
|
55081
55435
|
async storeBuffer(data, name, mimeType) {
|
|
55082
55436
|
const hash = this.computeHashSync(data);
|
|
55083
55437
|
const storagePath = this.getStoragePath(hash);
|
|
55084
|
-
if (
|
|
55438
|
+
if (fs15.existsSync(storagePath)) {
|
|
55085
55439
|
return { hash, localPath: storagePath };
|
|
55086
55440
|
}
|
|
55087
|
-
|
|
55441
|
+
fs15.writeFileSync(storagePath, data);
|
|
55088
55442
|
this.index.files[hash] = {
|
|
55089
55443
|
hash,
|
|
55090
55444
|
name,
|
|
@@ -55156,7 +55510,7 @@ var FileCache = class _FileCache {
|
|
|
55156
55510
|
getPathHint(filePath) {
|
|
55157
55511
|
try {
|
|
55158
55512
|
const resolvedPath = this.getResolvedHintPath(filePath);
|
|
55159
|
-
const stat2 =
|
|
55513
|
+
const stat2 = fs15.statSync(resolvedPath);
|
|
55160
55514
|
if (!stat2.isFile()) return void 0;
|
|
55161
55515
|
const normalizedMtimeMs = this.normalizeHintMtimeMs(stat2.mtimeMs);
|
|
55162
55516
|
const key = this.getPathHintKey(resolvedPath);
|
|
@@ -55186,7 +55540,7 @@ var FileCache = class _FileCache {
|
|
|
55186
55540
|
rememberPathHint(filePath, hash, name) {
|
|
55187
55541
|
try {
|
|
55188
55542
|
const resolvedPath = this.getResolvedHintPath(filePath);
|
|
55189
|
-
const stat2 =
|
|
55543
|
+
const stat2 = fs15.statSync(resolvedPath);
|
|
55190
55544
|
if (!stat2.isFile()) return;
|
|
55191
55545
|
const entry = this.index.files[hash];
|
|
55192
55546
|
const normalizedMtimeMs = this.normalizeHintMtimeMs(stat2.mtimeMs);
|
|
@@ -55245,8 +55599,8 @@ var FileCache = class _FileCache {
|
|
|
55245
55599
|
entry = entry || this.index.files[hash];
|
|
55246
55600
|
if (!entry) return;
|
|
55247
55601
|
const localPath = path14.join(this.dataDir, entry.localPath);
|
|
55248
|
-
if (
|
|
55249
|
-
|
|
55602
|
+
if (fs15.existsSync(localPath)) {
|
|
55603
|
+
fs15.unlinkSync(localPath);
|
|
55250
55604
|
}
|
|
55251
55605
|
delete this.index.files[hash];
|
|
55252
55606
|
if (this.index.pathHints) {
|
|
@@ -55261,8 +55615,8 @@ var FileCache = class _FileCache {
|
|
|
55261
55615
|
clear() {
|
|
55262
55616
|
for (const entry of Object.values(this.index.files)) {
|
|
55263
55617
|
const localPath = path14.join(this.dataDir, entry.localPath);
|
|
55264
|
-
if (
|
|
55265
|
-
|
|
55618
|
+
if (fs15.existsSync(localPath)) {
|
|
55619
|
+
fs15.unlinkSync(localPath);
|
|
55266
55620
|
}
|
|
55267
55621
|
}
|
|
55268
55622
|
this.index = { version: CACHE_VERSION, files: {}, pathHints: {} };
|
|
@@ -55350,7 +55704,7 @@ var FileCache = class _FileCache {
|
|
|
55350
55704
|
getResolvedHintPath(filePath) {
|
|
55351
55705
|
const resolvedPath = resolvePath(filePath);
|
|
55352
55706
|
try {
|
|
55353
|
-
return
|
|
55707
|
+
return fs15.realpathSync.native ? fs15.realpathSync.native(resolvedPath) : fs15.realpathSync(resolvedPath);
|
|
55354
55708
|
} catch {
|
|
55355
55709
|
return resolvedPath;
|
|
55356
55710
|
}
|
|
@@ -55358,7 +55712,7 @@ var FileCache = class _FileCache {
|
|
|
55358
55712
|
};
|
|
55359
55713
|
|
|
55360
55714
|
// src/files/session-file-manager.ts
|
|
55361
|
-
import * as
|
|
55715
|
+
import * as fs16 from "node:fs";
|
|
55362
55716
|
import * as path15 from "node:path";
|
|
55363
55717
|
var INITIAL_REFRESH_BACKOFF_MS = 6e4;
|
|
55364
55718
|
var MAX_REFRESH_BACKOFF_MS = 60 * 60 * 1e3;
|
|
@@ -55383,15 +55737,15 @@ var SessionFileManager = class {
|
|
|
55383
55737
|
// Directory Management
|
|
55384
55738
|
// ============================================================================
|
|
55385
55739
|
ensureDirectories() {
|
|
55386
|
-
if (!
|
|
55387
|
-
|
|
55740
|
+
if (!fs16.existsSync(this.sessionsDir)) {
|
|
55741
|
+
fs16.mkdirSync(this.sessionsDir, { recursive: true });
|
|
55388
55742
|
}
|
|
55389
55743
|
}
|
|
55390
55744
|
// ============================================================================
|
|
55391
55745
|
// State Management
|
|
55392
55746
|
// ============================================================================
|
|
55393
55747
|
loadState() {
|
|
55394
|
-
if (!
|
|
55748
|
+
if (!fs16.existsSync(this.statePath)) {
|
|
55395
55749
|
return {
|
|
55396
55750
|
sessionId: this.sessionId,
|
|
55397
55751
|
lastSyncedAt: 0,
|
|
@@ -55399,7 +55753,7 @@ var SessionFileManager = class {
|
|
|
55399
55753
|
};
|
|
55400
55754
|
}
|
|
55401
55755
|
try {
|
|
55402
|
-
return JSON.parse(
|
|
55756
|
+
return JSON.parse(fs16.readFileSync(this.statePath, "utf-8"));
|
|
55403
55757
|
} catch (err) {
|
|
55404
55758
|
sessionLogger.error(" Failed to load state:", err);
|
|
55405
55759
|
return {
|
|
@@ -55412,12 +55766,12 @@ var SessionFileManager = class {
|
|
|
55412
55766
|
saveState() {
|
|
55413
55767
|
try {
|
|
55414
55768
|
if (Object.keys(this.state.files).length === 0) {
|
|
55415
|
-
if (
|
|
55416
|
-
|
|
55769
|
+
if (fs16.existsSync(this.statePath)) {
|
|
55770
|
+
fs16.unlinkSync(this.statePath);
|
|
55417
55771
|
}
|
|
55418
55772
|
return;
|
|
55419
55773
|
}
|
|
55420
|
-
|
|
55774
|
+
fs16.writeFileSync(this.statePath, JSON.stringify(this.state, null, 2));
|
|
55421
55775
|
} catch (err) {
|
|
55422
55776
|
sessionLogger.error(" Failed to save state:", err);
|
|
55423
55777
|
}
|
|
@@ -55563,7 +55917,7 @@ var SessionFileManager = class {
|
|
|
55563
55917
|
return { success: false, coolingDown: true };
|
|
55564
55918
|
}
|
|
55565
55919
|
const localPath = this.fileCache.getLocalPath(entry.hash);
|
|
55566
|
-
if (!localPath || !
|
|
55920
|
+
if (!localPath || !fs16.existsSync(localPath)) {
|
|
55567
55921
|
sessionLogger.warn(`Local file not found for ${fileId}`);
|
|
55568
55922
|
entry.status = "expired";
|
|
55569
55923
|
entry.error = "Local file missing";
|
|
@@ -55714,15 +56068,15 @@ var SessionFileManager = class {
|
|
|
55714
56068
|
// Static Utilities
|
|
55715
56069
|
// ============================================================================
|
|
55716
56070
|
static cleanupOldSessions(sessionsDir, maxAge = 30 * 24 * 60 * 60 * 1e3) {
|
|
55717
|
-
if (!
|
|
56071
|
+
if (!fs16.existsSync(sessionsDir)) return;
|
|
55718
56072
|
const now = Date.now();
|
|
55719
|
-
const files =
|
|
56073
|
+
const files = fs16.readdirSync(sessionsDir);
|
|
55720
56074
|
for (const file of files) {
|
|
55721
56075
|
if (!file.endsWith(".json")) continue;
|
|
55722
56076
|
const filePath = path15.join(sessionsDir, file);
|
|
55723
|
-
const stat2 =
|
|
56077
|
+
const stat2 = fs16.statSync(filePath);
|
|
55724
56078
|
if (now - stat2.mtime.getTime() > maxAge) {
|
|
55725
|
-
|
|
56079
|
+
fs16.unlinkSync(filePath);
|
|
55726
56080
|
sessionLogger.debug(`Cleaned up old session: ${file}`);
|
|
55727
56081
|
}
|
|
55728
56082
|
}
|
|
@@ -55730,7 +56084,7 @@ var SessionFileManager = class {
|
|
|
55730
56084
|
};
|
|
55731
56085
|
|
|
55732
56086
|
// src/files/ffmpeg-processor.ts
|
|
55733
|
-
import * as
|
|
56087
|
+
import * as fs17 from "node:fs";
|
|
55734
56088
|
import * as path16 from "node:path";
|
|
55735
56089
|
import { spawn } from "node:child_process";
|
|
55736
56090
|
var FFmpegProcessor = class {
|
|
@@ -55866,7 +56220,7 @@ var FFmpegProcessor = class {
|
|
|
55866
56220
|
onProgress?.(percent);
|
|
55867
56221
|
}
|
|
55868
56222
|
});
|
|
55869
|
-
const outputStat =
|
|
56223
|
+
const outputStat = fs17.statSync(outputPath);
|
|
55870
56224
|
return {
|
|
55871
56225
|
type: "video",
|
|
55872
56226
|
output: outputPath,
|
|
@@ -55898,7 +56252,7 @@ var FFmpegProcessor = class {
|
|
|
55898
56252
|
async extractKeyframes(inputPath, outputDir, info, opts, onProgress) {
|
|
55899
56253
|
const interval = Math.floor(info.duration / opts.keyframeCount);
|
|
55900
56254
|
const framesDir = path16.join(outputDir, `keyframes_${Date.now()}`);
|
|
55901
|
-
|
|
56255
|
+
fs17.mkdirSync(framesDir, { recursive: true });
|
|
55902
56256
|
const outputPattern = path16.join(framesDir, "frame_%03d.jpg");
|
|
55903
56257
|
const args = [
|
|
55904
56258
|
"-i",
|
|
@@ -55917,10 +56271,10 @@ var FFmpegProcessor = class {
|
|
|
55917
56271
|
onProgress?.(percent);
|
|
55918
56272
|
}
|
|
55919
56273
|
});
|
|
55920
|
-
let frames =
|
|
56274
|
+
let frames = fs17.readdirSync(framesDir).filter((f) => f.endsWith(".jpg")).sort().map((f) => path16.join(framesDir, f));
|
|
55921
56275
|
if (frames.length < opts.keyframeCount / 2) {
|
|
55922
|
-
|
|
55923
|
-
|
|
56276
|
+
fs17.rmSync(framesDir, { recursive: true, force: true });
|
|
56277
|
+
fs17.mkdirSync(framesDir, { recursive: true });
|
|
55924
56278
|
const uniformArgs = [
|
|
55925
56279
|
"-i",
|
|
55926
56280
|
inputPath,
|
|
@@ -55936,10 +56290,10 @@ var FFmpegProcessor = class {
|
|
|
55936
56290
|
onProgress?.(percent);
|
|
55937
56291
|
}
|
|
55938
56292
|
});
|
|
55939
|
-
frames =
|
|
56293
|
+
frames = fs17.readdirSync(framesDir).filter((f) => f.endsWith(".jpg")).sort().map((f) => path16.join(framesDir, f));
|
|
55940
56294
|
}
|
|
55941
56295
|
const totalOutputSize = frames.reduce(
|
|
55942
|
-
(sum, f) => sum +
|
|
56296
|
+
(sum, f) => sum + fs17.statSync(f).size,
|
|
55943
56297
|
0
|
|
55944
56298
|
);
|
|
55945
56299
|
return {
|
|
@@ -56159,8 +56513,8 @@ var FileManager = class {
|
|
|
56159
56513
|
directoryListingCache = /* @__PURE__ */ new Map();
|
|
56160
56514
|
authFingerprint;
|
|
56161
56515
|
ensureDirectories() {
|
|
56162
|
-
if (!
|
|
56163
|
-
|
|
56516
|
+
if (!fs18.existsSync(this.tempDir)) {
|
|
56517
|
+
fs18.mkdirSync(this.tempDir, { recursive: true });
|
|
56164
56518
|
}
|
|
56165
56519
|
}
|
|
56166
56520
|
// ============================================================================
|
|
@@ -56191,7 +56545,7 @@ var FileManager = class {
|
|
|
56191
56545
|
async stageLocal(filePath, options = {}) {
|
|
56192
56546
|
const resolvedPath = resolvePath(filePath);
|
|
56193
56547
|
const sourceName = options.sourceName || path17.basename(resolvedPath);
|
|
56194
|
-
if (!
|
|
56548
|
+
if (!fs18.existsSync(resolvedPath)) {
|
|
56195
56549
|
throw new FileManagerError(
|
|
56196
56550
|
"LOCAL_FILE_MISSING" /* LOCAL_FILE_MISSING */,
|
|
56197
56551
|
`File not found: ${filePath}`
|
|
@@ -56206,7 +56560,7 @@ var FileManager = class {
|
|
|
56206
56560
|
this.fileCache.rememberPathHint(resolvedPath, hash, sourceName);
|
|
56207
56561
|
this.invalidateDirectoryListingCacheForPath(resolvedPath);
|
|
56208
56562
|
const entry = this.fileCache.getByHash(hash);
|
|
56209
|
-
const size = entry?.size ??
|
|
56563
|
+
const size = entry?.size ?? fs18.statSync(resolvedPath).size;
|
|
56210
56564
|
return {
|
|
56211
56565
|
success: true,
|
|
56212
56566
|
hash,
|
|
@@ -56221,7 +56575,7 @@ var FileManager = class {
|
|
|
56221
56575
|
async upload(filePath, options = {}) {
|
|
56222
56576
|
const resolvedPath = resolvePath(filePath);
|
|
56223
56577
|
const sourceName = options.sourceName || path17.basename(resolvedPath);
|
|
56224
|
-
if (!
|
|
56578
|
+
if (!fs18.existsSync(resolvedPath)) {
|
|
56225
56579
|
throw new FileManagerError(
|
|
56226
56580
|
"LOCAL_FILE_MISSING" /* LOCAL_FILE_MISSING */,
|
|
56227
56581
|
`File not found: ${filePath}`
|
|
@@ -56302,7 +56656,7 @@ var FileManager = class {
|
|
|
56302
56656
|
// ============================================================================
|
|
56303
56657
|
async uploadPic(filePath, options = {}) {
|
|
56304
56658
|
const resolvedPath = resolvePath(filePath);
|
|
56305
|
-
if (!
|
|
56659
|
+
if (!fs18.existsSync(resolvedPath)) {
|
|
56306
56660
|
throw new FileManagerError(
|
|
56307
56661
|
"LOCAL_FILE_MISSING" /* LOCAL_FILE_MISSING */,
|
|
56308
56662
|
`File not found: ${filePath}`
|
|
@@ -56332,7 +56686,7 @@ var FileManager = class {
|
|
|
56332
56686
|
this.fileCache.rememberPathHint(resolvedPath, result.hash, path17.basename(resolvedPath));
|
|
56333
56687
|
this.invalidateDirectoryListingCacheForPath(resolvedPath);
|
|
56334
56688
|
try {
|
|
56335
|
-
|
|
56689
|
+
fs18.unlinkSync(optimizedPath);
|
|
56336
56690
|
} catch {
|
|
56337
56691
|
}
|
|
56338
56692
|
return result;
|
|
@@ -56342,7 +56696,7 @@ var FileManager = class {
|
|
|
56342
56696
|
// ============================================================================
|
|
56343
56697
|
async uploadVideo(filePath, options = {}) {
|
|
56344
56698
|
const resolvedPath = resolvePath(filePath);
|
|
56345
|
-
if (!
|
|
56699
|
+
if (!fs18.existsSync(resolvedPath)) {
|
|
56346
56700
|
throw new FileManagerError(
|
|
56347
56701
|
"LOCAL_FILE_MISSING" /* LOCAL_FILE_MISSING */,
|
|
56348
56702
|
`File not found: ${filePath}`
|
|
@@ -56736,13 +57090,13 @@ var FileManager = class {
|
|
|
56736
57090
|
cleanupTempFiles(output) {
|
|
56737
57091
|
try {
|
|
56738
57092
|
if (typeof output === "string") {
|
|
56739
|
-
if (
|
|
56740
|
-
|
|
57093
|
+
if (fs18.existsSync(output)) {
|
|
57094
|
+
fs18.unlinkSync(output);
|
|
56741
57095
|
}
|
|
56742
57096
|
} else {
|
|
56743
57097
|
for (const file of output) {
|
|
56744
|
-
if (
|
|
56745
|
-
|
|
57098
|
+
if (fs18.existsSync(file)) {
|
|
57099
|
+
fs18.unlinkSync(file);
|
|
56746
57100
|
}
|
|
56747
57101
|
}
|
|
56748
57102
|
}
|
|
@@ -56774,7 +57128,7 @@ var FileManager = class {
|
|
|
56774
57128
|
}];
|
|
56775
57129
|
}
|
|
56776
57130
|
const localPath = this.fileCache.getLocalPath(entry.hash);
|
|
56777
|
-
if (localPath &&
|
|
57131
|
+
if (localPath && fs18.existsSync(localPath)) {
|
|
56778
57132
|
return [{
|
|
56779
57133
|
fileId,
|
|
56780
57134
|
name: cacheEntry.name,
|
|
@@ -56871,7 +57225,7 @@ var FileManager = class {
|
|
|
56871
57225
|
directories: []
|
|
56872
57226
|
};
|
|
56873
57227
|
try {
|
|
56874
|
-
const entries =
|
|
57228
|
+
const entries = fs18.readdirSync(resolvedDir, { withFileTypes: true });
|
|
56875
57229
|
for (const entry of entries) {
|
|
56876
57230
|
if (!entry.name || entry.name.startsWith(".")) {
|
|
56877
57231
|
continue;
|
|
@@ -56885,7 +57239,7 @@ var FileManager = class {
|
|
|
56885
57239
|
let isFile = entry.isFile();
|
|
56886
57240
|
if (entry.isSymbolicLink()) {
|
|
56887
57241
|
try {
|
|
56888
|
-
const targetStat =
|
|
57242
|
+
const targetStat = fs18.statSync(fullPath);
|
|
56889
57243
|
isDirectory = targetStat.isDirectory();
|
|
56890
57244
|
isFile = targetStat.isFile();
|
|
56891
57245
|
} catch {
|
|
@@ -56903,7 +57257,7 @@ var FileManager = class {
|
|
|
56903
57257
|
if (!type) {
|
|
56904
57258
|
continue;
|
|
56905
57259
|
}
|
|
56906
|
-
const stat2 =
|
|
57260
|
+
const stat2 = fs18.statSync(fullPath);
|
|
56907
57261
|
listing.files.push({
|
|
56908
57262
|
name: entry.name,
|
|
56909
57263
|
path: fullPath,
|
|
@@ -57002,7 +57356,7 @@ function isInlineMediaRequest(request) {
|
|
|
57002
57356
|
return request.kind === "image" || request.kind === "video";
|
|
57003
57357
|
}
|
|
57004
57358
|
async function prepareInlineMediaContent(params) {
|
|
57005
|
-
const stat2 = await
|
|
57359
|
+
const stat2 = await fs19.stat(params.request.absolutePath);
|
|
57006
57360
|
const limitMb = getCapabilityLimitMb(params.model, params.request.kind);
|
|
57007
57361
|
const limitBytes = limitMb * 1024 * 1024;
|
|
57008
57362
|
if (stat2.size > limitBytes) {
|
|
@@ -57010,7 +57364,7 @@ async function prepareInlineMediaContent(params) {
|
|
|
57010
57364
|
`${params.request.kind} understanding for ${params.model.provider}/${params.model.id} supports inline files up to ${limitMb}MB; ${path18.basename(params.request.displayPath)} is ${(stat2.size / 1024 / 1024).toFixed(1)}MB. Configure a model with a file upload adapter, or compress/trim the file before reading it.`
|
|
57011
57365
|
);
|
|
57012
57366
|
}
|
|
57013
|
-
const data = await
|
|
57367
|
+
const data = await fs19.readFile(params.request.absolutePath, "base64");
|
|
57014
57368
|
const content = params.request.kind === "video" ? [{ type: "video", data, mimeType: params.request.mimeType }] : [{ type: "image", data, mimeType: params.request.mimeType }];
|
|
57015
57369
|
return {
|
|
57016
57370
|
content,
|
|
@@ -57380,22 +57734,22 @@ var ExecutionStateManager = class {
|
|
|
57380
57734
|
};
|
|
57381
57735
|
|
|
57382
57736
|
// src/session-trace.ts
|
|
57383
|
-
import * as
|
|
57737
|
+
import * as fs20 from "node:fs";
|
|
57384
57738
|
import * as path19 from "node:path";
|
|
57385
57739
|
function saveTraceFileBestEffort(tracePath, content) {
|
|
57386
57740
|
const tempPath = `${tracePath}.${process.pid}.${Date.now()}.tmp`;
|
|
57387
57741
|
try {
|
|
57388
|
-
|
|
57742
|
+
fs20.writeFileSync(tempPath, content, "utf8");
|
|
57389
57743
|
try {
|
|
57390
|
-
|
|
57744
|
+
fs20.renameSync(tempPath, tracePath);
|
|
57391
57745
|
return;
|
|
57392
57746
|
} catch {
|
|
57393
57747
|
try {
|
|
57394
|
-
|
|
57748
|
+
fs20.copyFileSync(tempPath, tracePath);
|
|
57395
57749
|
} catch {
|
|
57396
57750
|
} finally {
|
|
57397
57751
|
try {
|
|
57398
|
-
|
|
57752
|
+
fs20.unlinkSync(tempPath);
|
|
57399
57753
|
} catch {
|
|
57400
57754
|
}
|
|
57401
57755
|
}
|
|
@@ -57409,9 +57763,9 @@ var SessionTraceWriter = class extends SessionTraceSnapshotWriter {
|
|
|
57409
57763
|
getSessionId: () => sessionManager.getActiveSessionId(),
|
|
57410
57764
|
loadTrace: (sessionId) => {
|
|
57411
57765
|
const tracePath = path19.join(sessionsDir, `${sessionId}.trace.json`);
|
|
57412
|
-
if (!
|
|
57766
|
+
if (!fs20.existsSync(tracePath)) return null;
|
|
57413
57767
|
try {
|
|
57414
|
-
return JSON.parse(
|
|
57768
|
+
return JSON.parse(fs20.readFileSync(tracePath, "utf8"));
|
|
57415
57769
|
} catch {
|
|
57416
57770
|
return null;
|
|
57417
57771
|
}
|
|
@@ -60128,7 +60482,7 @@ async function handleForkCommand(host) {
|
|
|
60128
60482
|
}
|
|
60129
60483
|
|
|
60130
60484
|
// src/commands/interactive-skill-commands.ts
|
|
60131
|
-
import * as
|
|
60485
|
+
import * as fs21 from "fs";
|
|
60132
60486
|
import * as os4 from "os";
|
|
60133
60487
|
import * as path20 from "path";
|
|
60134
60488
|
|
|
@@ -60472,7 +60826,7 @@ function expandSkillCommand(host, text) {
|
|
|
60472
60826
|
const skill = host.skills.find((s) => s.name === skillName);
|
|
60473
60827
|
if (!skill) return text;
|
|
60474
60828
|
try {
|
|
60475
|
-
const content =
|
|
60829
|
+
const content = fs21.readFileSync(skill.filePath, "utf-8");
|
|
60476
60830
|
const body = host.stripFrontmatter(content).trim();
|
|
60477
60831
|
const skillBlock = `<skill name="${skill.name}" location="${skill.filePath}">
|
|
60478
60832
|
References are relative to ${skill.baseDir}.
|
|
@@ -60542,13 +60896,13 @@ async function handleSkillsCreate(host, args) {
|
|
|
60542
60896
|
const skillDir = path20.join(skillsDir, name);
|
|
60543
60897
|
const skillFile = path20.join(skillDir, "SKILL.md");
|
|
60544
60898
|
console.error(`[SkillsCreate] Creating at: ${skillFile}`);
|
|
60545
|
-
if (
|
|
60899
|
+
if (fs21.existsSync(skillDir)) {
|
|
60546
60900
|
host.showError(`Skill "${name}" already exists at ${skillDir}`);
|
|
60547
60901
|
return;
|
|
60548
60902
|
}
|
|
60549
|
-
|
|
60903
|
+
fs21.mkdirSync(skillDir, { recursive: true });
|
|
60550
60904
|
const template = createSkillTemplate(name, description);
|
|
60551
|
-
|
|
60905
|
+
fs21.writeFileSync(skillFile, template, "utf-8");
|
|
60552
60906
|
console.error(`[SkillsCreate] Successfully created skill`);
|
|
60553
60907
|
host.chatContainer.addChild(new Spacer(1));
|
|
60554
60908
|
host.chatContainer.addChild(new Text(theme.fg("accent", `\u2713 Created skill: ${name}`), 1, 0));
|
|
@@ -61258,6 +61612,7 @@ async function handleCompactCommand(host) {
|
|
|
61258
61612
|
host.sessionManager.appendCompaction(summary, firstKeptEntryId, tokensBefore);
|
|
61259
61613
|
const compactedMessages = host.sessionManager.getMessages();
|
|
61260
61614
|
host.replaceAgentMessagesAndMarkSynced(compactedMessages);
|
|
61615
|
+
host.resetFileObservationState();
|
|
61261
61616
|
host.streamingComponent = void 0;
|
|
61262
61617
|
host.pendingTools.clear();
|
|
61263
61618
|
host.chatContainer.clear();
|
|
@@ -62018,7 +62373,7 @@ function setupInteractiveEditorSubmitHandler(host) {
|
|
|
62018
62373
|
}
|
|
62019
62374
|
|
|
62020
62375
|
// src/input/interactive-file-pipeline.ts
|
|
62021
|
-
import * as
|
|
62376
|
+
import * as fs24 from "fs";
|
|
62022
62377
|
import * as path23 from "path";
|
|
62023
62378
|
|
|
62024
62379
|
// src/components/file-picker.ts
|
|
@@ -62240,7 +62595,7 @@ var FilePickerComponent = class extends Container {
|
|
|
62240
62595
|
};
|
|
62241
62596
|
|
|
62242
62597
|
// src/files/commands/file-commands.ts
|
|
62243
|
-
import * as
|
|
62598
|
+
import * as fs22 from "node:fs";
|
|
62244
62599
|
import * as path21 from "node:path";
|
|
62245
62600
|
var FileCommands = class {
|
|
62246
62601
|
context;
|
|
@@ -62257,7 +62612,7 @@ var FileCommands = class {
|
|
|
62257
62612
|
return;
|
|
62258
62613
|
}
|
|
62259
62614
|
const filePath = resolvePath(parsed.path);
|
|
62260
|
-
if (!
|
|
62615
|
+
if (!fs22.existsSync(filePath)) {
|
|
62261
62616
|
this.context.showError(`File not found: ${parsed.path}`);
|
|
62262
62617
|
return;
|
|
62263
62618
|
}
|
|
@@ -62296,7 +62651,7 @@ var FileCommands = class {
|
|
|
62296
62651
|
return;
|
|
62297
62652
|
}
|
|
62298
62653
|
const resolvedPath = resolvePath(filePath);
|
|
62299
|
-
if (!
|
|
62654
|
+
if (!fs22.existsSync(resolvedPath)) {
|
|
62300
62655
|
this.context.showError(`File not found: ${filePath}`);
|
|
62301
62656
|
return;
|
|
62302
62657
|
}
|
|
@@ -62327,7 +62682,7 @@ var FileCommands = class {
|
|
|
62327
62682
|
return;
|
|
62328
62683
|
}
|
|
62329
62684
|
const resolvedPath = resolvePath(parsed.path);
|
|
62330
|
-
if (!
|
|
62685
|
+
if (!fs22.existsSync(resolvedPath)) {
|
|
62331
62686
|
this.context.showError(`File not found: ${parsed.path}`);
|
|
62332
62687
|
return;
|
|
62333
62688
|
}
|
|
@@ -62805,7 +63160,7 @@ var FileStatusMonitor = class {
|
|
|
62805
63160
|
};
|
|
62806
63161
|
|
|
62807
63162
|
// src/files/mention/mention-handler.ts
|
|
62808
|
-
import * as
|
|
63163
|
+
import * as fs23 from "node:fs";
|
|
62809
63164
|
import * as path22 from "node:path";
|
|
62810
63165
|
var MentionHandler = class {
|
|
62811
63166
|
fileManager;
|
|
@@ -63175,8 +63530,8 @@ var MentionHandler = class {
|
|
|
63175
63530
|
}
|
|
63176
63531
|
if (this.isPath(query)) {
|
|
63177
63532
|
const resolvedPath = resolvePath(query);
|
|
63178
|
-
if (
|
|
63179
|
-
const stats =
|
|
63533
|
+
if (fs23.existsSync(resolvedPath)) {
|
|
63534
|
+
const stats = fs23.statSync(resolvedPath);
|
|
63180
63535
|
if (stats.isFile()) {
|
|
63181
63536
|
const type = FileCache.getFileTypeFromName(resolvedPath);
|
|
63182
63537
|
const name = path22.basename(resolvedPath);
|
|
@@ -63200,7 +63555,7 @@ var MentionHandler = class {
|
|
|
63200
63555
|
return void 0;
|
|
63201
63556
|
}
|
|
63202
63557
|
const queryPath = this.isPath(query) ? resolvePath(query) : void 0;
|
|
63203
|
-
const filter = queryPath ?
|
|
63558
|
+
const filter = queryPath ? fs23.existsSync(queryPath) && fs23.statSync(queryPath).isDirectory() ? "" : path22.basename(queryPath) : query;
|
|
63204
63559
|
const entries = this.fileManager.listPathEntries(currentDir, filter);
|
|
63205
63560
|
const options = [];
|
|
63206
63561
|
const homeDir = process.env.HOME || "";
|
|
@@ -63241,7 +63596,7 @@ var MentionHandler = class {
|
|
|
63241
63596
|
getBrowserDirectory(query = this.currentQuery) {
|
|
63242
63597
|
if (this.isPath(query)) {
|
|
63243
63598
|
const resolvedPath = resolvePath(query);
|
|
63244
|
-
if (
|
|
63599
|
+
if (fs23.existsSync(resolvedPath) && fs23.statSync(resolvedPath).isDirectory()) {
|
|
63245
63600
|
return resolvedPath;
|
|
63246
63601
|
}
|
|
63247
63602
|
return path22.dirname(resolvedPath);
|
|
@@ -63605,13 +63960,13 @@ function convertPreparedAttachmentItems(items) {
|
|
|
63605
63960
|
break;
|
|
63606
63961
|
case "image": {
|
|
63607
63962
|
if (!item.data && !item.path) return void 0;
|
|
63608
|
-
const data = item.data ??
|
|
63963
|
+
const data = item.data ?? fs24.readFileSync(item.path, "base64");
|
|
63609
63964
|
converted.push({ type: "image", data, mimeType: item.mimeType });
|
|
63610
63965
|
break;
|
|
63611
63966
|
}
|
|
63612
63967
|
case "video": {
|
|
63613
63968
|
if (!item.data && !item.path) return void 0;
|
|
63614
|
-
const data = item.data ??
|
|
63969
|
+
const data = item.data ?? fs24.readFileSync(item.path, "base64");
|
|
63615
63970
|
converted.push({ type: "video", data, mimeType: item.mimeType });
|
|
63616
63971
|
break;
|
|
63617
63972
|
}
|
|
@@ -64017,6 +64372,10 @@ function buildCodingAgentGuidelinesSection(tools = []) {
|
|
|
64017
64372
|
if (hasGrep || hasFind || hasList) {
|
|
64018
64373
|
guidelines.push("Prefer grep_text, find_files, and list_dir for workspace exploration when they are sufficient.");
|
|
64019
64374
|
}
|
|
64375
|
+
if (hasGrep) {
|
|
64376
|
+
guidelines.push("Use grep_text outputMode='files_with_matches' to find candidate files, outputMode='count' to estimate impact, and outputMode='content' when you need matching lines and context.");
|
|
64377
|
+
guidelines.push("After a broad grep_text search, narrow the path, glob, pattern, outputMode, offset, or limit instead of repeating the same broad search.");
|
|
64378
|
+
}
|
|
64020
64379
|
if (hasWebResearch) {
|
|
64021
64380
|
guidelines.push("Use web_research for general public web research, current information, official docs, news, releases, issues, or webpage summaries; it searches, fetches, and returns cited sources.");
|
|
64022
64381
|
guidelines.push("When web_research returns fetched sources that answer the request, synthesize the answer from that pack instead of calling web_search or web_fetch again.");
|
|
@@ -64036,20 +64395,26 @@ function buildCodingAgentGuidelinesSection(tools = []) {
|
|
|
64036
64395
|
guidelines.push("Read the current file before edit_file changes, then use a precise unique replacement.");
|
|
64037
64396
|
}
|
|
64038
64397
|
if (hasRead) {
|
|
64398
|
+
guidelines.push("Use read_file offset/limit for large files; if read_file says a range is unchanged, do not repeat the same read and choose a different range or search instead.");
|
|
64039
64399
|
guidelines.push("Use read_file directly for media and documents when the file-understanding route is available.");
|
|
64040
64400
|
}
|
|
64041
64401
|
if (hasEdit) {
|
|
64042
|
-
guidelines.push("If edit_file fails because text is missing
|
|
64402
|
+
guidelines.push("If edit_file fails because text is missing, read the current file and retry with exact text copied from the latest file contents.");
|
|
64403
|
+
guidelines.push("If edit_file fails because text is not unique, read the current file and retry with a larger exact block, or set replaceAll to true if every occurrence should be replaced.");
|
|
64043
64404
|
}
|
|
64044
64405
|
if (hasWrite) {
|
|
64045
|
-
guidelines.push("Use write_file for new files or complete rewrites
|
|
64406
|
+
guidelines.push("Use write_file for new files or true complete rewrites; before overwriting an existing file, read the current full file with read_file, and prefer edit_file for targeted changes.");
|
|
64046
64407
|
}
|
|
64047
64408
|
if (hasBash) {
|
|
64048
64409
|
guidelines.push("Pass only executable shell commands to bash, not numbered plan items, headings, or prose.");
|
|
64410
|
+
if (hasWrite || hasEdit) {
|
|
64411
|
+
guidelines.push("Do not use shell redirection, cat > file, tee, or heredoc to create or overwrite files when write_file or edit_file can do it; never use Bash to bypass write_file overwrite guards.");
|
|
64412
|
+
}
|
|
64049
64413
|
guidelines.push("If bash times out or truncates output, adjust the command or inspect the reported full output path instead of repeating the same command.");
|
|
64050
64414
|
}
|
|
64051
64415
|
if (hasTodo) {
|
|
64052
|
-
guidelines.push("Use manage_todo_list for multi-step work: create the list, complete only the current item,
|
|
64416
|
+
guidelines.push("Use manage_todo_list only for multi-step work: create the list, complete only the current item when it is genuinely done, and let the tool advance the next item.");
|
|
64417
|
+
guidelines.push("Do not complete a todo item while implementation is partial, tests or verification are failing, or the required verification has not run.");
|
|
64053
64418
|
}
|
|
64054
64419
|
guidelines.push(
|
|
64055
64420
|
"Once the root cause or required change is clear, make a small concrete edit instead of continuing unrelated exploration.",
|
|
@@ -65056,6 +65421,7 @@ function createInteractiveAgentSessionController(host) {
|
|
|
65056
65421
|
host.footer.setState({ status: "ready" });
|
|
65057
65422
|
return;
|
|
65058
65423
|
}
|
|
65424
|
+
host.resetFileObservationState();
|
|
65059
65425
|
const contextUsage = host.calculateContextUsage();
|
|
65060
65426
|
const contextWindow = host.options.model?.contextWindow ?? 0;
|
|
65061
65427
|
const contextPercent = contextWindow > 0 && contextUsage.tokens !== null ? contextUsage.tokens / contextWindow * 100 : 0;
|
|
@@ -65086,7 +65452,7 @@ var RUNTIME_MODE_CONTEXT_MARKER = "<runtime-mode-context>";
|
|
|
65086
65452
|
var RUNTIME_MODE_CONTEXT_END_MARKER = "</runtime-mode-context>";
|
|
65087
65453
|
var STALE_SYSTEM_REMINDER_RE = /<system-reminder>\s*# Plan Mode[\s\S]*?<\/system-reminder>\s*/gi;
|
|
65088
65454
|
var STALE_RUNTIME_CONTEXT_RE = /<runtime-mode-context>[\s\S]*?<\/runtime-mode-context>\s*/gi;
|
|
65089
|
-
function
|
|
65455
|
+
function isRecord3(value) {
|
|
65090
65456
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
65091
65457
|
}
|
|
65092
65458
|
function cleanText(text) {
|
|
@@ -65102,7 +65468,7 @@ function cleanText(text) {
|
|
|
65102
65468
|
return { text: withoutPlanReminder, stripped };
|
|
65103
65469
|
}
|
|
65104
65470
|
function stripUserMessage(message) {
|
|
65105
|
-
if (!
|
|
65471
|
+
if (!isRecord3(message) || message.role !== "user") {
|
|
65106
65472
|
return { message, stripped: 0 };
|
|
65107
65473
|
}
|
|
65108
65474
|
const content = message.content;
|
|
@@ -65122,13 +65488,13 @@ function stripUserMessage(message) {
|
|
|
65122
65488
|
}
|
|
65123
65489
|
let stripped = 0;
|
|
65124
65490
|
const nextContent = content.map((block) => {
|
|
65125
|
-
if (!
|
|
65491
|
+
if (!isRecord3(block) || block.type !== "text" || typeof block.text !== "string") {
|
|
65126
65492
|
return block;
|
|
65127
65493
|
}
|
|
65128
65494
|
const cleaned = cleanText(block.text);
|
|
65129
65495
|
stripped += cleaned.stripped;
|
|
65130
65496
|
return { ...block, text: cleaned.text };
|
|
65131
|
-
}).filter((block) => !(
|
|
65497
|
+
}).filter((block) => !(isRecord3(block) && block.type === "text" && String(block.text ?? "").length === 0));
|
|
65132
65498
|
if (stripped === 0) return { message, stripped: 0 };
|
|
65133
65499
|
return {
|
|
65134
65500
|
message: {
|
|
@@ -65144,7 +65510,7 @@ function stripRuntimeModeContext(messages) {
|
|
|
65144
65510
|
for (const message of messages) {
|
|
65145
65511
|
const result = stripUserMessage(message);
|
|
65146
65512
|
stripped += result.stripped;
|
|
65147
|
-
if (
|
|
65513
|
+
if (isRecord3(result.message) && result.message.role === "user") {
|
|
65148
65514
|
const content = result.message.content;
|
|
65149
65515
|
if (typeof content === "string" && content.trim().length === 0) {
|
|
65150
65516
|
continue;
|
|
@@ -65186,7 +65552,7 @@ function buildRuntimeModeContext(state) {
|
|
|
65186
65552
|
function findLatestUserIndex(messages) {
|
|
65187
65553
|
for (let index = messages.length - 1; index >= 0; index--) {
|
|
65188
65554
|
const message = messages[index];
|
|
65189
|
-
if (
|
|
65555
|
+
if (isRecord3(message) && message.role === "user") {
|
|
65190
65556
|
return index;
|
|
65191
65557
|
}
|
|
65192
65558
|
}
|
|
@@ -65665,7 +66031,7 @@ var AttachmentResolver = class {
|
|
|
65665
66031
|
};
|
|
65666
66032
|
|
|
65667
66033
|
// src/extensions/loader.ts
|
|
65668
|
-
import * as
|
|
66034
|
+
import * as fs25 from "node:fs";
|
|
65669
66035
|
import * as os5 from "os";
|
|
65670
66036
|
import * as path24 from "path";
|
|
65671
66037
|
import { pathToFileURL } from "node:url";
|
|
@@ -65849,7 +66215,7 @@ function normalizeExtensionImportPath(extensionPath) {
|
|
|
65849
66215
|
}
|
|
65850
66216
|
async function loadExtension(extensionPath, cwd, uiContext, abortFn, isIdleFn, hasUI, actions) {
|
|
65851
66217
|
const resolvedPath = resolvePath2(extensionPath, cwd);
|
|
65852
|
-
if (!
|
|
66218
|
+
if (!fs25.existsSync(resolvedPath)) {
|
|
65853
66219
|
return { extension: null, error: `Extension not found: ${extensionPath}` };
|
|
65854
66220
|
}
|
|
65855
66221
|
try {
|
|
@@ -65870,12 +66236,12 @@ async function loadExtension(extensionPath, cwd, uiContext, abortFn, isIdleFn, h
|
|
|
65870
66236
|
}
|
|
65871
66237
|
}
|
|
65872
66238
|
function discoverExtensionsInDir(dir) {
|
|
65873
|
-
if (!
|
|
66239
|
+
if (!fs25.existsSync(dir)) {
|
|
65874
66240
|
return [];
|
|
65875
66241
|
}
|
|
65876
66242
|
const discovered = [];
|
|
65877
66243
|
try {
|
|
65878
|
-
const entries =
|
|
66244
|
+
const entries = fs25.readdirSync(dir, { withFileTypes: true });
|
|
65879
66245
|
for (const entry of entries) {
|
|
65880
66246
|
const entryPath = path24.join(dir, entry.name);
|
|
65881
66247
|
if (entry.isFile() && (entry.name.endsWith(".cjs") || entry.name.endsWith(".js") || entry.name.endsWith(".ts"))) {
|
|
@@ -65884,13 +66250,13 @@ function discoverExtensionsInDir(dir) {
|
|
|
65884
66250
|
}
|
|
65885
66251
|
if (entry.isDirectory()) {
|
|
65886
66252
|
const packageJsonPath = path24.join(entryPath, "package.json");
|
|
65887
|
-
if (
|
|
66253
|
+
if (fs25.existsSync(packageJsonPath)) {
|
|
65888
66254
|
try {
|
|
65889
|
-
const pkg = JSON.parse(
|
|
66255
|
+
const pkg = JSON.parse(fs25.readFileSync(packageJsonPath, "utf-8"));
|
|
65890
66256
|
const manifest = pkg.pie;
|
|
65891
66257
|
if (manifest?.main) {
|
|
65892
66258
|
const mainPath = path24.resolve(entryPath, manifest.main);
|
|
65893
|
-
if (
|
|
66259
|
+
if (fs25.existsSync(mainPath)) {
|
|
65894
66260
|
discovered.push({
|
|
65895
66261
|
entryPath: mainPath,
|
|
65896
66262
|
manifestName: manifest.name || pkg.name
|
|
@@ -65902,17 +66268,17 @@ function discoverExtensionsInDir(dir) {
|
|
|
65902
66268
|
}
|
|
65903
66269
|
}
|
|
65904
66270
|
const indexCjs = path24.join(entryPath, "index.cjs");
|
|
65905
|
-
if (
|
|
66271
|
+
if (fs25.existsSync(indexCjs)) {
|
|
65906
66272
|
discovered.push({ entryPath: indexCjs });
|
|
65907
66273
|
continue;
|
|
65908
66274
|
}
|
|
65909
66275
|
const indexJs = path24.join(entryPath, "index.js");
|
|
65910
|
-
if (
|
|
66276
|
+
if (fs25.existsSync(indexJs)) {
|
|
65911
66277
|
discovered.push({ entryPath: indexJs });
|
|
65912
66278
|
continue;
|
|
65913
66279
|
}
|
|
65914
66280
|
const indexTs = path24.join(entryPath, "index.ts");
|
|
65915
|
-
if (
|
|
66281
|
+
if (fs25.existsSync(indexTs)) {
|
|
65916
66282
|
discovered.push({ entryPath: indexTs });
|
|
65917
66283
|
continue;
|
|
65918
66284
|
}
|
|
@@ -65961,11 +66327,11 @@ async function loadExtensions(configuredPaths, cwd, uiContext, abortFn, isIdleFn
|
|
|
65961
66327
|
}
|
|
65962
66328
|
for (const p of configuredPaths) {
|
|
65963
66329
|
const resolved = resolvePath2(p, cwd);
|
|
65964
|
-
if (!
|
|
66330
|
+
if (!fs25.existsSync(resolved)) {
|
|
65965
66331
|
errors.push({ path: p, error: `Extension path not found: ${p}` });
|
|
65966
66332
|
continue;
|
|
65967
66333
|
}
|
|
65968
|
-
if (!
|
|
66334
|
+
if (!fs25.statSync(resolved).isDirectory()) {
|
|
65969
66335
|
errors.push({ path: p, error: `Extension path must be a directory: ${p}` });
|
|
65970
66336
|
continue;
|
|
65971
66337
|
}
|
|
@@ -66810,6 +67176,7 @@ var InteractiveMode = class {
|
|
|
66810
67176
|
allowlistedDirs
|
|
66811
67177
|
}),
|
|
66812
67178
|
configDir: this.options.configDir,
|
|
67179
|
+
fileObservationState: this.options.fileObservationState,
|
|
66813
67180
|
getAgentModel: () => this.options.model,
|
|
66814
67181
|
getSessionId: () => this.sessionManager.getActiveSessionId() || void 0,
|
|
66815
67182
|
resolveToolModel: (purpose) => this.options.modelRegistry.resolveToolModel(purpose, this.options.model),
|
|
@@ -66837,6 +67204,9 @@ var InteractiveMode = class {
|
|
|
66837
67204
|
)
|
|
66838
67205
|
};
|
|
66839
67206
|
}
|
|
67207
|
+
resetFileObservationState() {
|
|
67208
|
+
this.options.fileObservationState.clear();
|
|
67209
|
+
}
|
|
66840
67210
|
getRuntimeModeState() {
|
|
66841
67211
|
const pendingTransition = this.getPendingRuntimeModeTransition();
|
|
66842
67212
|
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone || "local";
|
|
@@ -66945,7 +67315,7 @@ var InteractiveMode = class {
|
|
|
66945
67315
|
if (savedLevel) {
|
|
66946
67316
|
this.thinkingLevel = savedLevel;
|
|
66947
67317
|
}
|
|
66948
|
-
const { Agent } = await import("./chunks/src-
|
|
67318
|
+
const { Agent } = await import("./chunks/src-2FHZO63Y.js");
|
|
66949
67319
|
const activeSession = this.sessionManager.getActiveSession();
|
|
66950
67320
|
this.agent = new Agent({
|
|
66951
67321
|
initialState: {
|
|
@@ -67347,10 +67717,12 @@ async function composeCliRuntime(params) {
|
|
|
67347
67717
|
inputSummary: `provider=${settingsManager.getDefaultProvider() || "unset"} model=${settingsManager.getDefaultModel() || "unset"}`,
|
|
67348
67718
|
outputSummary: `provider=${provider} model=${modelId} configured=${!initialModel.unconfigured}`
|
|
67349
67719
|
});
|
|
67350
|
-
const cwd = process.cwd();
|
|
67720
|
+
const cwd = params.cwd ?? process.cwd();
|
|
67351
67721
|
const sessionManager = createSessionManager({ sessionsDir: paths.sessionsDir });
|
|
67352
67722
|
if (params.explicitSessionId) {
|
|
67353
|
-
const loaded = await sessionManager.loadSession(params.explicitSessionId
|
|
67723
|
+
const loaded = await sessionManager.loadSession(params.explicitSessionId, {
|
|
67724
|
+
warnIfMissing: params.warnIfExplicitSessionMissing
|
|
67725
|
+
});
|
|
67354
67726
|
if (!loaded) {
|
|
67355
67727
|
await sessionManager.createSession(void 0, void 0, params.explicitSessionId);
|
|
67356
67728
|
} else {
|
|
@@ -67374,7 +67746,13 @@ async function composeCliRuntime(params) {
|
|
|
67374
67746
|
await sessionManager.createSession();
|
|
67375
67747
|
}
|
|
67376
67748
|
syncSessionModelMetadata(sessionManager, model, settingsManager.getDefaultThinkingLevel() || "off");
|
|
67749
|
+
const activeSession = sessionManager.getActiveSession();
|
|
67750
|
+
if (activeSession && activeSession.metadata.cwd !== cwd) {
|
|
67751
|
+
activeSession.metadata.cwd = cwd;
|
|
67752
|
+
await sessionManager.save();
|
|
67753
|
+
}
|
|
67377
67754
|
const sessionId = sessionManager.getActiveSession()?.id;
|
|
67755
|
+
const fileObservationState = createFileObservationState();
|
|
67378
67756
|
if (sessionId) {
|
|
67379
67757
|
if (process.env.PIE_DEBUG && !fileLogger.isEnabled()) {
|
|
67380
67758
|
fileLogger.enable();
|
|
@@ -67403,6 +67781,7 @@ async function composeCliRuntime(params) {
|
|
|
67403
67781
|
const fileSystemToolOptions = {
|
|
67404
67782
|
...buildCliFileAccessOptions({ cwd, configDir: paths.configDir, skills, allowlistedDirs: [paths.configDir] }),
|
|
67405
67783
|
configDir: paths.configDir,
|
|
67784
|
+
fileObservationState,
|
|
67406
67785
|
getAgentModel: getCurrentModel,
|
|
67407
67786
|
getSessionId: () => sessionManager.getActiveSessionId() || void 0,
|
|
67408
67787
|
resolveToolModel: (purpose) => modelRegistry.resolveToolModel(purpose, getCurrentModel()),
|
|
@@ -67475,6 +67854,7 @@ async function composeCliRuntime(params) {
|
|
|
67475
67854
|
skillsSection,
|
|
67476
67855
|
knowledgeSection,
|
|
67477
67856
|
tools,
|
|
67857
|
+
fileObservationState,
|
|
67478
67858
|
extensionPaths: params.extensionPaths,
|
|
67479
67859
|
compositionTrace,
|
|
67480
67860
|
createInteractiveOptions() {
|
|
@@ -67482,6 +67862,7 @@ async function composeCliRuntime(params) {
|
|
|
67482
67862
|
model,
|
|
67483
67863
|
apiKey,
|
|
67484
67864
|
tools,
|
|
67865
|
+
fileObservationState,
|
|
67485
67866
|
sessionManager,
|
|
67486
67867
|
skills,
|
|
67487
67868
|
cwd,
|
|
@@ -67612,7 +67993,7 @@ async function runPrintMode(params) {
|
|
|
67612
67993
|
`);
|
|
67613
67994
|
console.log("Assistant: ");
|
|
67614
67995
|
}
|
|
67615
|
-
const { Agent: AgentClass } = await import("./chunks/src-
|
|
67996
|
+
const { Agent: AgentClass } = await import("./chunks/src-2FHZO63Y.js");
|
|
67616
67997
|
let agent;
|
|
67617
67998
|
const printModeExtensions = await loadPrintModeExtensions({
|
|
67618
67999
|
cwd: runtime.cwd,
|
|
@@ -67704,6 +68085,8 @@ async function runPrintMode(params) {
|
|
|
67704
68085
|
console.error(event.failure.kind === "context_overflow" ? "Context overflow detected, compacting..." : "Auto-compacting context before retry...");
|
|
67705
68086
|
} else if (event.type === "auto_compaction_start") {
|
|
67706
68087
|
console.error(event.reason === "overflow" ? "Context overflow detected, compacting..." : "Auto-compacting context...");
|
|
68088
|
+
} else if (event.type === "auto_compaction_end" && !event.errorMessage) {
|
|
68089
|
+
runtime.fileObservationState.clear();
|
|
67707
68090
|
} else if (event.type === "turn_retry_started") {
|
|
67708
68091
|
console.error(`Retrying request (${event.attempt}/${event.maxRetries})...`);
|
|
67709
68092
|
} else if (event.type === "turn_retry_succeeded") {
|
|
@@ -67830,7 +68213,7 @@ function toJsonValue(value, depth = 0) {
|
|
|
67830
68213
|
}
|
|
67831
68214
|
return result;
|
|
67832
68215
|
}
|
|
67833
|
-
function
|
|
68216
|
+
function isRecord4(value) {
|
|
67834
68217
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
67835
68218
|
}
|
|
67836
68219
|
function parseInput(line) {
|
|
@@ -67840,7 +68223,7 @@ function parseInput(line) {
|
|
|
67840
68223
|
} catch {
|
|
67841
68224
|
return null;
|
|
67842
68225
|
}
|
|
67843
|
-
if (!
|
|
68226
|
+
if (!isRecord4(parsed) || typeof parsed.type !== "string") return null;
|
|
67844
68227
|
if (parsed.type === "shutdown") {
|
|
67845
68228
|
return { type: "shutdown", reason: typeof parsed.reason === "string" ? parsed.reason : void 0 };
|
|
67846
68229
|
}
|
|
@@ -67859,7 +68242,7 @@ function parseInput(line) {
|
|
|
67859
68242
|
turnId: parsed.turnId,
|
|
67860
68243
|
prompt: parsed.prompt,
|
|
67861
68244
|
cwd: typeof parsed.cwd === "string" ? parsed.cwd : void 0,
|
|
67862
|
-
metadata:
|
|
68245
|
+
metadata: isRecord4(parsed.metadata) ? parsed.metadata : void 0
|
|
67863
68246
|
};
|
|
67864
68247
|
}
|
|
67865
68248
|
return null;
|
|
@@ -67893,15 +68276,15 @@ function readProgressText(value) {
|
|
|
67893
68276
|
function extractJsonEventsToolProgressText(partialResult) {
|
|
67894
68277
|
const plainText = readProgressText(partialResult).trim();
|
|
67895
68278
|
if (plainText) return plainText;
|
|
67896
|
-
if (!
|
|
68279
|
+
if (!isRecord4(partialResult)) return "";
|
|
67897
68280
|
const content = partialResult.content;
|
|
67898
68281
|
if (Array.isArray(content)) {
|
|
67899
|
-
return content.map((block) =>
|
|
68282
|
+
return content.map((block) => isRecord4(block) && block.type === "text" ? readProgressText(block.text) : "").filter(Boolean).join("\n").trim();
|
|
67900
68283
|
}
|
|
67901
68284
|
const directText = readProgressText(partialResult.text) || readProgressText(partialResult.message);
|
|
67902
68285
|
if (directText) return directText.trim();
|
|
67903
68286
|
const details = partialResult.details;
|
|
67904
|
-
if (
|
|
68287
|
+
if (isRecord4(details)) {
|
|
67905
68288
|
return (readProgressText(details.text) || readProgressText(details.message)).trim();
|
|
67906
68289
|
}
|
|
67907
68290
|
return "";
|
|
@@ -67988,12 +68371,14 @@ async function loadJsonModeExtensions(params) {
|
|
|
67988
68371
|
async function runJsonEventsMode(params) {
|
|
67989
68372
|
const sessionId = params.explicitSessionId || params.runtime?.sessionManager.getActiveSession()?.id || `pie-json-${Date.now()}`;
|
|
67990
68373
|
let activeTurn = null;
|
|
68374
|
+
let runtime = params.runtime;
|
|
67991
68375
|
let agent;
|
|
67992
68376
|
let controller;
|
|
67993
68377
|
let disposeAgentSubscription;
|
|
67994
68378
|
let disposeSemanticSubscription;
|
|
67995
68379
|
let trace;
|
|
67996
68380
|
let lastRetryEvent;
|
|
68381
|
+
let mockActiveEntryId;
|
|
67997
68382
|
const noProgressTimeoutMs = Number(process.env.PIE_JSON_EVENTS_NO_PROGRESS_MS || 6e5);
|
|
67998
68383
|
const mockResponseDelayMs = Number(process.env.PIE_TEST_MOCK_RESPONSE_DELAY_MS || 0);
|
|
67999
68384
|
writeEvent({ type: "agent.ready", sessionId });
|
|
@@ -68013,6 +68398,7 @@ async function runJsonEventsMode(params) {
|
|
|
68013
68398
|
}
|
|
68014
68399
|
function display(chunk, options) {
|
|
68015
68400
|
if (!activeTurn || !chunk) return;
|
|
68401
|
+
activeTurn.outputStarted = true;
|
|
68016
68402
|
if (options?.appendToSummary !== false) {
|
|
68017
68403
|
activeTurn.summary += chunk;
|
|
68018
68404
|
}
|
|
@@ -68035,6 +68421,78 @@ async function runJsonEventsMode(params) {
|
|
|
68035
68421
|
activeTurn.pendingAssistantOutput = "";
|
|
68036
68422
|
}
|
|
68037
68423
|
}
|
|
68424
|
+
function activeHeadEntryId() {
|
|
68425
|
+
return mockActiveEntryId ?? runtime?.sessionManager.getActiveEntryId() ?? void 0;
|
|
68426
|
+
}
|
|
68427
|
+
function persistedMockMetadata(existing, activeEntryId, rootEntryId, cwd) {
|
|
68428
|
+
const metadata = {};
|
|
68429
|
+
if (existing) {
|
|
68430
|
+
for (const [key, value] of Object.entries(existing)) {
|
|
68431
|
+
if (["id", "createdAt", "updatedAt", "entryCount", "messageCount", "activeEntryId", "rootEntryId"].includes(key)) {
|
|
68432
|
+
continue;
|
|
68433
|
+
}
|
|
68434
|
+
metadata[key] = value;
|
|
68435
|
+
}
|
|
68436
|
+
}
|
|
68437
|
+
metadata.name = typeof existing?.name === "string" ? existing.name : `Session ${sessionId.slice(0, 8)}`;
|
|
68438
|
+
if (cwd || existing?.cwd || runtime?.cwd) {
|
|
68439
|
+
metadata.cwd = cwd ?? existing?.cwd ?? runtime?.cwd;
|
|
68440
|
+
}
|
|
68441
|
+
metadata.activeEntryId = activeEntryId;
|
|
68442
|
+
metadata.rootEntryId = existing?.rootEntryId ?? rootEntryId;
|
|
68443
|
+
return metadata;
|
|
68444
|
+
}
|
|
68445
|
+
async function persistMockTurn(message, assistantText) {
|
|
68446
|
+
const store = new FileSessionStore(getSessionsDir());
|
|
68447
|
+
const existing = await store.load(message.sessionId ?? sessionId);
|
|
68448
|
+
const startedAt = activeTurn?.startedAt ?? Date.now();
|
|
68449
|
+
const userEntryId = generateEntryId();
|
|
68450
|
+
const assistantEntryId = generateEntryId();
|
|
68451
|
+
const parentId = existing?.metadata.activeEntryId ?? null;
|
|
68452
|
+
const userEntry = {
|
|
68453
|
+
id: userEntryId,
|
|
68454
|
+
parentId,
|
|
68455
|
+
type: "message",
|
|
68456
|
+
timestamp: startedAt,
|
|
68457
|
+
message: {
|
|
68458
|
+
role: "user",
|
|
68459
|
+
content: message.prompt,
|
|
68460
|
+
timestamp: startedAt
|
|
68461
|
+
}
|
|
68462
|
+
};
|
|
68463
|
+
const assistantTimestamp = Date.now();
|
|
68464
|
+
const assistantMessage = {
|
|
68465
|
+
role: "assistant",
|
|
68466
|
+
content: [{ type: "text", text: assistantText }],
|
|
68467
|
+
api: "mock",
|
|
68468
|
+
provider: "mock",
|
|
68469
|
+
model: "mock",
|
|
68470
|
+
usage: {
|
|
68471
|
+
input: 0,
|
|
68472
|
+
output: 0,
|
|
68473
|
+
cacheRead: 0,
|
|
68474
|
+
cacheWrite: 0,
|
|
68475
|
+
totalTokens: 0,
|
|
68476
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }
|
|
68477
|
+
},
|
|
68478
|
+
stopReason: "stop",
|
|
68479
|
+
timestamp: assistantTimestamp
|
|
68480
|
+
};
|
|
68481
|
+
const assistantEntry = {
|
|
68482
|
+
id: assistantEntryId,
|
|
68483
|
+
parentId: userEntryId,
|
|
68484
|
+
type: "message",
|
|
68485
|
+
timestamp: assistantTimestamp,
|
|
68486
|
+
message: assistantMessage
|
|
68487
|
+
};
|
|
68488
|
+
const entries = [...existing?.entries ?? [], userEntry, assistantEntry];
|
|
68489
|
+
await store.save(
|
|
68490
|
+
message.sessionId ?? sessionId,
|
|
68491
|
+
entries,
|
|
68492
|
+
persistedMockMetadata(existing?.metadata, assistantEntryId, existing?.metadata.rootEntryId ?? userEntryId, message.cwd)
|
|
68493
|
+
);
|
|
68494
|
+
return assistantEntryId;
|
|
68495
|
+
}
|
|
68038
68496
|
function flushAssistantOutput(fallbackText = "") {
|
|
68039
68497
|
if (!activeTurn) return;
|
|
68040
68498
|
const chunk = activeTurn.pendingAssistantOutput || fallbackText;
|
|
@@ -68047,21 +68505,38 @@ async function runJsonEventsMode(params) {
|
|
|
68047
68505
|
const turn = activeTurn;
|
|
68048
68506
|
if (!turn || turn.finalized) return;
|
|
68049
68507
|
turn.finalized = true;
|
|
68508
|
+
const headEntryId = activeHeadEntryId();
|
|
68509
|
+
const base = {
|
|
68510
|
+
sessionId: turn.sessionId,
|
|
68511
|
+
turnId: turn.turnId,
|
|
68512
|
+
headEntryId,
|
|
68513
|
+
activeEntryId: headEntryId
|
|
68514
|
+
};
|
|
68050
68515
|
switch (kind) {
|
|
68051
68516
|
case "completed":
|
|
68052
|
-
writeEvent({ type: "turn.completed",
|
|
68517
|
+
writeEvent({ type: "turn.completed", ...base, summary: (detail ?? turn.summary).trim() });
|
|
68053
68518
|
break;
|
|
68054
68519
|
case "failed":
|
|
68055
|
-
writeEvent({ type: "turn.failed",
|
|
68520
|
+
writeEvent({ type: "turn.failed", ...base, error: detail || "turn failed" });
|
|
68056
68521
|
break;
|
|
68057
68522
|
case "cancelled":
|
|
68058
|
-
writeEvent({ type: "turn.cancelled",
|
|
68523
|
+
writeEvent({ type: "turn.cancelled", ...base, reason: detail || "interrupted" });
|
|
68059
68524
|
break;
|
|
68060
68525
|
case "stalled":
|
|
68061
|
-
writeEvent({ type: "turn.stalled",
|
|
68526
|
+
writeEvent({ type: "turn.stalled", ...base, reason: detail || "no_progress_timeout" });
|
|
68062
68527
|
break;
|
|
68063
68528
|
}
|
|
68064
68529
|
}
|
|
68530
|
+
function emitSettled(turn) {
|
|
68531
|
+
const headEntryId = activeHeadEntryId();
|
|
68532
|
+
writeEvent({
|
|
68533
|
+
type: "turn.settled",
|
|
68534
|
+
sessionId: turn.sessionId,
|
|
68535
|
+
turnId: turn.turnId,
|
|
68536
|
+
headEntryId,
|
|
68537
|
+
activeEntryId: headEntryId
|
|
68538
|
+
});
|
|
68539
|
+
}
|
|
68065
68540
|
function rememberTerminal(kind, detail, options) {
|
|
68066
68541
|
if (!activeTurn || activeTurn.finalized) return;
|
|
68067
68542
|
if (activeTurn.pendingTerminal && options?.overwrite === false) return;
|
|
@@ -68120,13 +68595,11 @@ async function runJsonEventsMode(params) {
|
|
|
68120
68595
|
}
|
|
68121
68596
|
function handleControllerEvent(event) {
|
|
68122
68597
|
trace?.noteRuntimeEvent(event.type, event);
|
|
68598
|
+
if (event.type === "auto_compaction_end" && !event.errorMessage) {
|
|
68599
|
+
runtime?.fileObservationState.clear();
|
|
68600
|
+
}
|
|
68123
68601
|
if (event.type === "turn_settled" && activeTurn) {
|
|
68124
|
-
|
|
68125
|
-
writeEvent({
|
|
68126
|
-
type: "turn.settled",
|
|
68127
|
-
sessionId: activeTurn.sessionId,
|
|
68128
|
-
turnId: activeTurn.turnId
|
|
68129
|
-
});
|
|
68602
|
+
touch();
|
|
68130
68603
|
return;
|
|
68131
68604
|
}
|
|
68132
68605
|
if (!activeTurn || activeTurn.finalized) return;
|
|
@@ -68226,16 +68699,35 @@ async function runJsonEventsMode(params) {
|
|
|
68226
68699
|
rememberTerminal("cancelled", event.reason, { overwrite: false });
|
|
68227
68700
|
}
|
|
68228
68701
|
}
|
|
68229
|
-
async function
|
|
68230
|
-
|
|
68231
|
-
|
|
68702
|
+
async function disposeRuntime() {
|
|
68703
|
+
disposeAgentSubscription?.();
|
|
68704
|
+
disposeAgentSubscription = void 0;
|
|
68705
|
+
disposeSemanticSubscription?.();
|
|
68706
|
+
disposeSemanticSubscription = void 0;
|
|
68707
|
+
controller?.dispose();
|
|
68708
|
+
controller = void 0;
|
|
68709
|
+
agent = void 0;
|
|
68710
|
+
try {
|
|
68711
|
+
await runtime?.sessionManager.save();
|
|
68712
|
+
} catch {
|
|
68713
|
+
}
|
|
68714
|
+
trace?.flush();
|
|
68715
|
+
trace = void 0;
|
|
68716
|
+
}
|
|
68717
|
+
async function ensureRuntime(requestedCwd) {
|
|
68718
|
+
if (params.mockResponse !== void 0) return;
|
|
68719
|
+
const effectiveCwd = requestedCwd ?? process.cwd();
|
|
68720
|
+
if (params.createRuntime && (!runtime || runtime.cwd !== effectiveCwd)) {
|
|
68721
|
+
await disposeRuntime();
|
|
68722
|
+
runtime = await params.createRuntime({ cwd: effectiveCwd, sessionId });
|
|
68723
|
+
}
|
|
68232
68724
|
if (!runtime) {
|
|
68233
68725
|
throw new Error("JSON events mode requires a CLI runtime");
|
|
68234
68726
|
}
|
|
68235
|
-
if (runtime.initialModel.unconfigured) {
|
|
68727
|
+
if (runtime.initialModel.unconfigured || controller) {
|
|
68236
68728
|
return;
|
|
68237
68729
|
}
|
|
68238
|
-
const { Agent: AgentClass } = await import("./chunks/src-
|
|
68730
|
+
const { Agent: AgentClass } = await import("./chunks/src-2FHZO63Y.js");
|
|
68239
68731
|
const jsonModeExtensions = await loadJsonModeExtensions({ runtime, getAgent: () => agent });
|
|
68240
68732
|
const tools = [...runtime.tools, ...jsonModeExtensions.extensionTools];
|
|
68241
68733
|
recordCliCompositionStep(runtime.compositionTrace, {
|
|
@@ -68341,6 +68833,7 @@ async function runJsonEventsMode(params) {
|
|
|
68341
68833
|
interrupted: false,
|
|
68342
68834
|
stalled: false,
|
|
68343
68835
|
finalized: false,
|
|
68836
|
+
outputStarted: false,
|
|
68344
68837
|
summary: "",
|
|
68345
68838
|
pendingAssistantOutput: ""
|
|
68346
68839
|
};
|
|
@@ -68354,30 +68847,43 @@ async function runJsonEventsMode(params) {
|
|
|
68354
68847
|
return;
|
|
68355
68848
|
}
|
|
68356
68849
|
display(params.mockResponse);
|
|
68850
|
+
try {
|
|
68851
|
+
mockActiveEntryId = await persistMockTurn(message, params.mockResponse);
|
|
68852
|
+
} catch (error) {
|
|
68853
|
+
finalize("failed", error instanceof Error ? error.message : String(error));
|
|
68854
|
+
if (activeTurn === turn) emitSettled(turn);
|
|
68855
|
+
if (activeTurn === turn) activeTurn = null;
|
|
68856
|
+
return;
|
|
68857
|
+
}
|
|
68357
68858
|
finalize("completed");
|
|
68859
|
+
if (activeTurn === turn) emitSettled(turn);
|
|
68358
68860
|
if (activeTurn === turn) activeTurn = null;
|
|
68359
68861
|
return;
|
|
68360
68862
|
}
|
|
68361
68863
|
if (params.startupError) {
|
|
68362
68864
|
finalize("failed", params.startupError);
|
|
68865
|
+
if (activeTurn === turn) emitSettled(turn);
|
|
68363
68866
|
if (activeTurn === turn) activeTurn = null;
|
|
68364
68867
|
return;
|
|
68365
68868
|
}
|
|
68366
68869
|
try {
|
|
68367
|
-
await ensureRuntime();
|
|
68870
|
+
await ensureRuntime(message.cwd);
|
|
68368
68871
|
} catch (error) {
|
|
68369
68872
|
finalize("failed", error instanceof Error ? error.message : String(error));
|
|
68873
|
+
if (activeTurn === turn) emitSettled(turn);
|
|
68370
68874
|
if (activeTurn === turn) activeTurn = null;
|
|
68371
68875
|
return;
|
|
68372
68876
|
}
|
|
68373
|
-
const
|
|
68374
|
-
if (
|
|
68375
|
-
finalize("failed",
|
|
68877
|
+
const activeRuntime = runtime;
|
|
68878
|
+
if (activeRuntime?.initialModel.unconfigured) {
|
|
68879
|
+
finalize("failed", activeRuntime.initialModel.warning || "No models are configured.");
|
|
68880
|
+
if (activeTurn === turn) emitSettled(turn);
|
|
68376
68881
|
if (activeTurn === turn) activeTurn = null;
|
|
68377
68882
|
return;
|
|
68378
68883
|
}
|
|
68379
68884
|
if (!controller || !agent) {
|
|
68380
68885
|
finalize("failed", "JSON events runtime was not initialized");
|
|
68886
|
+
if (activeTurn === turn) emitSettled(turn);
|
|
68381
68887
|
if (activeTurn === turn) activeTurn = null;
|
|
68382
68888
|
return;
|
|
68383
68889
|
}
|
|
@@ -68399,31 +68905,36 @@ async function runJsonEventsMode(params) {
|
|
|
68399
68905
|
trace?.noteWaitForIdleStart({ mode: "json-events" });
|
|
68400
68906
|
await controller.waitForSettled();
|
|
68401
68907
|
trace?.noteWaitForIdleSettled({ mode: "json-events" });
|
|
68908
|
+
await activeRuntime?.sessionManager.save();
|
|
68402
68909
|
finalizePendingTerminal();
|
|
68403
68910
|
if (!activeTurn?.finalized) {
|
|
68404
68911
|
const finalError = assistantErrorFromAgent(agent);
|
|
68405
68912
|
if (activeTurn?.interrupted) {
|
|
68406
68913
|
finalize("cancelled", "user_interrupt");
|
|
68407
|
-
|
|
68408
|
-
}
|
|
68409
|
-
if (finalError) {
|
|
68914
|
+
} else if (finalError) {
|
|
68410
68915
|
finalize("failed", finalError);
|
|
68411
|
-
|
|
68916
|
+
} else {
|
|
68917
|
+
const text = assistantTextFromAgent(agent);
|
|
68918
|
+
flushAssistantOutput(text);
|
|
68919
|
+
finalize("completed", text || activeTurn?.summary.trim());
|
|
68412
68920
|
}
|
|
68413
|
-
const text = assistantTextFromAgent(agent);
|
|
68414
|
-
flushAssistantOutput(text);
|
|
68415
|
-
finalize("completed", text || activeTurn?.summary.trim());
|
|
68416
68921
|
}
|
|
68922
|
+
if (activeTurn === turn) emitSettled(turn);
|
|
68417
68923
|
} catch (error) {
|
|
68418
68924
|
const messageText = error instanceof Error ? error.message : String(error);
|
|
68419
68925
|
trace?.noteStalled(messageText, { mode: "json-events" });
|
|
68926
|
+
try {
|
|
68927
|
+
await activeRuntime?.sessionManager.save();
|
|
68928
|
+
} catch {
|
|
68929
|
+
}
|
|
68420
68930
|
if (!activeTurn?.finalized) {
|
|
68421
68931
|
finalize(activeTurn?.interrupted ? "cancelled" : "failed", activeTurn?.interrupted ? "user_interrupt" : messageText);
|
|
68422
68932
|
}
|
|
68933
|
+
if (activeTurn === turn) emitSettled(turn);
|
|
68423
68934
|
} finally {
|
|
68424
68935
|
clearInterval(progressTimer);
|
|
68425
68936
|
trace?.flush();
|
|
68426
|
-
await
|
|
68937
|
+
await activeRuntime?.sessionManager.save();
|
|
68427
68938
|
if (activeTurn === turn) activeTurn = null;
|
|
68428
68939
|
}
|
|
68429
68940
|
}
|
|
@@ -68455,12 +68966,29 @@ async function runJsonEventsMode(params) {
|
|
|
68455
68966
|
});
|
|
68456
68967
|
return;
|
|
68457
68968
|
}
|
|
68969
|
+
if (params.mockResponse !== void 0) {
|
|
68970
|
+
if (activeTurn.outputStarted) return;
|
|
68971
|
+
activeTurn.interrupted = true;
|
|
68972
|
+
finalize("cancelled", message.reason || "user_interrupt");
|
|
68973
|
+
emitSettled(activeTurn);
|
|
68974
|
+
activeTurn = null;
|
|
68975
|
+
return;
|
|
68976
|
+
}
|
|
68458
68977
|
activeTurn.interrupted = true;
|
|
68459
68978
|
controller?.abort();
|
|
68979
|
+
}
|
|
68980
|
+
function shutdownActiveTurn(reason) {
|
|
68981
|
+
if (!activeTurn || activeTurn.finalized) return;
|
|
68460
68982
|
if (params.mockResponse !== void 0) {
|
|
68461
|
-
|
|
68983
|
+
if (activeTurn.outputStarted) return;
|
|
68984
|
+
activeTurn.interrupted = true;
|
|
68985
|
+
finalize("cancelled", reason || "shutdown");
|
|
68986
|
+
emitSettled(activeTurn);
|
|
68462
68987
|
activeTurn = null;
|
|
68988
|
+
return;
|
|
68463
68989
|
}
|
|
68990
|
+
activeTurn.interrupted = true;
|
|
68991
|
+
controller?.abort();
|
|
68464
68992
|
}
|
|
68465
68993
|
const input = readline.createInterface({ input: process.stdin });
|
|
68466
68994
|
let activeTurnPromise = null;
|
|
@@ -68472,15 +69000,7 @@ async function runJsonEventsMode(params) {
|
|
|
68472
69000
|
continue;
|
|
68473
69001
|
}
|
|
68474
69002
|
if (message.type === "shutdown") {
|
|
68475
|
-
|
|
68476
|
-
activeTurn.interrupted = true;
|
|
68477
|
-
controller?.abort();
|
|
68478
|
-
if (!controller) {
|
|
68479
|
-
finalize("cancelled", message.reason || "shutdown");
|
|
68480
|
-
} else {
|
|
68481
|
-
rememberTerminal("cancelled", message.reason || "shutdown");
|
|
68482
|
-
}
|
|
68483
|
-
}
|
|
69003
|
+
shutdownActiveTurn(message.reason);
|
|
68484
69004
|
break;
|
|
68485
69005
|
}
|
|
68486
69006
|
if (message.type === "turn.interrupt") {
|
|
@@ -68505,11 +69025,7 @@ async function runJsonEventsMode(params) {
|
|
|
68505
69025
|
}
|
|
68506
69026
|
}
|
|
68507
69027
|
await activeTurnPromise;
|
|
68508
|
-
|
|
68509
|
-
disposeSemanticSubscription?.();
|
|
68510
|
-
controller?.dispose();
|
|
68511
|
-
await params.runtime?.sessionManager.save();
|
|
68512
|
-
trace?.flush();
|
|
69028
|
+
await disposeRuntime();
|
|
68513
69029
|
}
|
|
68514
69030
|
|
|
68515
69031
|
// src/cli.ts
|
|
@@ -68518,8 +69034,8 @@ var logError = (msg, err) => {
|
|
|
68518
69034
|
const logPath = getRuntimeLogPath();
|
|
68519
69035
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
68520
69036
|
const stack = err instanceof Error ? err.stack || "" : "";
|
|
68521
|
-
|
|
68522
|
-
|
|
69037
|
+
fs26.mkdirSync(path26.dirname(logPath), { recursive: true });
|
|
69038
|
+
fs26.appendFileSync(logPath, `[${timestamp}] ${msg}
|
|
68523
69039
|
${stack}
|
|
68524
69040
|
|
|
68525
69041
|
`);
|
|
@@ -68538,6 +69054,7 @@ Commands:
|
|
|
68538
69054
|
doctor Diagnose local Pie configuration and runtime dependencies
|
|
68539
69055
|
models init Create a starter ~/.pie/models.json
|
|
68540
69056
|
models validate Validate ~/.pie/models.json
|
|
69057
|
+
sessions List, read, rename, rewind, and fork Pie sessions
|
|
68541
69058
|
permissions Explain Pie tool and shell safety defaults
|
|
68542
69059
|
help Show this help message
|
|
68543
69060
|
|
|
@@ -68662,7 +69179,7 @@ async function createCliTestStreamFnFromEnv() {
|
|
|
68662
69179
|
if (!process.env.PIE_TEST_MOCK_STREAM_SEQUENCE) {
|
|
68663
69180
|
return void 0;
|
|
68664
69181
|
}
|
|
68665
|
-
const { createTestStreamFnFromSequenceEnv } = await import("./chunks/test-stream-
|
|
69182
|
+
const { createTestStreamFnFromSequenceEnv } = await import("./chunks/test-stream-UW74PA6T.js");
|
|
68666
69183
|
return createTestStreamFnFromSequenceEnv();
|
|
68667
69184
|
}
|
|
68668
69185
|
async function startChat(initialPrompt, testCommand) {
|
|
@@ -68681,23 +69198,15 @@ async function startChat(initialPrompt, testCommand) {
|
|
|
68681
69198
|
});
|
|
68682
69199
|
return;
|
|
68683
69200
|
}
|
|
68684
|
-
let runtime2;
|
|
68685
|
-
try {
|
|
68686
|
-
runtime2 = await composeCliRuntime({ explicitSessionId, extensionPaths });
|
|
68687
|
-
} catch (error) {
|
|
68688
|
-
if (error instanceof CliMissingApiKeyError) {
|
|
68689
|
-
await runJsonEventsMode({
|
|
68690
|
-
explicitSessionId,
|
|
68691
|
-
startupError: error.message
|
|
68692
|
-
});
|
|
68693
|
-
return;
|
|
68694
|
-
}
|
|
68695
|
-
throw error;
|
|
68696
|
-
}
|
|
68697
69201
|
await runJsonEventsMode({
|
|
68698
|
-
runtime: runtime2,
|
|
68699
69202
|
explicitSessionId,
|
|
68700
|
-
streamFn: await createCliTestStreamFnFromEnv()
|
|
69203
|
+
streamFn: await createCliTestStreamFnFromEnv(),
|
|
69204
|
+
createRuntime: async ({ cwd, sessionId }) => composeCliRuntime({
|
|
69205
|
+
explicitSessionId: explicitSessionId ?? sessionId,
|
|
69206
|
+
extensionPaths,
|
|
69207
|
+
cwd,
|
|
69208
|
+
warnIfExplicitSessionMissing: false
|
|
69209
|
+
})
|
|
68701
69210
|
});
|
|
68702
69211
|
});
|
|
68703
69212
|
return;
|
|
@@ -68768,6 +69277,10 @@ async function startChat(initialPrompt, testCommand) {
|
|
|
68768
69277
|
}
|
|
68769
69278
|
async function main() {
|
|
68770
69279
|
const args = process.argv.slice(2);
|
|
69280
|
+
if (args[0] === "--version" || args[0] === "-v") {
|
|
69281
|
+
console.log(VERSION);
|
|
69282
|
+
return;
|
|
69283
|
+
}
|
|
68771
69284
|
if (args[0] === "doctor") {
|
|
68772
69285
|
await runDoctorCommand(args.slice(1));
|
|
68773
69286
|
return;
|
|
@@ -68781,6 +69294,10 @@ async function main() {
|
|
|
68781
69294
|
}
|
|
68782
69295
|
return;
|
|
68783
69296
|
}
|
|
69297
|
+
if (args[0] === "sessions") {
|
|
69298
|
+
await runSessionsCommand(args.slice(1));
|
|
69299
|
+
return;
|
|
69300
|
+
}
|
|
68784
69301
|
if (args[0] === "permissions") {
|
|
68785
69302
|
console.log(formatPermissionsHelp());
|
|
68786
69303
|
return;
|