poe-code 3.0.191 → 3.0.192
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/cli/commands/configure-payload.d.ts +1 -1
- package/dist/cli/commands/configure-payload.js +16 -9
- package/dist/cli/commands/configure-payload.js.map +1 -1
- package/dist/cli/commands/configure.d.ts +7 -0
- package/dist/cli/commands/configure.js +25 -5
- package/dist/cli/commands/configure.js.map +1 -1
- package/dist/cli/commands/ensure-isolated-config.js +3 -2
- package/dist/cli/commands/ensure-isolated-config.js.map +1 -1
- package/dist/cli/commands/experiment.js +38 -39
- package/dist/cli/commands/experiment.js.map +1 -1
- package/dist/cli/commands/memory.js +20 -15
- package/dist/cli/commands/memory.js.map +1 -1
- package/dist/cli/commands/pipeline-loop-agent.d.ts +1 -0
- package/dist/cli/commands/pipeline-loop-agent.js +2 -0
- package/dist/cli/commands/pipeline-loop-agent.js.map +1 -0
- package/dist/cli/commands/pipeline.js +42 -71
- package/dist/cli/commands/pipeline.js.map +1 -1
- package/dist/cli/commands/ralph.js +37 -20
- package/dist/cli/commands/ralph.js.map +1 -1
- package/dist/cli/commands/shared.d.ts +1 -0
- package/dist/cli/commands/shared.js +30 -1
- package/dist/cli/commands/shared.js.map +1 -1
- package/dist/cli/commands/test.js +5 -2
- package/dist/cli/commands/test.js.map +1 -1
- package/dist/cli/poe-code-command-runner.js +2 -7
- package/dist/cli/poe-code-command-runner.js.map +1 -1
- package/dist/cli/program.js +55 -46
- package/dist/cli/program.js.map +1 -1
- package/dist/cli/service-registry.d.ts +7 -1
- package/dist/cli/service-registry.js.map +1 -1
- package/dist/index.js +9189 -2108
- package/dist/index.js.map +4 -4
- package/dist/providers/claude-code.js +18 -1
- package/dist/providers/claude-code.js.map +3 -3
- package/dist/providers/codex.js +18 -1
- package/dist/providers/codex.js.map +3 -3
- package/dist/providers/create-provider.d.ts +1 -0
- package/dist/providers/create-provider.js +3 -0
- package/dist/providers/create-provider.js.map +1 -1
- package/dist/providers/goose.js +19 -2
- package/dist/providers/goose.js.map +3 -3
- package/dist/providers/kimi.js +18 -1
- package/dist/providers/kimi.js.map +3 -3
- package/dist/providers/opencode.js +18 -1
- package/dist/providers/opencode.js.map +3 -3
- package/dist/providers/poe-agent.js +723 -300
- package/dist/providers/poe-agent.js.map +4 -4
- package/dist/providers/tiny-http-mcp-server.d.ts +22 -0
- package/dist/providers/tiny-http-mcp-server.js +1471 -0
- package/dist/providers/tiny-http-mcp-server.js.map +7 -0
- package/dist/templates/pipeline/SKILL_plan.md +64 -52
- package/package.json +10 -2
- package/packages/memory/dist/explain.cli.d.ts +1 -2
- package/packages/memory/dist/explain.cli.js +1 -2
- package/packages/memory/dist/explain.d.ts +1 -2
- package/packages/memory/dist/explain.js +19 -12
- package/packages/memory/dist/handle.d.ts +37 -0
- package/packages/memory/dist/handle.js +41 -0
- package/packages/memory/dist/index.d.ts +3 -1
- package/packages/memory/dist/index.js +1474 -452
- package/packages/memory/dist/index.js.map +4 -4
- package/packages/memory/dist/ingest.d.ts +12 -1
- package/packages/memory/dist/ingest.js +23 -12
- package/packages/memory/dist/mcp.d.ts +4 -2
- package/packages/memory/dist/mcp.js +6 -10
- package/packages/memory/dist/query.js +2 -8
- package/packages/memory/dist/types.d.ts +0 -21
- package/packages/tiny-oauth-test-server/dist/cli.js +191 -0
- package/packages/tiny-stdio-mcp-server/dist/server.js +9 -1
- package/packages/tiny-stdio-mcp-server/dist/types.d.ts +1 -1
|
@@ -7,8 +7,8 @@ var MEMORY_PAGES_DIR_RELPATH = "pages";
|
|
|
7
7
|
var MEMORY_CACHE_DIR_RELPATH = ".cache";
|
|
8
8
|
var MEMORY_INGEST_CACHE_DIR_RELPATH = `${MEMORY_CACHE_DIR_RELPATH}/ingest`;
|
|
9
9
|
var MemoryPathError = class extends Error {
|
|
10
|
-
constructor(
|
|
11
|
-
super(
|
|
10
|
+
constructor(message2) {
|
|
11
|
+
super(message2);
|
|
12
12
|
this.name = "MemoryPathError";
|
|
13
13
|
}
|
|
14
14
|
};
|
|
@@ -60,7 +60,7 @@ import path6 from "node:path";
|
|
|
60
60
|
|
|
61
61
|
// packages/config-extends/src/discover.ts
|
|
62
62
|
import path2 from "node:path";
|
|
63
|
-
async function findBase(name, bases,
|
|
63
|
+
async function findBase(name, bases, fs14) {
|
|
64
64
|
const checkedPaths = [];
|
|
65
65
|
for (const basePath of bases) {
|
|
66
66
|
for (const extension of [".md", ".yaml", ".yml", ".json"]) {
|
|
@@ -68,14 +68,14 @@ async function findBase(name, bases, fs13) {
|
|
|
68
68
|
checkedPaths.push(filePath);
|
|
69
69
|
try {
|
|
70
70
|
return {
|
|
71
|
-
content: await
|
|
71
|
+
content: await fs14.readFile(filePath, "utf8"),
|
|
72
72
|
filePath
|
|
73
73
|
};
|
|
74
|
-
} catch (
|
|
75
|
-
if (hasCode(
|
|
74
|
+
} catch (error2) {
|
|
75
|
+
if (hasCode(error2, "ENOENT")) {
|
|
76
76
|
continue;
|
|
77
77
|
}
|
|
78
|
-
throw
|
|
78
|
+
throw error2;
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
}
|
|
@@ -83,8 +83,8 @@ async function findBase(name, bases, fs13) {
|
|
|
83
83
|
Checked paths:
|
|
84
84
|
- ${checkedPaths.join("\n- ")}`);
|
|
85
85
|
}
|
|
86
|
-
function hasCode(
|
|
87
|
-
return typeof
|
|
86
|
+
function hasCode(error2, code) {
|
|
87
|
+
return typeof error2 === "object" && error2 !== null && "code" in error2 && error2.code === code;
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
// packages/config-extends/src/parse.ts
|
|
@@ -148,11 +148,11 @@ function stripBom(content) {
|
|
|
148
148
|
function mergeLayers(layers) {
|
|
149
149
|
return mergeObjectLayers(layers, []);
|
|
150
150
|
}
|
|
151
|
-
function mergeObjectLayers(layers,
|
|
151
|
+
function mergeObjectLayers(layers, path30) {
|
|
152
152
|
const data = {};
|
|
153
153
|
const sources = {};
|
|
154
154
|
for (const key of collectKeys(layers)) {
|
|
155
|
-
const resolved = resolveKey(layers, key,
|
|
155
|
+
const resolved = resolveKey(layers, key, path30);
|
|
156
156
|
if (resolved === void 0) {
|
|
157
157
|
continue;
|
|
158
158
|
}
|
|
@@ -170,7 +170,7 @@ function collectKeys(layers) {
|
|
|
170
170
|
}
|
|
171
171
|
return [...keys];
|
|
172
172
|
}
|
|
173
|
-
function resolveKey(layers, key,
|
|
173
|
+
function resolveKey(layers, key, path30) {
|
|
174
174
|
let winningSource;
|
|
175
175
|
let winningValue;
|
|
176
176
|
const objectLayers = [];
|
|
@@ -200,9 +200,9 @@ function resolveKey(layers, key, path25) {
|
|
|
200
200
|
if (winningSource === void 0) {
|
|
201
201
|
return void 0;
|
|
202
202
|
}
|
|
203
|
-
const fullPath = buildPath(
|
|
203
|
+
const fullPath = buildPath(path30, key);
|
|
204
204
|
if (isPlainObject(winningValue)) {
|
|
205
|
-
const merged = mergeObjectLayers(objectLayers, [...
|
|
205
|
+
const merged = mergeObjectLayers(objectLayers, [...path30, key]);
|
|
206
206
|
return {
|
|
207
207
|
value: merged.data,
|
|
208
208
|
sources: {
|
|
@@ -227,8 +227,8 @@ function isWinningCandidate(key, value) {
|
|
|
227
227
|
}
|
|
228
228
|
return true;
|
|
229
229
|
}
|
|
230
|
-
function buildPath(
|
|
231
|
-
return [...
|
|
230
|
+
function buildPath(path30, key) {
|
|
231
|
+
return [...path30, key].join(".");
|
|
232
232
|
}
|
|
233
233
|
function isPlainObject(value) {
|
|
234
234
|
if (value === null || Array.isArray(value) || typeof value !== "object") {
|
|
@@ -333,11 +333,11 @@ async function resolveBaseChain({
|
|
|
333
333
|
baseLayers.map((layer) => layer.path),
|
|
334
334
|
options.fs
|
|
335
335
|
);
|
|
336
|
-
} catch (
|
|
337
|
-
if (optional && isBaseNotFoundError(
|
|
336
|
+
} catch (error2) {
|
|
337
|
+
if (optional && isBaseNotFoundError(error2)) {
|
|
338
338
|
return void 0;
|
|
339
339
|
}
|
|
340
|
-
throw
|
|
340
|
+
throw error2;
|
|
341
341
|
}
|
|
342
342
|
if (visited.has(discoveredBase.filePath)) {
|
|
343
343
|
throw new Error(
|
|
@@ -466,8 +466,8 @@ function getBaseName(filePath) {
|
|
|
466
466
|
function shouldResolveBase(parsedDocument, autoExtend) {
|
|
467
467
|
return parsedDocument.extends || autoExtend === true && !parsedDocument.hasExtendsField;
|
|
468
468
|
}
|
|
469
|
-
function isBaseNotFoundError(
|
|
470
|
-
return
|
|
469
|
+
function isBaseNotFoundError(error2) {
|
|
470
|
+
return error2 instanceof Error && error2.message.startsWith('Base "') && error2.message.includes('" not found.\nChecked paths:');
|
|
471
471
|
}
|
|
472
472
|
function isDataLayer(layer) {
|
|
473
473
|
return "data" in layer;
|
|
@@ -859,16 +859,16 @@ function getConfigFormat(pathOrFormat) {
|
|
|
859
859
|
}
|
|
860
860
|
return formatRegistry[formatName];
|
|
861
861
|
}
|
|
862
|
-
function detectFormat2(
|
|
863
|
-
const ext = getExtension(
|
|
862
|
+
function detectFormat2(path30) {
|
|
863
|
+
const ext = getExtension(path30);
|
|
864
864
|
return extensionMap[ext];
|
|
865
865
|
}
|
|
866
|
-
function getExtension(
|
|
867
|
-
const lastDot =
|
|
866
|
+
function getExtension(path30) {
|
|
867
|
+
const lastDot = path30.lastIndexOf(".");
|
|
868
868
|
if (lastDot === -1) {
|
|
869
869
|
return "";
|
|
870
870
|
}
|
|
871
|
-
return
|
|
871
|
+
return path30.slice(lastDot).toLowerCase();
|
|
872
872
|
}
|
|
873
873
|
|
|
874
874
|
// packages/config-mutations/src/execution/path-utils.ts
|
|
@@ -916,28 +916,28 @@ function resolvePath(rawPath, homeDir, pathMapper) {
|
|
|
916
916
|
}
|
|
917
917
|
|
|
918
918
|
// packages/config-mutations/src/fs-utils.ts
|
|
919
|
-
function isNotFound(
|
|
920
|
-
return typeof
|
|
919
|
+
function isNotFound(error2) {
|
|
920
|
+
return typeof error2 === "object" && error2 !== null && "code" in error2 && error2.code === "ENOENT";
|
|
921
921
|
}
|
|
922
|
-
async function readFileIfExists(
|
|
922
|
+
async function readFileIfExists(fs14, target) {
|
|
923
923
|
try {
|
|
924
|
-
return await
|
|
925
|
-
} catch (
|
|
926
|
-
if (isNotFound(
|
|
924
|
+
return await fs14.readFile(target, "utf8");
|
|
925
|
+
} catch (error2) {
|
|
926
|
+
if (isNotFound(error2)) {
|
|
927
927
|
return null;
|
|
928
928
|
}
|
|
929
|
-
throw
|
|
929
|
+
throw error2;
|
|
930
930
|
}
|
|
931
931
|
}
|
|
932
|
-
async function pathExists(
|
|
932
|
+
async function pathExists(fs14, target) {
|
|
933
933
|
try {
|
|
934
|
-
await
|
|
934
|
+
await fs14.stat(target);
|
|
935
935
|
return true;
|
|
936
|
-
} catch (
|
|
937
|
-
if (isNotFound(
|
|
936
|
+
} catch (error2) {
|
|
937
|
+
if (isNotFound(error2)) {
|
|
938
938
|
return false;
|
|
939
939
|
}
|
|
940
|
-
throw
|
|
940
|
+
throw error2;
|
|
941
941
|
}
|
|
942
942
|
}
|
|
943
943
|
function createTimestamp() {
|
|
@@ -955,9 +955,9 @@ function createInvalidDocumentBackupPath(targetPath) {
|
|
|
955
955
|
const ext = targetPath.includes(".") ? targetPath.split(".").pop() : "bak";
|
|
956
956
|
return `${targetPath}.invalid-${createTimestamp()}.${ext}`;
|
|
957
957
|
}
|
|
958
|
-
async function backupInvalidDocument(
|
|
958
|
+
async function backupInvalidDocument(fs14, targetPath, content) {
|
|
959
959
|
const backupPath = createInvalidDocumentBackupPath(targetPath);
|
|
960
|
-
await
|
|
960
|
+
await fs14.writeFile(backupPath, content, { encoding: "utf8" });
|
|
961
961
|
}
|
|
962
962
|
function describeMutation(kind, targetPath) {
|
|
963
963
|
const displayPath = targetPath ?? "target";
|
|
@@ -1145,14 +1145,14 @@ async function applyRemoveFile(mutation, context, options) {
|
|
|
1145
1145
|
outcome: { changed: true, effect: "delete", detail: "delete" },
|
|
1146
1146
|
details
|
|
1147
1147
|
};
|
|
1148
|
-
} catch (
|
|
1149
|
-
if (isNotFound(
|
|
1148
|
+
} catch (error2) {
|
|
1149
|
+
if (isNotFound(error2)) {
|
|
1150
1150
|
return {
|
|
1151
1151
|
outcome: { changed: false, effect: "none", detail: "noop" },
|
|
1152
1152
|
details
|
|
1153
1153
|
};
|
|
1154
1154
|
}
|
|
1155
|
-
throw
|
|
1155
|
+
throw error2;
|
|
1156
1156
|
}
|
|
1157
1157
|
}
|
|
1158
1158
|
async function applyChmod(mutation, context, options) {
|
|
@@ -1185,14 +1185,14 @@ async function applyChmod(mutation, context, options) {
|
|
|
1185
1185
|
outcome: { changed: true, effect: "chmod", detail: "update" },
|
|
1186
1186
|
details
|
|
1187
1187
|
};
|
|
1188
|
-
} catch (
|
|
1189
|
-
if (isNotFound(
|
|
1188
|
+
} catch (error2) {
|
|
1189
|
+
if (isNotFound(error2)) {
|
|
1190
1190
|
return {
|
|
1191
1191
|
outcome: { changed: false, effect: "none", detail: "noop" },
|
|
1192
1192
|
details
|
|
1193
1193
|
};
|
|
1194
1194
|
}
|
|
1195
|
-
throw
|
|
1195
|
+
throw error2;
|
|
1196
1196
|
}
|
|
1197
1197
|
}
|
|
1198
1198
|
async function applyBackup(mutation, context, options) {
|
|
@@ -1437,10 +1437,10 @@ async function applyTemplateMerge(mutation, context, options, formatName) {
|
|
|
1437
1437
|
let templateDoc;
|
|
1438
1438
|
try {
|
|
1439
1439
|
templateDoc = format.parse(rendered);
|
|
1440
|
-
} catch (
|
|
1440
|
+
} catch (error2) {
|
|
1441
1441
|
throw new Error(
|
|
1442
|
-
`Failed to parse rendered template "${mutation.templateId}" as ${formatName.toUpperCase()}: ${
|
|
1443
|
-
{ cause:
|
|
1442
|
+
`Failed to parse rendered template "${mutation.templateId}" as ${formatName.toUpperCase()}: ${error2}`,
|
|
1443
|
+
{ cause: error2 }
|
|
1444
1444
|
);
|
|
1445
1445
|
}
|
|
1446
1446
|
const rawContent = await readFileIfExists(context.fs, targetPath);
|
|
@@ -1501,16 +1501,16 @@ async function executeMutation(mutation, context, options) {
|
|
|
1501
1501
|
const { outcome, details } = await applyMutation(mutation, context, options);
|
|
1502
1502
|
context.observers?.onComplete?.(details, outcome);
|
|
1503
1503
|
return { outcome, details };
|
|
1504
|
-
} catch (
|
|
1504
|
+
} catch (error2) {
|
|
1505
1505
|
context.observers?.onError?.(
|
|
1506
1506
|
{
|
|
1507
1507
|
kind: mutation.kind,
|
|
1508
1508
|
label: mutation.label ?? mutation.kind,
|
|
1509
1509
|
targetPath: void 0
|
|
1510
1510
|
},
|
|
1511
|
-
|
|
1511
|
+
error2
|
|
1512
1512
|
);
|
|
1513
|
-
throw
|
|
1513
|
+
throw error2;
|
|
1514
1514
|
}
|
|
1515
1515
|
}
|
|
1516
1516
|
|
|
@@ -1519,12 +1519,12 @@ import Mustache2 from "mustache";
|
|
|
1519
1519
|
var originalEscape = Mustache2.escape;
|
|
1520
1520
|
|
|
1521
1521
|
// packages/poe-code-config/src/store.ts
|
|
1522
|
-
async function readMergedDocument(
|
|
1523
|
-
const globalDocument = await readStoredDocument(
|
|
1522
|
+
async function readMergedDocument(fs14, globalPath, projectPath) {
|
|
1523
|
+
const globalDocument = await readStoredDocument(fs14, globalPath);
|
|
1524
1524
|
if (!projectPath) {
|
|
1525
1525
|
return globalDocument.data;
|
|
1526
1526
|
}
|
|
1527
|
-
const projectDocument = await readStoredDocument(
|
|
1527
|
+
const projectDocument = await readStoredDocument(fs14, projectPath);
|
|
1528
1528
|
const resolved = await resolve(
|
|
1529
1529
|
[
|
|
1530
1530
|
{
|
|
@@ -1538,41 +1538,41 @@ async function readMergedDocument(fs13, globalPath, projectPath) {
|
|
|
1538
1538
|
}
|
|
1539
1539
|
],
|
|
1540
1540
|
{
|
|
1541
|
-
fs: createResolvedConfigFs(
|
|
1541
|
+
fs: createResolvedConfigFs(fs14, globalPath, globalDocument.content),
|
|
1542
1542
|
autoExtend: true
|
|
1543
1543
|
}
|
|
1544
1544
|
);
|
|
1545
1545
|
return normalizeDocument(resolved.data);
|
|
1546
1546
|
}
|
|
1547
|
-
async function readStoredDocument(
|
|
1547
|
+
async function readStoredDocument(fs14, filePath) {
|
|
1548
1548
|
try {
|
|
1549
|
-
const raw = await
|
|
1550
|
-
return await parseStoredDocument(
|
|
1551
|
-
} catch (
|
|
1552
|
-
if (isNotFound(
|
|
1549
|
+
const raw = await fs14.readFile(filePath, "utf8");
|
|
1550
|
+
return await parseStoredDocument(fs14, filePath, raw);
|
|
1551
|
+
} catch (error2) {
|
|
1552
|
+
if (isNotFound(error2)) {
|
|
1553
1553
|
return {
|
|
1554
1554
|
content: EMPTY_DOCUMENT,
|
|
1555
1555
|
data: {}
|
|
1556
1556
|
};
|
|
1557
1557
|
}
|
|
1558
|
-
throw
|
|
1558
|
+
throw error2;
|
|
1559
1559
|
}
|
|
1560
1560
|
}
|
|
1561
|
-
async function parseStoredDocument(
|
|
1561
|
+
async function parseStoredDocument(fs14, filePath, raw) {
|
|
1562
1562
|
try {
|
|
1563
1563
|
return {
|
|
1564
1564
|
content: raw,
|
|
1565
1565
|
data: normalizeDocument(JSON.parse(raw))
|
|
1566
1566
|
};
|
|
1567
|
-
} catch (
|
|
1568
|
-
if (
|
|
1569
|
-
await recoverInvalidDocument(
|
|
1567
|
+
} catch (error2) {
|
|
1568
|
+
if (error2 instanceof SyntaxError) {
|
|
1569
|
+
await recoverInvalidDocument(fs14, filePath, raw);
|
|
1570
1570
|
return {
|
|
1571
1571
|
content: EMPTY_DOCUMENT,
|
|
1572
1572
|
data: {}
|
|
1573
1573
|
};
|
|
1574
1574
|
}
|
|
1575
|
-
throw
|
|
1575
|
+
throw error2;
|
|
1576
1576
|
}
|
|
1577
1577
|
}
|
|
1578
1578
|
function normalizeDocument(value) {
|
|
@@ -1600,21 +1600,21 @@ function normalizeScopeValues(value) {
|
|
|
1600
1600
|
}
|
|
1601
1601
|
return normalized;
|
|
1602
1602
|
}
|
|
1603
|
-
function createResolvedConfigFs(
|
|
1603
|
+
function createResolvedConfigFs(fs14, globalPath, globalContent) {
|
|
1604
1604
|
return {
|
|
1605
1605
|
readFile(filePath, _encoding) {
|
|
1606
1606
|
if (filePath === globalPath) {
|
|
1607
1607
|
return Promise.resolve(globalContent);
|
|
1608
1608
|
}
|
|
1609
|
-
return
|
|
1609
|
+
return fs14.readFile(filePath, "utf8");
|
|
1610
1610
|
}
|
|
1611
1611
|
};
|
|
1612
1612
|
}
|
|
1613
|
-
async function recoverInvalidDocument(
|
|
1614
|
-
await
|
|
1613
|
+
async function recoverInvalidDocument(fs14, filePath, content) {
|
|
1614
|
+
await fs14.mkdir(path6.dirname(filePath), { recursive: true });
|
|
1615
1615
|
const backupPath = createInvalidBackupPath(filePath);
|
|
1616
|
-
await
|
|
1617
|
-
await
|
|
1616
|
+
await fs14.writeFile(backupPath, content, { encoding: "utf8" });
|
|
1617
|
+
await fs14.writeFile(filePath, EMPTY_DOCUMENT, { encoding: "utf8" });
|
|
1618
1618
|
}
|
|
1619
1619
|
function createInvalidBackupPath(filePath) {
|
|
1620
1620
|
const directory = path6.dirname(filePath);
|
|
@@ -1709,14 +1709,14 @@ async function initMemory(root) {
|
|
|
1709
1709
|
async function writeFileIfMissing(filePath, content) {
|
|
1710
1710
|
try {
|
|
1711
1711
|
await fs.writeFile(filePath, content, { encoding: "utf8", flag: "wx" });
|
|
1712
|
-
} catch (
|
|
1713
|
-
if (!hasErrorCode(
|
|
1714
|
-
throw
|
|
1712
|
+
} catch (error2) {
|
|
1713
|
+
if (!hasErrorCode(error2, "EEXIST")) {
|
|
1714
|
+
throw error2;
|
|
1715
1715
|
}
|
|
1716
1716
|
}
|
|
1717
1717
|
}
|
|
1718
|
-
function hasErrorCode(
|
|
1719
|
-
return typeof
|
|
1718
|
+
function hasErrorCode(error2, code) {
|
|
1719
|
+
return typeof error2 === "object" && error2 !== null && "code" in error2 && error2.code === code;
|
|
1720
1720
|
}
|
|
1721
1721
|
|
|
1722
1722
|
// packages/memory/src/pages.ts
|
|
@@ -1860,9 +1860,9 @@ function parseYamlFrontmatter(yamlBlock) {
|
|
|
1860
1860
|
let parsed;
|
|
1861
1861
|
try {
|
|
1862
1862
|
parsed = parse5(normalizedYamlBlock);
|
|
1863
|
-
} catch (
|
|
1864
|
-
const
|
|
1865
|
-
throw new Error(`Invalid YAML frontmatter: ${
|
|
1863
|
+
} catch (error2) {
|
|
1864
|
+
const message2 = error2 instanceof Error ? error2.message : "Unknown YAML parse error";
|
|
1865
|
+
throw new Error(`Invalid YAML frontmatter: ${message2}`);
|
|
1866
1866
|
}
|
|
1867
1867
|
if (parsed === null) {
|
|
1868
1868
|
return {};
|
|
@@ -1901,10 +1901,10 @@ function parseSources(value) {
|
|
|
1901
1901
|
if (!isRecord2(item)) {
|
|
1902
1902
|
throw new Error('Invalid "sources" frontmatter. Expected each source to be a string or object.');
|
|
1903
1903
|
}
|
|
1904
|
-
const
|
|
1904
|
+
const path30 = readRequiredString(item.path, "sources[].path");
|
|
1905
1905
|
const startLine = readOptionalPositiveInteger(item.startLine, "sources[].startLine");
|
|
1906
1906
|
const endLine = readOptionalPositiveInteger(item.endLine, "sources[].endLine");
|
|
1907
|
-
return parseSourceRef(serializeSourceRef({ path:
|
|
1907
|
+
return parseSourceRef(serializeSourceRef({ path: path30, ...startLine === void 0 ? {} : { startLine }, ...endLine === void 0 ? {} : { endLine } }));
|
|
1908
1908
|
});
|
|
1909
1909
|
}
|
|
1910
1910
|
function readOptionalString(value, field) {
|
|
@@ -1960,9 +1960,9 @@ async function readPage(root, relPath) {
|
|
|
1960
1960
|
bytes: Buffer.byteLength(content),
|
|
1961
1961
|
mtimeMs: stat6.mtimeMs
|
|
1962
1962
|
};
|
|
1963
|
-
} catch (
|
|
1964
|
-
const
|
|
1965
|
-
console.warn(`Failed to parse frontmatter for "${normalizedRelPath}": ${
|
|
1963
|
+
} catch (error2) {
|
|
1964
|
+
const message2 = error2 instanceof Error ? error2.message : String(error2);
|
|
1965
|
+
console.warn(`Failed to parse frontmatter for "${normalizedRelPath}": ${message2}`);
|
|
1966
1966
|
return {
|
|
1967
1967
|
relPath: normalizedRelPath,
|
|
1968
1968
|
frontmatter: {},
|
|
@@ -1982,11 +1982,11 @@ async function collectMarkdownRelPathsInto(root, currentRelPath, relPaths) {
|
|
|
1982
1982
|
let entryNames;
|
|
1983
1983
|
try {
|
|
1984
1984
|
entryNames = await fs2.readdir(absPath);
|
|
1985
|
-
} catch (
|
|
1986
|
-
if (isMissing(
|
|
1985
|
+
} catch (error2) {
|
|
1986
|
+
if (isMissing(error2)) {
|
|
1987
1987
|
return;
|
|
1988
1988
|
}
|
|
1989
|
-
throw
|
|
1989
|
+
throw error2;
|
|
1990
1990
|
}
|
|
1991
1991
|
for (const entryName of entryNames.sort((left, right) => left.localeCompare(right))) {
|
|
1992
1992
|
const entryRelPath = currentRelPath.length === 0 ? entryName : path10.posix.join(currentRelPath, entryName);
|
|
@@ -2022,8 +2022,8 @@ function assertMarkdownRelPath(relPath) {
|
|
|
2022
2022
|
function isMarkdownPath(relPath) {
|
|
2023
2023
|
return path10.posix.extname(relPath).toLowerCase() === ".md";
|
|
2024
2024
|
}
|
|
2025
|
-
function isMissing(
|
|
2026
|
-
return typeof
|
|
2025
|
+
function isMissing(error2) {
|
|
2026
|
+
return typeof error2 === "object" && error2 !== null && "code" in error2 && error2.code === "ENOENT";
|
|
2027
2027
|
}
|
|
2028
2028
|
|
|
2029
2029
|
// packages/memory/src/search.ts
|
|
@@ -2090,11 +2090,11 @@ async function pathExists2(targetPath) {
|
|
|
2090
2090
|
try {
|
|
2091
2091
|
await fs4.stat(targetPath);
|
|
2092
2092
|
return true;
|
|
2093
|
-
} catch (
|
|
2094
|
-
if (typeof
|
|
2093
|
+
} catch (error2) {
|
|
2094
|
+
if (typeof error2 === "object" && error2 !== null && "code" in error2 && error2.code === "ENOENT") {
|
|
2095
2095
|
return false;
|
|
2096
2096
|
}
|
|
2097
|
-
throw
|
|
2097
|
+
throw error2;
|
|
2098
2098
|
}
|
|
2099
2099
|
}
|
|
2100
2100
|
|
|
@@ -2119,8 +2119,8 @@ function createDefaultFs() {
|
|
|
2119
2119
|
function sleep(ms) {
|
|
2120
2120
|
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
2121
2121
|
}
|
|
2122
|
-
function hasErrorCode2(
|
|
2123
|
-
return typeof
|
|
2122
|
+
function hasErrorCode2(error2, code) {
|
|
2123
|
+
return typeof error2 === "object" && error2 !== null && "code" in error2 && error2.code === code;
|
|
2124
2124
|
}
|
|
2125
2125
|
function lockDelay(attempt, minTimeoutMs, maxTimeoutMs) {
|
|
2126
2126
|
return Math.min(maxTimeoutMs, minTimeoutMs * Math.pow(2, attempt));
|
|
@@ -2142,31 +2142,31 @@ function isPidRunning(pid) {
|
|
|
2142
2142
|
try {
|
|
2143
2143
|
process.kill(pid, 0);
|
|
2144
2144
|
return true;
|
|
2145
|
-
} catch (
|
|
2146
|
-
return !hasErrorCode2(
|
|
2145
|
+
} catch (error2) {
|
|
2146
|
+
return !hasErrorCode2(error2, "ESRCH");
|
|
2147
2147
|
}
|
|
2148
2148
|
}
|
|
2149
|
-
async function removeLockFile(
|
|
2149
|
+
async function removeLockFile(fs14, lockPath) {
|
|
2150
2150
|
try {
|
|
2151
|
-
await
|
|
2152
|
-
} catch (
|
|
2153
|
-
if (!hasErrorCode2(
|
|
2154
|
-
throw
|
|
2151
|
+
await fs14.unlink(lockPath);
|
|
2152
|
+
} catch (error2) {
|
|
2153
|
+
if (!hasErrorCode2(error2, "ENOENT")) {
|
|
2154
|
+
throw error2;
|
|
2155
2155
|
}
|
|
2156
2156
|
}
|
|
2157
2157
|
}
|
|
2158
|
-
async function readLockPid(
|
|
2158
|
+
async function readLockPid(fs14, lockPath) {
|
|
2159
2159
|
try {
|
|
2160
|
-
return parsePid(await
|
|
2161
|
-
} catch (
|
|
2162
|
-
if (hasErrorCode2(
|
|
2160
|
+
return parsePid(await fs14.readFile(lockPath, "utf8"));
|
|
2161
|
+
} catch (error2) {
|
|
2162
|
+
if (hasErrorCode2(error2, "ENOENT")) {
|
|
2163
2163
|
return null;
|
|
2164
2164
|
}
|
|
2165
|
-
throw
|
|
2165
|
+
throw error2;
|
|
2166
2166
|
}
|
|
2167
2167
|
}
|
|
2168
2168
|
async function withLock(root, run, options = {}) {
|
|
2169
|
-
const
|
|
2169
|
+
const fs14 = options.fs ?? createDefaultFs();
|
|
2170
2170
|
const lockPath = path13.join(root, MEMORY_LOCK_RELPATH);
|
|
2171
2171
|
const pid = options.pid ?? process.pid;
|
|
2172
2172
|
const retries = options.retries ?? 20;
|
|
@@ -2175,24 +2175,24 @@ async function withLock(root, run, options = {}) {
|
|
|
2175
2175
|
const pidIsRunning = options.isPidRunning ?? isPidRunning;
|
|
2176
2176
|
for (let attempt = 0; attempt <= retries; attempt += 1) {
|
|
2177
2177
|
try {
|
|
2178
|
-
await
|
|
2178
|
+
await fs14.writeFile(lockPath, `${pid}
|
|
2179
2179
|
`, { encoding: "utf8", flag: "wx" });
|
|
2180
2180
|
try {
|
|
2181
2181
|
return await run();
|
|
2182
2182
|
} finally {
|
|
2183
|
-
await removeLockFile(
|
|
2183
|
+
await removeLockFile(fs14, lockPath);
|
|
2184
2184
|
}
|
|
2185
|
-
} catch (
|
|
2186
|
-
if (!hasErrorCode2(
|
|
2187
|
-
throw
|
|
2185
|
+
} catch (error2) {
|
|
2186
|
+
if (!hasErrorCode2(error2, "EEXIST")) {
|
|
2187
|
+
throw error2;
|
|
2188
2188
|
}
|
|
2189
2189
|
}
|
|
2190
|
-
const existingPid = await readLockPid(
|
|
2190
|
+
const existingPid = await readLockPid(fs14, lockPath);
|
|
2191
2191
|
if (existingPid === null) {
|
|
2192
2192
|
continue;
|
|
2193
2193
|
}
|
|
2194
2194
|
if (existingPid === void 0 || !pidIsRunning(existingPid)) {
|
|
2195
|
-
await removeLockFile(
|
|
2195
|
+
await removeLockFile(fs14, lockPath);
|
|
2196
2196
|
continue;
|
|
2197
2197
|
}
|
|
2198
2198
|
if (attempt < retries) {
|
|
@@ -2452,10 +2452,10 @@ async function reconcile(root, before, _verb, detail) {
|
|
|
2452
2452
|
await Promise.all(
|
|
2453
2453
|
currentPages.filter((page) => page.currentMarkdown !== page.nextMarkdown).map((page) => fs5.writeFile(path14.join(root, page.relPath), page.nextMarkdown, "utf8"))
|
|
2454
2454
|
);
|
|
2455
|
-
const
|
|
2455
|
+
const diff2 = diffSnapshots(before, await snapshot(root));
|
|
2456
2456
|
await writeIndex(root);
|
|
2457
|
-
await appendLogEntries(root,
|
|
2458
|
-
return
|
|
2457
|
+
await appendLogEntries(root, diff2, detail, timestamp);
|
|
2458
|
+
return diff2;
|
|
2459
2459
|
}
|
|
2460
2460
|
function renderIndex(entries) {
|
|
2461
2461
|
if (entries.length === 0) {
|
|
@@ -2471,11 +2471,11 @@ function renderIndex(entries) {
|
|
|
2471
2471
|
""
|
|
2472
2472
|
].join("\n");
|
|
2473
2473
|
}
|
|
2474
|
-
async function appendLogEntries(root,
|
|
2474
|
+
async function appendLogEntries(root, diff2, detail, timestamp = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
2475
2475
|
const entries = [
|
|
2476
|
-
...
|
|
2477
|
-
...
|
|
2478
|
-
...
|
|
2476
|
+
...diff2.updated.map((relPath) => formatLogLine(timestamp, "update", relPath, detail)),
|
|
2477
|
+
...diff2.deleted.map((relPath) => formatLogLine(timestamp, "delete", relPath, detail)),
|
|
2478
|
+
...diff2.created.map((relPath) => formatLogLine(timestamp, "create", relPath, detail))
|
|
2479
2479
|
];
|
|
2480
2480
|
if (entries.length === 0) {
|
|
2481
2481
|
return;
|
|
@@ -2509,9 +2509,9 @@ async function writeIndex(root) {
|
|
|
2509
2509
|
function parsePageMarkdown(relPath, markdown) {
|
|
2510
2510
|
try {
|
|
2511
2511
|
return parseFrontmatter(markdown);
|
|
2512
|
-
} catch (
|
|
2513
|
-
const
|
|
2514
|
-
console.warn(`Failed to parse frontmatter for "${relPath}": ${
|
|
2512
|
+
} catch (error2) {
|
|
2513
|
+
const message2 = error2 instanceof Error ? error2.message : String(error2);
|
|
2514
|
+
console.warn(`Failed to parse frontmatter for "${relPath}": ${message2}`);
|
|
2515
2515
|
return {
|
|
2516
2516
|
frontmatter: {},
|
|
2517
2517
|
body: markdown
|
|
@@ -2610,11 +2610,11 @@ function assertPageRelPath(relPath) {
|
|
|
2610
2610
|
async function readMarkdownIfPresent(filePath) {
|
|
2611
2611
|
try {
|
|
2612
2612
|
return await fs6.readFile(filePath, "utf8");
|
|
2613
|
-
} catch (
|
|
2614
|
-
if (typeof
|
|
2613
|
+
} catch (error2) {
|
|
2614
|
+
if (typeof error2 === "object" && error2 !== null && "code" in error2 && error2.code === "ENOENT") {
|
|
2615
2615
|
return void 0;
|
|
2616
2616
|
}
|
|
2617
|
-
throw
|
|
2617
|
+
throw error2;
|
|
2618
2618
|
}
|
|
2619
2619
|
}
|
|
2620
2620
|
|
|
@@ -2634,13 +2634,13 @@ async function editPage(root, relPath, opts) {
|
|
|
2634
2634
|
return { changed: false };
|
|
2635
2635
|
}
|
|
2636
2636
|
const parsed = parseFrontmatter(edited);
|
|
2637
|
-
const
|
|
2637
|
+
const diff2 = await writePage(root, relPath, parsed.body, {
|
|
2638
2638
|
frontmatter: parsed.frontmatter,
|
|
2639
2639
|
reason: opts.reason
|
|
2640
2640
|
});
|
|
2641
2641
|
return {
|
|
2642
2642
|
changed: true,
|
|
2643
|
-
diff
|
|
2643
|
+
diff: diff2
|
|
2644
2644
|
};
|
|
2645
2645
|
} finally {
|
|
2646
2646
|
await fs7.rm(tempDir, { recursive: true, force: true });
|
|
@@ -2649,11 +2649,11 @@ async function editPage(root, relPath, opts) {
|
|
|
2649
2649
|
async function readIfPresent(filePath) {
|
|
2650
2650
|
try {
|
|
2651
2651
|
return await fs7.readFile(filePath, "utf8");
|
|
2652
|
-
} catch (
|
|
2653
|
-
if (typeof
|
|
2652
|
+
} catch (error2) {
|
|
2653
|
+
if (typeof error2 === "object" && error2 !== null && "code" in error2 && error2.code === "ENOENT") {
|
|
2654
2654
|
return void 0;
|
|
2655
2655
|
}
|
|
2656
|
-
throw
|
|
2656
|
+
throw error2;
|
|
2657
2657
|
}
|
|
2658
2658
|
}
|
|
2659
2659
|
|
|
@@ -2675,8 +2675,8 @@ async function auditClaims(root, repoRoot, options = {}) {
|
|
|
2675
2675
|
let claims;
|
|
2676
2676
|
try {
|
|
2677
2677
|
claims = parseClaims(page.body);
|
|
2678
|
-
} catch (
|
|
2679
|
-
issues.push(formatError(
|
|
2678
|
+
} catch (error2) {
|
|
2679
|
+
issues.push(formatError(error2));
|
|
2680
2680
|
audits.push({ page: page.relPath, issues });
|
|
2681
2681
|
continue;
|
|
2682
2682
|
}
|
|
@@ -2745,22 +2745,22 @@ function auditFrontmatterSources(frontmatterSources, inlineSources) {
|
|
|
2745
2745
|
return issues;
|
|
2746
2746
|
}
|
|
2747
2747
|
function readSourceFile(absPath, sourceCache) {
|
|
2748
|
-
const
|
|
2749
|
-
if (
|
|
2750
|
-
return
|
|
2748
|
+
const cached2 = sourceCache.get(absPath);
|
|
2749
|
+
if (cached2 !== void 0) {
|
|
2750
|
+
return cached2;
|
|
2751
2751
|
}
|
|
2752
2752
|
const pending = fs8.readFile(absPath, "utf8").then((content) => ({
|
|
2753
2753
|
exists: true,
|
|
2754
2754
|
absPath,
|
|
2755
2755
|
lineCount: countLines(content)
|
|
2756
|
-
})).catch((
|
|
2757
|
-
if (isMissing2(
|
|
2756
|
+
})).catch((error2) => {
|
|
2757
|
+
if (isMissing2(error2)) {
|
|
2758
2758
|
return {
|
|
2759
2759
|
exists: false,
|
|
2760
2760
|
absPath
|
|
2761
2761
|
};
|
|
2762
2762
|
}
|
|
2763
|
-
throw
|
|
2763
|
+
throw error2;
|
|
2764
2764
|
});
|
|
2765
2765
|
sourceCache.set(absPath, pending);
|
|
2766
2766
|
return pending;
|
|
@@ -2773,11 +2773,11 @@ function countLines(content) {
|
|
|
2773
2773
|
const trimmed = normalized.endsWith("\n") ? normalized.slice(0, -1) : normalized;
|
|
2774
2774
|
return trimmed.length === 0 ? 0 : trimmed.split("\n").length;
|
|
2775
2775
|
}
|
|
2776
|
-
function formatError(
|
|
2777
|
-
return
|
|
2776
|
+
function formatError(error2) {
|
|
2777
|
+
return error2 instanceof Error ? error2.message : String(error2);
|
|
2778
2778
|
}
|
|
2779
|
-
function isMissing2(
|
|
2780
|
-
return typeof
|
|
2779
|
+
function isMissing2(error2) {
|
|
2780
|
+
return typeof error2 === "object" && error2 !== null && "code" in error2 && error2.code === "ENOENT";
|
|
2781
2781
|
}
|
|
2782
2782
|
function isUrlLike(value) {
|
|
2783
2783
|
return /^[a-z][a-z\d+.-]*:\/\//i.test(value);
|
|
@@ -2807,17 +2807,17 @@ async function readCacheEntry(root, key) {
|
|
|
2807
2807
|
let raw;
|
|
2808
2808
|
try {
|
|
2809
2809
|
raw = await fs9.readFile(cachePath, "utf8");
|
|
2810
|
-
} catch (
|
|
2811
|
-
if (isMissing3(
|
|
2810
|
+
} catch (error2) {
|
|
2811
|
+
if (isMissing3(error2)) {
|
|
2812
2812
|
return null;
|
|
2813
2813
|
}
|
|
2814
|
-
throw
|
|
2814
|
+
throw error2;
|
|
2815
2815
|
}
|
|
2816
2816
|
try {
|
|
2817
2817
|
return parseCacheEntry(JSON.parse(raw), key);
|
|
2818
|
-
} catch (
|
|
2819
|
-
const
|
|
2820
|
-
console.warn(`Ignoring ingest cache entry "${key}": ${
|
|
2818
|
+
} catch (error2) {
|
|
2819
|
+
const message2 = error2 instanceof Error ? error2.message : String(error2);
|
|
2820
|
+
console.warn(`Ignoring ingest cache entry "${key}": ${message2}`);
|
|
2821
2821
|
return null;
|
|
2822
2822
|
}
|
|
2823
2823
|
}
|
|
@@ -2904,67 +2904,1182 @@ function expectStringArray(value, field) {
|
|
|
2904
2904
|
if (!Array.isArray(value) || value.some((entry) => typeof entry !== "string")) {
|
|
2905
2905
|
throw new Error(`Expected string[] at "${field}".`);
|
|
2906
2906
|
}
|
|
2907
|
-
return value;
|
|
2907
|
+
return value;
|
|
2908
|
+
}
|
|
2909
|
+
async function readCacheFileNames(ingestDir) {
|
|
2910
|
+
try {
|
|
2911
|
+
return (await fs9.readdir(ingestDir)).filter((fileName) => path18.posix.extname(fileName).toLowerCase() === ".json").sort((left, right) => left.localeCompare(right));
|
|
2912
|
+
} catch (error2) {
|
|
2913
|
+
if (isMissing3(error2)) {
|
|
2914
|
+
return [];
|
|
2915
|
+
}
|
|
2916
|
+
throw error2;
|
|
2917
|
+
}
|
|
2918
|
+
}
|
|
2919
|
+
async function removeEmptyDirectory(directoryPath) {
|
|
2920
|
+
try {
|
|
2921
|
+
const remainingEntries = await fs9.readdir(directoryPath);
|
|
2922
|
+
if (remainingEntries.length === 0) {
|
|
2923
|
+
await fs9.rmdir(directoryPath);
|
|
2924
|
+
}
|
|
2925
|
+
} catch (error2) {
|
|
2926
|
+
if (isMissing3(error2)) {
|
|
2927
|
+
return;
|
|
2928
|
+
}
|
|
2929
|
+
throw error2;
|
|
2930
|
+
}
|
|
2931
|
+
}
|
|
2932
|
+
function isMissing3(error2) {
|
|
2933
|
+
return typeof error2 === "object" && error2 !== null && "code" in error2 && error2.code === "ENOENT";
|
|
2934
|
+
}
|
|
2935
|
+
|
|
2936
|
+
// packages/memory/src/cache.cli.ts
|
|
2937
|
+
import parseDuration from "parse-duration";
|
|
2938
|
+
async function runMemoryCacheStatus() {
|
|
2939
|
+
console.log("cache status not implemented yet");
|
|
2940
|
+
}
|
|
2941
|
+
async function runMemoryCacheClear(input) {
|
|
2942
|
+
if (!input.yes) {
|
|
2943
|
+
throw new Error("Refusing to clear cache without --yes.");
|
|
2944
|
+
}
|
|
2945
|
+
const olderThanMs = parseOlderThan(input.olderThan);
|
|
2946
|
+
const result = await clearCache(input.root, olderThanMs === void 0 ? {} : { olderThanMs });
|
|
2947
|
+
console.log(`removed ${result.removed} cache ${result.removed === 1 ? "entry" : "entries"}`);
|
|
2948
|
+
return result;
|
|
2949
|
+
}
|
|
2950
|
+
function parseOlderThan(value) {
|
|
2951
|
+
if (value === void 0) {
|
|
2952
|
+
return void 0;
|
|
2953
|
+
}
|
|
2954
|
+
const duration = parseDuration(value);
|
|
2955
|
+
if (duration === null || Number.isNaN(duration) || duration < 0) {
|
|
2956
|
+
throw new Error(`Invalid duration for --older-than: "${value}".`);
|
|
2957
|
+
}
|
|
2958
|
+
return duration;
|
|
2959
|
+
}
|
|
2960
|
+
|
|
2961
|
+
// packages/memory/src/ingest.ts
|
|
2962
|
+
import * as fs11 from "node:fs/promises";
|
|
2963
|
+
import path23 from "node:path";
|
|
2964
|
+
|
|
2965
|
+
// packages/agent-spawn/src/run-command.ts
|
|
2966
|
+
import { spawn } from "node:child_process";
|
|
2967
|
+
|
|
2968
|
+
// packages/agent-spawn/src/types.ts
|
|
2969
|
+
function resolveModeConfig(modeConfig) {
|
|
2970
|
+
if (Array.isArray(modeConfig)) {
|
|
2971
|
+
return { args: modeConfig };
|
|
2972
|
+
}
|
|
2973
|
+
return {
|
|
2974
|
+
args: modeConfig.args ?? [],
|
|
2975
|
+
env: modeConfig.env && Object.keys(modeConfig.env).length > 0 ? modeConfig.env : void 0
|
|
2976
|
+
};
|
|
2977
|
+
}
|
|
2978
|
+
|
|
2979
|
+
// packages/agent-defs/src/agents/claude-code.ts
|
|
2980
|
+
var claudeCodeAgent = {
|
|
2981
|
+
id: "claude-code",
|
|
2982
|
+
name: "claude-code",
|
|
2983
|
+
label: "Claude Code",
|
|
2984
|
+
summary: "Configure Claude Code to route through Poe.",
|
|
2985
|
+
aliases: ["claude"],
|
|
2986
|
+
binaryName: "claude",
|
|
2987
|
+
configPath: "~/.claude/settings.json",
|
|
2988
|
+
branding: {
|
|
2989
|
+
colors: {
|
|
2990
|
+
dark: "#C15F3C",
|
|
2991
|
+
light: "#C15F3C"
|
|
2992
|
+
}
|
|
2993
|
+
}
|
|
2994
|
+
};
|
|
2995
|
+
|
|
2996
|
+
// packages/agent-defs/src/agents/claude-desktop.ts
|
|
2997
|
+
var claudeDesktopAgent = {
|
|
2998
|
+
id: "claude-desktop",
|
|
2999
|
+
name: "claude-desktop",
|
|
3000
|
+
label: "Claude Desktop",
|
|
3001
|
+
summary: "Anthropic's official desktop application for Claude",
|
|
3002
|
+
configPath: "~/.claude/settings.json",
|
|
3003
|
+
branding: {
|
|
3004
|
+
colors: {
|
|
3005
|
+
dark: "#D97757",
|
|
3006
|
+
light: "#D97757"
|
|
3007
|
+
}
|
|
3008
|
+
}
|
|
3009
|
+
};
|
|
3010
|
+
|
|
3011
|
+
// packages/agent-defs/src/agents/codex.ts
|
|
3012
|
+
var codexAgent = {
|
|
3013
|
+
id: "codex",
|
|
3014
|
+
name: "codex",
|
|
3015
|
+
label: "Codex",
|
|
3016
|
+
summary: "Configure Codex to use Poe as the model provider.",
|
|
3017
|
+
binaryName: "codex",
|
|
3018
|
+
configPath: "~/.codex/config.toml",
|
|
3019
|
+
branding: {
|
|
3020
|
+
colors: {
|
|
3021
|
+
dark: "#D5D9DF",
|
|
3022
|
+
light: "#7A7F86"
|
|
3023
|
+
}
|
|
3024
|
+
}
|
|
3025
|
+
};
|
|
3026
|
+
|
|
3027
|
+
// packages/agent-defs/src/agents/opencode.ts
|
|
3028
|
+
var openCodeAgent = {
|
|
3029
|
+
id: "opencode",
|
|
3030
|
+
name: "opencode",
|
|
3031
|
+
label: "OpenCode CLI",
|
|
3032
|
+
summary: "Configure OpenCode CLI to use the Poe API.",
|
|
3033
|
+
binaryName: "opencode",
|
|
3034
|
+
configPath: "~/.config/opencode/config.json",
|
|
3035
|
+
branding: {
|
|
3036
|
+
colors: {
|
|
3037
|
+
dark: "#4A4F55",
|
|
3038
|
+
light: "#2F3338"
|
|
3039
|
+
}
|
|
3040
|
+
}
|
|
3041
|
+
};
|
|
3042
|
+
|
|
3043
|
+
// packages/agent-defs/src/agents/kimi.ts
|
|
3044
|
+
var kimiAgent = {
|
|
3045
|
+
id: "kimi",
|
|
3046
|
+
name: "kimi",
|
|
3047
|
+
label: "Kimi",
|
|
3048
|
+
summary: "Configure Kimi CLI to use Poe API",
|
|
3049
|
+
aliases: ["kimi-cli"],
|
|
3050
|
+
binaryName: "kimi",
|
|
3051
|
+
configPath: "~/.kimi/config.toml",
|
|
3052
|
+
branding: {
|
|
3053
|
+
colors: {
|
|
3054
|
+
dark: "#7B68EE",
|
|
3055
|
+
light: "#6A5ACD"
|
|
3056
|
+
}
|
|
3057
|
+
}
|
|
3058
|
+
};
|
|
3059
|
+
|
|
3060
|
+
// packages/agent-defs/src/agents/goose.ts
|
|
3061
|
+
var gooseAgent = {
|
|
3062
|
+
id: "goose",
|
|
3063
|
+
name: "goose",
|
|
3064
|
+
label: "Goose",
|
|
3065
|
+
summary: "Block's open-source AI agent with ACP support.",
|
|
3066
|
+
binaryName: "goose",
|
|
3067
|
+
configPath: "~/.config/goose/config.yaml",
|
|
3068
|
+
branding: {
|
|
3069
|
+
colors: {
|
|
3070
|
+
dark: "#FF6B35",
|
|
3071
|
+
light: "#E85D26"
|
|
3072
|
+
}
|
|
3073
|
+
}
|
|
3074
|
+
};
|
|
3075
|
+
|
|
3076
|
+
// packages/agent-defs/src/agents/poe-agent.ts
|
|
3077
|
+
var poeAgentAgent = {
|
|
3078
|
+
id: "poe-agent",
|
|
3079
|
+
name: "poe-agent",
|
|
3080
|
+
label: "Poe Agent",
|
|
3081
|
+
summary: "Run one-shot prompts with the built-in Poe agent runtime.",
|
|
3082
|
+
configPath: "~/.poe-code/config.json",
|
|
3083
|
+
branding: {
|
|
3084
|
+
colors: {
|
|
3085
|
+
dark: "#A465F7",
|
|
3086
|
+
light: "#7A3FD3"
|
|
3087
|
+
}
|
|
3088
|
+
}
|
|
3089
|
+
};
|
|
3090
|
+
|
|
3091
|
+
// packages/agent-defs/src/registry.ts
|
|
3092
|
+
var allAgents = [
|
|
3093
|
+
claudeCodeAgent,
|
|
3094
|
+
claudeDesktopAgent,
|
|
3095
|
+
codexAgent,
|
|
3096
|
+
openCodeAgent,
|
|
3097
|
+
kimiAgent,
|
|
3098
|
+
gooseAgent,
|
|
3099
|
+
poeAgentAgent
|
|
3100
|
+
];
|
|
3101
|
+
var lookup = /* @__PURE__ */ new Map();
|
|
3102
|
+
for (const agent of allAgents) {
|
|
3103
|
+
const values = [agent.id, agent.name, ...agent.aliases ?? []];
|
|
3104
|
+
for (const value of values) {
|
|
3105
|
+
const normalized = value.toLowerCase();
|
|
3106
|
+
if (!lookup.has(normalized)) {
|
|
3107
|
+
lookup.set(normalized, agent.id);
|
|
3108
|
+
}
|
|
3109
|
+
}
|
|
3110
|
+
}
|
|
3111
|
+
function resolveAgentId(input) {
|
|
3112
|
+
if (!input) {
|
|
3113
|
+
return void 0;
|
|
3114
|
+
}
|
|
3115
|
+
return lookup.get(input.toLowerCase());
|
|
3116
|
+
}
|
|
3117
|
+
|
|
3118
|
+
// packages/agent-spawn/src/configs/mcp.ts
|
|
3119
|
+
function toJsonMcpServers(servers) {
|
|
3120
|
+
const out = {};
|
|
3121
|
+
for (const [name, server] of Object.entries(servers)) {
|
|
3122
|
+
const mapped = { command: server.command };
|
|
3123
|
+
if (server.args && server.args.length > 0) {
|
|
3124
|
+
mapped.args = server.args;
|
|
3125
|
+
}
|
|
3126
|
+
if (server.env && Object.keys(server.env).length > 0) {
|
|
3127
|
+
mapped.env = server.env;
|
|
3128
|
+
}
|
|
3129
|
+
if (server.timeout !== void 0) {
|
|
3130
|
+
mapped.timeout = server.timeout;
|
|
3131
|
+
}
|
|
3132
|
+
out[name] = mapped;
|
|
3133
|
+
}
|
|
3134
|
+
return out;
|
|
3135
|
+
}
|
|
3136
|
+
function toTomlString(value) {
|
|
3137
|
+
return JSON.stringify(value);
|
|
3138
|
+
}
|
|
3139
|
+
function toTomlArray(values) {
|
|
3140
|
+
const serialized = values.map((value) => toTomlString(value));
|
|
3141
|
+
return `[${serialized.join(", ")}]`;
|
|
3142
|
+
}
|
|
3143
|
+
function toTomlInlineTable(values) {
|
|
3144
|
+
const parts = [];
|
|
3145
|
+
for (const [key, value] of Object.entries(values)) {
|
|
3146
|
+
parts.push(`${JSON.stringify(key)}=${toTomlString(value)}`);
|
|
3147
|
+
}
|
|
3148
|
+
return `{${parts.join(", ")}}`;
|
|
3149
|
+
}
|
|
3150
|
+
function serializeJsonMcpArgs(servers) {
|
|
3151
|
+
return ["--mcp-config", JSON.stringify({ mcpServers: toJsonMcpServers(servers) })];
|
|
3152
|
+
}
|
|
3153
|
+
function serializeOpenCodeMcpEnv(servers) {
|
|
3154
|
+
const mcp = {};
|
|
3155
|
+
for (const [name, server] of Object.entries(servers)) {
|
|
3156
|
+
const entry = { type: "local", command: [server.command, ...server.args ?? []] };
|
|
3157
|
+
if (server.env && Object.keys(server.env).length > 0) {
|
|
3158
|
+
entry.environment = server.env;
|
|
3159
|
+
}
|
|
3160
|
+
mcp[name] = entry;
|
|
3161
|
+
}
|
|
3162
|
+
return { OPENCODE_CONFIG_CONTENT: JSON.stringify({ mcp }) };
|
|
3163
|
+
}
|
|
3164
|
+
function serializeCodexMcpArgs(servers) {
|
|
3165
|
+
const args = [];
|
|
3166
|
+
for (const [name, server] of Object.entries(servers)) {
|
|
3167
|
+
const prefix = `mcp_servers.${name}`;
|
|
3168
|
+
args.push("-c", `${prefix}.command=${toTomlString(server.command)}`);
|
|
3169
|
+
if (server.args && server.args.length > 0) {
|
|
3170
|
+
args.push("-c", `${prefix}.args=${toTomlArray(server.args)}`);
|
|
3171
|
+
}
|
|
3172
|
+
if (server.env && Object.keys(server.env).length > 0) {
|
|
3173
|
+
args.push("-c", `${prefix}.env=${toTomlInlineTable(server.env)}`);
|
|
3174
|
+
}
|
|
3175
|
+
if (server.timeout !== void 0) {
|
|
3176
|
+
args.push("-c", `${prefix}.timeout=${server.timeout}`);
|
|
3177
|
+
}
|
|
3178
|
+
}
|
|
3179
|
+
return args;
|
|
3180
|
+
}
|
|
3181
|
+
function serializeGooseMcpArgs(servers) {
|
|
3182
|
+
return Object.values(servers).flatMap((server) => [
|
|
3183
|
+
"--with-extension",
|
|
3184
|
+
[server.command, ...server.args ?? []].join(" ")
|
|
3185
|
+
]);
|
|
3186
|
+
}
|
|
3187
|
+
|
|
3188
|
+
// packages/agent-spawn/src/configs/claude-code.ts
|
|
3189
|
+
var claudeCodeSpawnConfig = {
|
|
3190
|
+
kind: "cli",
|
|
3191
|
+
agentId: "claude-code",
|
|
3192
|
+
// ACP adapter support: yes (adapter: "claude")
|
|
3193
|
+
adapter: "claude",
|
|
3194
|
+
promptFlag: "-p",
|
|
3195
|
+
modelFlag: "--model",
|
|
3196
|
+
modelStripProviderPrefix: true,
|
|
3197
|
+
modelTransform: (model) => model.replaceAll(".", "-"),
|
|
3198
|
+
defaultArgs: [
|
|
3199
|
+
"--output-format",
|
|
3200
|
+
"stream-json",
|
|
3201
|
+
"--verbose"
|
|
3202
|
+
],
|
|
3203
|
+
mcpArgs: serializeJsonMcpArgs,
|
|
3204
|
+
modes: {
|
|
3205
|
+
yolo: ["--dangerously-skip-permissions"],
|
|
3206
|
+
edit: ["--permission-mode", "acceptEdits", "--allowedTools", "Bash,Read,Write,Edit,Glob,Grep,NotebookEdit"],
|
|
3207
|
+
read: ["--permission-mode", "plan"]
|
|
3208
|
+
},
|
|
3209
|
+
stdinMode: {
|
|
3210
|
+
omitPrompt: true,
|
|
3211
|
+
extraArgs: ["--input-format", "text"]
|
|
3212
|
+
},
|
|
3213
|
+
interactive: {
|
|
3214
|
+
defaultArgs: []
|
|
3215
|
+
},
|
|
3216
|
+
resumeCommand: (threadId) => ["--resume", threadId]
|
|
3217
|
+
};
|
|
3218
|
+
|
|
3219
|
+
// packages/agent-spawn/src/configs/codex.ts
|
|
3220
|
+
var codexSpawnConfig = {
|
|
3221
|
+
kind: "cli",
|
|
3222
|
+
agentId: "codex",
|
|
3223
|
+
// ACP adapter support: yes (adapter: "codex")
|
|
3224
|
+
adapter: "codex",
|
|
3225
|
+
promptFlag: "exec",
|
|
3226
|
+
modelFlag: "--model",
|
|
3227
|
+
modelStripProviderPrefix: true,
|
|
3228
|
+
defaultArgs: ["--skip-git-repo-check", "--json"],
|
|
3229
|
+
mcpArgs: serializeCodexMcpArgs,
|
|
3230
|
+
mcpArgsBeforeCommand: true,
|
|
3231
|
+
modes: {
|
|
3232
|
+
yolo: ["-s", "danger-full-access"],
|
|
3233
|
+
edit: ["-s", "workspace-write"],
|
|
3234
|
+
read: ["-s", "read-only"]
|
|
3235
|
+
},
|
|
3236
|
+
stdinMode: {
|
|
3237
|
+
omitPrompt: true,
|
|
3238
|
+
extraArgs: ["-"]
|
|
3239
|
+
},
|
|
3240
|
+
interactive: {
|
|
3241
|
+
defaultArgs: ["-a", "never"]
|
|
3242
|
+
},
|
|
3243
|
+
resumeCommand: (threadId, cwd) => ["resume", "-C", cwd, threadId]
|
|
3244
|
+
};
|
|
3245
|
+
|
|
3246
|
+
// packages/agent-spawn/src/configs/opencode.ts
|
|
3247
|
+
var openCodeSpawnConfig = {
|
|
3248
|
+
kind: "cli",
|
|
3249
|
+
agentId: "opencode",
|
|
3250
|
+
// ACP adapter support: yes (adapter: "opencode").
|
|
3251
|
+
// OpenCode's `--format json` emits NDJSON events with `{ type, sessionID, part }`
|
|
3252
|
+
// (no `{ event, ... }` field), so it needs the OpenCode adapter (not "native").
|
|
3253
|
+
adapter: "opencode",
|
|
3254
|
+
promptFlag: "run",
|
|
3255
|
+
modelFlag: "--model",
|
|
3256
|
+
modelStripProviderPrefix: false,
|
|
3257
|
+
modelTransform: (model) => {
|
|
3258
|
+
return model.startsWith("poe/") ? model : `poe/${model}`;
|
|
3259
|
+
},
|
|
3260
|
+
defaultArgs: ["--format", "json"],
|
|
3261
|
+
modes: {
|
|
3262
|
+
yolo: [],
|
|
3263
|
+
edit: [],
|
|
3264
|
+
read: ["--agent", "plan"]
|
|
3265
|
+
},
|
|
3266
|
+
interactive: {
|
|
3267
|
+
defaultArgs: [],
|
|
3268
|
+
promptFlag: "--prompt"
|
|
3269
|
+
},
|
|
3270
|
+
resumeCommand: (threadId, cwd) => [cwd, "--session", threadId],
|
|
3271
|
+
mcpEnv: serializeOpenCodeMcpEnv
|
|
3272
|
+
};
|
|
3273
|
+
var openCodeAcpSpawnConfig = {
|
|
3274
|
+
kind: "acp",
|
|
3275
|
+
agentId: "opencode",
|
|
3276
|
+
acpArgs: ["acp"],
|
|
3277
|
+
skipAuth: true,
|
|
3278
|
+
mcpEnv: serializeOpenCodeMcpEnv
|
|
3279
|
+
};
|
|
3280
|
+
|
|
3281
|
+
// packages/agent-spawn/src/configs/kimi.ts
|
|
3282
|
+
var kimiSpawnConfig = {
|
|
3283
|
+
kind: "cli",
|
|
3284
|
+
agentId: "kimi",
|
|
3285
|
+
// ACP adapter support: yes (adapter: "kimi").
|
|
3286
|
+
// Kimi's `--output-format stream-json` emits OpenAI-style `{ role, content }` JSON
|
|
3287
|
+
// (no `{ event, ... }` field), so it needs the Kimi adapter (not "native").
|
|
3288
|
+
adapter: "kimi",
|
|
3289
|
+
promptFlag: "-p",
|
|
3290
|
+
modelStripProviderPrefix: true,
|
|
3291
|
+
defaultArgs: ["--print", "--output-format", "stream-json"],
|
|
3292
|
+
mcpArgs: serializeJsonMcpArgs,
|
|
3293
|
+
modes: {
|
|
3294
|
+
yolo: ["--yolo"],
|
|
3295
|
+
edit: [],
|
|
3296
|
+
read: []
|
|
3297
|
+
},
|
|
3298
|
+
stdinMode: {
|
|
3299
|
+
omitPrompt: true,
|
|
3300
|
+
extraArgs: ["--input-format", "stream-json"]
|
|
3301
|
+
},
|
|
3302
|
+
interactive: {
|
|
3303
|
+
defaultArgs: [],
|
|
3304
|
+
promptFlag: "-p"
|
|
3305
|
+
},
|
|
3306
|
+
resumeCommand: (threadId, cwd) => ["--session", threadId, "--work-dir", cwd]
|
|
3307
|
+
};
|
|
3308
|
+
var kimiAcpSpawnConfig = {
|
|
3309
|
+
kind: "acp",
|
|
3310
|
+
agentId: "kimi",
|
|
3311
|
+
acpArgs: ["acp"]
|
|
3312
|
+
};
|
|
3313
|
+
|
|
3314
|
+
// packages/agent-spawn/src/configs/goose.ts
|
|
3315
|
+
var gooseSpawnConfig = {
|
|
3316
|
+
kind: "cli",
|
|
3317
|
+
agentId: "goose",
|
|
3318
|
+
adapter: "native",
|
|
3319
|
+
promptFlag: "--text",
|
|
3320
|
+
modelFlag: "--model",
|
|
3321
|
+
modelStripProviderPrefix: false,
|
|
3322
|
+
defaultArgs: ["run", "--output-format", "stream-json"],
|
|
3323
|
+
defaultArgsPosition: "beforePrompt",
|
|
3324
|
+
mcpArgs: serializeGooseMcpArgs,
|
|
3325
|
+
mcpArgsPosition: "beforePrompt",
|
|
3326
|
+
modes: {
|
|
3327
|
+
yolo: { env: { GOOSE_MODE: "auto" } },
|
|
3328
|
+
edit: { env: { GOOSE_MODE: "smart_approve" } },
|
|
3329
|
+
read: { env: { GOOSE_MODE: "chat" } }
|
|
3330
|
+
},
|
|
3331
|
+
stdinMode: {
|
|
3332
|
+
omitPrompt: true,
|
|
3333
|
+
extraArgs: ["--instructions", "-"]
|
|
3334
|
+
},
|
|
3335
|
+
interactive: {
|
|
3336
|
+
defaultArgs: ["session"],
|
|
3337
|
+
defaultArgsPosition: "beforePrompt"
|
|
3338
|
+
},
|
|
3339
|
+
resumeCommand: () => ["run", "--resume", "--text", "continue"]
|
|
3340
|
+
};
|
|
3341
|
+
var gooseAcpSpawnConfig = {
|
|
3342
|
+
kind: "acp",
|
|
3343
|
+
agentId: "goose",
|
|
3344
|
+
acpArgs: ["acp"],
|
|
3345
|
+
skipAuth: true
|
|
3346
|
+
};
|
|
3347
|
+
|
|
3348
|
+
// packages/agent-spawn/src/configs/index.ts
|
|
3349
|
+
var allSpawnConfigs = [
|
|
3350
|
+
claudeCodeSpawnConfig,
|
|
3351
|
+
codexSpawnConfig,
|
|
3352
|
+
openCodeSpawnConfig,
|
|
3353
|
+
kimiSpawnConfig,
|
|
3354
|
+
gooseSpawnConfig
|
|
3355
|
+
];
|
|
3356
|
+
var lookup2 = /* @__PURE__ */ new Map();
|
|
3357
|
+
for (const config of allSpawnConfigs) {
|
|
3358
|
+
lookup2.set(config.agentId, config);
|
|
3359
|
+
}
|
|
3360
|
+
var acpLookup = /* @__PURE__ */ new Map();
|
|
3361
|
+
acpLookup.set(openCodeAcpSpawnConfig.agentId, openCodeAcpSpawnConfig);
|
|
3362
|
+
acpLookup.set(kimiAcpSpawnConfig.agentId, kimiAcpSpawnConfig);
|
|
3363
|
+
acpLookup.set(gooseAcpSpawnConfig.agentId, gooseAcpSpawnConfig);
|
|
3364
|
+
function getSpawnConfig(input) {
|
|
3365
|
+
const resolvedId = resolveAgentId(input);
|
|
3366
|
+
if (!resolvedId) {
|
|
3367
|
+
return void 0;
|
|
3368
|
+
}
|
|
3369
|
+
return lookup2.get(resolvedId);
|
|
3370
|
+
}
|
|
3371
|
+
function listMcpSupportedAgents() {
|
|
3372
|
+
const supported = [];
|
|
3373
|
+
for (const config of allSpawnConfigs) {
|
|
3374
|
+
if (config.kind !== "cli" || typeof config.mcpArgs !== "function" && typeof config.mcpEnv !== "function") {
|
|
3375
|
+
continue;
|
|
3376
|
+
}
|
|
3377
|
+
supported.push(config.agentId);
|
|
3378
|
+
}
|
|
3379
|
+
return supported;
|
|
3380
|
+
}
|
|
3381
|
+
|
|
3382
|
+
// packages/agent-spawn/src/spawn.ts
|
|
3383
|
+
import { spawn as spawnChildProcess } from "node:child_process";
|
|
3384
|
+
import { mkdirSync, openSync, writeSync, closeSync } from "node:fs";
|
|
3385
|
+
import path19 from "node:path";
|
|
3386
|
+
|
|
3387
|
+
// packages/agent-spawn/src/configs/resolve-config.ts
|
|
3388
|
+
function resolveConfig(agentId) {
|
|
3389
|
+
const resolvedAgentId = resolveAgentId(agentId);
|
|
3390
|
+
if (!resolvedAgentId) {
|
|
3391
|
+
throw new Error(`Unknown agent "${agentId}".`);
|
|
3392
|
+
}
|
|
3393
|
+
const agentDefinition = allAgents.find((agent) => agent.id === resolvedAgentId);
|
|
3394
|
+
if (!agentDefinition) {
|
|
3395
|
+
throw new Error(`Unknown agent "${agentId}".`);
|
|
3396
|
+
}
|
|
3397
|
+
const spawnConfig = getSpawnConfig(resolvedAgentId);
|
|
3398
|
+
const binaryName = agentDefinition.binaryName;
|
|
3399
|
+
return { agentId: resolvedAgentId, binaryName, spawnConfig };
|
|
3400
|
+
}
|
|
3401
|
+
|
|
3402
|
+
// packages/agent-spawn/src/mcp-args.ts
|
|
3403
|
+
function hasMcpServers(servers) {
|
|
3404
|
+
if (!servers) {
|
|
3405
|
+
return false;
|
|
3406
|
+
}
|
|
3407
|
+
return Object.keys(servers).length > 0;
|
|
3408
|
+
}
|
|
3409
|
+
function getMcpArgs(config, servers) {
|
|
3410
|
+
if (!hasMcpServers(servers)) {
|
|
3411
|
+
return [];
|
|
3412
|
+
}
|
|
3413
|
+
if (!config.mcpArgs && !config.mcpEnv) {
|
|
3414
|
+
throw new Error(formatUnsupportedMcpSpawnMessage(config.agentId));
|
|
3415
|
+
}
|
|
3416
|
+
if (!config.mcpArgs) {
|
|
3417
|
+
return [];
|
|
3418
|
+
}
|
|
3419
|
+
return config.mcpArgs(servers);
|
|
3420
|
+
}
|
|
3421
|
+
function formatUnsupportedMcpSpawnMessage(agentId) {
|
|
3422
|
+
const supported = listMcpSupportedAgents();
|
|
3423
|
+
const supportedText = supported.length > 0 ? supported.join(", ") : "(none)";
|
|
3424
|
+
return `Agent "${agentId}" does not support MCP servers at spawn time.
|
|
3425
|
+
Agents with spawn-time MCP support: ${supportedText}`;
|
|
3426
|
+
}
|
|
3427
|
+
|
|
3428
|
+
// packages/agent-spawn/src/model-utils.ts
|
|
3429
|
+
function stripModelNamespace(model) {
|
|
3430
|
+
const slashIndex = model.indexOf("/");
|
|
3431
|
+
return slashIndex === -1 ? model : model.slice(slashIndex + 1);
|
|
3432
|
+
}
|
|
3433
|
+
|
|
3434
|
+
// packages/agent-spawn/src/spawn.ts
|
|
3435
|
+
function createAbortError() {
|
|
3436
|
+
const error2 = new Error("Agent spawn aborted");
|
|
3437
|
+
error2.name = "AbortError";
|
|
3438
|
+
return error2;
|
|
3439
|
+
}
|
|
3440
|
+
function createActivityTimeoutError(timeoutMs) {
|
|
3441
|
+
const error2 = new Error(
|
|
3442
|
+
`Agent spawn timed out after ${timeoutMs / 1e3}s of inactivity`
|
|
3443
|
+
);
|
|
3444
|
+
error2.name = "ActivityTimeoutError";
|
|
3445
|
+
return error2;
|
|
3446
|
+
}
|
|
3447
|
+
function resolveCliConfig(agentId) {
|
|
3448
|
+
const resolved = resolveConfig(agentId);
|
|
3449
|
+
if (!resolved.spawnConfig) {
|
|
3450
|
+
throw new Error(`Agent "${resolved.agentId}" has no spawn config.`);
|
|
3451
|
+
}
|
|
3452
|
+
if (resolved.spawnConfig.kind !== "cli") {
|
|
3453
|
+
throw new Error(`Agent "${resolved.agentId}" does not support CLI spawn.`);
|
|
3454
|
+
}
|
|
3455
|
+
if (!resolved.binaryName) {
|
|
3456
|
+
throw new Error(`Agent "${resolved.agentId}" has no binaryName.`);
|
|
3457
|
+
}
|
|
3458
|
+
return {
|
|
3459
|
+
agentId: resolved.agentId,
|
|
3460
|
+
binaryName: resolved.binaryName,
|
|
3461
|
+
spawnConfig: resolved.spawnConfig
|
|
3462
|
+
};
|
|
3463
|
+
}
|
|
3464
|
+
function getDefaultArgsPosition(config) {
|
|
3465
|
+
return config.defaultArgsPosition ?? "afterPrompt";
|
|
3466
|
+
}
|
|
3467
|
+
function getMcpArgsPosition(config) {
|
|
3468
|
+
if (config.mcpArgsPosition) {
|
|
3469
|
+
return config.mcpArgsPosition;
|
|
3470
|
+
}
|
|
3471
|
+
return config.mcpArgsBeforeCommand ? "beforeCommand" : "afterCommand";
|
|
3472
|
+
}
|
|
3473
|
+
function buildCliArgs(config, options, stdinMode) {
|
|
3474
|
+
const mcpArgs = getMcpArgs(config, options.mcpServers);
|
|
3475
|
+
const defaultArgsPosition = getDefaultArgsPosition(config);
|
|
3476
|
+
const mcpArgsPosition = getMcpArgsPosition(config);
|
|
3477
|
+
const args = [];
|
|
3478
|
+
if (mcpArgsPosition === "beforeCommand") {
|
|
3479
|
+
args.push(...mcpArgs);
|
|
3480
|
+
}
|
|
3481
|
+
if (defaultArgsPosition === "beforePrompt") {
|
|
3482
|
+
args.push(...config.defaultArgs);
|
|
3483
|
+
}
|
|
3484
|
+
if (mcpArgsPosition === "beforePrompt") {
|
|
3485
|
+
args.push(...mcpArgs);
|
|
3486
|
+
}
|
|
3487
|
+
if (stdinMode) {
|
|
3488
|
+
args.push(
|
|
3489
|
+
config.promptFlag,
|
|
3490
|
+
...stdinMode.omitPrompt ? [] : [options.prompt],
|
|
3491
|
+
...stdinMode.extraArgs
|
|
3492
|
+
);
|
|
3493
|
+
} else {
|
|
3494
|
+
args.push(config.promptFlag, options.prompt);
|
|
3495
|
+
}
|
|
3496
|
+
if (options.model && config.modelFlag) {
|
|
3497
|
+
let model = config.modelStripProviderPrefix ? stripModelNamespace(options.model) : options.model;
|
|
3498
|
+
if (config.modelTransform) model = config.modelTransform(model);
|
|
3499
|
+
args.push(config.modelFlag, model);
|
|
3500
|
+
}
|
|
3501
|
+
if (defaultArgsPosition === "afterPrompt") {
|
|
3502
|
+
args.push(...config.defaultArgs);
|
|
3503
|
+
}
|
|
3504
|
+
if (mcpArgsPosition === "afterCommand") {
|
|
3505
|
+
args.push(...mcpArgs);
|
|
3506
|
+
}
|
|
3507
|
+
const mode = resolveModeConfig(config.modes[options.mode ?? "yolo"]);
|
|
3508
|
+
args.push(...mode.args);
|
|
3509
|
+
if (options.args && options.args.length > 0) {
|
|
3510
|
+
args.push(...options.args);
|
|
3511
|
+
}
|
|
3512
|
+
return { args, env: mode.env };
|
|
3513
|
+
}
|
|
3514
|
+
async function spawn2(agentId, options, context) {
|
|
3515
|
+
if (options.signal?.aborted) {
|
|
3516
|
+
throw createAbortError();
|
|
3517
|
+
}
|
|
3518
|
+
const { agentId: resolvedId, binaryName, spawnConfig } = resolveCliConfig(agentId);
|
|
3519
|
+
const stdinMode = options.useStdin && spawnConfig.stdinMode ? spawnConfig.stdinMode : void 0;
|
|
3520
|
+
const { args: spawnArgs, env: modeEnv } = buildCliArgs(spawnConfig, options, stdinMode);
|
|
3521
|
+
if (context?.dryRun) {
|
|
3522
|
+
const rendered = [binaryName, ...spawnArgs].join(" ");
|
|
3523
|
+
context.logger?.dryRun(rendered);
|
|
3524
|
+
return { stdout: "", stderr: "", exitCode: 0 };
|
|
3525
|
+
}
|
|
3526
|
+
const logFilePath = resolveSpawnLogPath(options);
|
|
3527
|
+
const logFd = logFilePath ? openSpawnLog(logFilePath) : void 0;
|
|
3528
|
+
const child = spawnChildProcess(binaryName, spawnArgs, {
|
|
3529
|
+
cwd: options.cwd,
|
|
3530
|
+
stdio: [stdinMode ? "pipe" : "inherit", "pipe", "pipe"],
|
|
3531
|
+
...modeEnv ? { env: { ...process.env, ...modeEnv } } : {}
|
|
3532
|
+
});
|
|
3533
|
+
if (!child.stdout || !child.stderr) {
|
|
3534
|
+
throw new Error(`Failed to spawn "${resolvedId}": missing stdio pipes.`);
|
|
3535
|
+
}
|
|
3536
|
+
const stdoutStream = child.stdout;
|
|
3537
|
+
const stderrStream = child.stderr;
|
|
3538
|
+
if (stdinMode) {
|
|
3539
|
+
if (!child.stdin) {
|
|
3540
|
+
throw new Error(`Failed to spawn "${resolvedId}": missing stdin pipe.`);
|
|
3541
|
+
}
|
|
3542
|
+
child.stdin.setDefaultEncoding("utf8");
|
|
3543
|
+
child.stdin.write(options.prompt);
|
|
3544
|
+
child.stdin.end();
|
|
3545
|
+
}
|
|
3546
|
+
return new Promise((resolve2, reject) => {
|
|
3547
|
+
let stdout = "";
|
|
3548
|
+
let stderr = "";
|
|
3549
|
+
let aborted = false;
|
|
3550
|
+
let timedOut = false;
|
|
3551
|
+
const onAbort = () => {
|
|
3552
|
+
aborted = true;
|
|
3553
|
+
child.kill("SIGTERM");
|
|
3554
|
+
};
|
|
3555
|
+
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
3556
|
+
let activityTimer;
|
|
3557
|
+
const resetActivityTimer = options.activityTimeoutMs ? () => {
|
|
3558
|
+
if (activityTimer) clearTimeout(activityTimer);
|
|
3559
|
+
activityTimer = setTimeout(() => {
|
|
3560
|
+
timedOut = true;
|
|
3561
|
+
child.kill("SIGTERM");
|
|
3562
|
+
}, options.activityTimeoutMs);
|
|
3563
|
+
} : void 0;
|
|
3564
|
+
resetActivityTimer?.();
|
|
3565
|
+
const cleanup = () => {
|
|
3566
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
3567
|
+
if (activityTimer) clearTimeout(activityTimer);
|
|
3568
|
+
};
|
|
3569
|
+
stdoutStream.setEncoding("utf8");
|
|
3570
|
+
stdoutStream.on("data", (chunk) => {
|
|
3571
|
+
stdout += chunk;
|
|
3572
|
+
resetActivityTimer?.();
|
|
3573
|
+
if (options.tee?.stdout) options.tee.stdout.write(chunk);
|
|
3574
|
+
appendSpawnLog(logFd, chunk);
|
|
3575
|
+
});
|
|
3576
|
+
stderrStream.setEncoding("utf8");
|
|
3577
|
+
stderrStream.on("data", (chunk) => {
|
|
3578
|
+
stderr += chunk;
|
|
3579
|
+
resetActivityTimer?.();
|
|
3580
|
+
if (options.tee?.stderr) options.tee.stderr.write(chunk);
|
|
3581
|
+
appendSpawnLog(logFd, chunk);
|
|
3582
|
+
});
|
|
3583
|
+
child.on("error", (error2) => {
|
|
3584
|
+
cleanup();
|
|
3585
|
+
closeSpawnLog(logFd);
|
|
3586
|
+
if (aborted) {
|
|
3587
|
+
reject(createAbortError());
|
|
3588
|
+
return;
|
|
3589
|
+
}
|
|
3590
|
+
reject(error2);
|
|
3591
|
+
});
|
|
3592
|
+
child.on("close", (code) => {
|
|
3593
|
+
cleanup();
|
|
3594
|
+
closeSpawnLog(logFd);
|
|
3595
|
+
if (aborted) {
|
|
3596
|
+
reject(createAbortError());
|
|
3597
|
+
return;
|
|
3598
|
+
}
|
|
3599
|
+
if (timedOut) {
|
|
3600
|
+
reject(createActivityTimeoutError(options.activityTimeoutMs));
|
|
3601
|
+
return;
|
|
3602
|
+
}
|
|
3603
|
+
resolve2({
|
|
3604
|
+
stdout,
|
|
3605
|
+
stderr,
|
|
3606
|
+
exitCode: code ?? 1,
|
|
3607
|
+
...logFilePath ? { logFile: logFilePath } : {}
|
|
3608
|
+
});
|
|
3609
|
+
});
|
|
3610
|
+
});
|
|
3611
|
+
}
|
|
3612
|
+
function resolveSpawnLogPath(options) {
|
|
3613
|
+
if (options.logPath) {
|
|
3614
|
+
return options.logPath;
|
|
3615
|
+
}
|
|
3616
|
+
if (!options.logDir || !options.logFileName) {
|
|
3617
|
+
return void 0;
|
|
3618
|
+
}
|
|
3619
|
+
return path19.join(options.logDir, options.logFileName);
|
|
3620
|
+
}
|
|
3621
|
+
function openSpawnLog(filePath) {
|
|
3622
|
+
try {
|
|
3623
|
+
mkdirSync(path19.dirname(filePath), { recursive: true });
|
|
3624
|
+
return openSync(filePath, "a");
|
|
3625
|
+
} catch {
|
|
3626
|
+
return void 0;
|
|
3627
|
+
}
|
|
3628
|
+
}
|
|
3629
|
+
function appendSpawnLog(fd, chunk) {
|
|
3630
|
+
if (fd === void 0) return;
|
|
3631
|
+
try {
|
|
3632
|
+
writeSync(fd, chunk);
|
|
3633
|
+
} catch {
|
|
3634
|
+
}
|
|
3635
|
+
}
|
|
3636
|
+
function closeSpawnLog(fd) {
|
|
3637
|
+
if (fd === void 0) return;
|
|
3638
|
+
try {
|
|
3639
|
+
closeSync(fd);
|
|
3640
|
+
} catch {
|
|
3641
|
+
}
|
|
3642
|
+
}
|
|
3643
|
+
|
|
3644
|
+
// packages/agent-spawn/src/spawn-interactive.ts
|
|
3645
|
+
import { spawn as spawnChildProcess2 } from "node:child_process";
|
|
3646
|
+
|
|
3647
|
+
// packages/design-system/src/tokens/colors.ts
|
|
3648
|
+
import chalk from "chalk";
|
|
3649
|
+
var dark = {
|
|
3650
|
+
header: (text4) => chalk.magentaBright.bold(text4),
|
|
3651
|
+
divider: (text4) => chalk.dim(text4),
|
|
3652
|
+
prompt: (text4) => chalk.cyan(text4),
|
|
3653
|
+
number: (text4) => chalk.cyanBright(text4),
|
|
3654
|
+
intro: (text4) => chalk.bgMagenta.white(` Poe - ${text4} `),
|
|
3655
|
+
resolvedSymbol: chalk.magenta("\u25C7"),
|
|
3656
|
+
errorSymbol: chalk.red("\u25A0"),
|
|
3657
|
+
accent: (text4) => chalk.cyan(text4),
|
|
3658
|
+
muted: (text4) => chalk.dim(text4),
|
|
3659
|
+
success: (text4) => chalk.green(text4),
|
|
3660
|
+
warning: (text4) => chalk.yellow(text4),
|
|
3661
|
+
error: (text4) => chalk.red(text4),
|
|
3662
|
+
info: (text4) => chalk.magenta(text4),
|
|
3663
|
+
badge: (text4) => chalk.bgYellow.black(` ${text4} `)
|
|
3664
|
+
};
|
|
3665
|
+
var light = {
|
|
3666
|
+
header: (text4) => chalk.hex("#a200ff").bold(text4),
|
|
3667
|
+
divider: (text4) => chalk.hex("#666666")(text4),
|
|
3668
|
+
prompt: (text4) => chalk.hex("#006699").bold(text4),
|
|
3669
|
+
number: (text4) => chalk.hex("#0077cc").bold(text4),
|
|
3670
|
+
intro: (text4) => chalk.bgHex("#a200ff").white(` Poe - ${text4} `),
|
|
3671
|
+
resolvedSymbol: chalk.hex("#a200ff")("\u25C7"),
|
|
3672
|
+
errorSymbol: chalk.hex("#cc0000")("\u25A0"),
|
|
3673
|
+
accent: (text4) => chalk.hex("#006699").bold(text4),
|
|
3674
|
+
muted: (text4) => chalk.hex("#666666")(text4),
|
|
3675
|
+
success: (text4) => chalk.hex("#008800")(text4),
|
|
3676
|
+
warning: (text4) => chalk.hex("#cc6600")(text4),
|
|
3677
|
+
error: (text4) => chalk.hex("#cc0000")(text4),
|
|
3678
|
+
info: (text4) => chalk.hex("#a200ff")(text4),
|
|
3679
|
+
badge: (text4) => chalk.bgHex("#cc6600").white(` ${text4} `)
|
|
3680
|
+
};
|
|
3681
|
+
|
|
3682
|
+
// packages/design-system/src/tokens/typography.ts
|
|
3683
|
+
import chalk2 from "chalk";
|
|
3684
|
+
|
|
3685
|
+
// packages/design-system/src/components/text.ts
|
|
3686
|
+
import chalk3 from "chalk";
|
|
3687
|
+
|
|
3688
|
+
// packages/design-system/src/internal/output-format.ts
|
|
3689
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
3690
|
+
var VALID_FORMATS = /* @__PURE__ */ new Set(["terminal", "markdown", "json"]);
|
|
3691
|
+
var formatStorage = new AsyncLocalStorage();
|
|
3692
|
+
var cached;
|
|
3693
|
+
function resolveOutputFormat(env = process.env) {
|
|
3694
|
+
const scoped = formatStorage.getStore();
|
|
3695
|
+
if (scoped) {
|
|
3696
|
+
return scoped;
|
|
3697
|
+
}
|
|
3698
|
+
if (cached) {
|
|
3699
|
+
return cached;
|
|
3700
|
+
}
|
|
3701
|
+
const raw = env.OUTPUT_FORMAT?.toLowerCase();
|
|
3702
|
+
cached = VALID_FORMATS.has(raw) ? raw : "terminal";
|
|
3703
|
+
return cached;
|
|
3704
|
+
}
|
|
3705
|
+
|
|
3706
|
+
// packages/design-system/src/internal/theme-detect.ts
|
|
3707
|
+
function detectThemeFromEnv(env) {
|
|
3708
|
+
const apple = env.APPLE_INTERFACE_STYLE;
|
|
3709
|
+
if (typeof apple === "string") {
|
|
3710
|
+
return apple.toLowerCase() === "dark" ? "dark" : "light";
|
|
3711
|
+
}
|
|
3712
|
+
const vscodeKind = env.VSCODE_COLOR_THEME_KIND;
|
|
3713
|
+
if (typeof vscodeKind === "string") {
|
|
3714
|
+
const normalized = vscodeKind.toLowerCase();
|
|
3715
|
+
if (normalized.includes("light")) {
|
|
3716
|
+
return "light";
|
|
3717
|
+
}
|
|
3718
|
+
if (normalized.includes("dark")) {
|
|
3719
|
+
return "dark";
|
|
3720
|
+
}
|
|
3721
|
+
}
|
|
3722
|
+
const colorFGBG = env.COLORFGBG;
|
|
3723
|
+
if (typeof colorFGBG === "string") {
|
|
3724
|
+
const parts = colorFGBG.split(";").map((part) => Number.parseInt(part, 10));
|
|
3725
|
+
const background = parts.at(-1);
|
|
3726
|
+
if (Number.isFinite(background)) {
|
|
3727
|
+
return background >= 8 ? "light" : "dark";
|
|
3728
|
+
}
|
|
3729
|
+
}
|
|
3730
|
+
return void 0;
|
|
3731
|
+
}
|
|
3732
|
+
function resolveThemeName(env = process.env) {
|
|
3733
|
+
const raw = (env.POE_CODE_THEME ?? env.POE_THEME)?.toLowerCase();
|
|
3734
|
+
if (raw === "light" || raw === "dark") {
|
|
3735
|
+
return raw;
|
|
3736
|
+
}
|
|
3737
|
+
const detected = detectThemeFromEnv(env);
|
|
3738
|
+
if (detected) {
|
|
3739
|
+
return detected;
|
|
3740
|
+
}
|
|
3741
|
+
return "dark";
|
|
3742
|
+
}
|
|
3743
|
+
var cachedTheme;
|
|
3744
|
+
function getTheme(env) {
|
|
3745
|
+
if (cachedTheme) {
|
|
3746
|
+
return cachedTheme;
|
|
3747
|
+
}
|
|
3748
|
+
const themeName = resolveThemeName(env);
|
|
3749
|
+
cachedTheme = themeName === "light" ? light : dark;
|
|
3750
|
+
return cachedTheme;
|
|
3751
|
+
}
|
|
3752
|
+
|
|
3753
|
+
// packages/design-system/src/components/symbols.ts
|
|
3754
|
+
import chalk4 from "chalk";
|
|
3755
|
+
var symbols = {
|
|
3756
|
+
get info() {
|
|
3757
|
+
const format = resolveOutputFormat();
|
|
3758
|
+
if (format === "json") return "info";
|
|
3759
|
+
if (format === "markdown") return "(i)";
|
|
3760
|
+
return chalk4.magenta("\u25CF");
|
|
3761
|
+
},
|
|
3762
|
+
get success() {
|
|
3763
|
+
const format = resolveOutputFormat();
|
|
3764
|
+
if (format === "json") return "success";
|
|
3765
|
+
if (format === "markdown") return "[ok]";
|
|
3766
|
+
return chalk4.magenta("\u25C6");
|
|
3767
|
+
},
|
|
3768
|
+
get resolved() {
|
|
3769
|
+
const format = resolveOutputFormat();
|
|
3770
|
+
if (format === "json") return "resolved";
|
|
3771
|
+
if (format === "markdown") return ">";
|
|
3772
|
+
return getTheme().resolvedSymbol;
|
|
3773
|
+
},
|
|
3774
|
+
get errorResolved() {
|
|
3775
|
+
const format = resolveOutputFormat();
|
|
3776
|
+
if (format === "json") return "error";
|
|
3777
|
+
if (format === "markdown") return "[!]";
|
|
3778
|
+
return getTheme().errorSymbol;
|
|
3779
|
+
},
|
|
3780
|
+
get bar() {
|
|
3781
|
+
const format = resolveOutputFormat();
|
|
3782
|
+
if (format === "json") return "";
|
|
3783
|
+
if (format === "markdown") return "|";
|
|
3784
|
+
return "\u2502";
|
|
3785
|
+
},
|
|
3786
|
+
cornerTopRight: "\u256E",
|
|
3787
|
+
cornerBottomRight: "\u256F",
|
|
3788
|
+
get warning() {
|
|
3789
|
+
const format = resolveOutputFormat();
|
|
3790
|
+
if (format === "json") return "warning";
|
|
3791
|
+
if (format === "markdown") return "[!]";
|
|
3792
|
+
return "\u25B2";
|
|
3793
|
+
},
|
|
3794
|
+
get active() {
|
|
3795
|
+
const format = resolveOutputFormat();
|
|
3796
|
+
if (format === "json") return "active";
|
|
3797
|
+
if (format === "markdown") return "[x]";
|
|
3798
|
+
return "\u25C6";
|
|
3799
|
+
},
|
|
3800
|
+
get inactive() {
|
|
3801
|
+
const format = resolveOutputFormat();
|
|
3802
|
+
if (format === "json") return "inactive";
|
|
3803
|
+
if (format === "markdown") return "[ ]";
|
|
3804
|
+
return "\u25CB";
|
|
3805
|
+
}
|
|
3806
|
+
};
|
|
3807
|
+
|
|
3808
|
+
// packages/design-system/src/components/logger.ts
|
|
3809
|
+
import chalk6 from "chalk";
|
|
3810
|
+
|
|
3811
|
+
// packages/design-system/src/prompts/primitives/log.ts
|
|
3812
|
+
import chalk5 from "chalk";
|
|
3813
|
+
|
|
3814
|
+
// packages/design-system/src/internal/strip-ansi.ts
|
|
3815
|
+
function stripAnsi(value) {
|
|
3816
|
+
return value.replace(/\u001b\[[0-9;]*m/g, "");
|
|
3817
|
+
}
|
|
3818
|
+
|
|
3819
|
+
// packages/design-system/src/prompts/primitives/log.ts
|
|
3820
|
+
function writeTerminalMessage(msg, {
|
|
3821
|
+
symbol = chalk5.gray("\u2502"),
|
|
3822
|
+
secondarySymbol = chalk5.gray("\u2502"),
|
|
3823
|
+
spacing: spacing2 = 1,
|
|
3824
|
+
withGuide = true
|
|
3825
|
+
} = {}) {
|
|
3826
|
+
const lines = [];
|
|
3827
|
+
const showGuide = withGuide !== false;
|
|
3828
|
+
const contentLines = msg.split("\n");
|
|
3829
|
+
const prefix = showGuide ? `${symbol} ` : "";
|
|
3830
|
+
const continuationPrefix = showGuide ? `${secondarySymbol} ` : "";
|
|
3831
|
+
const emptyGuide = showGuide ? secondarySymbol : "";
|
|
3832
|
+
for (let index = 0; index < spacing2; index += 1) {
|
|
3833
|
+
lines.push(emptyGuide);
|
|
3834
|
+
}
|
|
3835
|
+
if (contentLines.length === 0) {
|
|
3836
|
+
process.stdout.write("\n");
|
|
3837
|
+
return;
|
|
3838
|
+
}
|
|
3839
|
+
const [firstLine = "", ...continuationLines] = contentLines;
|
|
3840
|
+
if (firstLine.length > 0) {
|
|
3841
|
+
lines.push(`${prefix}${firstLine}`);
|
|
3842
|
+
} else {
|
|
3843
|
+
lines.push(showGuide ? symbol : "");
|
|
3844
|
+
}
|
|
3845
|
+
for (const line of continuationLines) {
|
|
3846
|
+
if (line.length > 0) {
|
|
3847
|
+
lines.push(`${continuationPrefix}${line}`);
|
|
3848
|
+
continue;
|
|
3849
|
+
}
|
|
3850
|
+
lines.push(emptyGuide);
|
|
3851
|
+
}
|
|
3852
|
+
process.stdout.write(`${lines.join("\n")}
|
|
3853
|
+
`);
|
|
3854
|
+
}
|
|
3855
|
+
function message(msg, options) {
|
|
3856
|
+
const format = resolveOutputFormat();
|
|
3857
|
+
if (format === "markdown") {
|
|
3858
|
+
process.stdout.write(`- ${stripAnsi(msg)}
|
|
3859
|
+
`);
|
|
3860
|
+
return;
|
|
3861
|
+
}
|
|
3862
|
+
if (format === "json") {
|
|
3863
|
+
process.stdout.write(
|
|
3864
|
+
`${JSON.stringify({ level: "message", message: stripAnsi(msg) })}
|
|
3865
|
+
`
|
|
3866
|
+
);
|
|
3867
|
+
return;
|
|
3868
|
+
}
|
|
3869
|
+
writeTerminalMessage(msg, options);
|
|
3870
|
+
}
|
|
3871
|
+
function info(msg) {
|
|
3872
|
+
const format = resolveOutputFormat();
|
|
3873
|
+
if (format === "markdown") {
|
|
3874
|
+
process.stdout.write(`- **info:** ${stripAnsi(msg)}
|
|
3875
|
+
`);
|
|
3876
|
+
return;
|
|
3877
|
+
}
|
|
3878
|
+
if (format === "json") {
|
|
3879
|
+
process.stdout.write(
|
|
3880
|
+
`${JSON.stringify({ level: "info", message: stripAnsi(msg) })}
|
|
3881
|
+
`
|
|
3882
|
+
);
|
|
3883
|
+
return;
|
|
3884
|
+
}
|
|
3885
|
+
message(msg, { symbol: symbols.info });
|
|
3886
|
+
}
|
|
3887
|
+
function success(msg) {
|
|
3888
|
+
const format = resolveOutputFormat();
|
|
3889
|
+
if (format === "markdown") {
|
|
3890
|
+
process.stdout.write(`- **success:** ${stripAnsi(msg)}
|
|
3891
|
+
`);
|
|
3892
|
+
return;
|
|
3893
|
+
}
|
|
3894
|
+
if (format === "json") {
|
|
3895
|
+
process.stdout.write(
|
|
3896
|
+
`${JSON.stringify({ level: "success", message: stripAnsi(msg) })}
|
|
3897
|
+
`
|
|
3898
|
+
);
|
|
3899
|
+
return;
|
|
3900
|
+
}
|
|
3901
|
+
message(msg, { symbol: symbols.success });
|
|
3902
|
+
}
|
|
3903
|
+
function warn(msg) {
|
|
3904
|
+
const format = resolveOutputFormat();
|
|
3905
|
+
if (format === "markdown") {
|
|
3906
|
+
process.stdout.write(`- **warning:** ${stripAnsi(msg)}
|
|
3907
|
+
`);
|
|
3908
|
+
return;
|
|
3909
|
+
}
|
|
3910
|
+
if (format === "json") {
|
|
3911
|
+
process.stdout.write(
|
|
3912
|
+
`${JSON.stringify({ level: "warn", message: stripAnsi(msg) })}
|
|
3913
|
+
`
|
|
3914
|
+
);
|
|
3915
|
+
return;
|
|
3916
|
+
}
|
|
3917
|
+
message(msg, { symbol: chalk5.yellow("\u25B2") });
|
|
2908
3918
|
}
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
}
|
|
2916
|
-
throw error;
|
|
3919
|
+
function error(msg) {
|
|
3920
|
+
const format = resolveOutputFormat();
|
|
3921
|
+
if (format === "markdown") {
|
|
3922
|
+
process.stdout.write(`- **error:** ${stripAnsi(msg)}
|
|
3923
|
+
`);
|
|
3924
|
+
return;
|
|
2917
3925
|
}
|
|
3926
|
+
if (format === "json") {
|
|
3927
|
+
process.stdout.write(
|
|
3928
|
+
`${JSON.stringify({ level: "error", message: stripAnsi(msg) })}
|
|
3929
|
+
`
|
|
3930
|
+
);
|
|
3931
|
+
return;
|
|
3932
|
+
}
|
|
3933
|
+
message(msg, { symbol: chalk5.red("\u25A0") });
|
|
2918
3934
|
}
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
3935
|
+
var log = {
|
|
3936
|
+
info,
|
|
3937
|
+
success,
|
|
3938
|
+
message,
|
|
3939
|
+
warn,
|
|
3940
|
+
error
|
|
3941
|
+
};
|
|
3942
|
+
|
|
3943
|
+
// packages/design-system/src/components/logger.ts
|
|
3944
|
+
function createLogger(emitter) {
|
|
3945
|
+
const emit = (level, message2) => {
|
|
3946
|
+
if (emitter) {
|
|
3947
|
+
emitter(message2);
|
|
3948
|
+
return;
|
|
2924
3949
|
}
|
|
2925
|
-
|
|
2926
|
-
|
|
3950
|
+
if (level === "success") {
|
|
3951
|
+
log.success(message2);
|
|
2927
3952
|
return;
|
|
2928
3953
|
}
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
3954
|
+
if (level === "warn") {
|
|
3955
|
+
log.warn(message2);
|
|
3956
|
+
return;
|
|
3957
|
+
}
|
|
3958
|
+
if (level === "error") {
|
|
3959
|
+
log.error(message2);
|
|
3960
|
+
return;
|
|
3961
|
+
}
|
|
3962
|
+
log.info(message2);
|
|
3963
|
+
};
|
|
3964
|
+
return {
|
|
3965
|
+
info(message2) {
|
|
3966
|
+
emit("info", message2);
|
|
3967
|
+
},
|
|
3968
|
+
success(message2) {
|
|
3969
|
+
emit("success", message2);
|
|
3970
|
+
},
|
|
3971
|
+
warn(message2) {
|
|
3972
|
+
emit("warn", message2);
|
|
3973
|
+
},
|
|
3974
|
+
error(message2) {
|
|
3975
|
+
emit("error", message2);
|
|
3976
|
+
},
|
|
3977
|
+
resolved(label, value) {
|
|
3978
|
+
if (emitter) {
|
|
3979
|
+
emitter(`${label}: ${value}`);
|
|
3980
|
+
return;
|
|
3981
|
+
}
|
|
3982
|
+
log.message(`${label}
|
|
3983
|
+
${value}`, { symbol: symbols.resolved });
|
|
3984
|
+
},
|
|
3985
|
+
errorResolved(label, value) {
|
|
3986
|
+
if (emitter) {
|
|
3987
|
+
emitter(`${label}: ${value}`);
|
|
3988
|
+
return;
|
|
3989
|
+
}
|
|
3990
|
+
log.message(`${label}
|
|
3991
|
+
${value}`, { symbol: symbols.errorResolved });
|
|
3992
|
+
},
|
|
3993
|
+
message(message2, symbol) {
|
|
3994
|
+
if (emitter) {
|
|
3995
|
+
emitter(message2);
|
|
3996
|
+
return;
|
|
3997
|
+
}
|
|
3998
|
+
log.message(message2, { symbol: symbol ?? chalk6.gray("\u2502") });
|
|
3999
|
+
}
|
|
4000
|
+
};
|
|
2934
4001
|
}
|
|
4002
|
+
var logger = createLogger();
|
|
2935
4003
|
|
|
2936
|
-
// packages/
|
|
2937
|
-
import
|
|
2938
|
-
async function runMemoryCacheStatus() {
|
|
2939
|
-
console.log("cache status not implemented yet");
|
|
2940
|
-
}
|
|
2941
|
-
async function runMemoryCacheClear(input) {
|
|
2942
|
-
if (!input.yes) {
|
|
2943
|
-
throw new Error("Refusing to clear cache without --yes.");
|
|
2944
|
-
}
|
|
2945
|
-
const olderThanMs = parseOlderThan(input.olderThan);
|
|
2946
|
-
const result = await clearCache(input.root, olderThanMs === void 0 ? {} : { olderThanMs });
|
|
2947
|
-
console.log(`removed ${result.removed} cache ${result.removed === 1 ? "entry" : "entries"}`);
|
|
2948
|
-
return result;
|
|
2949
|
-
}
|
|
2950
|
-
function parseOlderThan(value) {
|
|
2951
|
-
if (value === void 0) {
|
|
2952
|
-
return void 0;
|
|
2953
|
-
}
|
|
2954
|
-
const duration = parseDuration(value);
|
|
2955
|
-
if (duration === null || Number.isNaN(duration) || duration < 0) {
|
|
2956
|
-
throw new Error(`Invalid duration for --older-than: "${value}".`);
|
|
2957
|
-
}
|
|
2958
|
-
return duration;
|
|
2959
|
-
}
|
|
4004
|
+
// packages/design-system/src/components/table.ts
|
|
4005
|
+
import { Table } from "console-table-printer";
|
|
2960
4006
|
|
|
2961
|
-
// packages/
|
|
2962
|
-
import
|
|
4007
|
+
// packages/design-system/src/acp/components.ts
|
|
4008
|
+
import chalk7 from "chalk";
|
|
4009
|
+
|
|
4010
|
+
// packages/design-system/src/acp/writer.ts
|
|
4011
|
+
import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
|
|
4012
|
+
var storage = new AsyncLocalStorage2();
|
|
4013
|
+
|
|
4014
|
+
// packages/design-system/src/acp/components.ts
|
|
4015
|
+
var AGENT_PREFIX = `${chalk7.green.bold("\u2713")} agent: `;
|
|
4016
|
+
|
|
4017
|
+
// packages/design-system/src/dashboard/buffer.ts
|
|
4018
|
+
import chalk8 from "chalk";
|
|
4019
|
+
|
|
4020
|
+
// packages/design-system/src/dashboard/terminal.ts
|
|
4021
|
+
import readline from "node:readline";
|
|
4022
|
+
import { PassThrough } from "node:stream";
|
|
4023
|
+
|
|
4024
|
+
// packages/design-system/src/prompts/index.ts
|
|
4025
|
+
import chalk15 from "chalk";
|
|
4026
|
+
import * as clack from "@clack/prompts";
|
|
4027
|
+
|
|
4028
|
+
// packages/design-system/src/prompts/primitives/cancel.ts
|
|
4029
|
+
import chalk9 from "chalk";
|
|
4030
|
+
import { isCancel } from "@clack/prompts";
|
|
4031
|
+
|
|
4032
|
+
// packages/design-system/src/prompts/primitives/intro.ts
|
|
4033
|
+
import chalk10 from "chalk";
|
|
4034
|
+
|
|
4035
|
+
// packages/design-system/src/prompts/primitives/note.ts
|
|
4036
|
+
import chalk11 from "chalk";
|
|
4037
|
+
|
|
4038
|
+
// packages/design-system/src/prompts/primitives/outro.ts
|
|
4039
|
+
import chalk12 from "chalk";
|
|
4040
|
+
|
|
4041
|
+
// packages/design-system/src/prompts/primitives/spinner.ts
|
|
4042
|
+
import chalk14 from "chalk";
|
|
4043
|
+
|
|
4044
|
+
// packages/design-system/src/static/spinner.ts
|
|
4045
|
+
import chalk13 from "chalk";
|
|
4046
|
+
|
|
4047
|
+
// packages/design-system/src/static/menu.ts
|
|
4048
|
+
import chalk16 from "chalk";
|
|
4049
|
+
|
|
4050
|
+
// packages/agent-spawn/src/autonomous.ts
|
|
4051
|
+
var DEFAULT_ACTIVITY_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
4052
|
+
|
|
4053
|
+
// packages/agent-spawn/src/acp/replay.ts
|
|
2963
4054
|
import path20 from "node:path";
|
|
4055
|
+
import { homedir as homedir2 } from "node:os";
|
|
4056
|
+
import { open, readdir as readdir4 } from "node:fs/promises";
|
|
4057
|
+
import { createInterface } from "node:readline";
|
|
4058
|
+
|
|
4059
|
+
// packages/poe-acp-client/src/acp-client.ts
|
|
4060
|
+
import { isAbsolute } from "node:path";
|
|
4061
|
+
|
|
4062
|
+
// packages/poe-acp-client/src/acp-transport.ts
|
|
4063
|
+
import {
|
|
4064
|
+
spawn as spawnChildProcess3
|
|
4065
|
+
} from "node:child_process";
|
|
4066
|
+
|
|
4067
|
+
// packages/poe-acp-client/src/run-report.ts
|
|
4068
|
+
import * as fsPromises2 from "node:fs/promises";
|
|
4069
|
+
import { homedir } from "node:os";
|
|
4070
|
+
import { join } from "node:path";
|
|
4071
|
+
|
|
4072
|
+
// packages/agent-spawn/src/acp/spawn.ts
|
|
4073
|
+
import { spawn as spawnChildProcess4 } from "node:child_process";
|
|
4074
|
+
|
|
4075
|
+
// packages/agent-spawn/src/acp/middlewares/spawn-log.ts
|
|
4076
|
+
import path21 from "node:path";
|
|
4077
|
+
import { homedir as homedir3 } from "node:os";
|
|
4078
|
+
import { mkdir as mkdir5, open as open2 } from "node:fs/promises";
|
|
2964
4079
|
|
|
2965
4080
|
// packages/memory/src/tokens.ts
|
|
2966
4081
|
import * as fs10 from "node:fs/promises";
|
|
2967
|
-
import
|
|
4082
|
+
import path22 from "node:path";
|
|
2968
4083
|
|
|
2969
4084
|
// packages/tokenfill/src/tokenizer.ts
|
|
2970
4085
|
import { get_encoding } from "tiktoken";
|
|
@@ -2973,19 +4088,19 @@ function createTokenizer(options = {}) {
|
|
|
2973
4088
|
const encoding = options.encoding ?? DEFAULT_ENCODING;
|
|
2974
4089
|
const tokenizer = get_encoding(encoding);
|
|
2975
4090
|
const utf8Decoder = new TextDecoder();
|
|
2976
|
-
const encode = (
|
|
4091
|
+
const encode = (text4) => tokenizer.encode(text4);
|
|
2977
4092
|
const decode = (tokens) => {
|
|
2978
4093
|
const tokenArray = tokens instanceof Uint32Array ? tokens : Uint32Array.from(tokens);
|
|
2979
4094
|
return utf8Decoder.decode(tokenizer.decode(tokenArray));
|
|
2980
4095
|
};
|
|
2981
|
-
const count = (
|
|
2982
|
-
const
|
|
4096
|
+
const count = (text4) => encode(text4).length;
|
|
4097
|
+
const truncate2 = (text4, tokenCount) => {
|
|
2983
4098
|
if (tokenCount <= 0) {
|
|
2984
4099
|
return "";
|
|
2985
4100
|
}
|
|
2986
|
-
const tokens = encode(
|
|
4101
|
+
const tokens = encode(text4);
|
|
2987
4102
|
if (tokens.length <= tokenCount) {
|
|
2988
|
-
return
|
|
4103
|
+
return text4;
|
|
2989
4104
|
}
|
|
2990
4105
|
return decode(tokens.slice(0, tokenCount));
|
|
2991
4106
|
};
|
|
@@ -2994,22 +4109,22 @@ function createTokenizer(options = {}) {
|
|
|
2994
4109
|
encode,
|
|
2995
4110
|
decode,
|
|
2996
4111
|
count,
|
|
2997
|
-
truncate,
|
|
4112
|
+
truncate: truncate2,
|
|
2998
4113
|
free: () => tokenizer.free()
|
|
2999
4114
|
};
|
|
3000
4115
|
}
|
|
3001
4116
|
var defaultTokenizer;
|
|
3002
|
-
function countTokens(
|
|
4117
|
+
function countTokens(text4) {
|
|
3003
4118
|
defaultTokenizer ??= createTokenizer();
|
|
3004
|
-
return defaultTokenizer.count(
|
|
4119
|
+
return defaultTokenizer.count(text4);
|
|
3005
4120
|
}
|
|
3006
4121
|
|
|
3007
4122
|
// packages/tokenfill/src/corpus.ts
|
|
3008
4123
|
import { readdirSync, readFileSync } from "node:fs";
|
|
3009
|
-
import { dirname, join } from "node:path";
|
|
4124
|
+
import { dirname, join as join2 } from "node:path";
|
|
3010
4125
|
import { fileURLToPath } from "node:url";
|
|
3011
4126
|
var CORPUS_ARTICLE_SEPARATOR = "\n\n";
|
|
3012
|
-
var corpusDirectoryPath =
|
|
4127
|
+
var corpusDirectoryPath = join2(dirname(fileURLToPath(import.meta.url)), "corpus");
|
|
3013
4128
|
function getCorpusFileNames() {
|
|
3014
4129
|
return readdirSync(corpusDirectoryPath, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".md")).map((entry) => entry.name).sort((left, right) => left.localeCompare(right));
|
|
3015
4130
|
}
|
|
@@ -3018,7 +4133,7 @@ function loadBuiltInCorpusArticles() {
|
|
|
3018
4133
|
if (corpusFileNames.length === 0) {
|
|
3019
4134
|
throw new Error(`No built-in corpus markdown files found in ${corpusDirectoryPath}`);
|
|
3020
4135
|
}
|
|
3021
|
-
return corpusFileNames.map((fileName) => readFileSync(
|
|
4136
|
+
return corpusFileNames.map((fileName) => readFileSync(join2(corpusDirectoryPath, fileName), "utf8").trim());
|
|
3022
4137
|
}
|
|
3023
4138
|
var BUILT_IN_CORPUS_ARTICLES = loadBuiltInCorpusArticles();
|
|
3024
4139
|
|
|
@@ -3048,20 +4163,20 @@ async function computeTokenStats(root) {
|
|
|
3048
4163
|
}
|
|
3049
4164
|
}
|
|
3050
4165
|
}
|
|
3051
|
-
const repoRoot =
|
|
4166
|
+
const repoRoot = path22.resolve(root, "..", "..");
|
|
3052
4167
|
let sourceTokens = 0;
|
|
3053
4168
|
const missingSources = [];
|
|
3054
4169
|
for (const sourcePath of sourcePaths) {
|
|
3055
|
-
const absPath =
|
|
4170
|
+
const absPath = path22.isAbsolute(sourcePath) ? sourcePath : path22.resolve(repoRoot, sourcePath);
|
|
3056
4171
|
try {
|
|
3057
4172
|
const content = await fs10.readFile(absPath, "utf8");
|
|
3058
4173
|
sourceTokens += countTokens(content);
|
|
3059
|
-
} catch (
|
|
3060
|
-
if (isMissing4(
|
|
4174
|
+
} catch (error2) {
|
|
4175
|
+
if (isMissing4(error2)) {
|
|
3061
4176
|
missingSources.push(sourcePath);
|
|
3062
4177
|
continue;
|
|
3063
4178
|
}
|
|
3064
|
-
throw
|
|
4179
|
+
throw error2;
|
|
3065
4180
|
}
|
|
3066
4181
|
}
|
|
3067
4182
|
missingSources.sort((left, right) => left.localeCompare(right));
|
|
@@ -3077,42 +4192,53 @@ async function pathExists3(targetPath) {
|
|
|
3077
4192
|
try {
|
|
3078
4193
|
await fs10.stat(targetPath);
|
|
3079
4194
|
return true;
|
|
3080
|
-
} catch (
|
|
3081
|
-
if (isMissing4(
|
|
4195
|
+
} catch (error2) {
|
|
4196
|
+
if (isMissing4(error2)) {
|
|
3082
4197
|
return false;
|
|
3083
4198
|
}
|
|
3084
|
-
throw
|
|
4199
|
+
throw error2;
|
|
3085
4200
|
}
|
|
3086
4201
|
}
|
|
3087
|
-
function isMissing4(
|
|
3088
|
-
return typeof
|
|
4202
|
+
function isMissing4(error2) {
|
|
4203
|
+
return typeof error2 === "object" && error2 !== null && "code" in error2 && error2.code === "ENOENT";
|
|
3089
4204
|
}
|
|
3090
4205
|
|
|
3091
4206
|
// packages/memory/src/ingest.ts
|
|
3092
4207
|
var INGEST_PROMPT_VERSION = "v1";
|
|
3093
|
-
|
|
4208
|
+
function resolveRunners(overrides) {
|
|
4209
|
+
return {
|
|
4210
|
+
computeIngestKey: overrides?.computeIngestKey ?? computeIngestKey,
|
|
4211
|
+
readCacheEntry: overrides?.readCacheEntry ?? readCacheEntry,
|
|
4212
|
+
writeCacheEntry: overrides?.writeCacheEntry ?? writeCacheEntry,
|
|
4213
|
+
computeTokenStats: overrides?.computeTokenStats ?? computeTokenStats,
|
|
4214
|
+
snapshot: overrides?.snapshot ?? snapshot,
|
|
4215
|
+
reconcile: overrides?.reconcile ?? reconcile
|
|
4216
|
+
};
|
|
4217
|
+
}
|
|
4218
|
+
async function ingest(root, opts, runners) {
|
|
4219
|
+
const resolved = resolveRunners(runners);
|
|
3094
4220
|
const source = await materializeSource(opts.source);
|
|
3095
|
-
const indexMdBytes = await fs11.readFile(
|
|
4221
|
+
const indexMdBytes = await fs11.readFile(path23.join(root, MEMORY_INDEX_RELPATH));
|
|
3096
4222
|
const configOptions = {
|
|
3097
4223
|
fs: fs11,
|
|
3098
|
-
filePath:
|
|
4224
|
+
filePath: path23.join(inferRepoRoot(root), "poe-code.json")
|
|
3099
4225
|
};
|
|
3100
4226
|
const agentId = await resolveAgent(configOptions, opts.agent ?? null) ?? opts.agent ?? "claude-code";
|
|
3101
|
-
const key = computeIngestKey({
|
|
4227
|
+
const key = resolved.computeIngestKey({
|
|
3102
4228
|
sourceBytes: source.bytes,
|
|
3103
4229
|
indexMdBytes,
|
|
3104
4230
|
promptTemplateVersion: INGEST_PROMPT_VERSION,
|
|
3105
4231
|
agentId
|
|
3106
4232
|
});
|
|
3107
4233
|
if (!opts.force && await cacheEnabled(configOptions)) {
|
|
3108
|
-
const hit = await readCacheEntry(root, key);
|
|
4234
|
+
const hit = await resolved.readCacheEntry(root, key);
|
|
3109
4235
|
if (hit !== null) {
|
|
3110
4236
|
return {
|
|
3111
4237
|
diff: { created: [], updated: [], deleted: [] },
|
|
3112
4238
|
exitCode: 0,
|
|
3113
4239
|
durationMs: 0,
|
|
3114
4240
|
cacheHit: true,
|
|
3115
|
-
tokens: await computeTokenStats(root)
|
|
4241
|
+
tokens: await resolved.computeTokenStats(root)
|
|
3116
4242
|
};
|
|
3117
4243
|
}
|
|
3118
4244
|
}
|
|
@@ -3124,35 +4250,34 @@ async function ingest(root, opts) {
|
|
|
3124
4250
|
exitCode: 0,
|
|
3125
4251
|
durationMs: 0,
|
|
3126
4252
|
cacheHit: false,
|
|
3127
|
-
tokens: await computeTokenStats(root)
|
|
4253
|
+
tokens: await resolved.computeTokenStats(root)
|
|
3128
4254
|
};
|
|
3129
4255
|
}
|
|
3130
|
-
const before = await snapshot(root);
|
|
4256
|
+
const before = await resolved.snapshot(root);
|
|
3131
4257
|
let exitCode = 1;
|
|
3132
4258
|
let durationMs = 0;
|
|
3133
4259
|
let timeoutError;
|
|
3134
4260
|
try {
|
|
3135
|
-
const spawnFn = opts.spawnFn;
|
|
3136
4261
|
const result = await runWithTimeout(
|
|
3137
|
-
|
|
4262
|
+
spawn2(agentId, { prompt }),
|
|
3138
4263
|
opts.timeoutMs ?? await configuredTimeout(configOptions)
|
|
3139
4264
|
);
|
|
3140
4265
|
exitCode = result.exitCode;
|
|
3141
|
-
durationMs = result.durationMs;
|
|
3142
|
-
} catch (
|
|
3143
|
-
timeoutError =
|
|
4266
|
+
durationMs = result.durationMs ?? 0;
|
|
4267
|
+
} catch (error2) {
|
|
4268
|
+
timeoutError = error2 instanceof Error ? error2 : new Error(String(error2));
|
|
3144
4269
|
}
|
|
3145
|
-
const
|
|
3146
|
-
const tokens = await computeTokenStats(root);
|
|
4270
|
+
const diff2 = await resolved.reconcile(root, before, "ingest", opts.reason ?? `ingest ${source.label}`);
|
|
4271
|
+
const tokens = await resolved.computeTokenStats(root);
|
|
3147
4272
|
if (timeoutError !== void 0) {
|
|
3148
4273
|
throw timeoutError;
|
|
3149
4274
|
}
|
|
3150
4275
|
if (!opts.noCacheWrite && await cacheEnabled(configOptions) && exitCode === 0) {
|
|
3151
|
-
await writeCacheEntry(root, {
|
|
4276
|
+
await resolved.writeCacheEntry(root, {
|
|
3152
4277
|
key,
|
|
3153
4278
|
ingestedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3154
4279
|
sourceLabel: source.label,
|
|
3155
|
-
diff,
|
|
4280
|
+
diff: diff2,
|
|
3156
4281
|
exitCode,
|
|
3157
4282
|
durationMs,
|
|
3158
4283
|
memoryTokens: tokens.memoryTokens,
|
|
@@ -3161,7 +4286,7 @@ async function ingest(root, opts) {
|
|
|
3161
4286
|
agentId
|
|
3162
4287
|
});
|
|
3163
4288
|
}
|
|
3164
|
-
return { diff, exitCode, durationMs, cacheHit: false, tokens };
|
|
4289
|
+
return { diff: diff2, exitCode, durationMs, cacheHit: false, tokens };
|
|
3165
4290
|
}
|
|
3166
4291
|
function buildIngestPrompt(root, sourceLabel, sourceText) {
|
|
3167
4292
|
return [
|
|
@@ -3186,7 +4311,7 @@ async function materializeSource(source) {
|
|
|
3186
4311
|
throw new Error("URL ingest not implemented yet.");
|
|
3187
4312
|
}
|
|
3188
4313
|
function inferRepoRoot(root) {
|
|
3189
|
-
return
|
|
4314
|
+
return path23.resolve(root, "..", "..");
|
|
3190
4315
|
}
|
|
3191
4316
|
async function runWithTimeout(promise, timeoutMs) {
|
|
3192
4317
|
return await new Promise((resolve2, reject) => {
|
|
@@ -3198,16 +4323,16 @@ async function runWithTimeout(promise, timeoutMs) {
|
|
|
3198
4323
|
clearTimeout(timer);
|
|
3199
4324
|
resolve2(value);
|
|
3200
4325
|
},
|
|
3201
|
-
(
|
|
4326
|
+
(error2) => {
|
|
3202
4327
|
clearTimeout(timer);
|
|
3203
|
-
reject(
|
|
4328
|
+
reject(error2);
|
|
3204
4329
|
}
|
|
3205
4330
|
);
|
|
3206
4331
|
});
|
|
3207
4332
|
}
|
|
3208
4333
|
|
|
3209
4334
|
// packages/tiny-stdio-mcp-server/src/server.ts
|
|
3210
|
-
import * as
|
|
4335
|
+
import * as readline2 from "readline";
|
|
3211
4336
|
|
|
3212
4337
|
// packages/tiny-stdio-mcp-server/src/types.ts
|
|
3213
4338
|
var JSON_RPC_ERROR_CODES = {
|
|
@@ -3218,8 +4343,8 @@ var JSON_RPC_ERROR_CODES = {
|
|
|
3218
4343
|
INTERNAL_ERROR: -32603
|
|
3219
4344
|
};
|
|
3220
4345
|
var ToolError = class extends Error {
|
|
3221
|
-
constructor(code,
|
|
3222
|
-
super(
|
|
4346
|
+
constructor(code, message2) {
|
|
4347
|
+
super(message2);
|
|
3223
4348
|
this.code = code;
|
|
3224
4349
|
this.name = "ToolError";
|
|
3225
4350
|
}
|
|
@@ -3313,11 +4438,11 @@ function formatSuccessResponse(id, result) {
|
|
|
3313
4438
|
};
|
|
3314
4439
|
return JSON.stringify(response);
|
|
3315
4440
|
}
|
|
3316
|
-
function formatErrorResponse(id,
|
|
4441
|
+
function formatErrorResponse(id, error2) {
|
|
3317
4442
|
const response = {
|
|
3318
4443
|
jsonrpc: "2.0",
|
|
3319
4444
|
id,
|
|
3320
|
-
error
|
|
4445
|
+
error: error2
|
|
3321
4446
|
};
|
|
3322
4447
|
return JSON.stringify(response);
|
|
3323
4448
|
}
|
|
@@ -3529,8 +4654,8 @@ var File = class _File {
|
|
|
3529
4654
|
const isText = isTextMimeType(mimeType);
|
|
3530
4655
|
return new _File(data, mimeType, isText);
|
|
3531
4656
|
}
|
|
3532
|
-
static fromText(
|
|
3533
|
-
return new _File(
|
|
4657
|
+
static fromText(text4, mimeType = "text/plain") {
|
|
4658
|
+
return new _File(text4, mimeType, true);
|
|
3534
4659
|
}
|
|
3535
4660
|
static fromBase64(base64, mimeType) {
|
|
3536
4661
|
const data = Buffer.from(base64, "base64");
|
|
@@ -3540,18 +4665,18 @@ var File = class _File {
|
|
|
3540
4665
|
toContentBlock() {
|
|
3541
4666
|
const uri = this.name ? `file:///${this.name}` : "file:///data";
|
|
3542
4667
|
if (this.isText) {
|
|
3543
|
-
let
|
|
4668
|
+
let text4;
|
|
3544
4669
|
if (typeof this.data === "string") {
|
|
3545
|
-
|
|
4670
|
+
text4 = this.data;
|
|
3546
4671
|
} else {
|
|
3547
|
-
|
|
4672
|
+
text4 = new TextDecoder("utf-8").decode(this.data);
|
|
3548
4673
|
}
|
|
3549
4674
|
return {
|
|
3550
4675
|
type: "resource",
|
|
3551
4676
|
resource: {
|
|
3552
4677
|
uri,
|
|
3553
4678
|
mimeType: this.mimeType,
|
|
3554
|
-
text
|
|
4679
|
+
text: text4
|
|
3555
4680
|
}
|
|
3556
4681
|
};
|
|
3557
4682
|
} else {
|
|
@@ -3682,7 +4807,7 @@ function createServer(options) {
|
|
|
3682
4807
|
}
|
|
3683
4808
|
try {
|
|
3684
4809
|
const handlerResult = await tool.handler(toolArgs);
|
|
3685
|
-
const result = { content: toContentBlocks(handlerResult) };
|
|
4810
|
+
const result = isCallToolResult(handlerResult) ? handlerResult : { content: toContentBlocks(handlerResult) };
|
|
3686
4811
|
return { result };
|
|
3687
4812
|
} catch (err) {
|
|
3688
4813
|
if (err instanceof ToolError) {
|
|
@@ -3715,7 +4840,7 @@ function createServer(options) {
|
|
|
3715
4840
|
return;
|
|
3716
4841
|
}
|
|
3717
4842
|
const { request, isNotification } = parsed;
|
|
3718
|
-
const { result, error } = await server.handleMessage(
|
|
4843
|
+
const { result, error: error2 } = await server.handleMessage(
|
|
3719
4844
|
request.method,
|
|
3720
4845
|
request.params
|
|
3721
4846
|
);
|
|
@@ -3723,8 +4848,8 @@ function createServer(options) {
|
|
|
3723
4848
|
return;
|
|
3724
4849
|
}
|
|
3725
4850
|
const requestWithId = request;
|
|
3726
|
-
if (
|
|
3727
|
-
write2(formatErrorResponse(requestWithId.id,
|
|
4851
|
+
if (error2) {
|
|
4852
|
+
write2(formatErrorResponse(requestWithId.id, error2) + "\n");
|
|
3728
4853
|
} else if (result !== void 0) {
|
|
3729
4854
|
write2(formatSuccessResponse(requestWithId.id, result) + "\n");
|
|
3730
4855
|
}
|
|
@@ -3775,7 +4900,7 @@ function createServer(options) {
|
|
|
3775
4900
|
transport.writable.write(`${JSON.stringify(notification)}
|
|
3776
4901
|
`);
|
|
3777
4902
|
});
|
|
3778
|
-
const rl =
|
|
4903
|
+
const rl = readline2.createInterface({
|
|
3779
4904
|
input: transport.readable,
|
|
3780
4905
|
crlfDelay: Infinity
|
|
3781
4906
|
});
|
|
@@ -3793,24 +4918,24 @@ function createServer(options) {
|
|
|
3793
4918
|
const unsubscribe = server.onNotification((notification) => {
|
|
3794
4919
|
void transport.send(notification);
|
|
3795
4920
|
});
|
|
3796
|
-
transport.onmessage = async (
|
|
3797
|
-
if (!("method" in
|
|
4921
|
+
transport.onmessage = async (message2) => {
|
|
4922
|
+
if (!("method" in message2)) {
|
|
3798
4923
|
return;
|
|
3799
4924
|
}
|
|
3800
|
-
if (!("id" in
|
|
3801
|
-
await server.handleMessage(
|
|
4925
|
+
if (!("id" in message2) || message2.id === void 0) {
|
|
4926
|
+
await server.handleMessage(message2.method, message2.params);
|
|
3802
4927
|
return;
|
|
3803
4928
|
}
|
|
3804
|
-
const request =
|
|
3805
|
-
const { result, error } = await server.handleMessage(
|
|
4929
|
+
const request = message2;
|
|
4930
|
+
const { result, error: error2 } = await server.handleMessage(
|
|
3806
4931
|
request.method,
|
|
3807
4932
|
request.params
|
|
3808
4933
|
);
|
|
3809
|
-
if (
|
|
4934
|
+
if (error2) {
|
|
3810
4935
|
const response = {
|
|
3811
4936
|
jsonrpc: "2.0",
|
|
3812
4937
|
id: request.id,
|
|
3813
|
-
error
|
|
4938
|
+
error: error2
|
|
3814
4939
|
};
|
|
3815
4940
|
await transport.send(response);
|
|
3816
4941
|
} else if (result !== void 0) {
|
|
@@ -3832,6 +4957,12 @@ function createServer(options) {
|
|
|
3832
4957
|
};
|
|
3833
4958
|
return server;
|
|
3834
4959
|
}
|
|
4960
|
+
function isCallToolResult(value) {
|
|
4961
|
+
if (typeof value !== "object" || value === null || !("content" in value)) {
|
|
4962
|
+
return false;
|
|
4963
|
+
}
|
|
4964
|
+
return Array.isArray(value.content);
|
|
4965
|
+
}
|
|
3835
4966
|
|
|
3836
4967
|
// packages/tiny-stdio-mcp-server/src/schema.ts
|
|
3837
4968
|
function defineSchema(definition) {
|
|
@@ -3854,13 +4985,13 @@ function defineSchema(definition) {
|
|
|
3854
4985
|
}
|
|
3855
4986
|
|
|
3856
4987
|
// packages/memory/src/mcp.ts
|
|
3857
|
-
async function startMemoryMcpServer(opts) {
|
|
4988
|
+
async function startMemoryMcpServer(handle, opts) {
|
|
3858
4989
|
const server = createServer({
|
|
3859
4990
|
name: "poe-code-memory",
|
|
3860
4991
|
version: "0.0.1"
|
|
3861
4992
|
});
|
|
3862
4993
|
server.tool("list_pages", "List memory pages.", defineSchema({}), async () => ({
|
|
3863
|
-
pages: (await listPages(
|
|
4994
|
+
pages: (await handle.listPages()).map((page) => ({
|
|
3864
4995
|
rel_path: page.relPath,
|
|
3865
4996
|
description: page.frontmatter.description ?? ""
|
|
3866
4997
|
}))
|
|
@@ -3870,7 +5001,7 @@ async function startMemoryMcpServer(opts) {
|
|
|
3870
5001
|
"Read a memory page.",
|
|
3871
5002
|
defineSchema({ rel_path: { type: "string" } }),
|
|
3872
5003
|
async ({ rel_path }) => {
|
|
3873
|
-
const page = await readPage(
|
|
5004
|
+
const page = await handle.readPage(rel_path);
|
|
3874
5005
|
return {
|
|
3875
5006
|
rel_path: page.relPath,
|
|
3876
5007
|
frontmatter: page.frontmatter,
|
|
@@ -3887,11 +5018,11 @@ async function startMemoryMcpServer(opts) {
|
|
|
3887
5018
|
limit: { type: "number", optional: true }
|
|
3888
5019
|
}),
|
|
3889
5020
|
async ({ query, limit }) => {
|
|
3890
|
-
const hits = await searchMemory(
|
|
5021
|
+
const hits = await handle.searchMemory(query);
|
|
3891
5022
|
return { hits: typeof limit === "number" ? hits.slice(0, limit) : hits };
|
|
3892
5023
|
}
|
|
3893
5024
|
);
|
|
3894
|
-
server.tool("status", "Show memory status.", defineSchema({}), async () => statusOf(
|
|
5025
|
+
server.tool("status", "Show memory status.", defineSchema({}), async () => handle.statusOf());
|
|
3895
5026
|
if (opts.allowWrites) {
|
|
3896
5027
|
server.tool(
|
|
3897
5028
|
"append_to_page",
|
|
@@ -3902,7 +5033,7 @@ async function startMemoryMcpServer(opts) {
|
|
|
3902
5033
|
reason: { type: "string" }
|
|
3903
5034
|
}),
|
|
3904
5035
|
async ({ rel_path, content, reason }) => ({
|
|
3905
|
-
diff: await appendToPage(
|
|
5036
|
+
diff: await handle.appendToPage(rel_path, content, { reason })
|
|
3906
5037
|
})
|
|
3907
5038
|
);
|
|
3908
5039
|
}
|
|
@@ -3930,148 +5061,7 @@ function printMcpConfig() {
|
|
|
3930
5061
|
|
|
3931
5062
|
// packages/agent-skill-config/src/configs.ts
|
|
3932
5063
|
import os from "node:os";
|
|
3933
|
-
import
|
|
3934
|
-
|
|
3935
|
-
// packages/agent-defs/src/agents/claude-code.ts
|
|
3936
|
-
var claudeCodeAgent = {
|
|
3937
|
-
id: "claude-code",
|
|
3938
|
-
name: "claude-code",
|
|
3939
|
-
label: "Claude Code",
|
|
3940
|
-
summary: "Configure Claude Code to route through Poe.",
|
|
3941
|
-
aliases: ["claude"],
|
|
3942
|
-
binaryName: "claude",
|
|
3943
|
-
configPath: "~/.claude/settings.json",
|
|
3944
|
-
branding: {
|
|
3945
|
-
colors: {
|
|
3946
|
-
dark: "#C15F3C",
|
|
3947
|
-
light: "#C15F3C"
|
|
3948
|
-
}
|
|
3949
|
-
}
|
|
3950
|
-
};
|
|
3951
|
-
|
|
3952
|
-
// packages/agent-defs/src/agents/claude-desktop.ts
|
|
3953
|
-
var claudeDesktopAgent = {
|
|
3954
|
-
id: "claude-desktop",
|
|
3955
|
-
name: "claude-desktop",
|
|
3956
|
-
label: "Claude Desktop",
|
|
3957
|
-
summary: "Anthropic's official desktop application for Claude",
|
|
3958
|
-
configPath: "~/.claude/settings.json",
|
|
3959
|
-
branding: {
|
|
3960
|
-
colors: {
|
|
3961
|
-
dark: "#D97757",
|
|
3962
|
-
light: "#D97757"
|
|
3963
|
-
}
|
|
3964
|
-
}
|
|
3965
|
-
};
|
|
3966
|
-
|
|
3967
|
-
// packages/agent-defs/src/agents/codex.ts
|
|
3968
|
-
var codexAgent = {
|
|
3969
|
-
id: "codex",
|
|
3970
|
-
name: "codex",
|
|
3971
|
-
label: "Codex",
|
|
3972
|
-
summary: "Configure Codex to use Poe as the model provider.",
|
|
3973
|
-
binaryName: "codex",
|
|
3974
|
-
configPath: "~/.codex/config.toml",
|
|
3975
|
-
branding: {
|
|
3976
|
-
colors: {
|
|
3977
|
-
dark: "#D5D9DF",
|
|
3978
|
-
light: "#7A7F86"
|
|
3979
|
-
}
|
|
3980
|
-
}
|
|
3981
|
-
};
|
|
3982
|
-
|
|
3983
|
-
// packages/agent-defs/src/agents/opencode.ts
|
|
3984
|
-
var openCodeAgent = {
|
|
3985
|
-
id: "opencode",
|
|
3986
|
-
name: "opencode",
|
|
3987
|
-
label: "OpenCode CLI",
|
|
3988
|
-
summary: "Configure OpenCode CLI to use the Poe API.",
|
|
3989
|
-
binaryName: "opencode",
|
|
3990
|
-
configPath: "~/.config/opencode/config.json",
|
|
3991
|
-
branding: {
|
|
3992
|
-
colors: {
|
|
3993
|
-
dark: "#4A4F55",
|
|
3994
|
-
light: "#2F3338"
|
|
3995
|
-
}
|
|
3996
|
-
}
|
|
3997
|
-
};
|
|
3998
|
-
|
|
3999
|
-
// packages/agent-defs/src/agents/kimi.ts
|
|
4000
|
-
var kimiAgent = {
|
|
4001
|
-
id: "kimi",
|
|
4002
|
-
name: "kimi",
|
|
4003
|
-
label: "Kimi",
|
|
4004
|
-
summary: "Configure Kimi CLI to use Poe API",
|
|
4005
|
-
aliases: ["kimi-cli"],
|
|
4006
|
-
binaryName: "kimi",
|
|
4007
|
-
configPath: "~/.kimi/config.toml",
|
|
4008
|
-
branding: {
|
|
4009
|
-
colors: {
|
|
4010
|
-
dark: "#7B68EE",
|
|
4011
|
-
light: "#6A5ACD"
|
|
4012
|
-
}
|
|
4013
|
-
}
|
|
4014
|
-
};
|
|
4015
|
-
|
|
4016
|
-
// packages/agent-defs/src/agents/goose.ts
|
|
4017
|
-
var gooseAgent = {
|
|
4018
|
-
id: "goose",
|
|
4019
|
-
name: "goose",
|
|
4020
|
-
label: "Goose",
|
|
4021
|
-
summary: "Block's open-source AI agent with ACP support.",
|
|
4022
|
-
binaryName: "goose",
|
|
4023
|
-
configPath: "~/.config/goose/config.yaml",
|
|
4024
|
-
branding: {
|
|
4025
|
-
colors: {
|
|
4026
|
-
dark: "#FF6B35",
|
|
4027
|
-
light: "#E85D26"
|
|
4028
|
-
}
|
|
4029
|
-
}
|
|
4030
|
-
};
|
|
4031
|
-
|
|
4032
|
-
// packages/agent-defs/src/agents/poe-agent.ts
|
|
4033
|
-
var poeAgentAgent = {
|
|
4034
|
-
id: "poe-agent",
|
|
4035
|
-
name: "poe-agent",
|
|
4036
|
-
label: "Poe Agent",
|
|
4037
|
-
summary: "Run one-shot prompts with the built-in Poe agent runtime.",
|
|
4038
|
-
configPath: "~/.poe-code/config.json",
|
|
4039
|
-
branding: {
|
|
4040
|
-
colors: {
|
|
4041
|
-
dark: "#A465F7",
|
|
4042
|
-
light: "#7A3FD3"
|
|
4043
|
-
}
|
|
4044
|
-
}
|
|
4045
|
-
};
|
|
4046
|
-
|
|
4047
|
-
// packages/agent-defs/src/registry.ts
|
|
4048
|
-
var allAgents = [
|
|
4049
|
-
claudeCodeAgent,
|
|
4050
|
-
claudeDesktopAgent,
|
|
4051
|
-
codexAgent,
|
|
4052
|
-
openCodeAgent,
|
|
4053
|
-
kimiAgent,
|
|
4054
|
-
gooseAgent,
|
|
4055
|
-
poeAgentAgent
|
|
4056
|
-
];
|
|
4057
|
-
var lookup = /* @__PURE__ */ new Map();
|
|
4058
|
-
for (const agent of allAgents) {
|
|
4059
|
-
const values = [agent.id, agent.name, ...agent.aliases ?? []];
|
|
4060
|
-
for (const value of values) {
|
|
4061
|
-
const normalized = value.toLowerCase();
|
|
4062
|
-
if (!lookup.has(normalized)) {
|
|
4063
|
-
lookup.set(normalized, agent.id);
|
|
4064
|
-
}
|
|
4065
|
-
}
|
|
4066
|
-
}
|
|
4067
|
-
function resolveAgentId(input) {
|
|
4068
|
-
if (!input) {
|
|
4069
|
-
return void 0;
|
|
4070
|
-
}
|
|
4071
|
-
return lookup.get(input.toLowerCase());
|
|
4072
|
-
}
|
|
4073
|
-
|
|
4074
|
-
// packages/agent-skill-config/src/configs.ts
|
|
5064
|
+
import path24 from "node:path";
|
|
4075
5065
|
var agentSkillConfigs = {
|
|
4076
5066
|
"claude-code": {
|
|
4077
5067
|
globalSkillDir: "~/.claude/skills",
|
|
@@ -4105,7 +5095,7 @@ function resolveAgentSupport(input, registry = agentSkillConfigs) {
|
|
|
4105
5095
|
|
|
4106
5096
|
// packages/agent-skill-config/src/templates.ts
|
|
4107
5097
|
import { readFile as readFile11, stat as stat5 } from "node:fs/promises";
|
|
4108
|
-
import
|
|
5098
|
+
import path25 from "node:path";
|
|
4109
5099
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
4110
5100
|
|
|
4111
5101
|
// packages/agent-skill-config/src/apply.ts
|
|
@@ -4238,7 +5228,7 @@ function resolveConfigPath2(config, platform) {
|
|
|
4238
5228
|
}
|
|
4239
5229
|
|
|
4240
5230
|
// packages/agent-mcp-config/src/apply.ts
|
|
4241
|
-
import
|
|
5231
|
+
import path26 from "node:path";
|
|
4242
5232
|
import { parse as parseYaml3, stringify as stringifyYaml2 } from "yaml";
|
|
4243
5233
|
|
|
4244
5234
|
// packages/agent-mcp-config/src/shapes.ts
|
|
@@ -4330,7 +5320,7 @@ function getShapeTransformer(shape) {
|
|
|
4330
5320
|
|
|
4331
5321
|
// packages/agent-mcp-config/src/apply.ts
|
|
4332
5322
|
function getConfigDirectory(configPath) {
|
|
4333
|
-
return
|
|
5323
|
+
return path26.dirname(configPath);
|
|
4334
5324
|
}
|
|
4335
5325
|
var UnsupportedAgentError2 = class extends Error {
|
|
4336
5326
|
constructor(agentId) {
|
|
@@ -4356,9 +5346,9 @@ function expandHomePath(configPath, homeDir) {
|
|
|
4356
5346
|
return homeDir;
|
|
4357
5347
|
}
|
|
4358
5348
|
if (configPath.startsWith("~/")) {
|
|
4359
|
-
return
|
|
5349
|
+
return path26.join(homeDir, configPath.slice(2));
|
|
4360
5350
|
}
|
|
4361
|
-
return
|
|
5351
|
+
return path26.join(homeDir, configPath.slice(1));
|
|
4362
5352
|
}
|
|
4363
5353
|
function parseYamlDocument(content) {
|
|
4364
5354
|
if (content.trim() === "") {
|
|
@@ -4391,7 +5381,7 @@ async function writeYamlConfig(configPath, document, options) {
|
|
|
4391
5381
|
return;
|
|
4392
5382
|
}
|
|
4393
5383
|
const absolutePath = expandHomePath(configPath, options.homeDir);
|
|
4394
|
-
const configDir =
|
|
5384
|
+
const configDir = path26.dirname(absolutePath);
|
|
4395
5385
|
await options.fs.mkdir(configDir, { recursive: true });
|
|
4396
5386
|
await options.fs.writeFile(absolutePath, serializeYamlDocument(document), {
|
|
4397
5387
|
encoding: "utf8"
|
|
@@ -4569,7 +5559,7 @@ async function installMemory(options) {
|
|
|
4569
5559
|
|
|
4570
5560
|
// packages/memory/src/query.ts
|
|
4571
5561
|
import * as fs12 from "node:fs/promises";
|
|
4572
|
-
import
|
|
5562
|
+
import path27 from "node:path";
|
|
4573
5563
|
async function queryMemory(root, options) {
|
|
4574
5564
|
const pages = await listPages(root);
|
|
4575
5565
|
if (pages.length === 0) {
|
|
@@ -4583,18 +5573,11 @@ async function queryMemory(root, options) {
|
|
|
4583
5573
|
}
|
|
4584
5574
|
const configOptions = {
|
|
4585
5575
|
fs: fs12,
|
|
4586
|
-
filePath:
|
|
5576
|
+
filePath: path27.join(inferRepoRoot2(root), "poe-code.json")
|
|
4587
5577
|
};
|
|
4588
5578
|
const agentId = await resolveAgent(configOptions, options.agent ?? null) ?? options.agent ?? "claude-code";
|
|
4589
5579
|
const context = await selectQueryContext(root, options.question, options.budget);
|
|
4590
|
-
const
|
|
4591
|
-
const result = await spawnFn?.(agentId, context.prompt) ?? {
|
|
4592
|
-
answer: "",
|
|
4593
|
-
citations: [],
|
|
4594
|
-
tokensUsed: context.tokensUsed,
|
|
4595
|
-
budget: options.budget,
|
|
4596
|
-
exitCode: 0
|
|
4597
|
-
};
|
|
5580
|
+
const result = await spawn2(agentId, { prompt: context.prompt });
|
|
4598
5581
|
return {
|
|
4599
5582
|
answer: result.answer,
|
|
4600
5583
|
citations: result.citations,
|
|
@@ -4605,7 +5588,7 @@ async function queryMemory(root, options) {
|
|
|
4605
5588
|
}
|
|
4606
5589
|
async function selectQueryContext(root, question, budget) {
|
|
4607
5590
|
const [indexText, pages] = await Promise.all([
|
|
4608
|
-
fs12.readFile(
|
|
5591
|
+
fs12.readFile(path27.join(root, MEMORY_INDEX_RELPATH), "utf8"),
|
|
4609
5592
|
listPages(root)
|
|
4610
5593
|
]);
|
|
4611
5594
|
const indexTokens = countTokens(indexText);
|
|
@@ -4635,8 +5618,8 @@ async function selectQueryContext(root, question, budget) {
|
|
|
4635
5618
|
function rankPagesForQuery(pages, question) {
|
|
4636
5619
|
const terms = tokenize(question);
|
|
4637
5620
|
const documents = pages.map((page) => {
|
|
4638
|
-
const
|
|
4639
|
-
const tokens = tokenize(
|
|
5621
|
+
const text4 = [page.relPath, page.frontmatter.name ?? "", page.frontmatter.description ?? "", page.body].join("\n").toLowerCase();
|
|
5622
|
+
const tokens = tokenize(text4);
|
|
4640
5623
|
const counts = /* @__PURE__ */ new Map();
|
|
4641
5624
|
for (const token of tokens) {
|
|
4642
5625
|
counts.set(token, (counts.get(token) ?? 0) + 1);
|
|
@@ -4680,14 +5663,16 @@ function buildQueryPrompt(question, indexText, pages) {
|
|
|
4680
5663
|
function renderPageContext(page) {
|
|
4681
5664
|
return [`FILE: ${page.relPath}`, page.body].join("\n");
|
|
4682
5665
|
}
|
|
4683
|
-
function tokenize(
|
|
4684
|
-
return
|
|
5666
|
+
function tokenize(text4) {
|
|
5667
|
+
return text4.toLowerCase().split(/[^a-z0-9]+/).filter((token) => token.length > 0);
|
|
4685
5668
|
}
|
|
4686
5669
|
function inferRepoRoot2(root) {
|
|
4687
|
-
return
|
|
5670
|
+
return path27.resolve(root, "..", "..");
|
|
4688
5671
|
}
|
|
4689
5672
|
|
|
4690
5673
|
// packages/memory/src/explain.ts
|
|
5674
|
+
import * as fs13 from "node:fs/promises";
|
|
5675
|
+
import path28 from "node:path";
|
|
4691
5676
|
async function explainPage(root, options) {
|
|
4692
5677
|
const targetPage = await readPageIfPresent(root, options.relPath);
|
|
4693
5678
|
if (targetPage === void 0) {
|
|
@@ -4708,18 +5693,18 @@ async function explainPage(root, options) {
|
|
|
4708
5693
|
if (tokensUsed > options.budget) {
|
|
4709
5694
|
throw new Error(`budget too small; needs at least ${tokensUsed} tokens`);
|
|
4710
5695
|
}
|
|
4711
|
-
const
|
|
4712
|
-
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
const [agent] = args;
|
|
4718
|
-
return spawnFn(agent, prompt);
|
|
4719
|
-
}
|
|
4720
|
-
});
|
|
5696
|
+
const configOptions = {
|
|
5697
|
+
fs: fs13,
|
|
5698
|
+
filePath: path28.join(inferRepoRoot3(root), "poe-code.json")
|
|
5699
|
+
};
|
|
5700
|
+
const agentId = await resolveAgent(configOptions, options.agent ?? null) ?? options.agent ?? "claude-code";
|
|
5701
|
+
const response = await spawn2(agentId, { prompt });
|
|
4721
5702
|
return {
|
|
4722
|
-
|
|
5703
|
+
answer: response.answer,
|
|
5704
|
+
citations: response.citations,
|
|
5705
|
+
tokensUsed: response.tokensUsed,
|
|
5706
|
+
budget: options.budget,
|
|
5707
|
+
exitCode: response.exitCode,
|
|
4723
5708
|
inboundPages: relatedPages.filter((page) => page.relPath !== targetPage.relPath).filter((page) => (page.frontmatter.sources ?? []).some((source) => source.path === targetPage.relPath)).map((page) => page.relPath),
|
|
4724
5709
|
outboundSources: targetPage.frontmatter.sources ?? []
|
|
4725
5710
|
};
|
|
@@ -4751,23 +5736,59 @@ function buildExplainPrompt(targetRelPath, pages) {
|
|
|
4751
5736
|
async function readPageIfPresent(root, relPath) {
|
|
4752
5737
|
try {
|
|
4753
5738
|
return await readPage(root, relPath);
|
|
4754
|
-
} catch (
|
|
4755
|
-
if (typeof
|
|
5739
|
+
} catch (error2) {
|
|
5740
|
+
if (typeof error2 === "object" && error2 !== null && "code" in error2 && error2.code === "ENOENT") {
|
|
4756
5741
|
return void 0;
|
|
4757
5742
|
}
|
|
4758
|
-
throw
|
|
5743
|
+
throw error2;
|
|
4759
5744
|
}
|
|
4760
5745
|
}
|
|
5746
|
+
function inferRepoRoot3(root) {
|
|
5747
|
+
return path28.resolve(root, "..", "..");
|
|
5748
|
+
}
|
|
4761
5749
|
|
|
4762
5750
|
// packages/memory/src/explain.cli.ts
|
|
4763
5751
|
async function runMemoryExplain(input) {
|
|
4764
5752
|
return explainPage(input.root, {
|
|
4765
5753
|
relPath: input.relPath,
|
|
4766
5754
|
budget: input.budget,
|
|
4767
|
-
agent: input.agent
|
|
4768
|
-
spawnFn: input.spawnFn
|
|
5755
|
+
agent: input.agent
|
|
4769
5756
|
});
|
|
4770
5757
|
}
|
|
5758
|
+
|
|
5759
|
+
// packages/memory/src/handle.ts
|
|
5760
|
+
import path29 from "node:path";
|
|
5761
|
+
function openMemory(opts) {
|
|
5762
|
+
if (!path29.isAbsolute(opts.root)) {
|
|
5763
|
+
throw new Error(`openMemory: root must be absolute, got ${opts.root}`);
|
|
5764
|
+
}
|
|
5765
|
+
const root = opts.root;
|
|
5766
|
+
const defaultAgent = opts.agent;
|
|
5767
|
+
return {
|
|
5768
|
+
root,
|
|
5769
|
+
listPages: async () => await listPages(root),
|
|
5770
|
+
readPage: async (relPath) => await readPage(root, relPath),
|
|
5771
|
+
searchMemory: async (query) => await searchMemory(root, query),
|
|
5772
|
+
statusOf: async () => await statusOf(root),
|
|
5773
|
+
computeTokenStats: async () => await computeTokenStats(root),
|
|
5774
|
+
explainPage: async (options) => await explainPage(root, withDefaultAgent(options, defaultAgent)),
|
|
5775
|
+
writePage: async (relPath, body, options) => await writePage(root, relPath, body, options),
|
|
5776
|
+
appendToPage: async (relPath, content, options) => await appendToPage(root, relPath, content, options),
|
|
5777
|
+
clearMemory: async () => await clearMemory(root),
|
|
5778
|
+
query: async (options) => await queryMemory(root, withDefaultAgent(options, defaultAgent)),
|
|
5779
|
+
ingest: async (options) => await ingest(root, withDefaultAgent(options, defaultAgent)),
|
|
5780
|
+
auditClaims: async ({ repoRoot, ...options }) => await auditClaims(root, repoRoot, options)
|
|
5781
|
+
};
|
|
5782
|
+
}
|
|
5783
|
+
function withDefaultAgent(options, agent) {
|
|
5784
|
+
if (options.agent !== void 0 || agent === void 0) {
|
|
5785
|
+
return options;
|
|
5786
|
+
}
|
|
5787
|
+
return {
|
|
5788
|
+
...options,
|
|
5789
|
+
agent
|
|
5790
|
+
};
|
|
5791
|
+
}
|
|
4771
5792
|
export {
|
|
4772
5793
|
INGEST_PROMPT_VERSION,
|
|
4773
5794
|
MEMORY_ROOT_ENV_VAR,
|
|
@@ -4783,6 +5804,7 @@ export {
|
|
|
4783
5804
|
initMemory,
|
|
4784
5805
|
installMemory,
|
|
4785
5806
|
listPages,
|
|
5807
|
+
openMemory,
|
|
4786
5808
|
parseClaims,
|
|
4787
5809
|
printMcpConfig,
|
|
4788
5810
|
queryMemory,
|