@cydm/pie 1.0.35 → 1.0.37
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.
|
@@ -5,6 +5,28 @@ import {
|
|
|
5
5
|
import "./chunk-TG2EQLX2.js";
|
|
6
6
|
|
|
7
7
|
// src/app/test-stream.ts
|
|
8
|
+
function parseSystemPromptExpectations(value) {
|
|
9
|
+
if (!value) return [];
|
|
10
|
+
const parsed = JSON.parse(value);
|
|
11
|
+
const normalize = (item) => {
|
|
12
|
+
if (typeof item === "string") return [item];
|
|
13
|
+
if (Array.isArray(item) && item.every((entry) => typeof entry === "string")) return item;
|
|
14
|
+
throw new Error("PIE_TEST_EXPECT_SYSTEM_PROMPT_INCLUDES entries must be strings");
|
|
15
|
+
};
|
|
16
|
+
if (typeof parsed === "string" || Array.isArray(parsed) && parsed.every((entry) => typeof entry === "string")) {
|
|
17
|
+
return [normalize(parsed)];
|
|
18
|
+
}
|
|
19
|
+
if (!Array.isArray(parsed)) throw new Error("PIE_TEST_EXPECT_SYSTEM_PROMPT_INCLUDES must be JSON");
|
|
20
|
+
return parsed.map(normalize);
|
|
21
|
+
}
|
|
22
|
+
function assertSystemPromptIncludes(systemPrompt, callIndex) {
|
|
23
|
+
const expectations = parseSystemPromptExpectations(process.env.PIE_TEST_EXPECT_SYSTEM_PROMPT_INCLUDES);
|
|
24
|
+
for (const expected of expectations[Math.min(callIndex, Math.max(0, expectations.length - 1))] ?? []) {
|
|
25
|
+
if (!systemPrompt.includes(expected)) {
|
|
26
|
+
throw new Error(`Expected system prompt to include ${JSON.stringify(expected)}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
8
30
|
function createAssistantMessage(model, text, stopReason = "stop", errorMessage) {
|
|
9
31
|
return {
|
|
10
32
|
role: "assistant",
|
|
@@ -68,8 +90,9 @@ function createTestStreamFnFromSequenceEnv(value = process.env.PIE_TEST_MOCK_STR
|
|
|
68
90
|
}
|
|
69
91
|
const steps = parseMockStreamSequence(value);
|
|
70
92
|
let callIndex = 0;
|
|
71
|
-
return async (model) => {
|
|
93
|
+
return async (model, context) => {
|
|
72
94
|
const step = steps[Math.min(callIndex, steps.length - 1)];
|
|
95
|
+
assertSystemPromptIncludes(context.systemPrompt, callIndex);
|
|
73
96
|
callIndex += 1;
|
|
74
97
|
const stream = new EventStream(
|
|
75
98
|
(event) => event.type === "done" || event.type === "error",
|
package/dist/cli.js
CHANGED
|
@@ -985,15 +985,15 @@ var require_route = __commonJS({
|
|
|
985
985
|
};
|
|
986
986
|
}
|
|
987
987
|
function wrapConversion(toModel, graph) {
|
|
988
|
-
const
|
|
988
|
+
const path31 = [graph[toModel].parent, toModel];
|
|
989
989
|
let fn = conversions[graph[toModel].parent][toModel];
|
|
990
990
|
let cur = graph[toModel].parent;
|
|
991
991
|
while (graph[cur].parent) {
|
|
992
|
-
|
|
992
|
+
path31.unshift(graph[cur].parent);
|
|
993
993
|
fn = link(conversions[graph[cur].parent][cur], fn);
|
|
994
994
|
cur = graph[cur].parent;
|
|
995
995
|
}
|
|
996
|
-
fn.conversion =
|
|
996
|
+
fn.conversion = path31;
|
|
997
997
|
return fn;
|
|
998
998
|
}
|
|
999
999
|
module.exports = function(fromModel) {
|
|
@@ -43957,11 +43957,11 @@ var require_dist = __commonJS({
|
|
|
43957
43957
|
});
|
|
43958
43958
|
|
|
43959
43959
|
// src/cli.ts
|
|
43960
|
-
import * as
|
|
43961
|
-
import * as
|
|
43960
|
+
import * as fs27 from "fs";
|
|
43961
|
+
import * as path30 from "path";
|
|
43962
43962
|
|
|
43963
43963
|
// src/cli-args.ts
|
|
43964
|
-
var FLAGS_WITH_VALUES = /* @__PURE__ */ new Set(["--session-id", "--extension-path"]);
|
|
43964
|
+
var FLAGS_WITH_VALUES = /* @__PURE__ */ new Set(["--session-id", "--extension-path", "--developer-instructions", "--developer-instructions-file"]);
|
|
43965
43965
|
var BOOLEAN_FLAGS = /* @__PURE__ */ new Set(["--raw-output", "--json-output", "--json-events", "--resume-required"]);
|
|
43966
43966
|
var HELP_FLAGS = /* @__PURE__ */ new Set(["help", "--help", "-h"]);
|
|
43967
43967
|
var COMMANDS = /* @__PURE__ */ new Set(["chat", "help"]);
|
|
@@ -44561,7 +44561,7 @@ async function acquireRemoteRefreshLock(modelsPath) {
|
|
|
44561
44561
|
throw lockError;
|
|
44562
44562
|
}
|
|
44563
44563
|
if (Date.now() >= deadline) throw new Error(`timed out waiting for remote catalog refresh lock: ${lockPath}`);
|
|
44564
|
-
await new Promise((
|
|
44564
|
+
await new Promise((resolve6) => setTimeout(resolve6, 25));
|
|
44565
44565
|
}
|
|
44566
44566
|
}
|
|
44567
44567
|
}
|
|
@@ -46565,6 +46565,165 @@ function parseModelsCommandArgs(args) {
|
|
|
46565
46565
|
|
|
46566
46566
|
// src/commands/sessions.ts
|
|
46567
46567
|
import fs6 from "node:fs";
|
|
46568
|
+
|
|
46569
|
+
// src/session-control.ts
|
|
46570
|
+
var SessionControlError = class extends Error {
|
|
46571
|
+
constructor(code, message, recoverable = sessionControlErrorRecoverable(code)) {
|
|
46572
|
+
super(message);
|
|
46573
|
+
this.code = code;
|
|
46574
|
+
this.recoverable = recoverable;
|
|
46575
|
+
this.name = "SessionControlError";
|
|
46576
|
+
}
|
|
46577
|
+
code;
|
|
46578
|
+
recoverable;
|
|
46579
|
+
};
|
|
46580
|
+
function sessionControlErrorRecoverable(code) {
|
|
46581
|
+
return code !== "session_unrecoverable" && code !== "session_mismatch";
|
|
46582
|
+
}
|
|
46583
|
+
async function loadRequiredSession(store, sessionId) {
|
|
46584
|
+
const exists = await store.exists(sessionId);
|
|
46585
|
+
const data = await store.load(sessionId);
|
|
46586
|
+
if (data) return data;
|
|
46587
|
+
throw new SessionControlError(
|
|
46588
|
+
exists ? "session_unrecoverable" : "session_not_found",
|
|
46589
|
+
exists ? `Session could not be recovered: ${sessionId}` : `Session not found: ${sessionId}`
|
|
46590
|
+
);
|
|
46591
|
+
}
|
|
46592
|
+
async function rewindStoredSession(params) {
|
|
46593
|
+
const data = await loadRequiredSession(params.store, params.sessionId);
|
|
46594
|
+
if (!data.entries.some((entry) => entry.id === params.entryId)) {
|
|
46595
|
+
throw new SessionControlError("checkpoint_not_found", `Entry not found: ${params.entryId}`);
|
|
46596
|
+
}
|
|
46597
|
+
try {
|
|
46598
|
+
await params.store.save(params.sessionId, data.entries, {
|
|
46599
|
+
...data.metadata,
|
|
46600
|
+
activeEntryId: params.entryId,
|
|
46601
|
+
updatedAt: params.now ?? Date.now()
|
|
46602
|
+
});
|
|
46603
|
+
const metadata = await params.store.getMetadata(params.sessionId);
|
|
46604
|
+
if (!metadata) {
|
|
46605
|
+
throw new SessionControlError("session_unrecoverable", `Session could not be recovered after rewind: ${params.sessionId}`, false);
|
|
46606
|
+
}
|
|
46607
|
+
return {
|
|
46608
|
+
sessionId: params.sessionId,
|
|
46609
|
+
entryId: params.entryId,
|
|
46610
|
+
checkpointId: params.entryId,
|
|
46611
|
+
activeEntryId: params.entryId,
|
|
46612
|
+
headEntryId: params.entryId,
|
|
46613
|
+
metadata
|
|
46614
|
+
};
|
|
46615
|
+
} catch (error) {
|
|
46616
|
+
if (error instanceof SessionControlError) throw error;
|
|
46617
|
+
throw new SessionControlError("session_io_error", error instanceof Error ? error.message : String(error));
|
|
46618
|
+
}
|
|
46619
|
+
}
|
|
46620
|
+
async function forkStoredSession(params) {
|
|
46621
|
+
try {
|
|
46622
|
+
const existingTarget = await maybeLoadExistingForkTarget(params);
|
|
46623
|
+
if (existingTarget) return existingTarget;
|
|
46624
|
+
const source = await loadRequiredSession(params.store, params.sourceSessionId);
|
|
46625
|
+
const pathEntries = pathToEntry(source, params.sourceEntryId);
|
|
46626
|
+
if (pathEntries.length === 0 || pathEntries[pathEntries.length - 1]?.id !== params.sourceEntryId) {
|
|
46627
|
+
throw new SessionControlError("checkpoint_not_found", `Entry not found: ${params.sourceEntryId}`);
|
|
46628
|
+
}
|
|
46629
|
+
const now = params.now ?? Date.now();
|
|
46630
|
+
const idMap = /* @__PURE__ */ new Map();
|
|
46631
|
+
for (const entry of pathEntries) idMap.set(entry.id, generateEntryId());
|
|
46632
|
+
const forkedEntries = pathEntries.map((entry) => {
|
|
46633
|
+
const nextId = idMap.get(entry.id);
|
|
46634
|
+
if (!nextId) throw new SessionControlError("session_io_error", `Failed to map entry: ${entry.id}`);
|
|
46635
|
+
const parentId = entry.parentId ? idMap.get(entry.parentId) ?? null : null;
|
|
46636
|
+
return {
|
|
46637
|
+
...cloneJson(entry),
|
|
46638
|
+
id: nextId,
|
|
46639
|
+
parentId,
|
|
46640
|
+
timestamp: entry.timestamp
|
|
46641
|
+
};
|
|
46642
|
+
});
|
|
46643
|
+
const activeEntryId = idMap.get(params.sourceEntryId);
|
|
46644
|
+
if (!activeEntryId) {
|
|
46645
|
+
throw new SessionControlError("session_io_error", `Failed to map active entry: ${params.sourceEntryId}`);
|
|
46646
|
+
}
|
|
46647
|
+
await params.store.save(params.targetSessionId, forkedEntries, {
|
|
46648
|
+
name: params.name,
|
|
46649
|
+
createdAt: now,
|
|
46650
|
+
updatedAt: now,
|
|
46651
|
+
activeEntryId,
|
|
46652
|
+
cwd: params.cwd ?? source.metadata.cwd,
|
|
46653
|
+
sourceSessionId: params.sourceSessionId,
|
|
46654
|
+
sourceEntryId: params.sourceEntryId,
|
|
46655
|
+
sourceActiveEntryId: source.metadata.activeEntryId ?? void 0,
|
|
46656
|
+
forkBaseEntryId: activeEntryId,
|
|
46657
|
+
...params.requestId ? { sessionControlRequestId: params.requestId } : {}
|
|
46658
|
+
});
|
|
46659
|
+
const metadata = await params.store.getMetadata(params.targetSessionId);
|
|
46660
|
+
if (!metadata) {
|
|
46661
|
+
throw new SessionControlError("session_unrecoverable", `Session could not be recovered after fork: ${params.targetSessionId}`, false);
|
|
46662
|
+
}
|
|
46663
|
+
return buildForkResult({
|
|
46664
|
+
metadata,
|
|
46665
|
+
sourceSessionId: params.sourceSessionId,
|
|
46666
|
+
sourceEntryId: params.sourceEntryId,
|
|
46667
|
+
sourceActiveEntryId: source.metadata.activeEntryId ?? null
|
|
46668
|
+
});
|
|
46669
|
+
} catch (error) {
|
|
46670
|
+
if (error instanceof SessionControlError) throw error;
|
|
46671
|
+
throw new SessionControlError("session_io_error", error instanceof Error ? error.message : String(error));
|
|
46672
|
+
}
|
|
46673
|
+
}
|
|
46674
|
+
async function maybeLoadExistingForkTarget(params) {
|
|
46675
|
+
if (!await params.store.exists(params.targetSessionId)) return null;
|
|
46676
|
+
const target = await params.store.load(params.targetSessionId);
|
|
46677
|
+
if (!target) {
|
|
46678
|
+
throw new SessionControlError("session_unrecoverable", `Session could not be recovered: ${params.targetSessionId}`, false);
|
|
46679
|
+
}
|
|
46680
|
+
const metadata = target.metadata;
|
|
46681
|
+
if (params.requestId && metadata.sessionControlRequestId === params.requestId && metadata.sourceSessionId === params.sourceSessionId && metadata.sourceEntryId === params.sourceEntryId && typeof metadata.forkBaseEntryId === "string" && metadata.activeEntryId === metadata.forkBaseEntryId) {
|
|
46682
|
+
return buildForkResult({
|
|
46683
|
+
metadata,
|
|
46684
|
+
sourceSessionId: params.sourceSessionId,
|
|
46685
|
+
sourceEntryId: params.sourceEntryId,
|
|
46686
|
+
sourceActiveEntryId: typeof metadata.sourceActiveEntryId === "string" ? metadata.sourceActiveEntryId : null
|
|
46687
|
+
});
|
|
46688
|
+
}
|
|
46689
|
+
throw new SessionControlError("target_exists", `Target session already exists: ${params.targetSessionId}`);
|
|
46690
|
+
}
|
|
46691
|
+
function buildForkResult(params) {
|
|
46692
|
+
const targetActiveEntryId = params.metadata.activeEntryId;
|
|
46693
|
+
if (!targetActiveEntryId) {
|
|
46694
|
+
throw new SessionControlError("session_unrecoverable", `Fork target has no active entry: ${params.metadata.id}`, false);
|
|
46695
|
+
}
|
|
46696
|
+
const forkBaseEntryId = typeof params.metadata.forkBaseEntryId === "string" ? params.metadata.forkBaseEntryId : targetActiveEntryId;
|
|
46697
|
+
return {
|
|
46698
|
+
sourceSessionId: params.sourceSessionId,
|
|
46699
|
+
sourceEntryId: params.sourceEntryId,
|
|
46700
|
+
sourceCheckpointId: params.sourceEntryId,
|
|
46701
|
+
targetSessionId: params.metadata.id,
|
|
46702
|
+
targetActiveEntryId,
|
|
46703
|
+
targetHeadEntryId: targetActiveEntryId,
|
|
46704
|
+
headEntryId: targetActiveEntryId,
|
|
46705
|
+
sourceActiveEntryId: params.sourceActiveEntryId,
|
|
46706
|
+
forkBaseEntryId,
|
|
46707
|
+
metadata: params.metadata
|
|
46708
|
+
};
|
|
46709
|
+
}
|
|
46710
|
+
function pathToEntry(data, entryId) {
|
|
46711
|
+
const byId = new Map(data.entries.map((entry) => [entry.id, entry]));
|
|
46712
|
+
const path31 = [];
|
|
46713
|
+
let current = entryId;
|
|
46714
|
+
while (current) {
|
|
46715
|
+
const entry = byId.get(current);
|
|
46716
|
+
if (!entry) return [];
|
|
46717
|
+
path31.unshift(entry);
|
|
46718
|
+
current = entry.parentId;
|
|
46719
|
+
}
|
|
46720
|
+
return path31;
|
|
46721
|
+
}
|
|
46722
|
+
function cloneJson(value) {
|
|
46723
|
+
return JSON.parse(JSON.stringify(value));
|
|
46724
|
+
}
|
|
46725
|
+
|
|
46726
|
+
// src/commands/sessions.ts
|
|
46568
46727
|
async function runSessionsCommand(args) {
|
|
46569
46728
|
const command = args[0] || "help";
|
|
46570
46729
|
const rest = args.slice(1);
|
|
@@ -46691,17 +46850,12 @@ async function rewindSession(args) {
|
|
|
46691
46850
|
const entryId = stringFlag(args, "--to");
|
|
46692
46851
|
if (!sessionId || !entryId) throw new Error("Usage: pie sessions rewind <sessionId> --to <entryId> [--json]");
|
|
46693
46852
|
const store = new FileSessionStore(getSessionsDir());
|
|
46694
|
-
const
|
|
46695
|
-
if (!data) throw new Error(`Session not found: ${sessionId}`);
|
|
46696
|
-
if (!data.entries.some((entry) => entry.id === entryId)) throw new Error(`Entry not found: ${entryId}`);
|
|
46697
|
-
await store.save(sessionId, data.entries, { ...data.metadata, activeEntryId: entryId, updatedAt: Date.now() });
|
|
46698
|
-
const updated = await store.getMetadata(sessionId);
|
|
46699
|
-
if (!updated) throw new Error(`Session not found after rewind: ${sessionId}`);
|
|
46853
|
+
const result = await rewindStoredSession({ store, sessionId, entryId });
|
|
46700
46854
|
const response = {
|
|
46701
46855
|
ok: true,
|
|
46702
|
-
session: sessionSummary(
|
|
46703
|
-
activeEntryId:
|
|
46704
|
-
currentHead:
|
|
46856
|
+
session: sessionSummary(result.metadata),
|
|
46857
|
+
activeEntryId: result.activeEntryId,
|
|
46858
|
+
currentHead: result.headEntryId
|
|
46705
46859
|
};
|
|
46706
46860
|
if (json) {
|
|
46707
46861
|
console.log(JSON.stringify(response, null, 2));
|
|
@@ -46720,50 +46874,23 @@ async function forkSession(args) {
|
|
|
46720
46874
|
throw new Error("Usage: pie sessions fork <sessionId> --from <entryId> --target <newSessionId> --name <name> [--cwd <path>] [--json]");
|
|
46721
46875
|
}
|
|
46722
46876
|
const store = new FileSessionStore(getSessionsDir());
|
|
46723
|
-
const
|
|
46724
|
-
|
|
46725
|
-
if (await store.exists(targetSessionId)) throw new Error(`Target session already exists: ${targetSessionId}`);
|
|
46726
|
-
const pathEntries = pathToEntry(source, sourceEntryId);
|
|
46727
|
-
if (pathEntries.length === 0 || pathEntries[pathEntries.length - 1]?.id !== sourceEntryId) {
|
|
46728
|
-
throw new Error(`Entry not found: ${sourceEntryId}`);
|
|
46729
|
-
}
|
|
46730
|
-
const now = Date.now();
|
|
46731
|
-
const idMap = /* @__PURE__ */ new Map();
|
|
46732
|
-
for (const entry of pathEntries) idMap.set(entry.id, generateEntryId());
|
|
46733
|
-
const forkedEntries = pathEntries.map((entry) => {
|
|
46734
|
-
const nextId = idMap.get(entry.id);
|
|
46735
|
-
if (!nextId) throw new Error(`Failed to map entry: ${entry.id}`);
|
|
46736
|
-
const parentId = entry.parentId ? idMap.get(entry.parentId) ?? null : null;
|
|
46737
|
-
return {
|
|
46738
|
-
...cloneJson(entry),
|
|
46739
|
-
id: nextId,
|
|
46740
|
-
parentId,
|
|
46741
|
-
timestamp: entry.timestamp
|
|
46742
|
-
};
|
|
46743
|
-
});
|
|
46744
|
-
const activeEntryId = idMap.get(sourceEntryId) ?? null;
|
|
46745
|
-
await store.save(targetSessionId, forkedEntries, {
|
|
46746
|
-
name,
|
|
46747
|
-
createdAt: now,
|
|
46748
|
-
updatedAt: now,
|
|
46749
|
-
activeEntryId,
|
|
46750
|
-
cwd: cwd ?? source.metadata.cwd,
|
|
46877
|
+
const result = await forkStoredSession({
|
|
46878
|
+
store,
|
|
46751
46879
|
sourceSessionId,
|
|
46752
46880
|
sourceEntryId,
|
|
46753
|
-
|
|
46754
|
-
|
|
46881
|
+
targetSessionId,
|
|
46882
|
+
name,
|
|
46883
|
+
cwd
|
|
46755
46884
|
});
|
|
46756
|
-
const updated = await store.getMetadata(targetSessionId);
|
|
46757
|
-
if (!updated) throw new Error(`Session not found after fork: ${targetSessionId}`);
|
|
46758
46885
|
const response = {
|
|
46759
46886
|
ok: true,
|
|
46760
|
-
session: sessionSummary(
|
|
46887
|
+
session: sessionSummary(result.metadata),
|
|
46761
46888
|
sourceSessionId,
|
|
46762
46889
|
sourceEntryId,
|
|
46763
|
-
sourceActiveEntryId:
|
|
46764
|
-
forkBaseEntryId:
|
|
46765
|
-
activeEntryId,
|
|
46766
|
-
currentHead:
|
|
46890
|
+
sourceActiveEntryId: result.sourceActiveEntryId,
|
|
46891
|
+
forkBaseEntryId: result.forkBaseEntryId,
|
|
46892
|
+
activeEntryId: result.targetActiveEntryId,
|
|
46893
|
+
currentHead: result.targetHeadEntryId
|
|
46767
46894
|
};
|
|
46768
46895
|
if (json) {
|
|
46769
46896
|
console.log(JSON.stringify(response, null, 2));
|
|
@@ -46856,7 +46983,7 @@ function activeTranscriptEvents(entries) {
|
|
|
46856
46983
|
role,
|
|
46857
46984
|
turnId,
|
|
46858
46985
|
content: textFromMessage(entry.message),
|
|
46859
|
-
message: entry.message ?
|
|
46986
|
+
message: entry.message ? cloneJson2(entry.message) : void 0
|
|
46860
46987
|
};
|
|
46861
46988
|
});
|
|
46862
46989
|
}
|
|
@@ -46879,18 +47006,6 @@ function activePathEntries(data) {
|
|
|
46879
47006
|
if (!activeEntryId) return [];
|
|
46880
47007
|
return pathToEntry(data, activeEntryId);
|
|
46881
47008
|
}
|
|
46882
|
-
function pathToEntry(data, entryId) {
|
|
46883
|
-
const byId = new Map(data.entries.map((entry) => [entry.id, entry]));
|
|
46884
|
-
const path30 = [];
|
|
46885
|
-
let current = entryId;
|
|
46886
|
-
while (current) {
|
|
46887
|
-
const entry = byId.get(current);
|
|
46888
|
-
if (!entry) return [];
|
|
46889
|
-
path30.unshift(entry);
|
|
46890
|
-
current = entry.parentId;
|
|
46891
|
-
}
|
|
46892
|
-
return path30;
|
|
46893
|
-
}
|
|
46894
47009
|
function resolveBeforeCursor(events, cursor) {
|
|
46895
47010
|
if (!cursor) return events.length;
|
|
46896
47011
|
const numeric = Number(cursor);
|
|
@@ -46900,7 +47015,7 @@ function resolveBeforeCursor(events, cursor) {
|
|
|
46900
47015
|
const index = events.findIndex((event) => event.entryId === cursor || event.checkpointId === cursor);
|
|
46901
47016
|
return index >= 0 ? index : events.length;
|
|
46902
47017
|
}
|
|
46903
|
-
function
|
|
47018
|
+
function cloneJson2(value) {
|
|
46904
47019
|
return JSON.parse(JSON.stringify(value));
|
|
46905
47020
|
}
|
|
46906
47021
|
function listCursorQueryKey(input) {
|
|
@@ -46952,19 +47067,19 @@ var CommandTree = class {
|
|
|
46952
47067
|
* register(["session", "new"], { description, handler })
|
|
46953
47068
|
* register(["tools", "subagent", "spawn", "local"], { description, handler })
|
|
46954
47069
|
*/
|
|
46955
|
-
register(
|
|
46956
|
-
if (
|
|
47070
|
+
register(path31, info) {
|
|
47071
|
+
if (path31.length === 0) {
|
|
46957
47072
|
throw new Error("Command path cannot be empty");
|
|
46958
47073
|
}
|
|
46959
47074
|
let current = this.root;
|
|
46960
47075
|
const fullPath = [];
|
|
46961
|
-
for (let i = 0; i <
|
|
46962
|
-
const segment =
|
|
47076
|
+
for (let i = 0; i < path31.length; i++) {
|
|
47077
|
+
const segment = path31[i];
|
|
46963
47078
|
fullPath.push(segment);
|
|
46964
47079
|
if (!current.children) {
|
|
46965
47080
|
current.children = [];
|
|
46966
47081
|
}
|
|
46967
|
-
const isLast = i ===
|
|
47082
|
+
const isLast = i === path31.length - 1;
|
|
46968
47083
|
let node = current.children.find((n) => n.name === segment);
|
|
46969
47084
|
if (!node) {
|
|
46970
47085
|
node = {
|
|
@@ -46994,31 +47109,31 @@ var CommandTree = class {
|
|
|
46994
47109
|
/**
|
|
46995
47110
|
* Find a node by path
|
|
46996
47111
|
*/
|
|
46997
|
-
find(
|
|
46998
|
-
if (
|
|
47112
|
+
find(path31) {
|
|
47113
|
+
if (path31.length === 0) {
|
|
46999
47114
|
return this.root;
|
|
47000
47115
|
}
|
|
47001
|
-
const key =
|
|
47116
|
+
const key = path31.join("/");
|
|
47002
47117
|
return this.pathCache.get(key) || null;
|
|
47003
47118
|
}
|
|
47004
47119
|
/**
|
|
47005
47120
|
* Get children of a path
|
|
47006
47121
|
*/
|
|
47007
|
-
getChildren(
|
|
47008
|
-
const node = this.find(
|
|
47122
|
+
getChildren(path31) {
|
|
47123
|
+
const node = this.find(path31);
|
|
47009
47124
|
return (node?.children || []).filter((child) => !child.hidden);
|
|
47010
47125
|
}
|
|
47011
47126
|
/**
|
|
47012
47127
|
* Check if a path exists (as category or command)
|
|
47013
47128
|
*/
|
|
47014
|
-
exists(
|
|
47015
|
-
return this.find(
|
|
47129
|
+
exists(path31) {
|
|
47130
|
+
return this.find(path31) !== null;
|
|
47016
47131
|
}
|
|
47017
47132
|
/**
|
|
47018
47133
|
* Check if path is a category (has children)
|
|
47019
47134
|
*/
|
|
47020
|
-
isCategory(
|
|
47021
|
-
const node = this.find(
|
|
47135
|
+
isCategory(path31) {
|
|
47136
|
+
const node = this.find(path31);
|
|
47022
47137
|
return node?.isCategory || false;
|
|
47023
47138
|
}
|
|
47024
47139
|
/**
|
|
@@ -47097,8 +47212,8 @@ var CommandTree = class {
|
|
|
47097
47212
|
* Supports dot notation: "tools.subagent.spawn.local"
|
|
47098
47213
|
*/
|
|
47099
47214
|
registerFromPath(pathStr, info) {
|
|
47100
|
-
const
|
|
47101
|
-
this.register(
|
|
47215
|
+
const path31 = pathStr.split(/[./]/).filter(Boolean);
|
|
47216
|
+
this.register(path31, info);
|
|
47102
47217
|
}
|
|
47103
47218
|
};
|
|
47104
47219
|
var commandTree = new CommandTree();
|
|
@@ -54388,7 +54503,7 @@ var ProcessTerminal = class {
|
|
|
54388
54503
|
const timeLeft = endTime - now;
|
|
54389
54504
|
if (timeLeft <= 0) break;
|
|
54390
54505
|
if (now - lastDataTime >= idleMs) break;
|
|
54391
|
-
await new Promise((
|
|
54506
|
+
await new Promise((resolve6) => setTimeout(resolve6, Math.min(idleMs, timeLeft)));
|
|
54392
54507
|
}
|
|
54393
54508
|
} finally {
|
|
54394
54509
|
process.stdin.removeListener("data", onData);
|
|
@@ -54922,10 +55037,10 @@ var KeybindingsManager = class _KeybindingsManager {
|
|
|
54922
55037
|
static inMemory(config = {}) {
|
|
54923
55038
|
return new _KeybindingsManager(config);
|
|
54924
55039
|
}
|
|
54925
|
-
static loadFromFile(
|
|
54926
|
-
if (!existsSync7(
|
|
55040
|
+
static loadFromFile(path31) {
|
|
55041
|
+
if (!existsSync7(path31)) return {};
|
|
54927
55042
|
try {
|
|
54928
|
-
return JSON.parse(readFileSync6(
|
|
55043
|
+
return JSON.parse(readFileSync6(path31, "utf-8"));
|
|
54929
55044
|
} catch {
|
|
54930
55045
|
return {};
|
|
54931
55046
|
}
|
|
@@ -57635,11 +57750,11 @@ var FileCache = class _FileCache {
|
|
|
57635
57750
|
// Hash Computation
|
|
57636
57751
|
// ============================================================================
|
|
57637
57752
|
async computeHash(filePath) {
|
|
57638
|
-
return new Promise((
|
|
57753
|
+
return new Promise((resolve6, reject) => {
|
|
57639
57754
|
const hash = crypto.createHash("sha256");
|
|
57640
57755
|
const stream = fs16.createReadStream(filePath);
|
|
57641
57756
|
stream.on("data", (chunk) => hash.update(chunk));
|
|
57642
|
-
stream.on("end", () =>
|
|
57757
|
+
stream.on("end", () => resolve6(hash.digest("hex")));
|
|
57643
57758
|
stream.on("error", reject);
|
|
57644
57759
|
});
|
|
57645
57760
|
}
|
|
@@ -58349,17 +58464,17 @@ var FFmpegProcessor = class {
|
|
|
58349
58464
|
// Detection
|
|
58350
58465
|
// ============================================================================
|
|
58351
58466
|
async checkAvailability() {
|
|
58352
|
-
return new Promise((
|
|
58467
|
+
return new Promise((resolve6) => {
|
|
58353
58468
|
const proc = spawn(this.ffmpegPath, ["-version"]);
|
|
58354
|
-
proc.on("error", () =>
|
|
58355
|
-
proc.on("exit", (code) =>
|
|
58469
|
+
proc.on("error", () => resolve6(false));
|
|
58470
|
+
proc.on("exit", (code) => resolve6(code === 0));
|
|
58356
58471
|
});
|
|
58357
58472
|
}
|
|
58358
58473
|
// ============================================================================
|
|
58359
58474
|
// Video Analysis
|
|
58360
58475
|
// ============================================================================
|
|
58361
58476
|
async analyzeVideo(videoPath) {
|
|
58362
|
-
return new Promise((
|
|
58477
|
+
return new Promise((resolve6, reject) => {
|
|
58363
58478
|
const args = [
|
|
58364
58479
|
"-v",
|
|
58365
58480
|
"error",
|
|
@@ -58388,7 +58503,7 @@ var FFmpegProcessor = class {
|
|
|
58388
58503
|
}
|
|
58389
58504
|
try {
|
|
58390
58505
|
const info = this.parseProbeOutput(stdout, videoPath);
|
|
58391
|
-
|
|
58506
|
+
resolve6(info);
|
|
58392
58507
|
} catch (err) {
|
|
58393
58508
|
reject(err);
|
|
58394
58509
|
}
|
|
@@ -58583,7 +58698,7 @@ var FFmpegProcessor = class {
|
|
|
58583
58698
|
// FFmpeg Execution
|
|
58584
58699
|
// ============================================================================
|
|
58585
58700
|
runFFmpeg(args) {
|
|
58586
|
-
return new Promise((
|
|
58701
|
+
return new Promise((resolve6, reject) => {
|
|
58587
58702
|
const proc = spawn(this.ffmpegPath, args);
|
|
58588
58703
|
let stderr = "";
|
|
58589
58704
|
proc.stderr.on("data", (data) => {
|
|
@@ -58598,7 +58713,7 @@ var FFmpegProcessor = class {
|
|
|
58598
58713
|
)
|
|
58599
58714
|
);
|
|
58600
58715
|
} else {
|
|
58601
|
-
|
|
58716
|
+
resolve6();
|
|
58602
58717
|
}
|
|
58603
58718
|
});
|
|
58604
58719
|
proc.on("error", (err) => {
|
|
@@ -58615,7 +58730,7 @@ var FFmpegProcessor = class {
|
|
|
58615
58730
|
// Progress Monitoring (for future use)
|
|
58616
58731
|
// ============================================================================
|
|
58617
58732
|
async runWithProgress(args, onProgress) {
|
|
58618
|
-
return new Promise((
|
|
58733
|
+
return new Promise((resolve6, reject) => {
|
|
58619
58734
|
const progressArgs = [
|
|
58620
58735
|
...args,
|
|
58621
58736
|
"-progress",
|
|
@@ -58645,7 +58760,7 @@ var FFmpegProcessor = class {
|
|
|
58645
58760
|
)
|
|
58646
58761
|
);
|
|
58647
58762
|
} else {
|
|
58648
|
-
|
|
58763
|
+
resolve6();
|
|
58649
58764
|
}
|
|
58650
58765
|
});
|
|
58651
58766
|
});
|
|
@@ -59635,7 +59750,7 @@ async function waitForReady(params) {
|
|
|
59635
59750
|
if (status.status === "error" || status.status === "expired") {
|
|
59636
59751
|
throw new Error(`Uploaded file is not ready: ${status.status}${status.error ? ` (${status.error})` : ""}`);
|
|
59637
59752
|
}
|
|
59638
|
-
await new Promise((
|
|
59753
|
+
await new Promise((resolve6) => setTimeout(resolve6, 1500));
|
|
59639
59754
|
}
|
|
59640
59755
|
throw new Error("Timed out waiting for uploaded file to become ready");
|
|
59641
59756
|
}
|
|
@@ -59731,8 +59846,8 @@ function createIsolatedRegexSession(pattern, ignoreCase) {
|
|
|
59731
59846
|
let initError;
|
|
59732
59847
|
let readyResolve;
|
|
59733
59848
|
let readyReject;
|
|
59734
|
-
const ready = new Promise((
|
|
59735
|
-
readyResolve =
|
|
59849
|
+
const ready = new Promise((resolve6, reject) => {
|
|
59850
|
+
readyResolve = resolve6;
|
|
59736
59851
|
readyReject = reject;
|
|
59737
59852
|
});
|
|
59738
59853
|
void ready.catch(() => void 0);
|
|
@@ -59754,7 +59869,7 @@ function createIsolatedRegexSession(pattern, ignoreCase) {
|
|
|
59754
59869
|
if (initError) throw initError;
|
|
59755
59870
|
if (signal?.aborted) throw new Error("Operation aborted");
|
|
59756
59871
|
const id = nextId++;
|
|
59757
|
-
return new Promise((
|
|
59872
|
+
return new Promise((resolve6, reject) => {
|
|
59758
59873
|
let settled = false;
|
|
59759
59874
|
const finish = (error, matches) => {
|
|
59760
59875
|
if (settled) return;
|
|
@@ -59764,7 +59879,7 @@ function createIsolatedRegexSession(pattern, ignoreCase) {
|
|
|
59764
59879
|
worker.off("message", onMessage);
|
|
59765
59880
|
worker.off("error", onWorkerError);
|
|
59766
59881
|
if (error) reject(error);
|
|
59767
|
-
else
|
|
59882
|
+
else resolve6(matches ?? []);
|
|
59768
59883
|
};
|
|
59769
59884
|
const terminate = (error) => {
|
|
59770
59885
|
disposed = true;
|
|
@@ -60992,7 +61107,7 @@ async function handleCacheTest(host) {
|
|
|
60992
61107
|
host.chatContainer.addChild(new Text(theme.fg("dim", ` ${summarizeUsage(result1.usage)}`), 1, 0));
|
|
60993
61108
|
host.chatContainer.addChild(new Text(theme.fg("dim", " Waiting 2s before replaying identical request..."), 1, 0));
|
|
60994
61109
|
host.ui.requestRender();
|
|
60995
|
-
await new Promise((
|
|
61110
|
+
await new Promise((resolve6) => setTimeout(resolve6, 2e3));
|
|
60996
61111
|
host.chatContainer.addChild(new Text(theme.fg("accent", "Request 2/2: replaying identical request..."), 1, 0));
|
|
60997
61112
|
host.ui.requestRender();
|
|
60998
61113
|
result2 = await completeSimple(model, context, options);
|
|
@@ -61982,16 +62097,16 @@ var Diff = class {
|
|
|
61982
62097
|
}
|
|
61983
62098
|
}
|
|
61984
62099
|
}
|
|
61985
|
-
addToPath(
|
|
61986
|
-
const last =
|
|
62100
|
+
addToPath(path31, added, removed, oldPosInc, options) {
|
|
62101
|
+
const last = path31.lastComponent;
|
|
61987
62102
|
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
61988
62103
|
return {
|
|
61989
|
-
oldPos:
|
|
62104
|
+
oldPos: path31.oldPos + oldPosInc,
|
|
61990
62105
|
lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
|
|
61991
62106
|
};
|
|
61992
62107
|
} else {
|
|
61993
62108
|
return {
|
|
61994
|
-
oldPos:
|
|
62109
|
+
oldPos: path31.oldPos + oldPosInc,
|
|
61995
62110
|
lastComponent: { count: 1, added, removed, previousComponent: last }
|
|
61996
62111
|
};
|
|
61997
62112
|
}
|
|
@@ -62439,13 +62554,13 @@ function formatSize2(bytes) {
|
|
|
62439
62554
|
}
|
|
62440
62555
|
var DEFAULT_MAX_BYTES = 102400;
|
|
62441
62556
|
var DEFAULT_MAX_LINES = 100;
|
|
62442
|
-
function shortenPath(
|
|
62443
|
-
if (typeof
|
|
62557
|
+
function shortenPath(path31) {
|
|
62558
|
+
if (typeof path31 !== "string") return "";
|
|
62444
62559
|
const home = os4.homedir();
|
|
62445
|
-
if (
|
|
62446
|
-
return `~${
|
|
62560
|
+
if (path31.startsWith(home)) {
|
|
62561
|
+
return `~${path31.slice(home.length)}`;
|
|
62447
62562
|
}
|
|
62448
|
-
return
|
|
62563
|
+
return path31;
|
|
62449
62564
|
}
|
|
62450
62565
|
function replaceTabs(text) {
|
|
62451
62566
|
return text.replace(/\t/g, " ");
|
|
@@ -62526,14 +62641,14 @@ ${renderManageTodoListResult(this.result, { expanded: this.expanded }, theme)}`;
|
|
|
62526
62641
|
}
|
|
62527
62642
|
} else if (this.toolName === "read_file") {
|
|
62528
62643
|
const rawPath = str(this.args?.file_path ?? this.args?.path);
|
|
62529
|
-
const
|
|
62644
|
+
const path31 = rawPath !== null ? shortenPath(rawPath) : null;
|
|
62530
62645
|
const offset = typeof this.args?.offset === "number" ? this.args.offset : void 0;
|
|
62531
62646
|
const limit = typeof this.args?.limit === "number" ? this.args.limit : void 0;
|
|
62532
62647
|
let pathDisplay;
|
|
62533
|
-
if (
|
|
62648
|
+
if (path31 === null) {
|
|
62534
62649
|
pathDisplay = invalidArg;
|
|
62535
|
-
} else if (
|
|
62536
|
-
pathDisplay = theme.fg("accent",
|
|
62650
|
+
} else if (path31) {
|
|
62651
|
+
pathDisplay = theme.fg("accent", path31);
|
|
62537
62652
|
} else {
|
|
62538
62653
|
const partialPath = partialStr(this.args?.file_path ?? this.args?.path);
|
|
62539
62654
|
pathDisplay = theme.fg("toolOutput", partialPath);
|
|
@@ -62580,12 +62695,12 @@ ${renderManageTodoListResult(this.result, { expanded: this.expanded }, theme)}`;
|
|
|
62580
62695
|
} else if (this.toolName === "write_file") {
|
|
62581
62696
|
const rawPath = str(this.args?.file_path ?? this.args?.path);
|
|
62582
62697
|
const fileContent = str(this.args?.content);
|
|
62583
|
-
const
|
|
62698
|
+
const path31 = rawPath !== null ? shortenPath(rawPath) : null;
|
|
62584
62699
|
let pathDisplay;
|
|
62585
|
-
if (
|
|
62700
|
+
if (path31 === null) {
|
|
62586
62701
|
pathDisplay = invalidArg;
|
|
62587
|
-
} else if (
|
|
62588
|
-
pathDisplay = theme.fg("accent",
|
|
62702
|
+
} else if (path31) {
|
|
62703
|
+
pathDisplay = theme.fg("accent", path31);
|
|
62589
62704
|
} else {
|
|
62590
62705
|
const partialPath = partialStr(this.args?.file_path ?? this.args?.path);
|
|
62591
62706
|
pathDisplay = theme.fg("toolOutput", partialPath);
|
|
@@ -62622,12 +62737,12 @@ ${theme.fg("error", errorText)}`;
|
|
|
62622
62737
|
}
|
|
62623
62738
|
} else if (this.toolName === "edit_file") {
|
|
62624
62739
|
const rawPath = str(this.args?.file_path ?? this.args?.path);
|
|
62625
|
-
const
|
|
62740
|
+
const path31 = rawPath !== null ? shortenPath(rawPath) : null;
|
|
62626
62741
|
let pathDisplay;
|
|
62627
|
-
if (
|
|
62742
|
+
if (path31 === null) {
|
|
62628
62743
|
pathDisplay = invalidArg;
|
|
62629
|
-
} else if (
|
|
62630
|
-
pathDisplay = theme.fg("accent",
|
|
62744
|
+
} else if (path31) {
|
|
62745
|
+
pathDisplay = theme.fg("accent", path31);
|
|
62631
62746
|
} else {
|
|
62632
62747
|
const partialPath = partialStr(this.args?.file_path ?? this.args?.path);
|
|
62633
62748
|
pathDisplay = theme.fg("toolOutput", partialPath);
|
|
@@ -62652,7 +62767,7 @@ ${theme.fg("error", errorText)}`;
|
|
|
62652
62767
|
const diff = this.result.details.diff;
|
|
62653
62768
|
const firstChangedLine = this.result.details.firstChangedLine;
|
|
62654
62769
|
if (firstChangedLine) {
|
|
62655
|
-
text = `${theme.fg("toolTitle", theme.bold("edit_file"))} ${theme.fg("accent",
|
|
62770
|
+
text = `${theme.fg("toolTitle", theme.bold("edit_file"))} ${theme.fg("accent", path31 || rawPath)}${theme.fg("warning", `:${firstChangedLine}`)}`;
|
|
62656
62771
|
}
|
|
62657
62772
|
const lines = diff.split("\n");
|
|
62658
62773
|
const maxLines = this.expanded ? lines.length : 15;
|
|
@@ -62672,7 +62787,7 @@ ${theme.fg("error", errorText)}`;
|
|
|
62672
62787
|
const diff = generateEditDiff(oldText, newText, rawPath);
|
|
62673
62788
|
const firstChangedLine = findFirstChangedLine(oldText, newText);
|
|
62674
62789
|
if (firstChangedLine) {
|
|
62675
|
-
text = `${theme.fg("toolTitle", theme.bold("edit_file"))} ${theme.fg("accent",
|
|
62790
|
+
text = `${theme.fg("toolTitle", theme.bold("edit_file"))} ${theme.fg("accent", path31 || rawPath)}${theme.fg("warning", `:${firstChangedLine}`)}`;
|
|
62676
62791
|
}
|
|
62677
62792
|
const lines = diff.split("\n");
|
|
62678
62793
|
const maxLines = this.expanded ? lines.length : 15;
|
|
@@ -62691,9 +62806,9 @@ ${theme.fg("error", errorText)}`;
|
|
|
62691
62806
|
}
|
|
62692
62807
|
} else if (this.toolName === "list_dir") {
|
|
62693
62808
|
const rawPath = str(this.args?.path);
|
|
62694
|
-
const
|
|
62809
|
+
const path31 = rawPath !== null ? shortenPath(rawPath || ".") : null;
|
|
62695
62810
|
const limit = this.args?.limit;
|
|
62696
|
-
text = `${theme.fg("toolTitle", theme.bold("list_dir"))} ${
|
|
62811
|
+
text = `${theme.fg("toolTitle", theme.bold("list_dir"))} ${path31 === null ? invalidArg : theme.fg("accent", path31)}`;
|
|
62697
62812
|
if (limit !== void 0) {
|
|
62698
62813
|
text += theme.fg("toolOutput", ` (limit ${limit})`);
|
|
62699
62814
|
}
|
|
@@ -62729,9 +62844,9 @@ ${theme.fg("warning", `[Truncated: ${warnings.join(", ")}]`)}`;
|
|
|
62729
62844
|
} else if (this.toolName === "find_files") {
|
|
62730
62845
|
const pattern = str(this.args?.pattern);
|
|
62731
62846
|
const rawPath = str(this.args?.path);
|
|
62732
|
-
const
|
|
62847
|
+
const path31 = rawPath !== null ? shortenPath(rawPath || ".") : null;
|
|
62733
62848
|
const limit = this.args?.limit;
|
|
62734
|
-
text = theme.fg("toolTitle", theme.bold("find_files")) + " " + (pattern === null ? invalidArg : theme.fg("accent", pattern || "")) + theme.fg("toolOutput", ` in ${
|
|
62849
|
+
text = theme.fg("toolTitle", theme.bold("find_files")) + " " + (pattern === null ? invalidArg : theme.fg("accent", pattern || "")) + theme.fg("toolOutput", ` in ${path31 === null ? invalidArg : path31}`);
|
|
62735
62850
|
if (limit !== void 0) {
|
|
62736
62851
|
text += theme.fg("toolOutput", ` (limit ${limit})`);
|
|
62737
62852
|
}
|
|
@@ -62767,10 +62882,10 @@ ${theme.fg("warning", `[Truncated: ${warnings.join(", ")}]`)}`;
|
|
|
62767
62882
|
} else if (this.toolName === "grep_text") {
|
|
62768
62883
|
const pattern = str(this.args?.pattern);
|
|
62769
62884
|
const rawPath = str(this.args?.path);
|
|
62770
|
-
const
|
|
62885
|
+
const path31 = rawPath !== null ? shortenPath(rawPath || ".") : null;
|
|
62771
62886
|
const glob = str(this.args?.glob);
|
|
62772
62887
|
const limit = this.args?.limit;
|
|
62773
|
-
text = theme.fg("toolTitle", theme.bold("grep_text")) + " " + (pattern === null ? invalidArg : theme.fg("accent", `/${pattern || ""}/`)) + theme.fg("toolOutput", ` in ${
|
|
62888
|
+
text = theme.fg("toolTitle", theme.bold("grep_text")) + " " + (pattern === null ? invalidArg : theme.fg("accent", `/${pattern || ""}/`)) + theme.fg("toolOutput", ` in ${path31 === null ? invalidArg : path31}`);
|
|
62774
62889
|
if (glob) {
|
|
62775
62890
|
text += theme.fg("toolOutput", ` (${glob})`);
|
|
62776
62891
|
}
|
|
@@ -63224,8 +63339,8 @@ async function forkAtEntry(host, entryId) {
|
|
|
63224
63339
|
host.showError("Failed to branch at entry");
|
|
63225
63340
|
return;
|
|
63226
63341
|
}
|
|
63227
|
-
const
|
|
63228
|
-
const pathNames =
|
|
63342
|
+
const path31 = host.sessionManager.getPathToEntry(entryId);
|
|
63343
|
+
const pathNames = path31.map((e) => e.message?.role || "entry").join(" \u2192 ");
|
|
63229
63344
|
const messages = host.sessionManager.getMessages();
|
|
63230
63345
|
host.syncAgentFromActiveSession(messages);
|
|
63231
63346
|
await host.syncSessionScopedState(messages);
|
|
@@ -63238,7 +63353,7 @@ async function forkAtEntry(host, entryId) {
|
|
|
63238
63353
|
host.updatePendingMessagesDisplay();
|
|
63239
63354
|
host.renderMessageHistory(messages);
|
|
63240
63355
|
await host.sessionManager.save();
|
|
63241
|
-
host.showStatus(`Branched at: ${pathNames} (${
|
|
63356
|
+
host.showStatus(`Branched at: ${pathNames} (${path31.length} messages). Continue to add to this branch.`);
|
|
63242
63357
|
} catch (error) {
|
|
63243
63358
|
host.showError(
|
|
63244
63359
|
`Failed to branch: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -63266,10 +63381,10 @@ async function navigateToEntry(host, entryId) {
|
|
|
63266
63381
|
host.sessionManager.save().catch((err) => {
|
|
63267
63382
|
console.error("[Session] Save after navigation failed:", err);
|
|
63268
63383
|
});
|
|
63269
|
-
const
|
|
63384
|
+
const path31 = host.sessionManager.getPathToEntry(entryId);
|
|
63270
63385
|
const entry = host.sessionManager.getEntry(entryId);
|
|
63271
63386
|
const role = entry?.message?.role || "entry";
|
|
63272
|
-
host.showStatus(`Switched to branch: ${role} (${
|
|
63387
|
+
host.showStatus(`Switched to branch: ${role} (${path31.length} messages in path)`);
|
|
63273
63388
|
} catch (error) {
|
|
63274
63389
|
host.showError(
|
|
63275
63390
|
`Failed to navigate: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -65059,7 +65174,7 @@ function setupInteractiveEditorSubmitHandler(host) {
|
|
|
65059
65174
|
host.chatContainer.addChild(userMsg);
|
|
65060
65175
|
host.editor.setText("");
|
|
65061
65176
|
host.ui.requestRender();
|
|
65062
|
-
await new Promise((
|
|
65177
|
+
await new Promise((resolve6) => setImmediate(resolve6));
|
|
65063
65178
|
let finalContent = messageContent;
|
|
65064
65179
|
const reminderPrefix = host.executionReminder;
|
|
65065
65180
|
const combinedPrefix = [reminderPrefix].filter((value) => Boolean(value)).join("");
|
|
@@ -67713,11 +67828,11 @@ var HierarchicalSelectorComponent = class extends Container {
|
|
|
67713
67828
|
// src/runtime/interactive-ui-helpers.ts
|
|
67714
67829
|
function showHierarchicalMenu(host, initialPath = []) {
|
|
67715
67830
|
const basePath = [...initialPath];
|
|
67716
|
-
const showAtPath = (
|
|
67831
|
+
const showAtPath = (path31) => {
|
|
67717
67832
|
host.showSelector((done) => {
|
|
67718
67833
|
const selector = new HierarchicalSelectorComponent({
|
|
67719
67834
|
tree: commandTree,
|
|
67720
|
-
path:
|
|
67835
|
+
path: path31,
|
|
67721
67836
|
basePath,
|
|
67722
67837
|
onNavigate: (newPath) => {
|
|
67723
67838
|
done();
|
|
@@ -67725,7 +67840,7 @@ function showHierarchicalMenu(host, initialPath = []) {
|
|
|
67725
67840
|
},
|
|
67726
67841
|
onSelect: async (selectedPath, node, searchArgs) => {
|
|
67727
67842
|
if (node.handler) {
|
|
67728
|
-
const args = searchArgs || (selectedPath.length >
|
|
67843
|
+
const args = searchArgs || (selectedPath.length > path31.length ? selectedPath.slice(path31.length).join(" ") : void 0);
|
|
67729
67844
|
const commandPath = "/" + selectedPath.join("/");
|
|
67730
67845
|
if (!args && host.isInteractiveCommand(commandPath)) {
|
|
67731
67846
|
done();
|
|
@@ -68404,7 +68519,7 @@ async function handleDirectBash(host, command) {
|
|
|
68404
68519
|
child.stderr.on("data", (data) => {
|
|
68405
68520
|
output.append(data.toString());
|
|
68406
68521
|
});
|
|
68407
|
-
return new Promise((
|
|
68522
|
+
return new Promise((resolve6) => {
|
|
68408
68523
|
let settled = false;
|
|
68409
68524
|
const finish = (code) => {
|
|
68410
68525
|
if (settled) return;
|
|
@@ -68417,7 +68532,7 @@ async function handleDirectBash(host, command) {
|
|
|
68417
68532
|
}
|
|
68418
68533
|
host.chatContainer.addChild(new Spacer(1));
|
|
68419
68534
|
host.ui.requestRender();
|
|
68420
|
-
|
|
68535
|
+
resolve6();
|
|
68421
68536
|
};
|
|
68422
68537
|
child.on("error", (error) => {
|
|
68423
68538
|
output.append(error.message);
|
|
@@ -68460,11 +68575,11 @@ function installInteractiveInteractionHandler(host) {
|
|
|
68460
68575
|
if (!("timeoutMs" in request) || !request.timeoutMs || request.timeoutMs <= 0) {
|
|
68461
68576
|
return { value: await promise, timedOut: false };
|
|
68462
68577
|
}
|
|
68463
|
-
return await new Promise((
|
|
68464
|
-
const timer = setTimeout(() =>
|
|
68578
|
+
return await new Promise((resolve6, reject) => {
|
|
68579
|
+
const timer = setTimeout(() => resolve6({ timedOut: true }), request.timeoutMs);
|
|
68465
68580
|
promise.then((value) => {
|
|
68466
68581
|
clearTimeout(timer);
|
|
68467
|
-
|
|
68582
|
+
resolve6({ value, timedOut: false });
|
|
68468
68583
|
}).catch((error) => {
|
|
68469
68584
|
clearTimeout(timer);
|
|
68470
68585
|
reject(error);
|
|
@@ -68564,15 +68679,15 @@ function showExtensionNotification(host, message, type = "info") {
|
|
|
68564
68679
|
host.ui.requestRender();
|
|
68565
68680
|
}
|
|
68566
68681
|
function showExtensionSelector2(host, title, options, opts) {
|
|
68567
|
-
return new Promise((
|
|
68682
|
+
return new Promise((resolve6) => {
|
|
68568
68683
|
host.showStatus(`Waiting for selection: ${title}`);
|
|
68569
68684
|
if (opts?.signal?.aborted) {
|
|
68570
|
-
|
|
68685
|
+
resolve6(void 0);
|
|
68571
68686
|
return;
|
|
68572
68687
|
}
|
|
68573
68688
|
const onAbort = () => {
|
|
68574
68689
|
host.restoreEditor();
|
|
68575
|
-
|
|
68690
|
+
resolve6(void 0);
|
|
68576
68691
|
};
|
|
68577
68692
|
opts?.signal?.addEventListener("abort", onAbort, { once: true });
|
|
68578
68693
|
const selector = new ExtensionSelectorComponent(
|
|
@@ -68581,12 +68696,12 @@ function showExtensionSelector2(host, title, options, opts) {
|
|
|
68581
68696
|
(option) => {
|
|
68582
68697
|
opts?.signal?.removeEventListener("abort", onAbort);
|
|
68583
68698
|
host.restoreEditor();
|
|
68584
|
-
|
|
68699
|
+
resolve6(option);
|
|
68585
68700
|
},
|
|
68586
68701
|
() => {
|
|
68587
68702
|
opts?.signal?.removeEventListener("abort", onAbort);
|
|
68588
68703
|
host.restoreEditor();
|
|
68589
|
-
|
|
68704
|
+
resolve6(void 0);
|
|
68590
68705
|
}
|
|
68591
68706
|
);
|
|
68592
68707
|
host.editorContainer.clear();
|
|
@@ -68602,15 +68717,15 @@ ${message}`, ["Yes", "No"], opts);
|
|
|
68602
68717
|
return result === "Yes";
|
|
68603
68718
|
}
|
|
68604
68719
|
function showExtensionInput(host, title, placeholder, opts) {
|
|
68605
|
-
return new Promise((
|
|
68720
|
+
return new Promise((resolve6) => {
|
|
68606
68721
|
host.showStatus(`Waiting for input: ${title}`);
|
|
68607
68722
|
if (opts?.signal?.aborted) {
|
|
68608
|
-
|
|
68723
|
+
resolve6(void 0);
|
|
68609
68724
|
return;
|
|
68610
68725
|
}
|
|
68611
68726
|
const onAbort = () => {
|
|
68612
68727
|
host.restoreEditor();
|
|
68613
|
-
|
|
68728
|
+
resolve6(void 0);
|
|
68614
68729
|
};
|
|
68615
68730
|
opts?.signal?.addEventListener("abort", onAbort, { once: true });
|
|
68616
68731
|
const input = new ExtensionInputComponent(
|
|
@@ -68619,12 +68734,12 @@ function showExtensionInput(host, title, placeholder, opts) {
|
|
|
68619
68734
|
(value) => {
|
|
68620
68735
|
opts?.signal?.removeEventListener("abort", onAbort);
|
|
68621
68736
|
host.restoreEditor();
|
|
68622
|
-
|
|
68737
|
+
resolve6(value);
|
|
68623
68738
|
},
|
|
68624
68739
|
() => {
|
|
68625
68740
|
opts?.signal?.removeEventListener("abort", onAbort);
|
|
68626
68741
|
host.restoreEditor();
|
|
68627
|
-
|
|
68742
|
+
resolve6(void 0);
|
|
68628
68743
|
}
|
|
68629
68744
|
);
|
|
68630
68745
|
host.editorContainer.clear();
|
|
@@ -68635,7 +68750,7 @@ function showExtensionInput(host, title, placeholder, opts) {
|
|
|
68635
68750
|
});
|
|
68636
68751
|
}
|
|
68637
68752
|
function showExtensionEditor(host, title, prefill) {
|
|
68638
|
-
return new Promise((
|
|
68753
|
+
return new Promise((resolve6) => {
|
|
68639
68754
|
host.showStatus(`Waiting for input: ${title}`);
|
|
68640
68755
|
const container = new Container();
|
|
68641
68756
|
container.addChild(new Text(theme.bold(theme.fg("accent", title)), 0, 0));
|
|
@@ -68657,12 +68772,12 @@ function showExtensionEditor(host, title, prefill) {
|
|
|
68657
68772
|
preview: value.slice(0, 120)
|
|
68658
68773
|
});
|
|
68659
68774
|
host.restoreEditor();
|
|
68660
|
-
|
|
68775
|
+
resolve6(value);
|
|
68661
68776
|
};
|
|
68662
68777
|
editor.onEscape = () => {
|
|
68663
68778
|
host.logDebug("extension:editor:cancel", { title });
|
|
68664
68779
|
host.restoreEditor();
|
|
68665
|
-
|
|
68780
|
+
resolve6(void 0);
|
|
68666
68781
|
};
|
|
68667
68782
|
container.addChild(editor);
|
|
68668
68783
|
container.addChild(new Spacer(1));
|
|
@@ -68676,14 +68791,14 @@ function showExtensionEditor(host, title, prefill) {
|
|
|
68676
68791
|
}
|
|
68677
68792
|
function showExtensionCustom(host, factory, options) {
|
|
68678
68793
|
const savedText = host.editor.getText();
|
|
68679
|
-
return new Promise((
|
|
68794
|
+
return new Promise((resolve6, reject) => {
|
|
68680
68795
|
let closed = false;
|
|
68681
68796
|
const close = (result) => {
|
|
68682
68797
|
if (closed) return;
|
|
68683
68798
|
closed = true;
|
|
68684
68799
|
host.restoreEditor();
|
|
68685
68800
|
host.editor.setText(savedText);
|
|
68686
|
-
|
|
68801
|
+
resolve6(result);
|
|
68687
68802
|
};
|
|
68688
68803
|
Promise.resolve(factory(host.ui, theme, close)).then((component) => {
|
|
68689
68804
|
if (closed) return;
|
|
@@ -68895,8 +69010,8 @@ async function loadInteractiveExtensions(host) {
|
|
|
68895
69010
|
);
|
|
68896
69011
|
host.extensionRunner.setUIContext(host.extensionUIContext);
|
|
68897
69012
|
if (process.env.PIE_VERBOSE) {
|
|
68898
|
-
for (const { path:
|
|
68899
|
-
console.error(`[Extension] Failed to load ${
|
|
69013
|
+
for (const { path: path31, error } of errors) {
|
|
69014
|
+
console.error(`[Extension] Failed to load ${path31}: ${error}`);
|
|
68900
69015
|
}
|
|
68901
69016
|
}
|
|
68902
69017
|
const extensionTools = convertExtensionTools(extensions);
|
|
@@ -70224,6 +70339,26 @@ function parseInput(line) {
|
|
|
70224
70339
|
reason: typeof parsed.reason === "string" ? parsed.reason : void 0
|
|
70225
70340
|
};
|
|
70226
70341
|
}
|
|
70342
|
+
if (parsed.type === "session.rewind") {
|
|
70343
|
+
return {
|
|
70344
|
+
type: "session.rewind",
|
|
70345
|
+
sessionId: typeof parsed.sessionId === "string" ? parsed.sessionId : void 0,
|
|
70346
|
+
requestId: typeof parsed.requestId === "string" ? parsed.requestId : void 0,
|
|
70347
|
+
entryId: typeof parsed.entryId === "string" ? parsed.entryId : void 0,
|
|
70348
|
+
checkpointId: typeof parsed.checkpointId === "string" ? parsed.checkpointId : void 0
|
|
70349
|
+
};
|
|
70350
|
+
}
|
|
70351
|
+
if (parsed.type === "session.fork") {
|
|
70352
|
+
return {
|
|
70353
|
+
type: "session.fork",
|
|
70354
|
+
sessionId: typeof parsed.sessionId === "string" ? parsed.sessionId : void 0,
|
|
70355
|
+
requestId: typeof parsed.requestId === "string" ? parsed.requestId : void 0,
|
|
70356
|
+
fromEntryId: typeof parsed.fromEntryId === "string" ? parsed.fromEntryId : void 0,
|
|
70357
|
+
targetSessionId: typeof parsed.targetSessionId === "string" ? parsed.targetSessionId : void 0,
|
|
70358
|
+
name: typeof parsed.name === "string" ? parsed.name : void 0,
|
|
70359
|
+
cwd: typeof parsed.cwd === "string" ? parsed.cwd : void 0
|
|
70360
|
+
};
|
|
70361
|
+
}
|
|
70227
70362
|
if ((parsed.type === "turn.request" || parsed.type === "turn.input") && typeof parsed.turnId === "string" && typeof parsed.prompt === "string") {
|
|
70228
70363
|
const streamingBehavior = parsed.streamingBehavior;
|
|
70229
70364
|
if (streamingBehavior !== void 0 && streamingBehavior !== "steer" && streamingBehavior !== "followUp") {
|
|
@@ -70386,6 +70521,7 @@ async function runJsonEventsMode(params) {
|
|
|
70386
70521
|
let thinkingLevel = "off";
|
|
70387
70522
|
let defaultRuntime;
|
|
70388
70523
|
let defaultModelState;
|
|
70524
|
+
const completedSessionControlRequests = /* @__PURE__ */ new Map();
|
|
70389
70525
|
const noProgressTimeoutMs = Number(process.env.PIE_JSON_EVENTS_NO_PROGRESS_MS || 6e5);
|
|
70390
70526
|
const mockResponseDelayMs = Number(process.env.PIE_TEST_MOCK_RESPONSE_DELAY_MS || 0);
|
|
70391
70527
|
writeEvent({ type: "agent.ready", sessionId });
|
|
@@ -70396,7 +70532,7 @@ async function runJsonEventsMode(params) {
|
|
|
70396
70532
|
return typeof message.sessionId === "string" && message.sessionId !== sessionId;
|
|
70397
70533
|
}
|
|
70398
70534
|
function delay(ms) {
|
|
70399
|
-
return new Promise((
|
|
70535
|
+
return new Promise((resolve6) => setTimeout(resolve6, Math.max(0, ms)));
|
|
70400
70536
|
}
|
|
70401
70537
|
async function waitForActiveController(timeoutMs = 1e3) {
|
|
70402
70538
|
const deadline = Date.now() + timeoutMs;
|
|
@@ -70534,6 +70670,148 @@ async function runJsonEventsMode(params) {
|
|
|
70534
70670
|
}
|
|
70535
70671
|
return error instanceof Error ? error.message : String(error);
|
|
70536
70672
|
}
|
|
70673
|
+
function sessionControlStore() {
|
|
70674
|
+
return new FileSessionStore(runtime?.paths.sessionsDir ?? getSessionsDir());
|
|
70675
|
+
}
|
|
70676
|
+
function invalidSessionControl(message) {
|
|
70677
|
+
return new SessionControlError("invalid_request", message);
|
|
70678
|
+
}
|
|
70679
|
+
function requireSessionControlString(value, field) {
|
|
70680
|
+
const normalized = value?.trim();
|
|
70681
|
+
if (!normalized) {
|
|
70682
|
+
throw invalidSessionControl(`${field} is required`);
|
|
70683
|
+
}
|
|
70684
|
+
return normalized;
|
|
70685
|
+
}
|
|
70686
|
+
function requireSessionControlBase(message) {
|
|
70687
|
+
const requestedSessionId = requireSessionControlString(message.sessionId, "sessionId");
|
|
70688
|
+
const requestId = requireSessionControlString(message.requestId, "requestId");
|
|
70689
|
+
if (requestedSessionId !== sessionId) {
|
|
70690
|
+
throw new SessionControlError("session_mismatch", sessionMismatchError(requestedSessionId), false);
|
|
70691
|
+
}
|
|
70692
|
+
if (activeTurn && !activeTurn.finalized) {
|
|
70693
|
+
throw new SessionControlError("session_busy", `Cannot ${message.type.slice("session.".length)} session while a turn is active`);
|
|
70694
|
+
}
|
|
70695
|
+
return { sessionId: requestedSessionId, requestId };
|
|
70696
|
+
}
|
|
70697
|
+
function resolveRewindEntryId(message) {
|
|
70698
|
+
const entryId = message.entryId?.trim();
|
|
70699
|
+
const checkpointId = message.checkpointId?.trim();
|
|
70700
|
+
if (entryId && checkpointId && entryId !== checkpointId) {
|
|
70701
|
+
throw invalidSessionControl("entryId and checkpointId must match when both are provided");
|
|
70702
|
+
}
|
|
70703
|
+
const resolved = entryId || checkpointId;
|
|
70704
|
+
if (!resolved) {
|
|
70705
|
+
throw invalidSessionControl("entryId or checkpointId is required");
|
|
70706
|
+
}
|
|
70707
|
+
return resolved;
|
|
70708
|
+
}
|
|
70709
|
+
function writeSessionControlFailure(message, operation, error) {
|
|
70710
|
+
const detail = error instanceof SessionControlError ? error : new SessionControlError("session_io_error", error instanceof Error ? error.message : String(error));
|
|
70711
|
+
writeEvent({
|
|
70712
|
+
type: "session.failed",
|
|
70713
|
+
sessionId: message.sessionId || sessionId,
|
|
70714
|
+
requestId: message.requestId,
|
|
70715
|
+
operation,
|
|
70716
|
+
error: detail.message,
|
|
70717
|
+
code: detail.code,
|
|
70718
|
+
recoverable: detail.recoverable
|
|
70719
|
+
});
|
|
70720
|
+
}
|
|
70721
|
+
async function saveRuntimeSessionForControl() {
|
|
70722
|
+
if (!runtime?.sessionManager.getActiveSession()) return;
|
|
70723
|
+
try {
|
|
70724
|
+
await runtime.sessionManager.save();
|
|
70725
|
+
} catch (error) {
|
|
70726
|
+
throw new SessionControlError("session_io_error", error instanceof Error ? error.message : String(error));
|
|
70727
|
+
}
|
|
70728
|
+
}
|
|
70729
|
+
async function syncRuntimeAfterRewind(controlSessionId) {
|
|
70730
|
+
if (params.mockResponse !== void 0) return;
|
|
70731
|
+
if (runtime?.sessionManager.getActiveSessionId() !== controlSessionId) return;
|
|
70732
|
+
const loaded = await runtime.sessionManager.loadSession(controlSessionId, { warnIfMissing: false });
|
|
70733
|
+
if (!loaded) {
|
|
70734
|
+
const exists = await runtime.sessionManager.hasSession(controlSessionId);
|
|
70735
|
+
throw new SessionControlError(
|
|
70736
|
+
exists ? "session_unrecoverable" : "session_not_found",
|
|
70737
|
+
exists ? `Session could not be recovered: ${controlSessionId}` : `Session not found: ${controlSessionId}`,
|
|
70738
|
+
!exists
|
|
70739
|
+
);
|
|
70740
|
+
}
|
|
70741
|
+
controller?.syncFromActiveSession();
|
|
70742
|
+
}
|
|
70743
|
+
async function handleSessionRewind(message) {
|
|
70744
|
+
try {
|
|
70745
|
+
const { sessionId: controlSessionId, requestId } = requireSessionControlBase(message);
|
|
70746
|
+
const cached = completedSessionControlRequests.get(requestId);
|
|
70747
|
+
if (cached) {
|
|
70748
|
+
writeEvent(cached);
|
|
70749
|
+
return;
|
|
70750
|
+
}
|
|
70751
|
+
const entryId = resolveRewindEntryId(message);
|
|
70752
|
+
await saveRuntimeSessionForControl();
|
|
70753
|
+
const result = await rewindStoredSession({
|
|
70754
|
+
store: sessionControlStore(),
|
|
70755
|
+
sessionId: controlSessionId,
|
|
70756
|
+
entryId
|
|
70757
|
+
});
|
|
70758
|
+
await syncRuntimeAfterRewind(controlSessionId);
|
|
70759
|
+
mockActiveEntryId = result.headEntryId;
|
|
70760
|
+
const event = {
|
|
70761
|
+
type: "session.rewound",
|
|
70762
|
+
sessionId: controlSessionId,
|
|
70763
|
+
requestId,
|
|
70764
|
+
entryId: result.entryId,
|
|
70765
|
+
checkpointId: result.checkpointId,
|
|
70766
|
+
headEntryId: result.headEntryId,
|
|
70767
|
+
activeEntryId: result.activeEntryId
|
|
70768
|
+
};
|
|
70769
|
+
completedSessionControlRequests.set(requestId, event);
|
|
70770
|
+
writeEvent(event);
|
|
70771
|
+
} catch (error) {
|
|
70772
|
+
writeSessionControlFailure(message, "rewind", error);
|
|
70773
|
+
}
|
|
70774
|
+
}
|
|
70775
|
+
async function handleSessionFork(message) {
|
|
70776
|
+
try {
|
|
70777
|
+
const { sessionId: controlSessionId, requestId } = requireSessionControlBase(message);
|
|
70778
|
+
const sourceEntryId = requireSessionControlString(message.fromEntryId, "fromEntryId");
|
|
70779
|
+
const targetSessionId = requireSessionControlString(message.targetSessionId, "targetSessionId");
|
|
70780
|
+
const name = requireSessionControlString(message.name, "name");
|
|
70781
|
+
const forkCwd = message.cwd?.trim() || void 0;
|
|
70782
|
+
const cached = completedSessionControlRequests.get(requestId);
|
|
70783
|
+
if (cached) {
|
|
70784
|
+
writeEvent(cached);
|
|
70785
|
+
return;
|
|
70786
|
+
}
|
|
70787
|
+
await saveRuntimeSessionForControl();
|
|
70788
|
+
const result = await forkStoredSession({
|
|
70789
|
+
store: sessionControlStore(),
|
|
70790
|
+
sourceSessionId: controlSessionId,
|
|
70791
|
+
sourceEntryId,
|
|
70792
|
+
targetSessionId,
|
|
70793
|
+
name,
|
|
70794
|
+
cwd: forkCwd,
|
|
70795
|
+
requestId
|
|
70796
|
+
});
|
|
70797
|
+
const event = {
|
|
70798
|
+
type: "session.forked",
|
|
70799
|
+
sessionId: controlSessionId,
|
|
70800
|
+
requestId,
|
|
70801
|
+
sourceSessionId: result.sourceSessionId,
|
|
70802
|
+
sourceEntryId: result.sourceEntryId,
|
|
70803
|
+
sourceCheckpointId: result.sourceCheckpointId,
|
|
70804
|
+
targetSessionId: result.targetSessionId,
|
|
70805
|
+
targetHeadEntryId: result.targetHeadEntryId,
|
|
70806
|
+
targetActiveEntryId: result.targetActiveEntryId,
|
|
70807
|
+
headEntryId: result.headEntryId
|
|
70808
|
+
};
|
|
70809
|
+
completedSessionControlRequests.set(requestId, event);
|
|
70810
|
+
writeEvent(event);
|
|
70811
|
+
} catch (error) {
|
|
70812
|
+
writeSessionControlFailure(message, "fork", error);
|
|
70813
|
+
}
|
|
70814
|
+
}
|
|
70537
70815
|
function finalize(kind, detail) {
|
|
70538
70816
|
const turn = activeTurn;
|
|
70539
70817
|
if (!turn || turn.finalized) return;
|
|
@@ -70783,6 +71061,7 @@ async function runJsonEventsMode(params) {
|
|
|
70783
71061
|
cwd: runtime.cwd,
|
|
70784
71062
|
skillsSection: runtime.skillsSection,
|
|
70785
71063
|
knowledgeSection: runtime.knowledgeSection,
|
|
71064
|
+
appendSystemPrompt: params.developerInstructions,
|
|
70786
71065
|
tools: tools.map((tool) => ({ name: tool.name, description: tool.description }))
|
|
70787
71066
|
});
|
|
70788
71067
|
agent = new AgentClass({
|
|
@@ -71168,6 +71447,14 @@ async function runJsonEventsMode(params) {
|
|
|
71168
71447
|
await interrupt(message);
|
|
71169
71448
|
continue;
|
|
71170
71449
|
}
|
|
71450
|
+
if (message.type === "session.rewind") {
|
|
71451
|
+
await handleSessionRewind(message);
|
|
71452
|
+
continue;
|
|
71453
|
+
}
|
|
71454
|
+
if (message.type === "session.fork") {
|
|
71455
|
+
await handleSessionFork(message);
|
|
71456
|
+
continue;
|
|
71457
|
+
}
|
|
71171
71458
|
const shouldTrackTurn = !activeTurn || activeTurn.finalized;
|
|
71172
71459
|
const turnPromise = runTurn(message).catch((error) => {
|
|
71173
71460
|
writeEvent({
|
|
@@ -71189,20 +71476,44 @@ async function runJsonEventsMode(params) {
|
|
|
71189
71476
|
await disposeRuntime();
|
|
71190
71477
|
}
|
|
71191
71478
|
|
|
71192
|
-
// src/
|
|
71193
|
-
|
|
71194
|
-
|
|
71195
|
-
|
|
71196
|
-
|
|
71197
|
-
const
|
|
71198
|
-
fs26.
|
|
71199
|
-
|
|
71200
|
-
${
|
|
71479
|
+
// src/developer-instructions.ts
|
|
71480
|
+
import * as fs26 from "fs";
|
|
71481
|
+
import * as path29 from "path";
|
|
71482
|
+
var MAX_DEVELOPER_INSTRUCTIONS_CHARS = 64e3;
|
|
71483
|
+
function readTextFileBounded(filePath) {
|
|
71484
|
+
const resolved = path29.resolve(filePath);
|
|
71485
|
+
const stat2 = fs26.statSync(resolved);
|
|
71486
|
+
if (!stat2.isFile()) {
|
|
71487
|
+
throw new Error(`Developer instructions file is not a regular file: ${filePath}`);
|
|
71488
|
+
}
|
|
71489
|
+
if (stat2.size > MAX_DEVELOPER_INSTRUCTIONS_CHARS * 4) {
|
|
71490
|
+
throw new Error(`Developer instructions file is too large: ${filePath}`);
|
|
71491
|
+
}
|
|
71492
|
+
return fs26.readFileSync(resolved, "utf8");
|
|
71493
|
+
}
|
|
71494
|
+
function collectFlagValues(args, flag) {
|
|
71495
|
+
const values = [];
|
|
71496
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
71497
|
+
if (args[i] === flag && args[i + 1]) {
|
|
71498
|
+
values.push(args[i + 1]);
|
|
71499
|
+
i += 1;
|
|
71500
|
+
}
|
|
71501
|
+
}
|
|
71502
|
+
return values;
|
|
71503
|
+
}
|
|
71504
|
+
function resolveDeveloperInstructionsFromArgs(args) {
|
|
71505
|
+
const direct = collectFlagValues(args, "--developer-instructions");
|
|
71506
|
+
const files = collectFlagValues(args, "--developer-instructions-file").map(readTextFileBounded);
|
|
71507
|
+
const parts = [...direct, ...files].map((part) => part.trim()).filter(Boolean);
|
|
71508
|
+
if (parts.length === 0) return void 0;
|
|
71509
|
+
const combined = parts.join("\n\n");
|
|
71510
|
+
if (combined.length > MAX_DEVELOPER_INSTRUCTIONS_CHARS) {
|
|
71511
|
+
throw new Error(`Developer instructions exceed ${MAX_DEVELOPER_INSTRUCTIONS_CHARS} characters`);
|
|
71512
|
+
}
|
|
71513
|
+
return combined;
|
|
71514
|
+
}
|
|
71201
71515
|
|
|
71202
|
-
|
|
71203
|
-
};
|
|
71204
|
-
setupGlobalErrorHandlers(logError);
|
|
71205
|
-
migrateConfigFromAgentDir();
|
|
71516
|
+
// src/cli-help.ts
|
|
71206
71517
|
function showHelp() {
|
|
71207
71518
|
console.log(`
|
|
71208
71519
|
Pie AI Agent CLI
|
|
@@ -71242,11 +71553,36 @@ Print Mode Options:
|
|
|
71242
71553
|
--json-events Run JSONL protocol mode over stdin/stdout
|
|
71243
71554
|
--session-id Reuse or create a specific session in non-interactive mode
|
|
71244
71555
|
--resume-required In JSON-events mode, fail if --session-id cannot be resumed
|
|
71556
|
+
--developer-instructions <text> Append stable host/developer instructions in JSON-events mode
|
|
71557
|
+
--developer-instructions-file <path> Read stable host/developer instructions from a file
|
|
71245
71558
|
--extension-path Add an extra extension search directory (repeatable)
|
|
71246
71559
|
--no-builtin-extensions Skip built-in extensions (keep user/project ones)
|
|
71247
71560
|
--no-extensions Skip all discovered extensions (keeps --extension-path)
|
|
71248
71561
|
`);
|
|
71249
71562
|
}
|
|
71563
|
+
|
|
71564
|
+
// src/cli.ts
|
|
71565
|
+
enableEarlyLogBuffer();
|
|
71566
|
+
var logError = (msg, err) => {
|
|
71567
|
+
const logPath = getRuntimeLogPath();
|
|
71568
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
71569
|
+
const stack = err instanceof Error ? err.stack || "" : "";
|
|
71570
|
+
fs27.mkdirSync(path30.dirname(logPath), { recursive: true });
|
|
71571
|
+
fs27.appendFileSync(logPath, `[${timestamp}] ${msg}
|
|
71572
|
+
${stack}
|
|
71573
|
+
|
|
71574
|
+
`);
|
|
71575
|
+
};
|
|
71576
|
+
setupGlobalErrorHandlers(logError);
|
|
71577
|
+
migrateConfigFromAgentDir();
|
|
71578
|
+
var STABLE_CLI_COMMANDS = {
|
|
71579
|
+
chat: "chat",
|
|
71580
|
+
doctor: "doctor",
|
|
71581
|
+
models: "models",
|
|
71582
|
+
sessions: "sessions",
|
|
71583
|
+
extensions: "extensions",
|
|
71584
|
+
permissions: "permissions"
|
|
71585
|
+
};
|
|
71250
71586
|
async function runDoctorCommand(args) {
|
|
71251
71587
|
const json = args.includes("--json");
|
|
71252
71588
|
const report = await runDoctor();
|
|
@@ -71339,7 +71675,7 @@ async function runWithJsonEventsConsoleIsolation(fn) {
|
|
|
71339
71675
|
}
|
|
71340
71676
|
async function createCliTestStreamFnFromEnv() {
|
|
71341
71677
|
if (!process.env.PIE_TEST_MOCK_STREAM_SEQUENCE) return void 0;
|
|
71342
|
-
return (await import("./chunks/test-stream-
|
|
71678
|
+
return (await import("./chunks/test-stream-L4PUYWQQ.js")).createTestStreamFnFromSequenceEnv();
|
|
71343
71679
|
}
|
|
71344
71680
|
async function startChat(initialPrompt, testCommand) {
|
|
71345
71681
|
const rawOutput = process.argv.includes("--raw-output");
|
|
@@ -71351,11 +71687,19 @@ async function startChat(initialPrompt, testCommand) {
|
|
|
71351
71687
|
const extensionPaths = parseRepeatedFlag(process.argv, "--extension-path");
|
|
71352
71688
|
const extensionFlags = parseExtensionFlags(process.argv);
|
|
71353
71689
|
if (jsonEvents) {
|
|
71690
|
+
let developerInstructions;
|
|
71691
|
+
try {
|
|
71692
|
+
developerInstructions = resolveDeveloperInstructionsFromArgs(process.argv);
|
|
71693
|
+
} catch (error) {
|
|
71694
|
+
console.error(error instanceof Error ? `Error: ${error.message}` : String(error));
|
|
71695
|
+
process.exit(1);
|
|
71696
|
+
}
|
|
71354
71697
|
await runWithJsonEventsConsoleIsolation(async () => {
|
|
71355
71698
|
if (process.env.PIE_TEST_MOCK_RESPONSE !== void 0) {
|
|
71356
71699
|
await runJsonEventsMode({
|
|
71357
71700
|
explicitSessionId,
|
|
71358
71701
|
resumeRequired,
|
|
71702
|
+
developerInstructions,
|
|
71359
71703
|
mockResponse: process.env.PIE_TEST_MOCK_RESPONSE
|
|
71360
71704
|
});
|
|
71361
71705
|
return;
|
|
@@ -71363,6 +71707,7 @@ async function startChat(initialPrompt, testCommand) {
|
|
|
71363
71707
|
await runJsonEventsMode({
|
|
71364
71708
|
explicitSessionId,
|
|
71365
71709
|
resumeRequired,
|
|
71710
|
+
developerInstructions,
|
|
71366
71711
|
streamFn: await createCliTestStreamFnFromEnv(),
|
|
71367
71712
|
createRuntime: async ({ cwd, sessionId }) => composeCliRuntime({
|
|
71368
71713
|
explicitSessionId: explicitSessionId ?? sessionId,
|
|
@@ -71425,9 +71770,9 @@ async function startChat(initialPrompt, testCommand) {
|
|
|
71425
71770
|
flushEarlyLogs();
|
|
71426
71771
|
if (testCommand) {
|
|
71427
71772
|
console.log(`[TEST] Auto-executing command: ${testCommand}`);
|
|
71428
|
-
await new Promise((
|
|
71773
|
+
await new Promise((resolve6) => setTimeout(resolve6, 500));
|
|
71429
71774
|
await interactive.executeCommand(testCommand);
|
|
71430
|
-
await new Promise((
|
|
71775
|
+
await new Promise((resolve6) => setTimeout(resolve6, 2e3));
|
|
71431
71776
|
console.log("[TEST] Command executed, exiting...");
|
|
71432
71777
|
process.exit(0);
|
|
71433
71778
|
return;
|
|
@@ -71448,11 +71793,11 @@ async function main() {
|
|
|
71448
71793
|
console.log(VERSION);
|
|
71449
71794
|
return;
|
|
71450
71795
|
}
|
|
71451
|
-
if (args[0] ===
|
|
71796
|
+
if (args[0] === STABLE_CLI_COMMANDS.doctor) {
|
|
71452
71797
|
await runDoctorCommand(args.slice(1));
|
|
71453
71798
|
return;
|
|
71454
71799
|
}
|
|
71455
|
-
if (args[0] ===
|
|
71800
|
+
if (args[0] === STABLE_CLI_COMMANDS.models) {
|
|
71456
71801
|
try {
|
|
71457
71802
|
await runModelsCommand(args.slice(1));
|
|
71458
71803
|
} catch (error) {
|
|
@@ -71461,15 +71806,15 @@ async function main() {
|
|
|
71461
71806
|
}
|
|
71462
71807
|
return;
|
|
71463
71808
|
}
|
|
71464
|
-
if (args[0] ===
|
|
71809
|
+
if (args[0] === STABLE_CLI_COMMANDS.sessions) {
|
|
71465
71810
|
await runSessionsCommand(args.slice(1));
|
|
71466
71811
|
return;
|
|
71467
71812
|
}
|
|
71468
|
-
if (args[0] ===
|
|
71813
|
+
if (args[0] === STABLE_CLI_COMMANDS.extensions) {
|
|
71469
71814
|
await runExtensionsCommand(args.slice(1));
|
|
71470
71815
|
return;
|
|
71471
71816
|
}
|
|
71472
|
-
if (args[0] ===
|
|
71817
|
+
if (args[0] === STABLE_CLI_COMMANDS.permissions) {
|
|
71473
71818
|
console.log(formatPermissionsHelp());
|
|
71474
71819
|
return;
|
|
71475
71820
|
}
|