poe-code 3.0.101 → 3.0.103
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/ralph.d.ts +3 -0
- package/dist/cli/commands/ralph.js +203 -0
- package/dist/cli/commands/ralph.js.map +1 -0
- package/dist/cli/container.js +2 -0
- package/dist/cli/container.js.map +1 -1
- package/dist/cli/environment.d.ts +0 -1
- package/dist/cli/environment.js +1 -3
- package/dist/cli/environment.js.map +1 -1
- package/dist/cli/options.d.ts +1 -2
- package/dist/cli/options.js +6 -44
- package/dist/cli/options.js.map +1 -1
- package/dist/cli/program.js +7 -5
- package/dist/cli/program.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1191 -546
- package/dist/index.js.map +4 -4
- package/dist/sdk/container.js +3 -1
- package/dist/sdk/container.js.map +1 -1
- package/dist/sdk/ralph.d.ts +3 -0
- package/dist/sdk/ralph.js +20 -0
- package/dist/sdk/ralph.js.map +1 -0
- package/dist/services/config.js +84 -71
- package/dist/services/config.js.map +1 -1
- package/package.json +3 -1
package/dist/index.js
CHANGED
|
@@ -714,16 +714,16 @@ function getConfigFormat(pathOrFormat) {
|
|
|
714
714
|
}
|
|
715
715
|
return formatRegistry[formatName];
|
|
716
716
|
}
|
|
717
|
-
function detectFormat(
|
|
718
|
-
const ext = getExtension(
|
|
717
|
+
function detectFormat(path27) {
|
|
718
|
+
const ext = getExtension(path27);
|
|
719
719
|
return extensionMap[ext];
|
|
720
720
|
}
|
|
721
|
-
function getExtension(
|
|
722
|
-
const lastDot =
|
|
721
|
+
function getExtension(path27) {
|
|
722
|
+
const lastDot = path27.lastIndexOf(".");
|
|
723
723
|
if (lastDot === -1) {
|
|
724
724
|
return "";
|
|
725
725
|
}
|
|
726
|
-
return
|
|
726
|
+
return path27.slice(lastDot).toLowerCase();
|
|
727
727
|
}
|
|
728
728
|
var formatRegistry, extensionMap;
|
|
729
729
|
var init_formats = __esm({
|
|
@@ -1054,8 +1054,8 @@ async function applyChmod(mutation, context, options) {
|
|
|
1054
1054
|
};
|
|
1055
1055
|
}
|
|
1056
1056
|
try {
|
|
1057
|
-
const
|
|
1058
|
-
const currentMode = typeof
|
|
1057
|
+
const stat8 = await context.fs.stat(targetPath);
|
|
1058
|
+
const currentMode = typeof stat8.mode === "number" ? stat8.mode & 511 : null;
|
|
1059
1059
|
if (currentMode === mutation.mode) {
|
|
1060
1060
|
return {
|
|
1061
1061
|
outcome: { changed: false, effect: "none", detail: "noop" },
|
|
@@ -1450,38 +1450,38 @@ import { createTwoFilesPatch } from "diff";
|
|
|
1450
1450
|
import chalk from "chalk";
|
|
1451
1451
|
function createDryRunFileSystem(base, recorder) {
|
|
1452
1452
|
const proxy = {
|
|
1453
|
-
async readFile(
|
|
1453
|
+
async readFile(path27, encoding) {
|
|
1454
1454
|
if (encoding) {
|
|
1455
|
-
return base.readFile(
|
|
1455
|
+
return base.readFile(path27, encoding);
|
|
1456
1456
|
}
|
|
1457
|
-
return base.readFile(
|
|
1457
|
+
return base.readFile(path27);
|
|
1458
1458
|
},
|
|
1459
|
-
async writeFile(
|
|
1460
|
-
const previousContent = await tryReadText(base,
|
|
1459
|
+
async writeFile(path27, data, options) {
|
|
1460
|
+
const previousContent = await tryReadText(base, path27);
|
|
1461
1461
|
const nextContent = formatData(data, options?.encoding);
|
|
1462
1462
|
recorder.record({
|
|
1463
1463
|
type: "writeFile",
|
|
1464
|
-
path:
|
|
1464
|
+
path: path27,
|
|
1465
1465
|
nextContent,
|
|
1466
1466
|
previousContent
|
|
1467
1467
|
});
|
|
1468
1468
|
},
|
|
1469
|
-
async mkdir(
|
|
1470
|
-
recorder.record({ type: "mkdir", path:
|
|
1469
|
+
async mkdir(path27, options) {
|
|
1470
|
+
recorder.record({ type: "mkdir", path: path27, options });
|
|
1471
1471
|
},
|
|
1472
|
-
async stat(
|
|
1473
|
-
return base.stat(
|
|
1472
|
+
async stat(path27) {
|
|
1473
|
+
return base.stat(path27);
|
|
1474
1474
|
},
|
|
1475
|
-
async unlink(
|
|
1476
|
-
recorder.record({ type: "unlink", path:
|
|
1475
|
+
async unlink(path27) {
|
|
1476
|
+
recorder.record({ type: "unlink", path: path27 });
|
|
1477
1477
|
},
|
|
1478
|
-
async readdir(
|
|
1479
|
-
return base.readdir(
|
|
1478
|
+
async readdir(path27) {
|
|
1479
|
+
return base.readdir(path27);
|
|
1480
1480
|
}
|
|
1481
1481
|
};
|
|
1482
1482
|
if (typeof base.rm === "function") {
|
|
1483
|
-
proxy.rm = async (
|
|
1484
|
-
recorder.record({ type: "rm", path:
|
|
1483
|
+
proxy.rm = async (path27, options) => {
|
|
1484
|
+
recorder.record({ type: "rm", path: path27, options });
|
|
1485
1485
|
};
|
|
1486
1486
|
}
|
|
1487
1487
|
if (typeof base.copyFile === "function") {
|
|
@@ -1571,8 +1571,8 @@ function describeWriteChange(previous, next) {
|
|
|
1571
1571
|
}
|
|
1572
1572
|
return "update";
|
|
1573
1573
|
}
|
|
1574
|
-
function renderWriteCommand(
|
|
1575
|
-
const command = `cat > ${
|
|
1574
|
+
function renderWriteCommand(path27, change) {
|
|
1575
|
+
const command = `cat > ${path27}`;
|
|
1576
1576
|
if (change === "create") {
|
|
1577
1577
|
return renderOperationCommand(command, chalk.green, "# create");
|
|
1578
1578
|
}
|
|
@@ -1734,9 +1734,9 @@ function redactTomlLine(line) {
|
|
|
1734
1734
|
}
|
|
1735
1735
|
return line;
|
|
1736
1736
|
}
|
|
1737
|
-
async function tryReadText(base,
|
|
1737
|
+
async function tryReadText(base, path27) {
|
|
1738
1738
|
try {
|
|
1739
|
-
return await base.readFile(
|
|
1739
|
+
return await base.readFile(path27, "utf8");
|
|
1740
1740
|
} catch (error2) {
|
|
1741
1741
|
if (isNotFound(error2)) {
|
|
1742
1742
|
return null;
|
|
@@ -3730,21 +3730,21 @@ async function* adaptClaude(lines) {
|
|
|
3730
3730
|
if (blockType !== "tool_result") continue;
|
|
3731
3731
|
const kind = toolKindsById.get(item.tool_use_id);
|
|
3732
3732
|
toolKindsById.delete(item.tool_use_id);
|
|
3733
|
-
let
|
|
3733
|
+
let path27;
|
|
3734
3734
|
if (typeof item.content === "string") {
|
|
3735
|
-
|
|
3735
|
+
path27 = item.content;
|
|
3736
3736
|
} else {
|
|
3737
3737
|
try {
|
|
3738
|
-
|
|
3738
|
+
path27 = JSON.stringify(item.content);
|
|
3739
3739
|
} catch {
|
|
3740
|
-
|
|
3740
|
+
path27 = String(item.content);
|
|
3741
3741
|
}
|
|
3742
3742
|
}
|
|
3743
3743
|
yield {
|
|
3744
3744
|
event: "tool_complete",
|
|
3745
3745
|
id: item.tool_use_id,
|
|
3746
3746
|
kind,
|
|
3747
|
-
path:
|
|
3747
|
+
path: path27
|
|
3748
3748
|
};
|
|
3749
3749
|
}
|
|
3750
3750
|
}
|
|
@@ -3866,10 +3866,10 @@ async function* adaptCodex(lines) {
|
|
|
3866
3866
|
const kindFromStart = toolKindById.get(item.id);
|
|
3867
3867
|
const kind = kindFromStart ?? (itemType === "command_execution" ? "exec" : itemType === "file_edit" ? "edit" : "other");
|
|
3868
3868
|
const titleFromEvent = isNonEmptyString(item.path) ? item.path : itemType === "mcp_tool_call" ? `${isNonEmptyString(item.server) ? item.server : "unknown"}.${isNonEmptyString(item.tool) ? item.tool : "unknown"}` : void 0;
|
|
3869
|
-
const
|
|
3869
|
+
const path27 = titleFromEvent ?? toolTitleById.get(item.id) ?? "";
|
|
3870
3870
|
toolTitleById.delete(item.id);
|
|
3871
3871
|
toolKindById.delete(item.id);
|
|
3872
|
-
yield { event: "tool_complete", id: item.id, kind, path:
|
|
3872
|
+
yield { event: "tool_complete", id: item.id, kind, path: path27 };
|
|
3873
3873
|
}
|
|
3874
3874
|
}
|
|
3875
3875
|
}
|
|
@@ -4311,7 +4311,7 @@ function updateSessionFromEvent(ctx, event, toolCallsById) {
|
|
|
4311
4311
|
}
|
|
4312
4312
|
const id = readString(event.id);
|
|
4313
4313
|
const kind = readString(event.kind);
|
|
4314
|
-
const
|
|
4314
|
+
const path27 = readString(event.path);
|
|
4315
4315
|
let toolCall = id ? toolCallsById.get(id) : void 0;
|
|
4316
4316
|
if (!toolCall) {
|
|
4317
4317
|
toolCall = {};
|
|
@@ -4326,8 +4326,8 @@ function updateSessionFromEvent(ctx, event, toolCallsById) {
|
|
|
4326
4326
|
if (kind) {
|
|
4327
4327
|
toolCall.kind = kind;
|
|
4328
4328
|
}
|
|
4329
|
-
if (
|
|
4330
|
-
toolCall.path =
|
|
4329
|
+
if (path27) {
|
|
4330
|
+
toolCall.path = path27;
|
|
4331
4331
|
}
|
|
4332
4332
|
}
|
|
4333
4333
|
var sessionCapture;
|
|
@@ -4835,15 +4835,142 @@ var init_spawn_core = __esm({
|
|
|
4835
4835
|
}
|
|
4836
4836
|
});
|
|
4837
4837
|
|
|
4838
|
-
// src/
|
|
4838
|
+
// packages/poe-code-config/src/schema.ts
|
|
4839
|
+
var init_schema = __esm({
|
|
4840
|
+
"packages/poe-code-config/src/schema.ts"() {
|
|
4841
|
+
"use strict";
|
|
4842
|
+
}
|
|
4843
|
+
});
|
|
4844
|
+
|
|
4845
|
+
// packages/poe-code-config/src/store.ts
|
|
4839
4846
|
import path7 from "node:path";
|
|
4847
|
+
async function readDocument(fs3, filePath) {
|
|
4848
|
+
try {
|
|
4849
|
+
const raw = await fs3.readFile(filePath, "utf8");
|
|
4850
|
+
return await parseDocument(fs3, filePath, raw);
|
|
4851
|
+
} catch (error2) {
|
|
4852
|
+
if (isNotFound(error2)) {
|
|
4853
|
+
return {};
|
|
4854
|
+
}
|
|
4855
|
+
throw error2;
|
|
4856
|
+
}
|
|
4857
|
+
}
|
|
4858
|
+
async function writeScope(fs3, filePath, scope, values) {
|
|
4859
|
+
const document = await readDocument(fs3, filePath);
|
|
4860
|
+
const normalizedValues = normalizeScopeValues(values);
|
|
4861
|
+
if (Object.keys(normalizedValues).length === 0) {
|
|
4862
|
+
delete document[scope];
|
|
4863
|
+
} else {
|
|
4864
|
+
document[scope] = normalizedValues;
|
|
4865
|
+
}
|
|
4866
|
+
await writeDocument(fs3, filePath, document);
|
|
4867
|
+
}
|
|
4868
|
+
async function parseDocument(fs3, filePath, raw) {
|
|
4869
|
+
try {
|
|
4870
|
+
return normalizeDocument(JSON.parse(raw));
|
|
4871
|
+
} catch (error2) {
|
|
4872
|
+
if (error2 instanceof SyntaxError) {
|
|
4873
|
+
await recoverInvalidDocument(fs3, filePath, raw);
|
|
4874
|
+
return {};
|
|
4875
|
+
}
|
|
4876
|
+
throw error2;
|
|
4877
|
+
}
|
|
4878
|
+
}
|
|
4879
|
+
function normalizeDocument(value) {
|
|
4880
|
+
if (!isRecord2(value)) {
|
|
4881
|
+
return {};
|
|
4882
|
+
}
|
|
4883
|
+
const document = {};
|
|
4884
|
+
for (const [scope, scopeValues] of Object.entries(value)) {
|
|
4885
|
+
const normalizedValues = normalizeScopeValues(scopeValues);
|
|
4886
|
+
if (Object.keys(normalizedValues).length > 0) {
|
|
4887
|
+
document[scope] = normalizedValues;
|
|
4888
|
+
}
|
|
4889
|
+
}
|
|
4890
|
+
return document;
|
|
4891
|
+
}
|
|
4892
|
+
function normalizeScopeValues(value) {
|
|
4893
|
+
if (!isRecord2(value)) {
|
|
4894
|
+
return {};
|
|
4895
|
+
}
|
|
4896
|
+
const normalized = {};
|
|
4897
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
4898
|
+
if (entry !== void 0) {
|
|
4899
|
+
normalized[key] = entry;
|
|
4900
|
+
}
|
|
4901
|
+
}
|
|
4902
|
+
return normalized;
|
|
4903
|
+
}
|
|
4904
|
+
async function writeDocument(fs3, filePath, document) {
|
|
4905
|
+
await fs3.mkdir(path7.dirname(filePath), { recursive: true });
|
|
4906
|
+
await fs3.writeFile(filePath, `${JSON.stringify(document, null, 2)}
|
|
4907
|
+
`, {
|
|
4908
|
+
encoding: "utf8"
|
|
4909
|
+
});
|
|
4910
|
+
}
|
|
4911
|
+
async function recoverInvalidDocument(fs3, filePath, content) {
|
|
4912
|
+
await fs3.mkdir(path7.dirname(filePath), { recursive: true });
|
|
4913
|
+
const backupPath = createInvalidBackupPath(filePath);
|
|
4914
|
+
await fs3.writeFile(backupPath, content, { encoding: "utf8" });
|
|
4915
|
+
await fs3.writeFile(filePath, EMPTY_DOCUMENT, { encoding: "utf8" });
|
|
4916
|
+
}
|
|
4917
|
+
function createInvalidBackupPath(filePath) {
|
|
4918
|
+
const directory = path7.dirname(filePath);
|
|
4919
|
+
const baseName = path7.basename(filePath);
|
|
4920
|
+
return path7.join(directory, `${baseName}.invalid-${createTimestamp()}.json`);
|
|
4921
|
+
}
|
|
4922
|
+
function isRecord2(value) {
|
|
4923
|
+
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
4924
|
+
}
|
|
4925
|
+
function resolveConfigPath(homeDir) {
|
|
4926
|
+
return path7.join(homeDir, ".poe-code", "config.json");
|
|
4927
|
+
}
|
|
4928
|
+
var EMPTY_DOCUMENT;
|
|
4929
|
+
var init_store = __esm({
|
|
4930
|
+
"packages/poe-code-config/src/store.ts"() {
|
|
4931
|
+
"use strict";
|
|
4932
|
+
init_src2();
|
|
4933
|
+
EMPTY_DOCUMENT = `${JSON.stringify({}, null, 2)}
|
|
4934
|
+
`;
|
|
4935
|
+
}
|
|
4936
|
+
});
|
|
4937
|
+
|
|
4938
|
+
// packages/poe-code-config/src/resolve.ts
|
|
4939
|
+
var init_resolve = __esm({
|
|
4940
|
+
"packages/poe-code-config/src/resolve.ts"() {
|
|
4941
|
+
"use strict";
|
|
4942
|
+
}
|
|
4943
|
+
});
|
|
4944
|
+
|
|
4945
|
+
// packages/poe-code-config/src/config.ts
|
|
4946
|
+
var init_config = __esm({
|
|
4947
|
+
"packages/poe-code-config/src/config.ts"() {
|
|
4948
|
+
"use strict";
|
|
4949
|
+
init_store();
|
|
4950
|
+
init_resolve();
|
|
4951
|
+
}
|
|
4952
|
+
});
|
|
4953
|
+
|
|
4954
|
+
// packages/poe-code-config/src/index.ts
|
|
4955
|
+
var init_src6 = __esm({
|
|
4956
|
+
"packages/poe-code-config/src/index.ts"() {
|
|
4957
|
+
"use strict";
|
|
4958
|
+
init_schema();
|
|
4959
|
+
init_config();
|
|
4960
|
+
init_resolve();
|
|
4961
|
+
init_store();
|
|
4962
|
+
}
|
|
4963
|
+
});
|
|
4964
|
+
|
|
4965
|
+
// src/cli/environment.ts
|
|
4966
|
+
import path8 from "node:path";
|
|
4840
4967
|
function createCliEnvironment(init) {
|
|
4841
4968
|
const platform = init.platform ?? process.platform;
|
|
4842
4969
|
const variables = init.variables ?? process.env;
|
|
4843
4970
|
const configPath = resolveConfigPath(init.homeDir);
|
|
4844
4971
|
const logDir = resolveLogDir(init.homeDir);
|
|
4845
4972
|
const { poeApiBaseUrl, poeBaseUrl } = resolvePoeBaseUrls(variables);
|
|
4846
|
-
const resolveHomePath = (...segments) =>
|
|
4973
|
+
const resolveHomePath = (...segments) => path8.join(init.homeDir, ...segments);
|
|
4847
4974
|
const getVariable = (name) => variables[name];
|
|
4848
4975
|
return {
|
|
4849
4976
|
cwd: init.cwd,
|
|
@@ -4858,11 +4985,8 @@ function createCliEnvironment(init) {
|
|
|
4858
4985
|
getVariable
|
|
4859
4986
|
};
|
|
4860
4987
|
}
|
|
4861
|
-
function resolveConfigPath(homeDir) {
|
|
4862
|
-
return path7.join(homeDir, ".poe-code", "config.json");
|
|
4863
|
-
}
|
|
4864
4988
|
function resolveLogDir(homeDir) {
|
|
4865
|
-
return
|
|
4989
|
+
return path8.join(homeDir, ".poe-code", "logs");
|
|
4866
4990
|
}
|
|
4867
4991
|
function resolvePoeBaseUrls(variables) {
|
|
4868
4992
|
const raw = variables.POE_BASE_URL;
|
|
@@ -4941,6 +5065,7 @@ var DEFAULT_POE_API_BASE_URL;
|
|
|
4941
5065
|
var init_environment = __esm({
|
|
4942
5066
|
"src/cli/environment.ts"() {
|
|
4943
5067
|
"use strict";
|
|
5068
|
+
init_src6();
|
|
4944
5069
|
DEFAULT_POE_API_BASE_URL = "https://api.poe.com/v1";
|
|
4945
5070
|
}
|
|
4946
5071
|
});
|
|
@@ -5085,33 +5210,251 @@ var init_prompts2 = __esm({
|
|
|
5085
5210
|
}
|
|
5086
5211
|
});
|
|
5087
5212
|
|
|
5088
|
-
// src/
|
|
5089
|
-
function
|
|
5090
|
-
|
|
5213
|
+
// packages/poe-oauth/src/check-auth.ts
|
|
5214
|
+
async function checkAuth(options) {
|
|
5215
|
+
try {
|
|
5216
|
+
const fetchImplementation = options.fetch ?? globalThis.fetch;
|
|
5217
|
+
const response = await fetchImplementation(
|
|
5218
|
+
createCurrentBalanceUrl(options.baseUrl ?? DEFAULT_BASE_URL),
|
|
5219
|
+
{
|
|
5220
|
+
method: "GET",
|
|
5221
|
+
headers: {
|
|
5222
|
+
Authorization: `Bearer ${options.apiKey}`
|
|
5223
|
+
}
|
|
5224
|
+
}
|
|
5225
|
+
);
|
|
5226
|
+
if (!response.ok) {
|
|
5227
|
+
return null;
|
|
5228
|
+
}
|
|
5229
|
+
const data = await response.json();
|
|
5230
|
+
if (typeof data.email !== "string" || data.email.length === 0) {
|
|
5231
|
+
return null;
|
|
5232
|
+
}
|
|
5233
|
+
return {
|
|
5234
|
+
email: data.email,
|
|
5235
|
+
balance: typeof data.current_point_balance === "number" ? data.current_point_balance : null
|
|
5236
|
+
};
|
|
5237
|
+
} catch {
|
|
5238
|
+
return null;
|
|
5239
|
+
}
|
|
5091
5240
|
}
|
|
5092
|
-
function
|
|
5093
|
-
|
|
5094
|
-
|
|
5095
|
-
|
|
5096
|
-
|
|
5097
|
-
|
|
5098
|
-
|
|
5099
|
-
|
|
5100
|
-
|
|
5101
|
-
return false;
|
|
5241
|
+
function createCurrentBalanceUrl(baseUrl) {
|
|
5242
|
+
const normalizedBaseUrl = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
|
|
5243
|
+
return `${normalizedBaseUrl}/usage/current_balance`;
|
|
5244
|
+
}
|
|
5245
|
+
var DEFAULT_BASE_URL;
|
|
5246
|
+
var init_check_auth = __esm({
|
|
5247
|
+
"packages/poe-oauth/src/check-auth.ts"() {
|
|
5248
|
+
"use strict";
|
|
5249
|
+
DEFAULT_BASE_URL = "https://poe.com";
|
|
5102
5250
|
}
|
|
5103
|
-
|
|
5251
|
+
});
|
|
5252
|
+
|
|
5253
|
+
// packages/poe-oauth/src/oauth-client.ts
|
|
5254
|
+
import http from "node:http";
|
|
5255
|
+
import crypto from "node:crypto";
|
|
5256
|
+
function createOAuthClient(config2) {
|
|
5257
|
+
const fetchFn = config2.fetch ?? globalThis.fetch;
|
|
5258
|
+
return {
|
|
5259
|
+
authorize: () => startAuthorization(config2, fetchFn)
|
|
5260
|
+
};
|
|
5261
|
+
}
|
|
5262
|
+
function generateCodeVerifier() {
|
|
5263
|
+
return crypto.randomBytes(32).toString("base64url");
|
|
5104
5264
|
}
|
|
5105
|
-
function
|
|
5106
|
-
return
|
|
5265
|
+
function generateCodeChallenge(verifier) {
|
|
5266
|
+
return crypto.createHash("sha256").update(verifier).digest("base64url");
|
|
5107
5267
|
}
|
|
5108
|
-
function
|
|
5109
|
-
|
|
5110
|
-
|
|
5111
|
-
|
|
5112
|
-
|
|
5268
|
+
async function startAuthorization(config2, fetchFn) {
|
|
5269
|
+
const authorizationEndpoint = config2.authorizationEndpoint ?? DEFAULT_AUTHORIZATION_ENDPOINT;
|
|
5270
|
+
const tokenEndpoint = config2.tokenEndpoint ?? DEFAULT_TOKEN_ENDPOINT;
|
|
5271
|
+
const codeVerifier = generateCodeVerifier();
|
|
5272
|
+
const codeChallenge = generateCodeChallenge(codeVerifier);
|
|
5273
|
+
const server = config2.createServer ? config2.createServer() : http.createServer();
|
|
5274
|
+
const port = await startServer(server);
|
|
5275
|
+
const redirectUri = `http://127.0.0.1:${port}/callback`;
|
|
5276
|
+
const authorizationUrl = buildAuthorizationUrl({
|
|
5277
|
+
endpoint: authorizationEndpoint,
|
|
5278
|
+
clientId: config2.clientId,
|
|
5279
|
+
redirectUri,
|
|
5280
|
+
codeChallenge
|
|
5281
|
+
});
|
|
5282
|
+
const waitForResult = async () => {
|
|
5283
|
+
try {
|
|
5284
|
+
const code = await waitForAuthorizationCode(server, config2, authorizationUrl);
|
|
5285
|
+
return await exchangeCodeForApiKey({
|
|
5286
|
+
tokenEndpoint,
|
|
5287
|
+
code,
|
|
5288
|
+
codeVerifier,
|
|
5289
|
+
clientId: config2.clientId,
|
|
5290
|
+
redirectUri,
|
|
5291
|
+
fetchFn
|
|
5292
|
+
});
|
|
5293
|
+
} finally {
|
|
5294
|
+
server.closeAllConnections?.();
|
|
5295
|
+
server.close();
|
|
5296
|
+
}
|
|
5297
|
+
};
|
|
5298
|
+
return { authorizationUrl, waitForResult };
|
|
5299
|
+
}
|
|
5300
|
+
function startServer(server) {
|
|
5301
|
+
return new Promise((resolve) => {
|
|
5302
|
+
server.listen(0, "127.0.0.1", () => {
|
|
5303
|
+
const address = server.address();
|
|
5304
|
+
resolve(address.port);
|
|
5305
|
+
});
|
|
5306
|
+
});
|
|
5307
|
+
}
|
|
5308
|
+
function buildAuthorizationUrl(params) {
|
|
5309
|
+
const url2 = new URL(params.endpoint);
|
|
5310
|
+
url2.searchParams.set("response_type", "code");
|
|
5311
|
+
url2.searchParams.set("client_id", params.clientId);
|
|
5312
|
+
url2.searchParams.set("scope", "apikey:create");
|
|
5313
|
+
url2.searchParams.set("code_challenge", params.codeChallenge);
|
|
5314
|
+
url2.searchParams.set("code_challenge_method", "S256");
|
|
5315
|
+
url2.searchParams.set("redirect_uri", params.redirectUri);
|
|
5316
|
+
return url2.toString();
|
|
5317
|
+
}
|
|
5318
|
+
function waitForAuthorizationCode(server, config2, authorizationUrl) {
|
|
5319
|
+
return new Promise((resolve, reject) => {
|
|
5320
|
+
let settled = false;
|
|
5321
|
+
const settle = (fn) => {
|
|
5322
|
+
if (!settled) {
|
|
5323
|
+
settled = true;
|
|
5324
|
+
fn();
|
|
5325
|
+
}
|
|
5326
|
+
};
|
|
5327
|
+
server.on("request", (req, res) => {
|
|
5328
|
+
const url2 = new URL(req.url, `http://127.0.0.1`);
|
|
5329
|
+
if (url2.pathname !== "/callback") {
|
|
5330
|
+
res.writeHead(404);
|
|
5331
|
+
res.end("Not found");
|
|
5332
|
+
return;
|
|
5333
|
+
}
|
|
5334
|
+
const error2 = url2.searchParams.get("error");
|
|
5335
|
+
if (error2) {
|
|
5336
|
+
const description = url2.searchParams.get("error_description") ?? error2;
|
|
5337
|
+
res.writeHead(400);
|
|
5338
|
+
res.end(`Authorization failed: ${description}`);
|
|
5339
|
+
settle(() => reject(new Error(`OAuth authorization failed: ${error2} \u2014 ${description}`)));
|
|
5340
|
+
return;
|
|
5341
|
+
}
|
|
5342
|
+
const code = url2.searchParams.get("code");
|
|
5343
|
+
if (!code) {
|
|
5344
|
+
res.writeHead(400);
|
|
5345
|
+
res.end("Missing authorization code");
|
|
5346
|
+
settle(() => reject(new Error("OAuth callback missing authorization code")));
|
|
5347
|
+
return;
|
|
5348
|
+
}
|
|
5349
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
5350
|
+
res.end(buildSuccessPage(config2.landingPage));
|
|
5351
|
+
settle(() => resolve(code));
|
|
5352
|
+
});
|
|
5353
|
+
if (config2.readLine) {
|
|
5354
|
+
config2.readLine().then((input) => {
|
|
5355
|
+
const code = extractCodeFromInput(input);
|
|
5356
|
+
if (code) {
|
|
5357
|
+
settle(() => resolve(code));
|
|
5358
|
+
}
|
|
5359
|
+
}).catch(() => {
|
|
5360
|
+
});
|
|
5361
|
+
}
|
|
5362
|
+
if (config2.openBrowser) {
|
|
5363
|
+
config2.openBrowser(authorizationUrl).catch(
|
|
5364
|
+
(err) => settle(() => reject(err))
|
|
5365
|
+
);
|
|
5366
|
+
}
|
|
5367
|
+
});
|
|
5368
|
+
}
|
|
5369
|
+
function extractCodeFromInput(input) {
|
|
5370
|
+
const trimmed = input.replace(/[\r\n]/g, "").trim();
|
|
5371
|
+
if (trimmed.length === 0) {
|
|
5372
|
+
return null;
|
|
5113
5373
|
}
|
|
5114
|
-
|
|
5374
|
+
try {
|
|
5375
|
+
const url2 = new URL(trimmed);
|
|
5376
|
+
return url2.searchParams.get("code");
|
|
5377
|
+
} catch {
|
|
5378
|
+
return trimmed;
|
|
5379
|
+
}
|
|
5380
|
+
}
|
|
5381
|
+
async function exchangeCodeForApiKey(params) {
|
|
5382
|
+
const body = new URLSearchParams({
|
|
5383
|
+
grant_type: "authorization_code",
|
|
5384
|
+
code: params.code,
|
|
5385
|
+
code_verifier: params.codeVerifier,
|
|
5386
|
+
client_id: params.clientId,
|
|
5387
|
+
redirect_uri: params.redirectUri
|
|
5388
|
+
});
|
|
5389
|
+
const response = await params.fetchFn(params.tokenEndpoint, {
|
|
5390
|
+
method: "POST",
|
|
5391
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
5392
|
+
body: body.toString()
|
|
5393
|
+
});
|
|
5394
|
+
if (!response.ok) {
|
|
5395
|
+
const text4 = await response.text();
|
|
5396
|
+
const description = parseErrorDescription(text4);
|
|
5397
|
+
throw new Error(description ?? `Token exchange failed (${response.status}): ${text4}`);
|
|
5398
|
+
}
|
|
5399
|
+
const data = await response.json();
|
|
5400
|
+
if (typeof data.api_key !== "string" || data.api_key.length === 0) {
|
|
5401
|
+
throw new Error("Token response missing api_key field");
|
|
5402
|
+
}
|
|
5403
|
+
return {
|
|
5404
|
+
apiKey: data.api_key,
|
|
5405
|
+
expiresIn: typeof data.api_key_expires_in === "number" ? data.api_key_expires_in : null
|
|
5406
|
+
};
|
|
5407
|
+
}
|
|
5408
|
+
function parseErrorDescription(text4) {
|
|
5409
|
+
try {
|
|
5410
|
+
const data = JSON.parse(text4);
|
|
5411
|
+
if (typeof data.error_description === "string") {
|
|
5412
|
+
return data.error_description;
|
|
5413
|
+
}
|
|
5414
|
+
if (typeof data.error === "string") {
|
|
5415
|
+
return data.error;
|
|
5416
|
+
}
|
|
5417
|
+
} catch {
|
|
5418
|
+
}
|
|
5419
|
+
return null;
|
|
5420
|
+
}
|
|
5421
|
+
function escapeHtml(text4) {
|
|
5422
|
+
return text4.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
5423
|
+
}
|
|
5424
|
+
function buildSuccessPage(landingPage) {
|
|
5425
|
+
const title = landingPage?.title ?? "Connected to Poe";
|
|
5426
|
+
const body = landingPage?.body ?? "You can close this tab and return to your terminal.";
|
|
5427
|
+
return [
|
|
5428
|
+
"<!DOCTYPE html>",
|
|
5429
|
+
`<html><head><meta charset=utf-8><title>${escapeHtml(title)}</title></head>`,
|
|
5430
|
+
'<body style="font-family:system-ui,sans-serif;display:flex;align-items:center;justify-content:center;min-height:100vh;margin:0">',
|
|
5431
|
+
'<div style="text-align:center">',
|
|
5432
|
+
`<h1>${escapeHtml(title)}</h1>`,
|
|
5433
|
+
`<p style="color:#666">${escapeHtml(body)}</p>`,
|
|
5434
|
+
"</div></body></html>"
|
|
5435
|
+
].join("");
|
|
5436
|
+
}
|
|
5437
|
+
var DEFAULT_AUTHORIZATION_ENDPOINT, DEFAULT_TOKEN_ENDPOINT;
|
|
5438
|
+
var init_oauth_client = __esm({
|
|
5439
|
+
"packages/poe-oauth/src/oauth-client.ts"() {
|
|
5440
|
+
"use strict";
|
|
5441
|
+
DEFAULT_AUTHORIZATION_ENDPOINT = "https://poe.com/oauth/authorize";
|
|
5442
|
+
DEFAULT_TOKEN_ENDPOINT = "https://api.poe.com/token";
|
|
5443
|
+
}
|
|
5444
|
+
});
|
|
5445
|
+
|
|
5446
|
+
// packages/poe-oauth/src/index.ts
|
|
5447
|
+
var init_src7 = __esm({
|
|
5448
|
+
"packages/poe-oauth/src/index.ts"() {
|
|
5449
|
+
"use strict";
|
|
5450
|
+
init_check_auth();
|
|
5451
|
+
init_oauth_client();
|
|
5452
|
+
}
|
|
5453
|
+
});
|
|
5454
|
+
|
|
5455
|
+
// src/cli/options.ts
|
|
5456
|
+
function stripBracketedPaste(value) {
|
|
5457
|
+
return value.replace(/\x1b\[200~/g, "").replace(/\x1b\[201~/g, "").replace(/undefinedndefined$/, "").replace(/undefined$/, "").replace(/ndefined$/, "");
|
|
5115
5458
|
}
|
|
5116
5459
|
function createOptionResolvers(init) {
|
|
5117
5460
|
const ensure = async (input) => {
|
|
@@ -5128,7 +5471,7 @@ function createOptionResolvers(init) {
|
|
|
5128
5471
|
}
|
|
5129
5472
|
return result;
|
|
5130
5473
|
};
|
|
5131
|
-
const
|
|
5474
|
+
const normalizeApiKey = (value) => {
|
|
5132
5475
|
const sanitized = stripBracketedPaste(value);
|
|
5133
5476
|
const trimmed = sanitized.trim();
|
|
5134
5477
|
if (trimmed.length === 0) {
|
|
@@ -5136,20 +5479,15 @@ function createOptionResolvers(init) {
|
|
|
5136
5479
|
}
|
|
5137
5480
|
return trimmed;
|
|
5138
5481
|
};
|
|
5139
|
-
const
|
|
5140
|
-
|
|
5141
|
-
if (assumeYes) return false;
|
|
5142
|
-
return await init.confirm(
|
|
5143
|
-
"Key doesn't match expected API key format. Use it anyway?"
|
|
5144
|
-
);
|
|
5482
|
+
const validateApiKey = async (apiKey) => {
|
|
5483
|
+
return await init.checkAuth(apiKey);
|
|
5145
5484
|
};
|
|
5146
5485
|
const resolveApiKey2 = async (input) => {
|
|
5147
5486
|
const assumeYes = input.assumeYes ?? false;
|
|
5148
5487
|
const allowStored = input.allowStored ?? true;
|
|
5149
5488
|
if (input.value != null) {
|
|
5150
|
-
const apiKey =
|
|
5151
|
-
|
|
5152
|
-
if (!accepted) {
|
|
5489
|
+
const apiKey = normalizeApiKey(input.value);
|
|
5490
|
+
if (!await validateApiKey(apiKey)) {
|
|
5153
5491
|
throw new Error("API key rejected.");
|
|
5154
5492
|
}
|
|
5155
5493
|
if (!input.dryRun) {
|
|
@@ -5163,9 +5501,8 @@ function createOptionResolvers(init) {
|
|
|
5163
5501
|
"Use API key from POE_API_KEY environment variable?"
|
|
5164
5502
|
);
|
|
5165
5503
|
if (useEnv) {
|
|
5166
|
-
const apiKey =
|
|
5167
|
-
|
|
5168
|
-
if (accepted) {
|
|
5504
|
+
const apiKey = normalizeApiKey(envValue);
|
|
5505
|
+
if (await validateApiKey(apiKey)) {
|
|
5169
5506
|
if (!input.dryRun) {
|
|
5170
5507
|
await init.apiKeyStore.write(apiKey);
|
|
5171
5508
|
}
|
|
@@ -5179,12 +5516,12 @@ function createOptionResolvers(init) {
|
|
|
5179
5516
|
if (allowStored) {
|
|
5180
5517
|
const stored = await init.apiKeyStore.read();
|
|
5181
5518
|
if (stored) {
|
|
5182
|
-
return
|
|
5519
|
+
return normalizeApiKey(stored);
|
|
5183
5520
|
}
|
|
5184
5521
|
}
|
|
5185
5522
|
if (init.loginViaOAuth) {
|
|
5186
5523
|
const apiKey = await init.loginViaOAuth();
|
|
5187
|
-
const normalized =
|
|
5524
|
+
const normalized = normalizeApiKey(apiKey);
|
|
5188
5525
|
if (!input.dryRun) {
|
|
5189
5526
|
await init.apiKeyStore.write(normalized);
|
|
5190
5527
|
}
|
|
@@ -5199,15 +5536,14 @@ function createOptionResolvers(init) {
|
|
|
5199
5536
|
}
|
|
5200
5537
|
let apiKey;
|
|
5201
5538
|
try {
|
|
5202
|
-
apiKey =
|
|
5539
|
+
apiKey = normalizeApiKey(result);
|
|
5203
5540
|
} catch (error2) {
|
|
5204
5541
|
if (error2 instanceof Error && error2.message === "POE API key cannot be empty.") {
|
|
5205
5542
|
continue;
|
|
5206
5543
|
}
|
|
5207
5544
|
throw error2;
|
|
5208
5545
|
}
|
|
5209
|
-
|
|
5210
|
-
if (!accepted) {
|
|
5546
|
+
if (!await validateApiKey(apiKey)) {
|
|
5211
5547
|
continue;
|
|
5212
5548
|
}
|
|
5213
5549
|
if (!input.dryRun) {
|
|
@@ -5270,19 +5606,12 @@ function createOptionResolvers(init) {
|
|
|
5270
5606
|
resolveModel: resolveModel2,
|
|
5271
5607
|
resolveReasoning,
|
|
5272
5608
|
resolveConfigName,
|
|
5273
|
-
resolveApiKey: resolveApiKey2
|
|
5274
|
-
normalizeApiKey: normalizeApiKey2
|
|
5609
|
+
resolveApiKey: resolveApiKey2
|
|
5275
5610
|
};
|
|
5276
5611
|
}
|
|
5277
|
-
var API_KEY_REFERENCE_LENGTH, API_KEY_MIN_LENGTH_RATIO, MIN_API_KEY_LENGTH;
|
|
5278
5612
|
var init_options = __esm({
|
|
5279
5613
|
"src/cli/options.ts"() {
|
|
5280
5614
|
"use strict";
|
|
5281
|
-
API_KEY_REFERENCE_LENGTH = 43;
|
|
5282
|
-
API_KEY_MIN_LENGTH_RATIO = 0.8;
|
|
5283
|
-
MIN_API_KEY_LENGTH = Math.ceil(
|
|
5284
|
-
API_KEY_REFERENCE_LENGTH * API_KEY_MIN_LENGTH_RATIO
|
|
5285
|
-
);
|
|
5286
5615
|
}
|
|
5287
5616
|
});
|
|
5288
5617
|
|
|
@@ -5555,7 +5884,7 @@ var init_logger2 = __esm({
|
|
|
5555
5884
|
});
|
|
5556
5885
|
|
|
5557
5886
|
// src/cli/error-logger.ts
|
|
5558
|
-
import
|
|
5887
|
+
import path9 from "node:path";
|
|
5559
5888
|
var DEFAULT_MAX_SIZE, DEFAULT_MAX_BACKUPS, ErrorLogger;
|
|
5560
5889
|
var init_error_logger = __esm({
|
|
5561
5890
|
"src/cli/error-logger.ts"() {
|
|
@@ -5572,7 +5901,7 @@ var init_error_logger = __esm({
|
|
|
5572
5901
|
fileLoggingAvailable;
|
|
5573
5902
|
constructor(options) {
|
|
5574
5903
|
this.fs = options.fs;
|
|
5575
|
-
this.logFilePath =
|
|
5904
|
+
this.logFilePath = path9.join(options.logDir, "errors.log");
|
|
5576
5905
|
this.logToStderr = options.logToStderr ?? true;
|
|
5577
5906
|
this.maxSize = options.maxSize ?? DEFAULT_MAX_SIZE;
|
|
5578
5907
|
this.maxBackups = options.maxBackups ?? DEFAULT_MAX_BACKUPS;
|
|
@@ -5691,7 +6020,7 @@ ${entry.stack}`);
|
|
|
5691
6020
|
return `${this.logFilePath}.${index}`;
|
|
5692
6021
|
}
|
|
5693
6022
|
ensureLogDirectory() {
|
|
5694
|
-
const directory =
|
|
6023
|
+
const directory = path9.dirname(this.logFilePath);
|
|
5695
6024
|
try {
|
|
5696
6025
|
if (!this.fs.existsSync(directory)) {
|
|
5697
6026
|
this.fs.mkdirSync(directory, { recursive: true });
|
|
@@ -5709,7 +6038,7 @@ ${entry.stack}`);
|
|
|
5709
6038
|
});
|
|
5710
6039
|
|
|
5711
6040
|
// src/providers/index.ts
|
|
5712
|
-
import
|
|
6041
|
+
import path10 from "node:path";
|
|
5713
6042
|
import { readdir } from "node:fs/promises";
|
|
5714
6043
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
5715
6044
|
function isProviderModule(filename) {
|
|
@@ -5736,7 +6065,7 @@ async function loadProviders() {
|
|
|
5736
6065
|
for (const entry of entries) {
|
|
5737
6066
|
if (!entry.isFile()) continue;
|
|
5738
6067
|
if (!isProviderModule(entry.name)) continue;
|
|
5739
|
-
const moduleUrl = pathToFileURL(
|
|
6068
|
+
const moduleUrl = pathToFileURL(path10.join(currentDir, entry.name)).href;
|
|
5740
6069
|
const moduleExports = await import(moduleUrl);
|
|
5741
6070
|
if (!moduleExports.provider) {
|
|
5742
6071
|
throw new Error(`Provider module "${entry.name}" must export "provider".`);
|
|
@@ -5752,8 +6081,8 @@ var moduleDir, currentDir, defaultProviders;
|
|
|
5752
6081
|
var init_providers = __esm({
|
|
5753
6082
|
async "src/providers/index.ts"() {
|
|
5754
6083
|
"use strict";
|
|
5755
|
-
moduleDir =
|
|
5756
|
-
currentDir =
|
|
6084
|
+
moduleDir = path10.dirname(fileURLToPath(import.meta.url));
|
|
6085
|
+
currentDir = path10.basename(moduleDir) === "providers" ? moduleDir : path10.join(moduleDir, "providers");
|
|
5757
6086
|
defaultProviders = await loadProviders();
|
|
5758
6087
|
}
|
|
5759
6088
|
});
|
|
@@ -6095,21 +6424,21 @@ function createSdkContainer(options) {
|
|
|
6095
6424
|
});
|
|
6096
6425
|
loggerFactory.setErrorLogger(errorLogger);
|
|
6097
6426
|
const asyncFs = {
|
|
6098
|
-
readFile: ((
|
|
6427
|
+
readFile: ((path27, encoding) => {
|
|
6099
6428
|
if (encoding) {
|
|
6100
|
-
return fs2.readFile(
|
|
6429
|
+
return fs2.readFile(path27, encoding);
|
|
6101
6430
|
}
|
|
6102
|
-
return fs2.readFile(
|
|
6431
|
+
return fs2.readFile(path27);
|
|
6103
6432
|
}),
|
|
6104
|
-
writeFile: (
|
|
6105
|
-
mkdir: (
|
|
6433
|
+
writeFile: (path27, data, opts) => fs2.writeFile(path27, data, opts),
|
|
6434
|
+
mkdir: (path27, opts) => fs2.mkdir(path27, opts).then(() => {
|
|
6106
6435
|
}),
|
|
6107
|
-
stat: (
|
|
6108
|
-
rm: (
|
|
6109
|
-
unlink: (
|
|
6110
|
-
readdir: (
|
|
6436
|
+
stat: (path27) => fs2.stat(path27),
|
|
6437
|
+
rm: (path27, opts) => fs2.rm(path27, opts),
|
|
6438
|
+
unlink: (path27) => fs2.unlink(path27),
|
|
6439
|
+
readdir: (path27) => fs2.readdir(path27),
|
|
6111
6440
|
copyFile: (src, dest) => fs2.copyFile(src, dest),
|
|
6112
|
-
chmod: (
|
|
6441
|
+
chmod: (path27, mode) => fs2.chmod(path27, mode)
|
|
6113
6442
|
};
|
|
6114
6443
|
const contextFactory = createCommandContextFactory({ fs: asyncFs });
|
|
6115
6444
|
const authFs = {
|
|
@@ -6145,7 +6474,8 @@ function createSdkContainer(options) {
|
|
|
6145
6474
|
read: readApiKey,
|
|
6146
6475
|
write: writeApiKey
|
|
6147
6476
|
},
|
|
6148
|
-
confirm: async () => true
|
|
6477
|
+
confirm: async () => true,
|
|
6478
|
+
checkAuth: async (apiKey) => await checkAuth({ apiKey }) !== null
|
|
6149
6479
|
});
|
|
6150
6480
|
const registry2 = createServiceRegistry();
|
|
6151
6481
|
const providers = getDefaultProviders().filter((adapter) => !adapter.disabled);
|
|
@@ -6202,6 +6532,7 @@ var init_container = __esm({
|
|
|
6202
6532
|
init_service_registry();
|
|
6203
6533
|
init_context();
|
|
6204
6534
|
init_prompts2();
|
|
6535
|
+
init_src7();
|
|
6205
6536
|
init_options();
|
|
6206
6537
|
init_logger2();
|
|
6207
6538
|
init_error_logger();
|
|
@@ -6811,8 +7142,8 @@ function resourceNotFound(resource) {
|
|
|
6811
7142
|
`Resource not found: ${resource}`
|
|
6812
7143
|
);
|
|
6813
7144
|
}
|
|
6814
|
-
function assertAbsolutePath(
|
|
6815
|
-
if (!isAbsolute(
|
|
7145
|
+
function assertAbsolutePath(path27) {
|
|
7146
|
+
if (!isAbsolute(path27)) {
|
|
6816
7147
|
throw invalidParams('"path" must be an absolute path');
|
|
6817
7148
|
}
|
|
6818
7149
|
}
|
|
@@ -7546,7 +7877,7 @@ var init_run_report = __esm({
|
|
|
7546
7877
|
});
|
|
7547
7878
|
|
|
7548
7879
|
// packages/poe-acp-client/src/index.ts
|
|
7549
|
-
var
|
|
7880
|
+
var init_src8 = __esm({
|
|
7550
7881
|
"packages/poe-acp-client/src/index.ts"() {
|
|
7551
7882
|
"use strict";
|
|
7552
7883
|
init_acp_client();
|
|
@@ -8573,7 +8904,7 @@ var init_acp_core = __esm({
|
|
|
8573
8904
|
});
|
|
8574
8905
|
|
|
8575
8906
|
// packages/poe-agent/src/plugins/plugin-args.ts
|
|
8576
|
-
import
|
|
8907
|
+
import path11 from "node:path";
|
|
8577
8908
|
function isObjectRecord3(value) {
|
|
8578
8909
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8579
8910
|
}
|
|
@@ -8604,13 +8935,13 @@ function getOptionalString(args, key) {
|
|
|
8604
8935
|
return value;
|
|
8605
8936
|
}
|
|
8606
8937
|
function resolveAllowedPath(cwd, allowedPaths, inputPath) {
|
|
8607
|
-
const resolvedPath =
|
|
8938
|
+
const resolvedPath = path11.resolve(cwd, inputPath);
|
|
8608
8939
|
const isAllowed = allowedPaths.some((allowedPath) => {
|
|
8609
8940
|
if (allowedPath === resolvedPath) {
|
|
8610
8941
|
return true;
|
|
8611
8942
|
}
|
|
8612
|
-
const rel =
|
|
8613
|
-
return rel.length > 0 && !rel.startsWith("..") && !
|
|
8943
|
+
const rel = path11.relative(allowedPath, resolvedPath);
|
|
8944
|
+
return rel.length > 0 && !rel.startsWith("..") && !path11.isAbsolute(rel);
|
|
8614
8945
|
});
|
|
8615
8946
|
if (!isAllowed) {
|
|
8616
8947
|
throw new Error(`Path is outside allowed paths: ${inputPath}`);
|
|
@@ -8625,7 +8956,7 @@ var init_plugin_args = __esm({
|
|
|
8625
8956
|
|
|
8626
8957
|
// packages/poe-agent/src/plugins/poe-agent-plugin-files.ts
|
|
8627
8958
|
import fsPromises2 from "node:fs/promises";
|
|
8628
|
-
import
|
|
8959
|
+
import path12 from "node:path";
|
|
8629
8960
|
async function fileExists(fs3, filePath) {
|
|
8630
8961
|
try {
|
|
8631
8962
|
await fs3.readFile(filePath, "utf8");
|
|
@@ -8649,9 +8980,9 @@ var init_poe_agent_plugin_files = __esm({
|
|
|
8649
8980
|
"use strict";
|
|
8650
8981
|
init_plugin_args();
|
|
8651
8982
|
filesPlugin = (options = {}) => {
|
|
8652
|
-
const cwd =
|
|
8983
|
+
const cwd = path12.resolve(options.cwd ?? process.cwd());
|
|
8653
8984
|
const allowedPaths = (options.allowedPaths ?? [cwd]).map(
|
|
8654
|
-
(allowedPath) =>
|
|
8985
|
+
(allowedPath) => path12.resolve(cwd, allowedPath)
|
|
8655
8986
|
);
|
|
8656
8987
|
const fs3 = options.fs ?? fsPromises2;
|
|
8657
8988
|
const readFileTool = {
|
|
@@ -8705,7 +9036,7 @@ var init_poe_agent_plugin_files = __esm({
|
|
|
8705
9036
|
async call(args) {
|
|
8706
9037
|
const command = getRequiredString(args, "command");
|
|
8707
9038
|
const filePath = resolveAllowedPath(cwd, allowedPaths, getRequiredString(args, "path"));
|
|
8708
|
-
const displayedPath =
|
|
9039
|
+
const displayedPath = path12.relative(cwd, filePath) || path12.basename(filePath);
|
|
8709
9040
|
if (command === "str_replace") {
|
|
8710
9041
|
const oldStr = getRequiredString(args, "old_str", true);
|
|
8711
9042
|
const newStr = getRequiredString(args, "new_str", true);
|
|
@@ -8725,7 +9056,7 @@ var init_poe_agent_plugin_files = __esm({
|
|
|
8725
9056
|
if (await fileExists(fs3, filePath)) {
|
|
8726
9057
|
throw new Error("File already exists \u2014 use str_replace to edit");
|
|
8727
9058
|
}
|
|
8728
|
-
await fs3.mkdir(
|
|
9059
|
+
await fs3.mkdir(path12.dirname(filePath), { recursive: true });
|
|
8729
9060
|
await fs3.writeFile(filePath, fileText, "utf8");
|
|
8730
9061
|
return `Created file: ${displayedPath}`;
|
|
8731
9062
|
}
|
|
@@ -8766,7 +9097,7 @@ var init_poe_agent_plugin_files = __esm({
|
|
|
8766
9097
|
|
|
8767
9098
|
// packages/poe-agent/src/plugins/poe-agent-plugin-shell.ts
|
|
8768
9099
|
import { exec as execCallback } from "node:child_process";
|
|
8769
|
-
import
|
|
9100
|
+
import path13 from "node:path";
|
|
8770
9101
|
import { promisify } from "node:util";
|
|
8771
9102
|
async function defaultRunCommand(command, cwd) {
|
|
8772
9103
|
try {
|
|
@@ -8799,9 +9130,9 @@ var init_poe_agent_plugin_shell = __esm({
|
|
|
8799
9130
|
init_plugin_args();
|
|
8800
9131
|
exec = promisify(execCallback);
|
|
8801
9132
|
shellPlugin = (options = {}) => {
|
|
8802
|
-
const cwd =
|
|
9133
|
+
const cwd = path13.resolve(options.cwd ?? process.cwd());
|
|
8803
9134
|
const allowedPaths = (options.allowedPaths ?? [cwd]).map(
|
|
8804
|
-
(allowedPath) =>
|
|
9135
|
+
(allowedPath) => path13.resolve(cwd, allowedPath)
|
|
8805
9136
|
);
|
|
8806
9137
|
const runCommand2 = options.runCommand ?? defaultRunCommand;
|
|
8807
9138
|
const runCommandTool = {
|
|
@@ -9585,7 +9916,7 @@ var AgentHost;
|
|
|
9585
9916
|
var init_agent_host = __esm({
|
|
9586
9917
|
"packages/poe-agent/src/runtime/agent-host.ts"() {
|
|
9587
9918
|
"use strict";
|
|
9588
|
-
|
|
9919
|
+
init_src8();
|
|
9589
9920
|
init_agent_session();
|
|
9590
9921
|
init_acp_core();
|
|
9591
9922
|
init_run_context();
|
|
@@ -9945,7 +10276,7 @@ function readDependencies(plugin) {
|
|
|
9945
10276
|
}
|
|
9946
10277
|
return normalized;
|
|
9947
10278
|
}
|
|
9948
|
-
var
|
|
10279
|
+
var init_config2 = __esm({
|
|
9949
10280
|
"packages/poe-agent/src/runtime/config.ts"() {
|
|
9950
10281
|
"use strict";
|
|
9951
10282
|
}
|
|
@@ -10872,7 +11203,7 @@ var init_internal = __esm({
|
|
|
10872
11203
|
});
|
|
10873
11204
|
|
|
10874
11205
|
// packages/tiny-mcp-client/src/index.ts
|
|
10875
|
-
var
|
|
11206
|
+
var init_src9 = __esm({
|
|
10876
11207
|
"packages/tiny-mcp-client/src/index.ts"() {
|
|
10877
11208
|
"use strict";
|
|
10878
11209
|
init_internal();
|
|
@@ -10921,7 +11252,7 @@ var DEFAULT_MCP_CLIENT_INFO, PluginApiImpl;
|
|
|
10921
11252
|
var init_plugin_api_impl = __esm({
|
|
10922
11253
|
"packages/poe-agent/src/runtime/plugin-api-impl.ts"() {
|
|
10923
11254
|
"use strict";
|
|
10924
|
-
|
|
11255
|
+
init_src9();
|
|
10925
11256
|
init_hooks();
|
|
10926
11257
|
DEFAULT_MCP_CLIENT_INFO = {
|
|
10927
11258
|
name: "poe-agent",
|
|
@@ -11252,7 +11583,7 @@ var init_agent = __esm({
|
|
|
11252
11583
|
init_acp_core();
|
|
11253
11584
|
init_agent_host();
|
|
11254
11585
|
init_hooks();
|
|
11255
|
-
|
|
11586
|
+
init_config2();
|
|
11256
11587
|
init_plugin_setup();
|
|
11257
11588
|
init_run_context();
|
|
11258
11589
|
ImmutableAgentBuilder = class _ImmutableAgentBuilder {
|
|
@@ -11488,7 +11819,7 @@ __export(src_exports, {
|
|
|
11488
11819
|
agent: () => agent,
|
|
11489
11820
|
createAgentSession: () => createAgentSession
|
|
11490
11821
|
});
|
|
11491
|
-
var
|
|
11822
|
+
var init_src10 = __esm({
|
|
11492
11823
|
"packages/poe-agent/src/index.ts"() {
|
|
11493
11824
|
"use strict";
|
|
11494
11825
|
init_agent();
|
|
@@ -11826,7 +12157,7 @@ function createInMemoryAcpTransport2(options) {
|
|
|
11826
12157
|
}
|
|
11827
12158
|
if (method === "session/new") {
|
|
11828
12159
|
const request = params;
|
|
11829
|
-
const { createAgentSession: createAgentSession2 } = await Promise.resolve().then(() => (
|
|
12160
|
+
const { createAgentSession: createAgentSession2 } = await Promise.resolve().then(() => (init_src10(), src_exports));
|
|
11830
12161
|
const session = await createAgentSession2({
|
|
11831
12162
|
model: options.model,
|
|
11832
12163
|
cwd: request.cwd || options.cwd,
|
|
@@ -11976,7 +12307,7 @@ var init_poe_agent = __esm({
|
|
|
11976
12307
|
"src/providers/poe-agent.ts"() {
|
|
11977
12308
|
"use strict";
|
|
11978
12309
|
init_constants();
|
|
11979
|
-
|
|
12310
|
+
init_src8();
|
|
11980
12311
|
init_create_provider();
|
|
11981
12312
|
poeAgentService = createProvider({
|
|
11982
12313
|
id: "poe-agent",
|
|
@@ -12145,7 +12476,7 @@ var init_spawn3 = __esm({
|
|
|
12145
12476
|
});
|
|
12146
12477
|
|
|
12147
12478
|
// packages/pipeline/src/utils.ts
|
|
12148
|
-
function
|
|
12479
|
+
function isRecord3(value) {
|
|
12149
12480
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
12150
12481
|
}
|
|
12151
12482
|
function isNotFound2(error2) {
|
|
@@ -12179,7 +12510,7 @@ var init_utils2 = __esm({
|
|
|
12179
12510
|
});
|
|
12180
12511
|
|
|
12181
12512
|
// packages/pipeline/src/config/loader.ts
|
|
12182
|
-
import
|
|
12513
|
+
import path14 from "node:path";
|
|
12183
12514
|
import { parse as parse4 } from "yaml";
|
|
12184
12515
|
function asStepMode(value) {
|
|
12185
12516
|
if (value === void 0 || value === null) {
|
|
@@ -12203,19 +12534,19 @@ function parseStepConfigDocument(filePath, content) {
|
|
|
12203
12534
|
if (document === null || document === void 0) {
|
|
12204
12535
|
return {};
|
|
12205
12536
|
}
|
|
12206
|
-
if (!
|
|
12537
|
+
if (!isRecord3(document)) {
|
|
12207
12538
|
throw new Error(`Invalid pipeline step config in "${filePath}": expected a top-level object.`);
|
|
12208
12539
|
}
|
|
12209
12540
|
const stepsValue = document.steps;
|
|
12210
12541
|
if (stepsValue === void 0 || stepsValue === null) {
|
|
12211
12542
|
return {};
|
|
12212
12543
|
}
|
|
12213
|
-
if (!
|
|
12544
|
+
if (!isRecord3(stepsValue)) {
|
|
12214
12545
|
throw new Error(`Invalid pipeline step config in "${filePath}": "steps" must be an object.`);
|
|
12215
12546
|
}
|
|
12216
12547
|
const steps = {};
|
|
12217
12548
|
for (const [stepName, value] of Object.entries(stepsValue)) {
|
|
12218
|
-
if (!
|
|
12549
|
+
if (!isRecord3(value)) {
|
|
12219
12550
|
throw new Error(`Invalid step "${stepName}" in "${filePath}": expected an object.`);
|
|
12220
12551
|
}
|
|
12221
12552
|
const instruction = value.instruction;
|
|
@@ -12237,7 +12568,7 @@ function parseConfigDocument(filePath, content) {
|
|
|
12237
12568
|
if (document === null || document === void 0) {
|
|
12238
12569
|
return {};
|
|
12239
12570
|
}
|
|
12240
|
-
if (!
|
|
12571
|
+
if (!isRecord3(document)) {
|
|
12241
12572
|
throw new Error(`Invalid pipeline config in "${filePath}": expected a top-level object.`);
|
|
12242
12573
|
}
|
|
12243
12574
|
const planPath = document.planPath;
|
|
@@ -12263,8 +12594,8 @@ async function loadStepsFile(fs3, filePath) {
|
|
|
12263
12594
|
return parseStepConfigDocument(filePath, content);
|
|
12264
12595
|
}
|
|
12265
12596
|
async function loadPipelineConfig(options) {
|
|
12266
|
-
const globalPath =
|
|
12267
|
-
const projectPath =
|
|
12597
|
+
const globalPath = path14.join(options.homeDir, ".poe-code", "pipeline", "config.yaml");
|
|
12598
|
+
const projectPath = path14.join(options.cwd, ".poe-code", "pipeline", "config.yaml");
|
|
12268
12599
|
const [globalConfig2, projectConfig] = await Promise.all([
|
|
12269
12600
|
loadConfigFile(options.fs, globalPath),
|
|
12270
12601
|
loadConfigFile(options.fs, projectPath)
|
|
@@ -12275,8 +12606,8 @@ async function loadPipelineConfig(options) {
|
|
|
12275
12606
|
};
|
|
12276
12607
|
}
|
|
12277
12608
|
async function loadResolvedSteps(options) {
|
|
12278
|
-
const globalPath =
|
|
12279
|
-
const projectPath =
|
|
12609
|
+
const globalPath = path14.join(options.homeDir, ".poe-code", "pipeline", "steps.yaml");
|
|
12610
|
+
const projectPath = path14.join(options.cwd, ".poe-code", "pipeline", "steps.yaml");
|
|
12280
12611
|
const [globalSteps, projectSteps] = await Promise.all([
|
|
12281
12612
|
loadStepsFile(options.fs, globalPath),
|
|
12282
12613
|
loadStepsFile(options.fs, projectPath)
|
|
@@ -12315,7 +12646,7 @@ function parseTaskStatus(value, availableSteps, taskId) {
|
|
|
12315
12646
|
if (typeof value === "string") {
|
|
12316
12647
|
return normalizeStatus(value, "task status");
|
|
12317
12648
|
}
|
|
12318
|
-
if (!
|
|
12649
|
+
if (!isRecord3(value)) {
|
|
12319
12650
|
throw new Error(`Invalid status for task "${taskId}": expected a string or step-status map.`);
|
|
12320
12651
|
}
|
|
12321
12652
|
const statusMap = {};
|
|
@@ -12335,7 +12666,7 @@ function parsePlan(yamlContent, options = {}) {
|
|
|
12335
12666
|
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
12336
12667
|
throw new Error(`Invalid plan YAML: ${message}`);
|
|
12337
12668
|
}
|
|
12338
|
-
if (!
|
|
12669
|
+
if (!isRecord3(document)) {
|
|
12339
12670
|
throw new Error("Invalid plan YAML: expected a top-level object.");
|
|
12340
12671
|
}
|
|
12341
12672
|
const tasksValue = document.tasks;
|
|
@@ -12344,7 +12675,7 @@ function parsePlan(yamlContent, options = {}) {
|
|
|
12344
12675
|
}
|
|
12345
12676
|
const ids = /* @__PURE__ */ new Set();
|
|
12346
12677
|
const tasks = tasksValue.map((value, index) => {
|
|
12347
|
-
if (!
|
|
12678
|
+
if (!isRecord3(value)) {
|
|
12348
12679
|
throw new Error(`Invalid tasks[${index}]: expected an object.`);
|
|
12349
12680
|
}
|
|
12350
12681
|
const id = asRequiredString(value.id, `tasks[${index}].id`);
|
|
@@ -12369,18 +12700,18 @@ var init_parser = __esm({
|
|
|
12369
12700
|
});
|
|
12370
12701
|
|
|
12371
12702
|
// packages/pipeline/src/plan/discovery.ts
|
|
12372
|
-
import
|
|
12703
|
+
import path15 from "node:path";
|
|
12373
12704
|
import * as fsPromises3 from "node:fs/promises";
|
|
12374
12705
|
function createDefaultFs() {
|
|
12375
12706
|
return {
|
|
12376
12707
|
readFile: fsPromises3.readFile,
|
|
12377
12708
|
readdir: fsPromises3.readdir,
|
|
12378
12709
|
stat: async (filePath) => {
|
|
12379
|
-
const
|
|
12710
|
+
const stat8 = await fsPromises3.stat(filePath);
|
|
12380
12711
|
return {
|
|
12381
|
-
isFile: () =>
|
|
12382
|
-
isDirectory: () =>
|
|
12383
|
-
mtimeMs:
|
|
12712
|
+
isFile: () => stat8.isFile(),
|
|
12713
|
+
isDirectory: () => stat8.isDirectory(),
|
|
12714
|
+
mtimeMs: stat8.mtimeMs
|
|
12384
12715
|
};
|
|
12385
12716
|
}
|
|
12386
12717
|
};
|
|
@@ -12405,10 +12736,10 @@ function countCompletedTasks(planPath, content) {
|
|
|
12405
12736
|
};
|
|
12406
12737
|
}
|
|
12407
12738
|
async function ensurePlanExists(fs3, cwd, planPath) {
|
|
12408
|
-
const absolutePath =
|
|
12739
|
+
const absolutePath = path15.isAbsolute(planPath) ? planPath : path15.resolve(cwd, planPath);
|
|
12409
12740
|
try {
|
|
12410
|
-
const
|
|
12411
|
-
if (!
|
|
12741
|
+
const stat8 = await fs3.stat(absolutePath);
|
|
12742
|
+
if (!stat8.isFile()) {
|
|
12412
12743
|
throw new Error(`Plan not found at "${planPath}".`);
|
|
12413
12744
|
}
|
|
12414
12745
|
} catch (error2) {
|
|
@@ -12433,20 +12764,20 @@ async function scanPlansDir(fs3, plansDir, displayPrefix) {
|
|
|
12433
12764
|
if (!isPlanCandidateFile(entry)) {
|
|
12434
12765
|
continue;
|
|
12435
12766
|
}
|
|
12436
|
-
const absolutePath =
|
|
12437
|
-
const
|
|
12438
|
-
if (!
|
|
12767
|
+
const absolutePath = path15.join(plansDir, entry);
|
|
12768
|
+
const stat8 = await fs3.stat(absolutePath);
|
|
12769
|
+
if (!stat8.isFile()) {
|
|
12439
12770
|
continue;
|
|
12440
12771
|
}
|
|
12441
|
-
const displayPath =
|
|
12772
|
+
const displayPath = path15.join(displayPrefix, entry);
|
|
12442
12773
|
const content = await fs3.readFile(absolutePath, "utf8");
|
|
12443
12774
|
candidates.push(countCompletedTasks(displayPath, content));
|
|
12444
12775
|
}
|
|
12445
12776
|
return candidates;
|
|
12446
12777
|
}
|
|
12447
12778
|
async function listPlanCandidates(fs3, cwd, homeDir) {
|
|
12448
|
-
const projectDir =
|
|
12449
|
-
const globalDir =
|
|
12779
|
+
const projectDir = path15.join(cwd, ".poe-code", "pipeline", "plans");
|
|
12780
|
+
const globalDir = path15.join(homeDir, ".poe-code", "pipeline", "plans");
|
|
12450
12781
|
const [projectCandidates, globalCandidates] = await Promise.all([
|
|
12451
12782
|
scanPlansDir(fs3, projectDir, ".poe-code/pipeline/plans"),
|
|
12452
12783
|
scanPlansDir(fs3, globalDir, "~/.poe-code/pipeline/plans")
|
|
@@ -12457,9 +12788,9 @@ async function listPlanCandidates(fs3, cwd, homeDir) {
|
|
|
12457
12788
|
}
|
|
12458
12789
|
function resolveAbsolutePlanPath(planPath, cwd, homeDir) {
|
|
12459
12790
|
if (planPath.startsWith("~/")) {
|
|
12460
|
-
return
|
|
12791
|
+
return path15.join(homeDir, planPath.slice(2));
|
|
12461
12792
|
}
|
|
12462
|
-
return
|
|
12793
|
+
return path15.isAbsolute(planPath) ? planPath : path15.resolve(cwd, planPath);
|
|
12463
12794
|
}
|
|
12464
12795
|
async function resolvePlanPath(options) {
|
|
12465
12796
|
const fs3 = options.fs ?? createDefaultFs();
|
|
@@ -12516,7 +12847,7 @@ var init_discovery = __esm({
|
|
|
12516
12847
|
});
|
|
12517
12848
|
|
|
12518
12849
|
// packages/pipeline/src/plan/writer.ts
|
|
12519
|
-
import { parseDocument, isMap, isSeq } from "yaml";
|
|
12850
|
+
import { parseDocument as parseDocument2, isMap, isSeq } from "yaml";
|
|
12520
12851
|
function getTasksNode(document) {
|
|
12521
12852
|
const tasksNode = document.get("tasks", true);
|
|
12522
12853
|
if (!tasksNode || !isSeq(tasksNode)) {
|
|
@@ -12540,7 +12871,7 @@ async function readPlanFile(fs3, planPath) {
|
|
|
12540
12871
|
}
|
|
12541
12872
|
async function writeTaskStatus(options) {
|
|
12542
12873
|
const content = await readPlanFile(options.fs, options.planPath);
|
|
12543
|
-
const document =
|
|
12874
|
+
const document = parseDocument2(content);
|
|
12544
12875
|
const tasksNode = getTasksNode(document);
|
|
12545
12876
|
const taskNode = getTaskNode(tasksNode, options.taskId);
|
|
12546
12877
|
if (options.stepName) {
|
|
@@ -12646,11 +12977,11 @@ function createDefaultFs2() {
|
|
|
12646
12977
|
},
|
|
12647
12978
|
rmdir: fsPromises4.rmdir,
|
|
12648
12979
|
stat: async (filePath) => {
|
|
12649
|
-
const
|
|
12980
|
+
const stat8 = await fsPromises4.stat(filePath);
|
|
12650
12981
|
return {
|
|
12651
|
-
isFile: () =>
|
|
12652
|
-
isDirectory: () =>
|
|
12653
|
-
mtimeMs:
|
|
12982
|
+
isFile: () => stat8.isFile(),
|
|
12983
|
+
isDirectory: () => stat8.isDirectory(),
|
|
12984
|
+
mtimeMs: stat8.mtimeMs
|
|
12654
12985
|
};
|
|
12655
12986
|
}
|
|
12656
12987
|
};
|
|
@@ -12683,8 +13014,8 @@ async function lockFile(filePath, options = {}) {
|
|
|
12683
13014
|
if (!error2 || typeof error2 !== "object" || !("code" in error2) || error2.code !== "EEXIST") {
|
|
12684
13015
|
throw error2;
|
|
12685
13016
|
}
|
|
12686
|
-
const
|
|
12687
|
-
if (Date.now() -
|
|
13017
|
+
const stat8 = await fs3.stat(lockPath);
|
|
13018
|
+
if (Date.now() - stat8.mtimeMs > staleMs) {
|
|
12688
13019
|
await fs3.rmdir(lockPath);
|
|
12689
13020
|
continue;
|
|
12690
13021
|
}
|
|
@@ -12702,7 +13033,7 @@ var init_lock = __esm({
|
|
|
12702
13033
|
});
|
|
12703
13034
|
|
|
12704
13035
|
// packages/pipeline/src/run/pipeline.ts
|
|
12705
|
-
import
|
|
13036
|
+
import path16 from "node:path";
|
|
12706
13037
|
import * as fsPromises5 from "node:fs/promises";
|
|
12707
13038
|
function createDefaultFs3() {
|
|
12708
13039
|
return {
|
|
@@ -12710,11 +13041,11 @@ function createDefaultFs3() {
|
|
|
12710
13041
|
writeFile: fsPromises5.writeFile,
|
|
12711
13042
|
readdir: fsPromises5.readdir,
|
|
12712
13043
|
stat: async (filePath) => {
|
|
12713
|
-
const
|
|
13044
|
+
const stat8 = await fsPromises5.stat(filePath);
|
|
12714
13045
|
return {
|
|
12715
|
-
isFile: () =>
|
|
12716
|
-
isDirectory: () =>
|
|
12717
|
-
mtimeMs:
|
|
13046
|
+
isFile: () => stat8.isFile(),
|
|
13047
|
+
isDirectory: () => stat8.isDirectory(),
|
|
13048
|
+
mtimeMs: stat8.mtimeMs
|
|
12718
13049
|
};
|
|
12719
13050
|
},
|
|
12720
13051
|
mkdir: async (filePath, options) => {
|
|
@@ -12738,9 +13069,9 @@ function resolveMode(stepName, steps) {
|
|
|
12738
13069
|
return step.mode;
|
|
12739
13070
|
}
|
|
12740
13071
|
async function archivePlan(fs3, absolutePlanPath) {
|
|
12741
|
-
const dir =
|
|
12742
|
-
const archiveDir =
|
|
12743
|
-
const archivePath =
|
|
13072
|
+
const dir = path16.dirname(absolutePlanPath);
|
|
13073
|
+
const archiveDir = path16.join(dir, "archive");
|
|
13074
|
+
const archivePath = path16.join(archiveDir, path16.basename(absolutePlanPath));
|
|
12744
13075
|
await fs3.mkdir(archiveDir, { recursive: true });
|
|
12745
13076
|
await fs3.rename(absolutePlanPath, archivePath);
|
|
12746
13077
|
}
|
|
@@ -12975,7 +13306,7 @@ var init_pipeline = __esm({
|
|
|
12975
13306
|
});
|
|
12976
13307
|
|
|
12977
13308
|
// packages/pipeline/src/index.ts
|
|
12978
|
-
var
|
|
13309
|
+
var init_src11 = __esm({
|
|
12979
13310
|
"packages/pipeline/src/index.ts"() {
|
|
12980
13311
|
"use strict";
|
|
12981
13312
|
init_loader();
|
|
@@ -13007,7 +13338,286 @@ async function runPipeline2(options) {
|
|
|
13007
13338
|
var init_pipeline2 = __esm({
|
|
13008
13339
|
async "src/sdk/pipeline.ts"() {
|
|
13009
13340
|
"use strict";
|
|
13010
|
-
|
|
13341
|
+
init_src11();
|
|
13342
|
+
init_src5();
|
|
13343
|
+
await init_spawn3();
|
|
13344
|
+
}
|
|
13345
|
+
});
|
|
13346
|
+
|
|
13347
|
+
// packages/ralph/src/discovery/discovery.ts
|
|
13348
|
+
import path17 from "node:path";
|
|
13349
|
+
import * as fsPromises6 from "node:fs/promises";
|
|
13350
|
+
function createDefaultFs4() {
|
|
13351
|
+
return {
|
|
13352
|
+
readFile: fsPromises6.readFile,
|
|
13353
|
+
readdir: fsPromises6.readdir,
|
|
13354
|
+
stat: async (filePath) => {
|
|
13355
|
+
const stat8 = await fsPromises6.stat(filePath);
|
|
13356
|
+
return {
|
|
13357
|
+
isFile: () => stat8.isFile(),
|
|
13358
|
+
mtimeMs: stat8.mtimeMs
|
|
13359
|
+
};
|
|
13360
|
+
}
|
|
13361
|
+
};
|
|
13362
|
+
}
|
|
13363
|
+
function isNotFound3(error2) {
|
|
13364
|
+
return !!error2 && typeof error2 === "object" && "code" in error2 && error2.code === "ENOENT";
|
|
13365
|
+
}
|
|
13366
|
+
function isMarkdownFile(entry) {
|
|
13367
|
+
return entry.toLowerCase().endsWith(".md");
|
|
13368
|
+
}
|
|
13369
|
+
async function scanDir(fs3, absoluteDir, displayDir) {
|
|
13370
|
+
let entries;
|
|
13371
|
+
try {
|
|
13372
|
+
entries = await fs3.readdir(absoluteDir);
|
|
13373
|
+
} catch (error2) {
|
|
13374
|
+
if (isNotFound3(error2)) {
|
|
13375
|
+
return [];
|
|
13376
|
+
}
|
|
13377
|
+
throw error2;
|
|
13378
|
+
}
|
|
13379
|
+
const docs = [];
|
|
13380
|
+
for (const entry of entries) {
|
|
13381
|
+
if (!isMarkdownFile(entry)) {
|
|
13382
|
+
continue;
|
|
13383
|
+
}
|
|
13384
|
+
const absolutePath = path17.join(absoluteDir, entry);
|
|
13385
|
+
const stat8 = await fs3.stat(absolutePath);
|
|
13386
|
+
if (!stat8.isFile()) {
|
|
13387
|
+
continue;
|
|
13388
|
+
}
|
|
13389
|
+
const displayPath = path17.join(displayDir, entry);
|
|
13390
|
+
docs.push({
|
|
13391
|
+
path: displayPath,
|
|
13392
|
+
displayPath
|
|
13393
|
+
});
|
|
13394
|
+
}
|
|
13395
|
+
return docs;
|
|
13396
|
+
}
|
|
13397
|
+
async function discoverDocs(options) {
|
|
13398
|
+
const fs3 = options.fs ?? createDefaultFs4();
|
|
13399
|
+
const [localDocs, globalDocs] = await Promise.all([
|
|
13400
|
+
scanDir(
|
|
13401
|
+
fs3,
|
|
13402
|
+
path17.join(options.cwd, ".poe-code", "ralph", "plans"),
|
|
13403
|
+
".poe-code/ralph/plans"
|
|
13404
|
+
),
|
|
13405
|
+
scanDir(
|
|
13406
|
+
fs3,
|
|
13407
|
+
path17.join(options.homeDir, ".poe-code", "ralph", "plans"),
|
|
13408
|
+
"~/.poe-code/ralph/plans"
|
|
13409
|
+
)
|
|
13410
|
+
]);
|
|
13411
|
+
return [...localDocs, ...globalDocs].sort((left, right) => {
|
|
13412
|
+
const leftName = path17.basename(left.displayPath).toLowerCase();
|
|
13413
|
+
const rightName = path17.basename(right.displayPath).toLowerCase();
|
|
13414
|
+
return leftName === rightName ? left.displayPath.localeCompare(right.displayPath) : leftName.localeCompare(rightName);
|
|
13415
|
+
});
|
|
13416
|
+
}
|
|
13417
|
+
var init_discovery2 = __esm({
|
|
13418
|
+
"packages/ralph/src/discovery/discovery.ts"() {
|
|
13419
|
+
"use strict";
|
|
13420
|
+
}
|
|
13421
|
+
});
|
|
13422
|
+
|
|
13423
|
+
// packages/ralph/src/overbaking/detector.ts
|
|
13424
|
+
var OverbakingDetector;
|
|
13425
|
+
var init_detector = __esm({
|
|
13426
|
+
"packages/ralph/src/overbaking/detector.ts"() {
|
|
13427
|
+
"use strict";
|
|
13428
|
+
OverbakingDetector = class {
|
|
13429
|
+
threshold;
|
|
13430
|
+
consecutiveFailures = 0;
|
|
13431
|
+
constructor(threshold) {
|
|
13432
|
+
this.threshold = threshold;
|
|
13433
|
+
}
|
|
13434
|
+
record(_success) {
|
|
13435
|
+
if (_success) {
|
|
13436
|
+
this.consecutiveFailures = 0;
|
|
13437
|
+
return {
|
|
13438
|
+
consecutiveFailures: 0,
|
|
13439
|
+
overbaked: false,
|
|
13440
|
+
shouldWarn: false
|
|
13441
|
+
};
|
|
13442
|
+
}
|
|
13443
|
+
this.consecutiveFailures += 1;
|
|
13444
|
+
return {
|
|
13445
|
+
consecutiveFailures: this.consecutiveFailures,
|
|
13446
|
+
overbaked: this.consecutiveFailures >= this.threshold,
|
|
13447
|
+
shouldWarn: this.consecutiveFailures === this.threshold
|
|
13448
|
+
};
|
|
13449
|
+
}
|
|
13450
|
+
};
|
|
13451
|
+
}
|
|
13452
|
+
});
|
|
13453
|
+
|
|
13454
|
+
// packages/ralph/src/run/ralph.ts
|
|
13455
|
+
import path18 from "node:path";
|
|
13456
|
+
import * as fsPromises7 from "node:fs/promises";
|
|
13457
|
+
async function runRalph(options) {
|
|
13458
|
+
const fs3 = options.fs ?? createDefaultFs5();
|
|
13459
|
+
const runAgent = options.runAgent;
|
|
13460
|
+
if (!runAgent) {
|
|
13461
|
+
throw new Error("runRalph requires a runAgent implementation.");
|
|
13462
|
+
}
|
|
13463
|
+
if (!Number.isInteger(options.maxIterations) || options.maxIterations < 1) {
|
|
13464
|
+
throw new Error("maxIterations must be a positive integer.");
|
|
13465
|
+
}
|
|
13466
|
+
const threshold = options.maxFailures ?? 3;
|
|
13467
|
+
if (!Number.isInteger(threshold) || threshold < 1) {
|
|
13468
|
+
throw new Error("maxFailures must be a positive integer.");
|
|
13469
|
+
}
|
|
13470
|
+
const absoluteDocPath = resolveAbsoluteDocPath(
|
|
13471
|
+
options.docPath,
|
|
13472
|
+
options.cwd,
|
|
13473
|
+
options.homeDir
|
|
13474
|
+
);
|
|
13475
|
+
const prompt = await fs3.readFile(absoluteDocPath, "utf8");
|
|
13476
|
+
const detector = new OverbakingDetector(threshold);
|
|
13477
|
+
const startTime = Date.now();
|
|
13478
|
+
let iterationsCompleted = 0;
|
|
13479
|
+
try {
|
|
13480
|
+
for (let iteration = 1; iteration <= options.maxIterations; iteration += 1) {
|
|
13481
|
+
assertNotAborted5(options.signal);
|
|
13482
|
+
options.onIterationStart?.(iteration, options.maxIterations);
|
|
13483
|
+
const iterationStart = Date.now();
|
|
13484
|
+
let result;
|
|
13485
|
+
try {
|
|
13486
|
+
result = await runAgent({
|
|
13487
|
+
agent: options.agent,
|
|
13488
|
+
prompt,
|
|
13489
|
+
cwd: options.cwd,
|
|
13490
|
+
...options.model ? { model: options.model } : {},
|
|
13491
|
+
...options.signal ? { signal: options.signal } : {}
|
|
13492
|
+
});
|
|
13493
|
+
} catch (error2) {
|
|
13494
|
+
if (isAbortError2(error2)) {
|
|
13495
|
+
return {
|
|
13496
|
+
stopReason: "cancelled",
|
|
13497
|
+
docPath: options.docPath,
|
|
13498
|
+
iterationsCompleted,
|
|
13499
|
+
totalDurationMs: Date.now() - startTime
|
|
13500
|
+
};
|
|
13501
|
+
}
|
|
13502
|
+
throw error2;
|
|
13503
|
+
}
|
|
13504
|
+
const success2 = result.exitCode === 0;
|
|
13505
|
+
iterationsCompleted += 1;
|
|
13506
|
+
options.onIterationComplete?.(
|
|
13507
|
+
iteration,
|
|
13508
|
+
Date.now() - iterationStart,
|
|
13509
|
+
success2
|
|
13510
|
+
);
|
|
13511
|
+
const overbake = detector.record(success2);
|
|
13512
|
+
if (!overbake.shouldWarn) {
|
|
13513
|
+
continue;
|
|
13514
|
+
}
|
|
13515
|
+
options.onOverbakeWarning?.(
|
|
13516
|
+
overbake.consecutiveFailures,
|
|
13517
|
+
threshold
|
|
13518
|
+
);
|
|
13519
|
+
const action = options.promptOverbake ? await options.promptOverbake({
|
|
13520
|
+
consecutiveFailures: overbake.consecutiveFailures,
|
|
13521
|
+
threshold
|
|
13522
|
+
}) : "abort";
|
|
13523
|
+
if (action === "abort") {
|
|
13524
|
+
return {
|
|
13525
|
+
stopReason: "overbake_abort",
|
|
13526
|
+
docPath: options.docPath,
|
|
13527
|
+
iterationsCompleted,
|
|
13528
|
+
totalDurationMs: Date.now() - startTime
|
|
13529
|
+
};
|
|
13530
|
+
}
|
|
13531
|
+
}
|
|
13532
|
+
} catch (error2) {
|
|
13533
|
+
if (isAbortError2(error2)) {
|
|
13534
|
+
return {
|
|
13535
|
+
stopReason: "cancelled",
|
|
13536
|
+
docPath: options.docPath,
|
|
13537
|
+
iterationsCompleted,
|
|
13538
|
+
totalDurationMs: Date.now() - startTime
|
|
13539
|
+
};
|
|
13540
|
+
}
|
|
13541
|
+
throw error2;
|
|
13542
|
+
}
|
|
13543
|
+
return {
|
|
13544
|
+
stopReason: "max_iterations",
|
|
13545
|
+
docPath: options.docPath,
|
|
13546
|
+
iterationsCompleted,
|
|
13547
|
+
totalDurationMs: Date.now() - startTime
|
|
13548
|
+
};
|
|
13549
|
+
}
|
|
13550
|
+
function createDefaultFs5() {
|
|
13551
|
+
return {
|
|
13552
|
+
readFile: fsPromises7.readFile,
|
|
13553
|
+
readdir: fsPromises7.readdir,
|
|
13554
|
+
stat: async (filePath) => {
|
|
13555
|
+
const stat8 = await fsPromises7.stat(filePath);
|
|
13556
|
+
return {
|
|
13557
|
+
isFile: () => stat8.isFile(),
|
|
13558
|
+
mtimeMs: stat8.mtimeMs
|
|
13559
|
+
};
|
|
13560
|
+
}
|
|
13561
|
+
};
|
|
13562
|
+
}
|
|
13563
|
+
function resolveAbsoluteDocPath(docPath, cwd, homeDir) {
|
|
13564
|
+
if (docPath.startsWith("~/")) {
|
|
13565
|
+
return path18.join(homeDir, docPath.slice(2));
|
|
13566
|
+
}
|
|
13567
|
+
return path18.isAbsolute(docPath) ? docPath : path18.resolve(cwd, docPath);
|
|
13568
|
+
}
|
|
13569
|
+
function assertNotAborted5(signal) {
|
|
13570
|
+
if (!signal?.aborted) {
|
|
13571
|
+
return;
|
|
13572
|
+
}
|
|
13573
|
+
throw createAbortError4();
|
|
13574
|
+
}
|
|
13575
|
+
function createAbortError4() {
|
|
13576
|
+
const error2 = new Error("Ralph run cancelled");
|
|
13577
|
+
error2.name = "AbortError";
|
|
13578
|
+
return error2;
|
|
13579
|
+
}
|
|
13580
|
+
function isAbortError2(error2) {
|
|
13581
|
+
return error2 instanceof Error && error2.name === "AbortError";
|
|
13582
|
+
}
|
|
13583
|
+
var init_ralph = __esm({
|
|
13584
|
+
"packages/ralph/src/run/ralph.ts"() {
|
|
13585
|
+
"use strict";
|
|
13586
|
+
init_detector();
|
|
13587
|
+
}
|
|
13588
|
+
});
|
|
13589
|
+
|
|
13590
|
+
// packages/ralph/src/index.ts
|
|
13591
|
+
var init_src12 = __esm({
|
|
13592
|
+
"packages/ralph/src/index.ts"() {
|
|
13593
|
+
"use strict";
|
|
13594
|
+
init_discovery2();
|
|
13595
|
+
init_detector();
|
|
13596
|
+
init_ralph();
|
|
13597
|
+
}
|
|
13598
|
+
});
|
|
13599
|
+
|
|
13600
|
+
// src/sdk/ralph.ts
|
|
13601
|
+
async function runRalph2(options) {
|
|
13602
|
+
return runRalph({
|
|
13603
|
+
...options,
|
|
13604
|
+
runAgent: async (input) => {
|
|
13605
|
+
const { events, result } = spawn5(input.agent, {
|
|
13606
|
+
prompt: input.prompt,
|
|
13607
|
+
cwd: input.cwd,
|
|
13608
|
+
model: input.model,
|
|
13609
|
+
mode: "yolo",
|
|
13610
|
+
...input.signal ? { signal: input.signal } : {}
|
|
13611
|
+
});
|
|
13612
|
+
await renderAcpStream(events);
|
|
13613
|
+
return result;
|
|
13614
|
+
}
|
|
13615
|
+
});
|
|
13616
|
+
}
|
|
13617
|
+
var init_ralph2 = __esm({
|
|
13618
|
+
async "src/sdk/ralph.ts"() {
|
|
13619
|
+
"use strict";
|
|
13620
|
+
init_src12();
|
|
13011
13621
|
init_src5();
|
|
13012
13622
|
await init_spawn3();
|
|
13013
13623
|
}
|
|
@@ -13077,13 +13687,13 @@ async function readErrorBody(response) {
|
|
|
13077
13687
|
}
|
|
13078
13688
|
}
|
|
13079
13689
|
function extractTextContent(data) {
|
|
13080
|
-
if (!
|
|
13690
|
+
if (!isRecord4(data)) return void 0;
|
|
13081
13691
|
const choices = data.choices;
|
|
13082
13692
|
if (!Array.isArray(choices) || choices.length === 0) return void 0;
|
|
13083
13693
|
const first = choices[0];
|
|
13084
|
-
if (!
|
|
13694
|
+
if (!isRecord4(first)) return void 0;
|
|
13085
13695
|
const message = first.message;
|
|
13086
|
-
if (!
|
|
13696
|
+
if (!isRecord4(message)) return void 0;
|
|
13087
13697
|
return typeof message.content === "string" ? message.content : void 0;
|
|
13088
13698
|
}
|
|
13089
13699
|
function extractMediaFromCompletion(data) {
|
|
@@ -13091,14 +13701,14 @@ function extractMediaFromCompletion(data) {
|
|
|
13091
13701
|
if (!content) return {};
|
|
13092
13702
|
try {
|
|
13093
13703
|
const parsed = JSON.parse(content);
|
|
13094
|
-
if (
|
|
13704
|
+
if (isRecord4(parsed) && typeof parsed.url === "string") {
|
|
13095
13705
|
return {
|
|
13096
13706
|
url: parsed.url,
|
|
13097
13707
|
mimeType: typeof parsed.mimeType === "string" ? parsed.mimeType : void 0,
|
|
13098
13708
|
data: typeof parsed.data === "string" ? parsed.data : void 0
|
|
13099
13709
|
};
|
|
13100
13710
|
}
|
|
13101
|
-
if (
|
|
13711
|
+
if (isRecord4(parsed) && typeof parsed.data === "string") {
|
|
13102
13712
|
return {
|
|
13103
13713
|
data: parsed.data,
|
|
13104
13714
|
mimeType: typeof parsed.mimeType === "string" ? parsed.mimeType : void 0
|
|
@@ -13132,7 +13742,7 @@ function isValidUrl(value) {
|
|
|
13132
13742
|
return false;
|
|
13133
13743
|
}
|
|
13134
13744
|
}
|
|
13135
|
-
function
|
|
13745
|
+
function isRecord4(value) {
|
|
13136
13746
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
13137
13747
|
}
|
|
13138
13748
|
var init_llm_client = __esm({
|
|
@@ -13172,218 +13782,6 @@ var init_client_instance = __esm({
|
|
|
13172
13782
|
}
|
|
13173
13783
|
});
|
|
13174
13784
|
|
|
13175
|
-
// packages/poe-oauth/src/check-auth.ts
|
|
13176
|
-
var init_check_auth = __esm({
|
|
13177
|
-
"packages/poe-oauth/src/check-auth.ts"() {
|
|
13178
|
-
"use strict";
|
|
13179
|
-
}
|
|
13180
|
-
});
|
|
13181
|
-
|
|
13182
|
-
// packages/poe-oauth/src/api-key-validation.ts
|
|
13183
|
-
var init_api_key_validation = __esm({
|
|
13184
|
-
"packages/poe-oauth/src/api-key-validation.ts"() {
|
|
13185
|
-
"use strict";
|
|
13186
|
-
}
|
|
13187
|
-
});
|
|
13188
|
-
|
|
13189
|
-
// packages/poe-oauth/src/oauth-client.ts
|
|
13190
|
-
import http from "node:http";
|
|
13191
|
-
import crypto from "node:crypto";
|
|
13192
|
-
function createOAuthClient(config2) {
|
|
13193
|
-
const fetchFn = config2.fetch ?? globalThis.fetch;
|
|
13194
|
-
return {
|
|
13195
|
-
authorize: () => startAuthorization(config2, fetchFn)
|
|
13196
|
-
};
|
|
13197
|
-
}
|
|
13198
|
-
function generateCodeVerifier() {
|
|
13199
|
-
return crypto.randomBytes(32).toString("base64url");
|
|
13200
|
-
}
|
|
13201
|
-
function generateCodeChallenge(verifier) {
|
|
13202
|
-
return crypto.createHash("sha256").update(verifier).digest("base64url");
|
|
13203
|
-
}
|
|
13204
|
-
async function startAuthorization(config2, fetchFn) {
|
|
13205
|
-
const authorizationEndpoint = config2.authorizationEndpoint ?? DEFAULT_AUTHORIZATION_ENDPOINT;
|
|
13206
|
-
const tokenEndpoint = config2.tokenEndpoint ?? DEFAULT_TOKEN_ENDPOINT;
|
|
13207
|
-
const codeVerifier = generateCodeVerifier();
|
|
13208
|
-
const codeChallenge = generateCodeChallenge(codeVerifier);
|
|
13209
|
-
const server = config2.createServer ? config2.createServer() : http.createServer();
|
|
13210
|
-
const port = await startServer(server);
|
|
13211
|
-
const redirectUri = `http://127.0.0.1:${port}/callback`;
|
|
13212
|
-
const authorizationUrl = buildAuthorizationUrl({
|
|
13213
|
-
endpoint: authorizationEndpoint,
|
|
13214
|
-
clientId: config2.clientId,
|
|
13215
|
-
redirectUri,
|
|
13216
|
-
codeChallenge
|
|
13217
|
-
});
|
|
13218
|
-
const waitForResult = async () => {
|
|
13219
|
-
try {
|
|
13220
|
-
const code = await waitForAuthorizationCode(server, config2, authorizationUrl);
|
|
13221
|
-
return await exchangeCodeForApiKey({
|
|
13222
|
-
tokenEndpoint,
|
|
13223
|
-
code,
|
|
13224
|
-
codeVerifier,
|
|
13225
|
-
clientId: config2.clientId,
|
|
13226
|
-
redirectUri,
|
|
13227
|
-
fetchFn
|
|
13228
|
-
});
|
|
13229
|
-
} finally {
|
|
13230
|
-
server.closeAllConnections?.();
|
|
13231
|
-
server.close();
|
|
13232
|
-
}
|
|
13233
|
-
};
|
|
13234
|
-
return { authorizationUrl, waitForResult };
|
|
13235
|
-
}
|
|
13236
|
-
function startServer(server) {
|
|
13237
|
-
return new Promise((resolve) => {
|
|
13238
|
-
server.listen(0, "127.0.0.1", () => {
|
|
13239
|
-
const address = server.address();
|
|
13240
|
-
resolve(address.port);
|
|
13241
|
-
});
|
|
13242
|
-
});
|
|
13243
|
-
}
|
|
13244
|
-
function buildAuthorizationUrl(params) {
|
|
13245
|
-
const url2 = new URL(params.endpoint);
|
|
13246
|
-
url2.searchParams.set("response_type", "code");
|
|
13247
|
-
url2.searchParams.set("client_id", params.clientId);
|
|
13248
|
-
url2.searchParams.set("scope", "apikey:create");
|
|
13249
|
-
url2.searchParams.set("code_challenge", params.codeChallenge);
|
|
13250
|
-
url2.searchParams.set("code_challenge_method", "S256");
|
|
13251
|
-
url2.searchParams.set("redirect_uri", params.redirectUri);
|
|
13252
|
-
return url2.toString();
|
|
13253
|
-
}
|
|
13254
|
-
function waitForAuthorizationCode(server, config2, authorizationUrl) {
|
|
13255
|
-
return new Promise((resolve, reject) => {
|
|
13256
|
-
let settled = false;
|
|
13257
|
-
const settle = (fn) => {
|
|
13258
|
-
if (!settled) {
|
|
13259
|
-
settled = true;
|
|
13260
|
-
fn();
|
|
13261
|
-
}
|
|
13262
|
-
};
|
|
13263
|
-
server.on("request", (req, res) => {
|
|
13264
|
-
const url2 = new URL(req.url, `http://127.0.0.1`);
|
|
13265
|
-
if (url2.pathname !== "/callback") {
|
|
13266
|
-
res.writeHead(404);
|
|
13267
|
-
res.end("Not found");
|
|
13268
|
-
return;
|
|
13269
|
-
}
|
|
13270
|
-
const error2 = url2.searchParams.get("error");
|
|
13271
|
-
if (error2) {
|
|
13272
|
-
const description = url2.searchParams.get("error_description") ?? error2;
|
|
13273
|
-
res.writeHead(400);
|
|
13274
|
-
res.end(`Authorization failed: ${description}`);
|
|
13275
|
-
settle(() => reject(new Error(`OAuth authorization failed: ${error2} \u2014 ${description}`)));
|
|
13276
|
-
return;
|
|
13277
|
-
}
|
|
13278
|
-
const code = url2.searchParams.get("code");
|
|
13279
|
-
if (!code) {
|
|
13280
|
-
res.writeHead(400);
|
|
13281
|
-
res.end("Missing authorization code");
|
|
13282
|
-
settle(() => reject(new Error("OAuth callback missing authorization code")));
|
|
13283
|
-
return;
|
|
13284
|
-
}
|
|
13285
|
-
res.writeHead(200, { "Content-Type": "text/html" });
|
|
13286
|
-
res.end(buildSuccessPage());
|
|
13287
|
-
settle(() => resolve(code));
|
|
13288
|
-
});
|
|
13289
|
-
if (config2.readLine) {
|
|
13290
|
-
config2.readLine().then((input) => {
|
|
13291
|
-
const code = extractCodeFromInput(input);
|
|
13292
|
-
if (code) {
|
|
13293
|
-
settle(() => resolve(code));
|
|
13294
|
-
}
|
|
13295
|
-
}).catch(() => {
|
|
13296
|
-
});
|
|
13297
|
-
}
|
|
13298
|
-
if (config2.openBrowser) {
|
|
13299
|
-
config2.openBrowser(authorizationUrl).catch(
|
|
13300
|
-
(err) => settle(() => reject(err))
|
|
13301
|
-
);
|
|
13302
|
-
}
|
|
13303
|
-
});
|
|
13304
|
-
}
|
|
13305
|
-
function extractCodeFromInput(input) {
|
|
13306
|
-
const trimmed = input.replace(/[\r\n]/g, "").trim();
|
|
13307
|
-
if (trimmed.length === 0) {
|
|
13308
|
-
return null;
|
|
13309
|
-
}
|
|
13310
|
-
try {
|
|
13311
|
-
const url2 = new URL(trimmed);
|
|
13312
|
-
return url2.searchParams.get("code");
|
|
13313
|
-
} catch {
|
|
13314
|
-
return trimmed;
|
|
13315
|
-
}
|
|
13316
|
-
}
|
|
13317
|
-
async function exchangeCodeForApiKey(params) {
|
|
13318
|
-
const body = new URLSearchParams({
|
|
13319
|
-
grant_type: "authorization_code",
|
|
13320
|
-
code: params.code,
|
|
13321
|
-
code_verifier: params.codeVerifier,
|
|
13322
|
-
client_id: params.clientId,
|
|
13323
|
-
redirect_uri: params.redirectUri
|
|
13324
|
-
});
|
|
13325
|
-
const response = await params.fetchFn(params.tokenEndpoint, {
|
|
13326
|
-
method: "POST",
|
|
13327
|
-
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
13328
|
-
body: body.toString()
|
|
13329
|
-
});
|
|
13330
|
-
if (!response.ok) {
|
|
13331
|
-
const text4 = await response.text();
|
|
13332
|
-
const description = parseErrorDescription(text4);
|
|
13333
|
-
throw new Error(description ?? `Token exchange failed (${response.status}): ${text4}`);
|
|
13334
|
-
}
|
|
13335
|
-
const data = await response.json();
|
|
13336
|
-
if (typeof data.api_key !== "string" || data.api_key.length === 0) {
|
|
13337
|
-
throw new Error("Token response missing api_key field");
|
|
13338
|
-
}
|
|
13339
|
-
return {
|
|
13340
|
-
apiKey: data.api_key,
|
|
13341
|
-
expiresIn: typeof data.api_key_expires_in === "number" ? data.api_key_expires_in : null
|
|
13342
|
-
};
|
|
13343
|
-
}
|
|
13344
|
-
function parseErrorDescription(text4) {
|
|
13345
|
-
try {
|
|
13346
|
-
const data = JSON.parse(text4);
|
|
13347
|
-
if (typeof data.error_description === "string") {
|
|
13348
|
-
return data.error_description;
|
|
13349
|
-
}
|
|
13350
|
-
if (typeof data.error === "string") {
|
|
13351
|
-
return data.error;
|
|
13352
|
-
}
|
|
13353
|
-
} catch {
|
|
13354
|
-
}
|
|
13355
|
-
return null;
|
|
13356
|
-
}
|
|
13357
|
-
function buildSuccessPage() {
|
|
13358
|
-
return [
|
|
13359
|
-
"<!DOCTYPE html>",
|
|
13360
|
-
"<html><head><meta charset=utf-8><title>Connected to Poe</title></head>",
|
|
13361
|
-
'<body style="font-family:system-ui,sans-serif;display:flex;align-items:center;justify-content:center;min-height:100vh;margin:0">',
|
|
13362
|
-
'<div style="text-align:center">',
|
|
13363
|
-
"<h1>Connected to Poe</h1>",
|
|
13364
|
-
'<p style="color:#666">You can close this tab and return to your terminal.</p>',
|
|
13365
|
-
"</div></body></html>"
|
|
13366
|
-
].join("");
|
|
13367
|
-
}
|
|
13368
|
-
var DEFAULT_AUTHORIZATION_ENDPOINT, DEFAULT_TOKEN_ENDPOINT;
|
|
13369
|
-
var init_oauth_client = __esm({
|
|
13370
|
-
"packages/poe-oauth/src/oauth-client.ts"() {
|
|
13371
|
-
"use strict";
|
|
13372
|
-
DEFAULT_AUTHORIZATION_ENDPOINT = "https://poe.com/oauth/authorize";
|
|
13373
|
-
DEFAULT_TOKEN_ENDPOINT = "https://api.poe.com/token";
|
|
13374
|
-
}
|
|
13375
|
-
});
|
|
13376
|
-
|
|
13377
|
-
// packages/poe-oauth/src/index.ts
|
|
13378
|
-
var init_src10 = __esm({
|
|
13379
|
-
"packages/poe-oauth/src/index.ts"() {
|
|
13380
|
-
"use strict";
|
|
13381
|
-
init_check_auth();
|
|
13382
|
-
init_api_key_validation();
|
|
13383
|
-
init_oauth_client();
|
|
13384
|
-
}
|
|
13385
|
-
});
|
|
13386
|
-
|
|
13387
13785
|
// src/cli/oauth-login.ts
|
|
13388
13786
|
import { exec as exec2 } from "node:child_process";
|
|
13389
13787
|
import readline from "node:readline";
|
|
@@ -13426,7 +13824,7 @@ function openInBrowser(url2) {
|
|
|
13426
13824
|
var init_oauth_login = __esm({
|
|
13427
13825
|
"src/cli/oauth-login.ts"() {
|
|
13428
13826
|
"use strict";
|
|
13429
|
-
|
|
13827
|
+
init_src7();
|
|
13430
13828
|
init_src4();
|
|
13431
13829
|
}
|
|
13432
13830
|
});
|
|
@@ -13496,6 +13894,7 @@ function createCliContainer(dependencies) {
|
|
|
13496
13894
|
read: readApiKey,
|
|
13497
13895
|
write: writeApiKey
|
|
13498
13896
|
},
|
|
13897
|
+
checkAuth: async (apiKey) => await checkAuth({ apiKey }) !== null,
|
|
13499
13898
|
confirm: async (message) => {
|
|
13500
13899
|
const result = await confirm2({ message });
|
|
13501
13900
|
if (isCancel2(result)) {
|
|
@@ -13544,6 +13943,7 @@ var init_container2 = __esm({
|
|
|
13544
13943
|
init_service_registry();
|
|
13545
13944
|
init_context();
|
|
13546
13945
|
init_prompts2();
|
|
13946
|
+
init_src7();
|
|
13547
13947
|
init_options();
|
|
13548
13948
|
init_logger2();
|
|
13549
13949
|
init_error_logger();
|
|
@@ -13557,7 +13957,7 @@ var init_container2 = __esm({
|
|
|
13557
13957
|
});
|
|
13558
13958
|
|
|
13559
13959
|
// src/services/config.ts
|
|
13560
|
-
import
|
|
13960
|
+
import path20 from "node:path";
|
|
13561
13961
|
async function deleteConfig(options) {
|
|
13562
13962
|
const { fs: fs3, filePath } = options;
|
|
13563
13963
|
try {
|
|
@@ -13572,31 +13972,32 @@ async function deleteConfig(options) {
|
|
|
13572
13972
|
}
|
|
13573
13973
|
async function loadConfiguredServices(options) {
|
|
13574
13974
|
const { fs: fs3, filePath } = options;
|
|
13575
|
-
|
|
13576
|
-
|
|
13975
|
+
await migrateLegacyCredentialsIfNeeded(fs3, filePath);
|
|
13976
|
+
const document = await readDocument(fs3, filePath);
|
|
13977
|
+
return normalizeConfiguredServices(document[configuredServicesScope]);
|
|
13577
13978
|
}
|
|
13578
13979
|
async function saveConfiguredService(options) {
|
|
13579
13980
|
const { fs: fs3, filePath, service, metadata } = options;
|
|
13580
|
-
|
|
13581
|
-
const
|
|
13582
|
-
|
|
13583
|
-
|
|
13584
|
-
|
|
13585
|
-
|
|
13586
|
-
await
|
|
13981
|
+
await migrateLegacyConfigIfNeeded(fs3, filePath);
|
|
13982
|
+
const document = await readDocument(fs3, filePath);
|
|
13983
|
+
const services = normalizeConfiguredServices(
|
|
13984
|
+
document[configuredServicesScope]
|
|
13985
|
+
);
|
|
13986
|
+
services[service] = normalizeConfiguredServiceMetadata(metadata);
|
|
13987
|
+
await writeScope(fs3, filePath, configuredServicesScope, services);
|
|
13587
13988
|
}
|
|
13588
13989
|
async function unconfigureService(options) {
|
|
13589
13990
|
const { fs: fs3, filePath, service } = options;
|
|
13590
|
-
|
|
13591
|
-
const
|
|
13592
|
-
|
|
13991
|
+
await migrateLegacyConfigIfNeeded(fs3, filePath);
|
|
13992
|
+
const document = await readDocument(fs3, filePath);
|
|
13993
|
+
const services = normalizeConfiguredServices(
|
|
13994
|
+
document[configuredServicesScope]
|
|
13995
|
+
);
|
|
13996
|
+
if (!(service in services)) {
|
|
13593
13997
|
return false;
|
|
13594
13998
|
}
|
|
13595
13999
|
delete services[service];
|
|
13596
|
-
|
|
13597
|
-
delete document.configured_services;
|
|
13598
|
-
}
|
|
13599
|
-
await writeConfigDocument(fs3, filePath, document);
|
|
14000
|
+
await writeScope(fs3, filePath, configuredServicesScope, services);
|
|
13600
14001
|
return true;
|
|
13601
14002
|
}
|
|
13602
14003
|
function normalizeConfiguredServiceMetadata(metadata) {
|
|
@@ -13611,47 +14012,78 @@ function normalizeConfiguredServiceMetadata(metadata) {
|
|
|
13611
14012
|
seen.add(entry);
|
|
13612
14013
|
}
|
|
13613
14014
|
}
|
|
13614
|
-
return {
|
|
13615
|
-
files
|
|
13616
|
-
};
|
|
14015
|
+
return { files };
|
|
13617
14016
|
}
|
|
13618
|
-
async function
|
|
13619
|
-
|
|
13620
|
-
|
|
13621
|
-
|
|
13622
|
-
|
|
13623
|
-
|
|
13624
|
-
|
|
13625
|
-
|
|
13626
|
-
|
|
14017
|
+
async function migrateLegacyConfigIfNeeded(fs3, filePath) {
|
|
14018
|
+
await migrateLegacyCredentialsIfNeeded(fs3, filePath);
|
|
14019
|
+
const currentRaw = await readFileIfExists(fs3, filePath);
|
|
14020
|
+
if (currentRaw === null) {
|
|
14021
|
+
return;
|
|
14022
|
+
}
|
|
14023
|
+
const legacyDocument = normalizeLegacyConfigDocument(
|
|
14024
|
+
parseLegacyConfigDocument(currentRaw)
|
|
14025
|
+
);
|
|
14026
|
+
if (!legacyDocument.apiKey) {
|
|
14027
|
+
return;
|
|
13627
14028
|
}
|
|
14029
|
+
const document = await readDocument(fs3, filePath);
|
|
14030
|
+
const existingCore = document[CORE_SCOPE] ?? {};
|
|
14031
|
+
if (typeof existingCore.apiKey === "string" && existingCore.apiKey.length > 0) {
|
|
14032
|
+
return;
|
|
14033
|
+
}
|
|
14034
|
+
await writeScope(fs3, filePath, CORE_SCOPE, {
|
|
14035
|
+
...existingCore,
|
|
14036
|
+
apiKey: legacyDocument.apiKey
|
|
14037
|
+
});
|
|
13628
14038
|
}
|
|
13629
|
-
async function
|
|
13630
|
-
const
|
|
13631
|
-
|
|
13632
|
-
|
|
13633
|
-
const document = await parseConfigDocument2(fs3, legacyPath, raw);
|
|
13634
|
-
await writeConfigDocument(fs3, configPath, document);
|
|
13635
|
-
await fs3.unlink(legacyPath);
|
|
13636
|
-
return document;
|
|
13637
|
-
} catch {
|
|
13638
|
-
return {};
|
|
14039
|
+
async function migrateLegacyCredentialsIfNeeded(fs3, filePath) {
|
|
14040
|
+
const currentRaw = await readFileIfExists(fs3, filePath);
|
|
14041
|
+
if (currentRaw !== null) {
|
|
14042
|
+
return;
|
|
13639
14043
|
}
|
|
14044
|
+
await migrateLegacyCredentialsFile(fs3, filePath);
|
|
13640
14045
|
}
|
|
13641
|
-
async function
|
|
14046
|
+
async function migrateLegacyCredentialsFile(fs3, configPath) {
|
|
14047
|
+
const legacyPath = path20.join(path20.dirname(configPath), "credentials.json");
|
|
14048
|
+
const raw = await readFileIfExists(fs3, legacyPath);
|
|
14049
|
+
if (raw === null) {
|
|
14050
|
+
return;
|
|
14051
|
+
}
|
|
14052
|
+
let legacyDocument;
|
|
13642
14053
|
try {
|
|
13643
|
-
|
|
13644
|
-
return normalizeConfigDocument(parsed);
|
|
14054
|
+
legacyDocument = normalizeLegacyConfigDocument(JSON.parse(raw));
|
|
13645
14055
|
} catch (error2) {
|
|
13646
14056
|
if (error2 instanceof SyntaxError) {
|
|
13647
|
-
await recoverInvalidConfig(fs3,
|
|
13648
|
-
|
|
14057
|
+
await recoverInvalidConfig(fs3, legacyPath, raw);
|
|
14058
|
+
await fs3.unlink(legacyPath);
|
|
14059
|
+
return;
|
|
13649
14060
|
}
|
|
13650
14061
|
throw error2;
|
|
13651
14062
|
}
|
|
14063
|
+
if (legacyDocument.configured_services) {
|
|
14064
|
+
await writeScope(
|
|
14065
|
+
fs3,
|
|
14066
|
+
configPath,
|
|
14067
|
+
configuredServicesScope,
|
|
14068
|
+
legacyDocument.configured_services
|
|
14069
|
+
);
|
|
14070
|
+
}
|
|
14071
|
+
if (legacyDocument.apiKey) {
|
|
14072
|
+
await writeScope(fs3, configPath, CORE_SCOPE, {
|
|
14073
|
+
apiKey: legacyDocument.apiKey
|
|
14074
|
+
});
|
|
14075
|
+
}
|
|
14076
|
+
await fs3.unlink(legacyPath);
|
|
13652
14077
|
}
|
|
13653
|
-
function
|
|
13654
|
-
|
|
14078
|
+
function parseLegacyConfigDocument(raw) {
|
|
14079
|
+
try {
|
|
14080
|
+
return JSON.parse(raw);
|
|
14081
|
+
} catch {
|
|
14082
|
+
return null;
|
|
14083
|
+
}
|
|
14084
|
+
}
|
|
14085
|
+
function normalizeLegacyConfigDocument(value) {
|
|
14086
|
+
if (!isRecord5(value)) {
|
|
13655
14087
|
return {};
|
|
13656
14088
|
}
|
|
13657
14089
|
const document = {};
|
|
@@ -13665,55 +14097,42 @@ function normalizeConfigDocument(value) {
|
|
|
13665
14097
|
return document;
|
|
13666
14098
|
}
|
|
13667
14099
|
function normalizeConfiguredServices(value) {
|
|
13668
|
-
if (!
|
|
14100
|
+
if (!isRecord5(value)) {
|
|
13669
14101
|
return {};
|
|
13670
14102
|
}
|
|
13671
14103
|
const entries = {};
|
|
13672
14104
|
for (const [key, entry] of Object.entries(value)) {
|
|
13673
|
-
if (!
|
|
14105
|
+
if (!isRecord5(entry)) {
|
|
13674
14106
|
continue;
|
|
13675
14107
|
}
|
|
13676
|
-
|
|
14108
|
+
entries[key] = normalizeConfiguredServiceMetadata({
|
|
13677
14109
|
files: Array.isArray(entry.files) ? entry.files : []
|
|
13678
14110
|
});
|
|
13679
|
-
entries[key] = normalized;
|
|
13680
14111
|
}
|
|
13681
14112
|
return entries;
|
|
13682
14113
|
}
|
|
13683
|
-
async function writeConfigDocument(fs3, filePath, document) {
|
|
13684
|
-
await fs3.mkdir(path17.dirname(filePath), { recursive: true });
|
|
13685
|
-
const payload = {};
|
|
13686
|
-
if (document.apiKey) {
|
|
13687
|
-
payload.apiKey = document.apiKey;
|
|
13688
|
-
}
|
|
13689
|
-
if (document.configured_services) {
|
|
13690
|
-
payload.configured_services = document.configured_services;
|
|
13691
|
-
}
|
|
13692
|
-
await fs3.writeFile(filePath, `${JSON.stringify(payload, null, 2)}
|
|
13693
|
-
`, {
|
|
13694
|
-
encoding: "utf8"
|
|
13695
|
-
});
|
|
13696
|
-
}
|
|
13697
14114
|
async function recoverInvalidConfig(fs3, filePath, content) {
|
|
13698
|
-
const backupPath =
|
|
14115
|
+
const backupPath = createInvalidBackupPath2(filePath);
|
|
13699
14116
|
await fs3.writeFile(backupPath, content, { encoding: "utf8" });
|
|
13700
|
-
await fs3.writeFile(filePath,
|
|
14117
|
+
await fs3.writeFile(filePath, EMPTY_DOCUMENT2, { encoding: "utf8" });
|
|
13701
14118
|
}
|
|
13702
|
-
function
|
|
13703
|
-
const
|
|
13704
|
-
const
|
|
13705
|
-
|
|
13706
|
-
return path17.join(dir, `${base}.invalid-${timestamp}.json`);
|
|
14119
|
+
function createInvalidBackupPath2(filePath) {
|
|
14120
|
+
const directory = path20.dirname(filePath);
|
|
14121
|
+
const baseName = path20.basename(filePath);
|
|
14122
|
+
return path20.join(directory, `${baseName}.invalid-${createTimestamp()}.json`);
|
|
13707
14123
|
}
|
|
13708
|
-
function
|
|
14124
|
+
function isRecord5(value) {
|
|
13709
14125
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
13710
14126
|
}
|
|
13711
|
-
var
|
|
13712
|
-
var
|
|
14127
|
+
var CORE_SCOPE, configuredServicesScope, EMPTY_DOCUMENT2;
|
|
14128
|
+
var init_config3 = __esm({
|
|
13713
14129
|
"src/services/config.ts"() {
|
|
13714
14130
|
"use strict";
|
|
13715
14131
|
init_src2();
|
|
13716
|
-
|
|
14132
|
+
init_src6();
|
|
14133
|
+
CORE_SCOPE = "core";
|
|
14134
|
+
configuredServicesScope = "configured_services";
|
|
14135
|
+
EMPTY_DOCUMENT2 = `${JSON.stringify({}, null, 2)}
|
|
13717
14136
|
`;
|
|
13718
14137
|
}
|
|
13719
14138
|
});
|
|
@@ -13882,7 +14301,7 @@ var init_configure = __esm({
|
|
|
13882
14301
|
"use strict";
|
|
13883
14302
|
init_shared();
|
|
13884
14303
|
init_errors();
|
|
13885
|
-
|
|
14304
|
+
init_config3();
|
|
13886
14305
|
init_mutation_events();
|
|
13887
14306
|
init_configure_payload();
|
|
13888
14307
|
serviceSelectionPrompt = (action) => `Pick an agent to ${action}:`;
|
|
@@ -13906,7 +14325,7 @@ function registerAgentCommand(program, container) {
|
|
|
13906
14325
|
}
|
|
13907
14326
|
let session;
|
|
13908
14327
|
try {
|
|
13909
|
-
const { createAgentSession: createAgentSession2 } = await Promise.resolve().then(() => (
|
|
14328
|
+
const { createAgentSession: createAgentSession2 } = await Promise.resolve().then(() => (init_src10(), src_exports));
|
|
13910
14329
|
session = await createAgentSession2({
|
|
13911
14330
|
model: options.model,
|
|
13912
14331
|
apiKey: options.apiKey,
|
|
@@ -13965,7 +14384,7 @@ var init_agent2 = __esm({
|
|
|
13965
14384
|
});
|
|
13966
14385
|
|
|
13967
14386
|
// src/cli/commands/spawn.ts
|
|
13968
|
-
import
|
|
14387
|
+
import path21 from "node:path";
|
|
13969
14388
|
function registerSpawnCommand(program, container, options = {}) {
|
|
13970
14389
|
const spawnServices = container.registry.list().filter((service) => typeof service.spawn === "function" || getSpawnConfig(service.name)).map((service) => service.name);
|
|
13971
14390
|
const extraServices = options.extraServices ?? [];
|
|
@@ -14176,10 +14595,10 @@ function resolveSpawnWorkingDirectory2(baseDir, candidate) {
|
|
|
14176
14595
|
if (!candidate || candidate.trim().length === 0) {
|
|
14177
14596
|
return void 0;
|
|
14178
14597
|
}
|
|
14179
|
-
if (
|
|
14598
|
+
if (path21.isAbsolute(candidate)) {
|
|
14180
14599
|
return candidate;
|
|
14181
14600
|
}
|
|
14182
|
-
return
|
|
14601
|
+
return path21.resolve(baseDir, candidate);
|
|
14183
14602
|
}
|
|
14184
14603
|
function parseMcpSpawnConfig2(input) {
|
|
14185
14604
|
if (!input) {
|
|
@@ -14290,7 +14709,7 @@ var init_spawn4 = __esm({
|
|
|
14290
14709
|
init_src5();
|
|
14291
14710
|
init_src3();
|
|
14292
14711
|
init_src4();
|
|
14293
|
-
|
|
14712
|
+
init_config3();
|
|
14294
14713
|
init_shared();
|
|
14295
14714
|
init_spawn_core();
|
|
14296
14715
|
await init_spawn3();
|
|
@@ -14299,7 +14718,7 @@ var init_spawn4 = __esm({
|
|
|
14299
14718
|
});
|
|
14300
14719
|
|
|
14301
14720
|
// src/sdk/research.ts
|
|
14302
|
-
import
|
|
14721
|
+
import path22 from "node:path";
|
|
14303
14722
|
async function research(container, options) {
|
|
14304
14723
|
const logger2 = options.logger;
|
|
14305
14724
|
const source = await resolveSource({
|
|
@@ -14334,7 +14753,7 @@ async function research(container, options) {
|
|
|
14334
14753
|
markdown: markdownOutput
|
|
14335
14754
|
});
|
|
14336
14755
|
outputPath = buildOutputPath(container.env.homeDir, options.prompt);
|
|
14337
|
-
await ensureDirectory2(container.fs,
|
|
14756
|
+
await ensureDirectory2(container.fs, path22.dirname(outputPath));
|
|
14338
14757
|
await container.fs.writeFile(outputPath, document, {
|
|
14339
14758
|
encoding: "utf8"
|
|
14340
14759
|
});
|
|
@@ -14409,7 +14828,7 @@ function buildResearchDocument(input) {
|
|
|
14409
14828
|
}
|
|
14410
14829
|
function buildClonePath(homeDir, github) {
|
|
14411
14830
|
const slug = extractRepoSlug(github);
|
|
14412
|
-
return
|
|
14831
|
+
return path22.join(homeDir, ".poe-code", "repos", slug);
|
|
14413
14832
|
}
|
|
14414
14833
|
function extractRepoSlug(value) {
|
|
14415
14834
|
const trimmed = value.trim();
|
|
@@ -14447,7 +14866,7 @@ function extractRepoSlug(value) {
|
|
|
14447
14866
|
function buildOutputPath(homeDir, prompt, now = /* @__PURE__ */ new Date()) {
|
|
14448
14867
|
const timestamp = formatTimestamp2(now);
|
|
14449
14868
|
const slug = buildSlug(prompt);
|
|
14450
|
-
return
|
|
14869
|
+
return path22.join(
|
|
14451
14870
|
homeDir,
|
|
14452
14871
|
".poe-code",
|
|
14453
14872
|
"research",
|
|
@@ -14468,7 +14887,7 @@ async function resolveSource(input) {
|
|
|
14468
14887
|
if (options.github) {
|
|
14469
14888
|
const cloneUrl = resolveGithubCloneUrl(options.github);
|
|
14470
14889
|
const clonePath = buildClonePath(container.env.homeDir, options.github);
|
|
14471
|
-
await ensureDirectory2(container.fs,
|
|
14890
|
+
await ensureDirectory2(container.fs, path22.dirname(clonePath));
|
|
14472
14891
|
const exists = await pathExists2(container.fs, clonePath);
|
|
14473
14892
|
if (!exists) {
|
|
14474
14893
|
const cloneResult = await container.commandRunner(
|
|
@@ -14566,10 +14985,10 @@ function formatYamlString(value) {
|
|
|
14566
14985
|
return JSON.stringify(value);
|
|
14567
14986
|
}
|
|
14568
14987
|
function resolvePath2(baseDir, candidate) {
|
|
14569
|
-
if (
|
|
14988
|
+
if (path22.isAbsolute(candidate)) {
|
|
14570
14989
|
return candidate;
|
|
14571
14990
|
}
|
|
14572
|
-
return
|
|
14991
|
+
return path22.resolve(baseDir, candidate);
|
|
14573
14992
|
}
|
|
14574
14993
|
function teeAcpStream(events) {
|
|
14575
14994
|
const chunks = [];
|
|
@@ -14629,7 +15048,7 @@ async function removePathFallback(fs3, target) {
|
|
|
14629
15048
|
if (stats && typeof stats.isDirectory === "function" && stats.isDirectory()) {
|
|
14630
15049
|
const entries = await fs3.readdir(target);
|
|
14631
15050
|
for (const entry of entries) {
|
|
14632
|
-
await removePathFallback(fs3,
|
|
15051
|
+
await removePathFallback(fs3, path22.join(target, entry));
|
|
14633
15052
|
}
|
|
14634
15053
|
}
|
|
14635
15054
|
try {
|
|
@@ -14796,7 +15215,7 @@ var init_research2 = __esm({
|
|
|
14796
15215
|
async "src/cli/commands/research.ts"() {
|
|
14797
15216
|
"use strict";
|
|
14798
15217
|
init_src5();
|
|
14799
|
-
|
|
15218
|
+
init_config3();
|
|
14800
15219
|
await init_research();
|
|
14801
15220
|
init_errors();
|
|
14802
15221
|
init_shared();
|
|
@@ -15026,7 +15445,7 @@ var init_login = __esm({
|
|
|
15026
15445
|
"use strict";
|
|
15027
15446
|
init_shared();
|
|
15028
15447
|
init_errors();
|
|
15029
|
-
|
|
15448
|
+
init_config3();
|
|
15030
15449
|
init_mutation_events();
|
|
15031
15450
|
}
|
|
15032
15451
|
});
|
|
@@ -15151,7 +15570,7 @@ function formatUnconfigureMessages(service, label, unconfigured, _payload) {
|
|
|
15151
15570
|
var init_unconfigure = __esm({
|
|
15152
15571
|
"src/cli/commands/unconfigure.ts"() {
|
|
15153
15572
|
"use strict";
|
|
15154
|
-
|
|
15573
|
+
init_config3();
|
|
15155
15574
|
init_mutation_events();
|
|
15156
15575
|
init_isolated_env();
|
|
15157
15576
|
init_shared();
|
|
@@ -15205,7 +15624,7 @@ async function executeLogout(program, container) {
|
|
|
15205
15624
|
var init_logout = __esm({
|
|
15206
15625
|
"src/cli/commands/logout.ts"() {
|
|
15207
15626
|
"use strict";
|
|
15208
|
-
|
|
15627
|
+
init_config3();
|
|
15209
15628
|
init_shared();
|
|
15210
15629
|
init_unconfigure();
|
|
15211
15630
|
}
|
|
@@ -15305,7 +15724,7 @@ var init_auth = __esm({
|
|
|
15305
15724
|
"src/cli/commands/auth.ts"() {
|
|
15306
15725
|
"use strict";
|
|
15307
15726
|
init_errors();
|
|
15308
|
-
|
|
15727
|
+
init_config3();
|
|
15309
15728
|
init_shared();
|
|
15310
15729
|
init_login();
|
|
15311
15730
|
init_logout();
|
|
@@ -15508,7 +15927,7 @@ var init_media_download = __esm({
|
|
|
15508
15927
|
});
|
|
15509
15928
|
|
|
15510
15929
|
// src/cli/commands/generate.ts
|
|
15511
|
-
import
|
|
15930
|
+
import path23 from "node:path";
|
|
15512
15931
|
function registerGenerateCommand(program, container) {
|
|
15513
15932
|
const generate2 = program.command("generate").description("Generate content via Poe API").option("--model <model>", `Model identifier (default: ${DEFAULT_TEXT_MODEL})`).option(
|
|
15514
15933
|
"--param <key=value>",
|
|
@@ -15774,11 +16193,11 @@ function getDefaultMimeType(type) {
|
|
|
15774
16193
|
return defaults[type];
|
|
15775
16194
|
}
|
|
15776
16195
|
function resolveOutputPath(filename, cwd) {
|
|
15777
|
-
if (
|
|
16196
|
+
if (path23.isAbsolute(filename)) {
|
|
15778
16197
|
return { path: filename, label: filename };
|
|
15779
16198
|
}
|
|
15780
16199
|
return {
|
|
15781
|
-
path:
|
|
16200
|
+
path: path23.join(cwd, filename),
|
|
15782
16201
|
label: `./${filename}`
|
|
15783
16202
|
};
|
|
15784
16203
|
}
|
|
@@ -16471,7 +16890,7 @@ function defineSchema(definition) {
|
|
|
16471
16890
|
required: required2
|
|
16472
16891
|
};
|
|
16473
16892
|
}
|
|
16474
|
-
var
|
|
16893
|
+
var init_schema2 = __esm({
|
|
16475
16894
|
"packages/tiny-stdio-mcp-server/src/schema.ts"() {
|
|
16476
16895
|
"use strict";
|
|
16477
16896
|
}
|
|
@@ -16882,8 +17301,8 @@ var init_parseUtil = __esm({
|
|
|
16882
17301
|
init_errors3();
|
|
16883
17302
|
init_en();
|
|
16884
17303
|
makeIssue = (params) => {
|
|
16885
|
-
const { data, path:
|
|
16886
|
-
const fullPath = [...
|
|
17304
|
+
const { data, path: path27, errorMaps, issueData } = params;
|
|
17305
|
+
const fullPath = [...path27, ...issueData.path || []];
|
|
16887
17306
|
const fullIssue = {
|
|
16888
17307
|
...issueData,
|
|
16889
17308
|
path: fullPath
|
|
@@ -17163,11 +17582,11 @@ var init_types4 = __esm({
|
|
|
17163
17582
|
init_parseUtil();
|
|
17164
17583
|
init_util();
|
|
17165
17584
|
ParseInputLazyPath = class {
|
|
17166
|
-
constructor(parent, value,
|
|
17585
|
+
constructor(parent, value, path27, key) {
|
|
17167
17586
|
this._cachedPath = [];
|
|
17168
17587
|
this.parent = parent;
|
|
17169
17588
|
this.data = value;
|
|
17170
|
-
this._path =
|
|
17589
|
+
this._path = path27;
|
|
17171
17590
|
this._key = key;
|
|
17172
17591
|
}
|
|
17173
17592
|
get path() {
|
|
@@ -20671,10 +21090,10 @@ function mergeDefs(...defs) {
|
|
|
20671
21090
|
function cloneDef(schema) {
|
|
20672
21091
|
return mergeDefs(schema._zod.def);
|
|
20673
21092
|
}
|
|
20674
|
-
function getElementAtPath(obj,
|
|
20675
|
-
if (!
|
|
21093
|
+
function getElementAtPath(obj, path27) {
|
|
21094
|
+
if (!path27)
|
|
20676
21095
|
return obj;
|
|
20677
|
-
return
|
|
21096
|
+
return path27.reduce((acc, key) => acc?.[key], obj);
|
|
20678
21097
|
}
|
|
20679
21098
|
function promiseAllObject(promisesObj) {
|
|
20680
21099
|
const keys = Object.keys(promisesObj);
|
|
@@ -20986,11 +21405,11 @@ function aborted(x, startIndex = 0) {
|
|
|
20986
21405
|
}
|
|
20987
21406
|
return false;
|
|
20988
21407
|
}
|
|
20989
|
-
function prefixIssues(
|
|
21408
|
+
function prefixIssues(path27, issues) {
|
|
20990
21409
|
return issues.map((iss) => {
|
|
20991
21410
|
var _a2;
|
|
20992
21411
|
(_a2 = iss).path ?? (_a2.path = []);
|
|
20993
|
-
iss.path.unshift(
|
|
21412
|
+
iss.path.unshift(path27);
|
|
20994
21413
|
return iss;
|
|
20995
21414
|
});
|
|
20996
21415
|
}
|
|
@@ -33151,8 +33570,8 @@ var require_utils = __commonJS({
|
|
|
33151
33570
|
}
|
|
33152
33571
|
return ind;
|
|
33153
33572
|
}
|
|
33154
|
-
function removeDotSegments(
|
|
33155
|
-
let input =
|
|
33573
|
+
function removeDotSegments(path27) {
|
|
33574
|
+
let input = path27;
|
|
33156
33575
|
const output = [];
|
|
33157
33576
|
let nextSlash = -1;
|
|
33158
33577
|
let len = 0;
|
|
@@ -33351,8 +33770,8 @@ var require_schemes = __commonJS({
|
|
|
33351
33770
|
wsComponent.secure = void 0;
|
|
33352
33771
|
}
|
|
33353
33772
|
if (wsComponent.resourceName) {
|
|
33354
|
-
const [
|
|
33355
|
-
wsComponent.path =
|
|
33773
|
+
const [path27, query] = wsComponent.resourceName.split("?");
|
|
33774
|
+
wsComponent.path = path27 && path27 !== "/" ? path27 : void 0;
|
|
33356
33775
|
wsComponent.query = query;
|
|
33357
33776
|
wsComponent.resourceName = void 0;
|
|
33358
33777
|
}
|
|
@@ -36585,11 +37004,11 @@ var init_content = __esm({
|
|
|
36585
37004
|
});
|
|
36586
37005
|
|
|
36587
37006
|
// packages/tiny-stdio-mcp-server/src/index.ts
|
|
36588
|
-
var
|
|
37007
|
+
var init_src13 = __esm({
|
|
36589
37008
|
"packages/tiny-stdio-mcp-server/src/index.ts"() {
|
|
36590
37009
|
"use strict";
|
|
36591
37010
|
init_server();
|
|
36592
|
-
|
|
37011
|
+
init_schema2();
|
|
36593
37012
|
init_testing();
|
|
36594
37013
|
init_content();
|
|
36595
37014
|
init_types3();
|
|
@@ -36889,7 +37308,7 @@ var generateTextSchema, generateImageSchema, generateVideoSchema, generateAudioS
|
|
|
36889
37308
|
var init_mcp_server = __esm({
|
|
36890
37309
|
"src/cli/mcp-server.ts"() {
|
|
36891
37310
|
"use strict";
|
|
36892
|
-
|
|
37311
|
+
init_src13();
|
|
36893
37312
|
init_client_instance();
|
|
36894
37313
|
init_constants();
|
|
36895
37314
|
generateTextSchema = defineSchema({
|
|
@@ -37295,9 +37714,9 @@ var init_shapes = __esm({
|
|
|
37295
37714
|
});
|
|
37296
37715
|
|
|
37297
37716
|
// packages/agent-mcp-config/src/apply.ts
|
|
37298
|
-
import
|
|
37717
|
+
import path24 from "node:path";
|
|
37299
37718
|
function getConfigDirectory(configPath) {
|
|
37300
|
-
return
|
|
37719
|
+
return path24.dirname(configPath);
|
|
37301
37720
|
}
|
|
37302
37721
|
function isConfigObject5(value) {
|
|
37303
37722
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
@@ -37399,7 +37818,7 @@ var init_apply = __esm({
|
|
|
37399
37818
|
});
|
|
37400
37819
|
|
|
37401
37820
|
// packages/agent-mcp-config/src/index.ts
|
|
37402
|
-
var
|
|
37821
|
+
var init_src14 = __esm({
|
|
37403
37822
|
"packages/agent-mcp-config/src/index.ts"() {
|
|
37404
37823
|
"use strict";
|
|
37405
37824
|
init_configs2();
|
|
@@ -37579,7 +37998,7 @@ var init_mcp2 = __esm({
|
|
|
37579
37998
|
init_shared();
|
|
37580
37999
|
init_mcp_output_format();
|
|
37581
38000
|
init_command_not_found();
|
|
37582
|
-
|
|
38001
|
+
init_src14();
|
|
37583
38002
|
init_execution_context();
|
|
37584
38003
|
DEFAULT_MCP_AGENT = "claude-code";
|
|
37585
38004
|
}
|
|
@@ -37587,7 +38006,7 @@ var init_mcp2 = __esm({
|
|
|
37587
38006
|
|
|
37588
38007
|
// packages/agent-skill-config/src/configs.ts
|
|
37589
38008
|
import os2 from "node:os";
|
|
37590
|
-
import
|
|
38009
|
+
import path25 from "node:path";
|
|
37591
38010
|
function resolveAgentSupport2(input, registry2 = agentSkillConfigs) {
|
|
37592
38011
|
const resolvedId = resolveAgentId(input);
|
|
37593
38012
|
if (!resolvedId) {
|
|
@@ -37623,7 +38042,7 @@ var init_configs3 = __esm({
|
|
|
37623
38042
|
});
|
|
37624
38043
|
|
|
37625
38044
|
// packages/agent-skill-config/src/templates.ts
|
|
37626
|
-
import { readFile as
|
|
38045
|
+
import { readFile as readFile7 } from "node:fs/promises";
|
|
37627
38046
|
async function getTemplates() {
|
|
37628
38047
|
if (templatesCache) {
|
|
37629
38048
|
return templatesCache;
|
|
@@ -37632,7 +38051,7 @@ async function getTemplates() {
|
|
|
37632
38051
|
"./templates/poe-generate.md",
|
|
37633
38052
|
import.meta.url
|
|
37634
38053
|
);
|
|
37635
|
-
const poeGenerateTemplate = await
|
|
38054
|
+
const poeGenerateTemplate = await readFile7(poeGenerateTemplateUrl, "utf8");
|
|
37636
38055
|
templatesCache = {
|
|
37637
38056
|
"poe-generate.md": poeGenerateTemplate
|
|
37638
38057
|
};
|
|
@@ -37779,7 +38198,7 @@ var init_apply2 = __esm({
|
|
|
37779
38198
|
});
|
|
37780
38199
|
|
|
37781
38200
|
// packages/agent-skill-config/src/index.ts
|
|
37782
|
-
var
|
|
38201
|
+
var init_src15 = __esm({
|
|
37783
38202
|
"packages/agent-skill-config/src/index.ts"() {
|
|
37784
38203
|
"use strict";
|
|
37785
38204
|
init_configs3();
|
|
@@ -38004,7 +38423,7 @@ var init_skill = __esm({
|
|
|
38004
38423
|
"src/cli/commands/skill.ts"() {
|
|
38005
38424
|
"use strict";
|
|
38006
38425
|
init_src4();
|
|
38007
|
-
|
|
38426
|
+
init_src15();
|
|
38008
38427
|
init_shared();
|
|
38009
38428
|
init_command_not_found();
|
|
38010
38429
|
DEFAULT_SKILL_AGENT = "claude-code";
|
|
@@ -38598,8 +39017,8 @@ var init_models = __esm({
|
|
|
38598
39017
|
});
|
|
38599
39018
|
|
|
38600
39019
|
// src/cli/commands/pipeline.ts
|
|
38601
|
-
import
|
|
38602
|
-
import { readFile as
|
|
39020
|
+
import path26 from "node:path";
|
|
39021
|
+
import { readFile as readFile8, stat as stat7 } from "node:fs/promises";
|
|
38603
39022
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
38604
39023
|
function formatDuration(ms) {
|
|
38605
39024
|
const totalSeconds = Math.round(ms / 1e3);
|
|
@@ -38630,11 +39049,11 @@ function resolveMaxRuns(value) {
|
|
|
38630
39049
|
return parsed;
|
|
38631
39050
|
}
|
|
38632
39051
|
function resolvePipelinePaths(scope, cwd, homeDir) {
|
|
38633
|
-
const rootPath = scope === "global" ?
|
|
39052
|
+
const rootPath = scope === "global" ? path26.join(homeDir, ".poe-code", "pipeline") : path26.join(cwd, ".poe-code", "pipeline");
|
|
38634
39053
|
const displayRoot = scope === "global" ? "~/.poe-code/pipeline" : ".poe-code/pipeline";
|
|
38635
39054
|
return {
|
|
38636
|
-
plansPath:
|
|
38637
|
-
stepsPath:
|
|
39055
|
+
plansPath: path26.join(rootPath, "plans"),
|
|
39056
|
+
stepsPath: path26.join(rootPath, "steps.yaml"),
|
|
38638
39057
|
displayPlansPath: `${displayRoot}/plans`,
|
|
38639
39058
|
displayStepsPath: `${displayRoot}/steps.yaml`
|
|
38640
39059
|
};
|
|
@@ -38645,16 +39064,16 @@ async function loadPipelineTemplates() {
|
|
|
38645
39064
|
}
|
|
38646
39065
|
const packageRoot = await findPackageRoot(fileURLToPath4(import.meta.url));
|
|
38647
39066
|
const templateRoots = [
|
|
38648
|
-
|
|
38649
|
-
|
|
39067
|
+
path26.join(packageRoot, "src", "templates", "pipeline"),
|
|
39068
|
+
path26.join(packageRoot, "dist", "templates", "pipeline")
|
|
38650
39069
|
];
|
|
38651
39070
|
for (const templateRoot of templateRoots) {
|
|
38652
39071
|
if (!await pathExistsOnDisk(templateRoot)) {
|
|
38653
39072
|
continue;
|
|
38654
39073
|
}
|
|
38655
39074
|
const [skillPlan, steps] = await Promise.all([
|
|
38656
|
-
|
|
38657
|
-
|
|
39075
|
+
readFile8(path26.join(templateRoot, "SKILL_plan.md"), "utf8"),
|
|
39076
|
+
readFile8(path26.join(templateRoot, "steps.yaml.hbs"), "utf8")
|
|
38658
39077
|
]);
|
|
38659
39078
|
pipelineTemplatesCache = { skillPlan, steps };
|
|
38660
39079
|
return pipelineTemplatesCache;
|
|
@@ -38663,7 +39082,7 @@ async function loadPipelineTemplates() {
|
|
|
38663
39082
|
}
|
|
38664
39083
|
async function pathExistsOnDisk(targetPath) {
|
|
38665
39084
|
try {
|
|
38666
|
-
await
|
|
39085
|
+
await stat7(targetPath);
|
|
38667
39086
|
return true;
|
|
38668
39087
|
} catch (error2) {
|
|
38669
39088
|
if (error2 && typeof error2 === "object" && "code" in error2 && error2.code === "ENOENT") {
|
|
@@ -38673,12 +39092,12 @@ async function pathExistsOnDisk(targetPath) {
|
|
|
38673
39092
|
}
|
|
38674
39093
|
}
|
|
38675
39094
|
async function findPackageRoot(entryFilePath) {
|
|
38676
|
-
let currentPath =
|
|
39095
|
+
let currentPath = path26.dirname(entryFilePath);
|
|
38677
39096
|
while (true) {
|
|
38678
|
-
if (await pathExistsOnDisk(
|
|
39097
|
+
if (await pathExistsOnDisk(path26.join(currentPath, "package.json"))) {
|
|
38679
39098
|
return currentPath;
|
|
38680
39099
|
}
|
|
38681
|
-
const parentPath =
|
|
39100
|
+
const parentPath = path26.dirname(currentPath);
|
|
38682
39101
|
if (parentPath === currentPath) {
|
|
38683
39102
|
throw new Error("Unable to locate package root for Pipeline templates.");
|
|
38684
39103
|
}
|
|
@@ -38956,7 +39375,7 @@ function registerPipelineCommand(program, container) {
|
|
|
38956
39375
|
`Would ${stepsExists ? "overwrite" : "create"}: ${pipelinePaths.displayStepsPath}`
|
|
38957
39376
|
);
|
|
38958
39377
|
} else {
|
|
38959
|
-
await container.fs.mkdir(
|
|
39378
|
+
await container.fs.mkdir(path26.dirname(pipelinePaths.stepsPath), {
|
|
38960
39379
|
recursive: true
|
|
38961
39380
|
});
|
|
38962
39381
|
await container.fs.writeFile(pipelinePaths.stepsPath, templates.steps, {
|
|
@@ -38981,24 +39400,244 @@ var init_pipeline4 = __esm({
|
|
|
38981
39400
|
"use strict";
|
|
38982
39401
|
init_src4();
|
|
38983
39402
|
init_src3();
|
|
38984
|
-
|
|
39403
|
+
init_src15();
|
|
38985
39404
|
init_errors();
|
|
38986
39405
|
init_shared();
|
|
38987
39406
|
await init_pipeline2();
|
|
38988
|
-
|
|
39407
|
+
init_src11();
|
|
38989
39408
|
DEFAULT_PIPELINE_AGENT = "claude-code";
|
|
38990
39409
|
DEFAULT_PIPELINE_SCOPE = "local";
|
|
38991
39410
|
pipelineTemplatesCache = null;
|
|
38992
39411
|
}
|
|
38993
39412
|
});
|
|
38994
39413
|
|
|
39414
|
+
// src/cli/commands/ralph.ts
|
|
39415
|
+
function formatDuration2(ms) {
|
|
39416
|
+
const totalSeconds = Math.round(ms / 1e3);
|
|
39417
|
+
const minutes = Math.floor(totalSeconds / 60);
|
|
39418
|
+
const seconds = totalSeconds % 60;
|
|
39419
|
+
return minutes > 0 ? `${minutes}m ${seconds}s` : `${seconds}s`;
|
|
39420
|
+
}
|
|
39421
|
+
function resolveRalphAgent(value) {
|
|
39422
|
+
if (!value || value.trim().length === 0) {
|
|
39423
|
+
return DEFAULT_RALPH_AGENT;
|
|
39424
|
+
}
|
|
39425
|
+
const resolved = resolveAgentId(value.trim());
|
|
39426
|
+
if (!resolved) {
|
|
39427
|
+
throw new ValidationError(`Unsupported agent: ${value}`);
|
|
39428
|
+
}
|
|
39429
|
+
return resolved;
|
|
39430
|
+
}
|
|
39431
|
+
function parsePositiveInt(value, fieldName) {
|
|
39432
|
+
if (value == null) {
|
|
39433
|
+
return void 0;
|
|
39434
|
+
}
|
|
39435
|
+
const parsed = Number.parseInt(value, 10);
|
|
39436
|
+
if (!Number.isFinite(parsed) || parsed < 1) {
|
|
39437
|
+
throw new ValidationError(
|
|
39438
|
+
`Invalid ${fieldName} "${value}". Expected a positive integer.`
|
|
39439
|
+
);
|
|
39440
|
+
}
|
|
39441
|
+
return parsed;
|
|
39442
|
+
}
|
|
39443
|
+
async function resolveAgent(options) {
|
|
39444
|
+
if (options.providedAgent) {
|
|
39445
|
+
return resolveRalphAgent(options.providedAgent);
|
|
39446
|
+
}
|
|
39447
|
+
const flags = resolveCommandFlags(options.program);
|
|
39448
|
+
if (flags.assumeYes) {
|
|
39449
|
+
return DEFAULT_RALPH_AGENT;
|
|
39450
|
+
}
|
|
39451
|
+
const selected = await select2({
|
|
39452
|
+
message: "Select agent to run Ralph with:",
|
|
39453
|
+
options: allSpawnConfigs.map((config2) => ({
|
|
39454
|
+
label: config2.agentId,
|
|
39455
|
+
value: config2.agentId
|
|
39456
|
+
}))
|
|
39457
|
+
});
|
|
39458
|
+
if (isCancel2(selected)) {
|
|
39459
|
+
cancel2("Ralph run cancelled.");
|
|
39460
|
+
return null;
|
|
39461
|
+
}
|
|
39462
|
+
return resolveRalphAgent(typeof selected === "string" ? selected : void 0);
|
|
39463
|
+
}
|
|
39464
|
+
async function resolveDocPath(options) {
|
|
39465
|
+
if (options.providedDoc && options.providedDoc.trim().length > 0) {
|
|
39466
|
+
return options.providedDoc.trim();
|
|
39467
|
+
}
|
|
39468
|
+
const docs = await discoverDocs({
|
|
39469
|
+
cwd: options.container.env.cwd,
|
|
39470
|
+
homeDir: options.container.env.homeDir,
|
|
39471
|
+
fs: options.container.fs
|
|
39472
|
+
});
|
|
39473
|
+
if (docs.length === 0) {
|
|
39474
|
+
throw new ValidationError(
|
|
39475
|
+
"No markdown doc found under .poe-code/ralph/plans/ or ~/.poe-code/ralph/plans/. Provide a doc path."
|
|
39476
|
+
);
|
|
39477
|
+
}
|
|
39478
|
+
const flags = resolveCommandFlags(options.program);
|
|
39479
|
+
if (flags.assumeYes) {
|
|
39480
|
+
return docs[0].path;
|
|
39481
|
+
}
|
|
39482
|
+
const selected = await select2({
|
|
39483
|
+
message: "Select the Ralph markdown doc to run:",
|
|
39484
|
+
options: docs.map((doc) => ({
|
|
39485
|
+
label: doc.displayPath,
|
|
39486
|
+
value: doc.path
|
|
39487
|
+
}))
|
|
39488
|
+
});
|
|
39489
|
+
if (isCancel2(selected)) {
|
|
39490
|
+
cancel2("Ralph run cancelled.");
|
|
39491
|
+
return null;
|
|
39492
|
+
}
|
|
39493
|
+
return typeof selected === "string" ? selected : null;
|
|
39494
|
+
}
|
|
39495
|
+
async function resolveIterations(options) {
|
|
39496
|
+
const explicitIterations = parsePositiveInt(
|
|
39497
|
+
options.providedIterations,
|
|
39498
|
+
"iterations"
|
|
39499
|
+
);
|
|
39500
|
+
if (explicitIterations != null) {
|
|
39501
|
+
return explicitIterations;
|
|
39502
|
+
}
|
|
39503
|
+
const flags = resolveCommandFlags(options.program);
|
|
39504
|
+
if (flags.assumeYes) {
|
|
39505
|
+
throw new ValidationError(
|
|
39506
|
+
"Iterations are required when using --yes. Provide poe-code ralph run <iterations> [doc]."
|
|
39507
|
+
);
|
|
39508
|
+
}
|
|
39509
|
+
const entered = await text3({
|
|
39510
|
+
message: "How many Ralph iterations should run?"
|
|
39511
|
+
});
|
|
39512
|
+
if (isCancel2(entered)) {
|
|
39513
|
+
cancel2("Ralph run cancelled.");
|
|
39514
|
+
return null;
|
|
39515
|
+
}
|
|
39516
|
+
return parsePositiveInt(
|
|
39517
|
+
typeof entered === "string" ? entered.trim() : void 0,
|
|
39518
|
+
"iterations"
|
|
39519
|
+
) ?? null;
|
|
39520
|
+
}
|
|
39521
|
+
function registerRalphCommand(program, container) {
|
|
39522
|
+
const ralph = program.command("ralph").description("Run a simple iterative markdown loop.");
|
|
39523
|
+
ralph.command("run").description("Run the selected markdown doc through repeated agent iterations.").argument("[iterations]", "Number of Ralph iterations to run").argument("[doc]", "Markdown doc path").option("--agent <name>", "Agent to run each iteration with").option("--model <model>", "Model override passed to the agent").option(
|
|
39524
|
+
"--max-failures <n>",
|
|
39525
|
+
"Consecutive failure threshold before overbake protection prompts"
|
|
39526
|
+
).action(async function(iterationsArg, docArg) {
|
|
39527
|
+
const flags = resolveCommandFlags(program);
|
|
39528
|
+
const resources = createExecutionResources(container, flags, "ralph:run");
|
|
39529
|
+
const options = this.opts();
|
|
39530
|
+
resources.logger.intro("ralph run");
|
|
39531
|
+
try {
|
|
39532
|
+
const docPath = await resolveDocPath({
|
|
39533
|
+
container,
|
|
39534
|
+
program,
|
|
39535
|
+
providedDoc: docArg
|
|
39536
|
+
});
|
|
39537
|
+
if (!docPath) {
|
|
39538
|
+
return;
|
|
39539
|
+
}
|
|
39540
|
+
const agent2 = await resolveAgent({
|
|
39541
|
+
program,
|
|
39542
|
+
providedAgent: options.agent
|
|
39543
|
+
});
|
|
39544
|
+
if (!agent2) {
|
|
39545
|
+
return;
|
|
39546
|
+
}
|
|
39547
|
+
const maxIterations = await resolveIterations({
|
|
39548
|
+
program,
|
|
39549
|
+
providedIterations: iterationsArg
|
|
39550
|
+
});
|
|
39551
|
+
if (maxIterations == null) {
|
|
39552
|
+
return;
|
|
39553
|
+
}
|
|
39554
|
+
const maxFailures = parsePositiveInt(
|
|
39555
|
+
options.maxFailures,
|
|
39556
|
+
"max-failures"
|
|
39557
|
+
);
|
|
39558
|
+
const result = await runRalph2({
|
|
39559
|
+
agent: agent2,
|
|
39560
|
+
cwd: container.env.cwd,
|
|
39561
|
+
homeDir: container.env.homeDir,
|
|
39562
|
+
docPath,
|
|
39563
|
+
maxIterations,
|
|
39564
|
+
...options.model ? { model: options.model } : {},
|
|
39565
|
+
...maxFailures != null ? { maxFailures } : {},
|
|
39566
|
+
promptOverbake: async (input) => {
|
|
39567
|
+
const selected = await select2({
|
|
39568
|
+
message: `Ralph hit ${input.consecutiveFailures} consecutive failures (threshold ${input.threshold}). What should happen next?`,
|
|
39569
|
+
options: [
|
|
39570
|
+
{ label: "Continue", value: "continue" },
|
|
39571
|
+
{ label: "Abort", value: "abort" }
|
|
39572
|
+
]
|
|
39573
|
+
});
|
|
39574
|
+
if (isCancel2(selected)) {
|
|
39575
|
+
cancel2("Ralph run cancelled.");
|
|
39576
|
+
return "abort";
|
|
39577
|
+
}
|
|
39578
|
+
return selected === "continue" ? "continue" : "abort";
|
|
39579
|
+
},
|
|
39580
|
+
onIterationStart(iteration, total) {
|
|
39581
|
+
resources.logger.info(`Iteration ${iteration}/${total}`);
|
|
39582
|
+
},
|
|
39583
|
+
onIterationComplete(iteration, durationMs, success2) {
|
|
39584
|
+
const status = success2 ? "done" : "failed";
|
|
39585
|
+
resources.logger.info(
|
|
39586
|
+
`Iteration ${iteration} ${status} in ${formatDuration2(durationMs)}`
|
|
39587
|
+
);
|
|
39588
|
+
},
|
|
39589
|
+
onOverbakeWarning(consecutiveFailures, threshold) {
|
|
39590
|
+
resources.logger.warn(
|
|
39591
|
+
`Overbake protection triggered at ${consecutiveFailures} consecutive failures (threshold ${threshold}).`
|
|
39592
|
+
);
|
|
39593
|
+
}
|
|
39594
|
+
});
|
|
39595
|
+
const summary = [
|
|
39596
|
+
`Iterations: ${result.iterationsCompleted}/${maxIterations}`,
|
|
39597
|
+
`Doc: ${result.docPath}`,
|
|
39598
|
+
`Duration: ${formatDuration2(result.totalDurationMs)}`
|
|
39599
|
+
].join("\n ");
|
|
39600
|
+
if (result.stopReason === "cancelled") {
|
|
39601
|
+
process.exitCode = 130;
|
|
39602
|
+
resources.logger.warn("Ralph run cancelled.");
|
|
39603
|
+
resources.logger.resolved("Run summary", summary);
|
|
39604
|
+
return;
|
|
39605
|
+
}
|
|
39606
|
+
if (result.stopReason === "overbake_abort") {
|
|
39607
|
+
process.exitCode = 1;
|
|
39608
|
+
resources.logger.warn("Ralph stopped after repeated failures.");
|
|
39609
|
+
resources.logger.resolved("Run summary", summary);
|
|
39610
|
+
return;
|
|
39611
|
+
}
|
|
39612
|
+
resources.logger.resolved("Run summary", summary);
|
|
39613
|
+
resources.logger.success("Ralph run finished.");
|
|
39614
|
+
} finally {
|
|
39615
|
+
resources.context.finalize();
|
|
39616
|
+
}
|
|
39617
|
+
});
|
|
39618
|
+
}
|
|
39619
|
+
var DEFAULT_RALPH_AGENT;
|
|
39620
|
+
var init_ralph3 = __esm({
|
|
39621
|
+
async "src/cli/commands/ralph.ts"() {
|
|
39622
|
+
"use strict";
|
|
39623
|
+
init_src4();
|
|
39624
|
+
init_src3();
|
|
39625
|
+
init_src5();
|
|
39626
|
+
init_src12();
|
|
39627
|
+
init_errors();
|
|
39628
|
+
init_shared();
|
|
39629
|
+
await init_ralph2();
|
|
39630
|
+
DEFAULT_RALPH_AGENT = "claude-code";
|
|
39631
|
+
}
|
|
39632
|
+
});
|
|
39633
|
+
|
|
38995
39634
|
// package.json
|
|
38996
39635
|
var package_default;
|
|
38997
39636
|
var init_package = __esm({
|
|
38998
39637
|
"package.json"() {
|
|
38999
39638
|
package_default = {
|
|
39000
39639
|
name: "poe-code",
|
|
39001
|
-
version: "3.0.
|
|
39640
|
+
version: "3.0.103",
|
|
39002
39641
|
description: "CLI tool to configure Poe API for developer workflows.",
|
|
39003
39642
|
type: "module",
|
|
39004
39643
|
main: "./dist/index.js",
|
|
@@ -39091,6 +39730,8 @@ var init_package = __esm({
|
|
|
39091
39730
|
"@poe-code/freeze-cli": "*",
|
|
39092
39731
|
"@poe-code/pipeline": "*",
|
|
39093
39732
|
"@poe-code/poe-acp-client": "*",
|
|
39733
|
+
"@poe-code/poe-code-config": "*",
|
|
39734
|
+
"@poe-code/ralph": "*",
|
|
39094
39735
|
"@types/mustache": "^4.2.6",
|
|
39095
39736
|
"@types/node": "^25.2.2",
|
|
39096
39737
|
"@types/semver": "^7.7.1",
|
|
@@ -39214,6 +39855,11 @@ function formatHelpText(input) {
|
|
|
39214
39855
|
args: "",
|
|
39215
39856
|
description: "Run a fixed-step task pipeline plan"
|
|
39216
39857
|
},
|
|
39858
|
+
{
|
|
39859
|
+
name: "ralph run",
|
|
39860
|
+
args: "[iterations] [doc]",
|
|
39861
|
+
description: "Run a markdown doc through repeated agent iterations"
|
|
39862
|
+
},
|
|
39217
39863
|
{
|
|
39218
39864
|
name: "usage",
|
|
39219
39865
|
args: "",
|
|
@@ -39223,11 +39869,6 @@ function formatHelpText(input) {
|
|
|
39223
39869
|
name: "usage list",
|
|
39224
39870
|
args: "",
|
|
39225
39871
|
description: "Display usage history"
|
|
39226
|
-
},
|
|
39227
|
-
{
|
|
39228
|
-
name: "pipeline run",
|
|
39229
|
-
args: "",
|
|
39230
|
-
description: "Run a fixed-step task pipeline plan"
|
|
39231
39872
|
}
|
|
39232
39873
|
];
|
|
39233
39874
|
const nameWidth = Math.max(0, ...commandRows.map((row) => row.name.length));
|
|
@@ -39377,6 +40018,7 @@ function bootstrapProgram(container) {
|
|
|
39377
40018
|
registerMcpCommand(program, container);
|
|
39378
40019
|
registerSkillCommand(program, container);
|
|
39379
40020
|
registerPipelineCommand(program, container);
|
|
40021
|
+
registerRalphCommand(program, container);
|
|
39380
40022
|
registerUsageCommand(program, container);
|
|
39381
40023
|
registerModelsCommand(program, container);
|
|
39382
40024
|
program.allowExcessArguments().action(function() {
|
|
@@ -39434,6 +40076,7 @@ var init_program = __esm({
|
|
|
39434
40076
|
init_usage();
|
|
39435
40077
|
init_models();
|
|
39436
40078
|
await init_pipeline4();
|
|
40079
|
+
await init_ralph3();
|
|
39437
40080
|
init_package();
|
|
39438
40081
|
init_command_not_found();
|
|
39439
40082
|
init_execution_context();
|
|
@@ -39607,6 +40250,7 @@ var init_bootstrap = __esm({
|
|
|
39607
40250
|
// src/index.ts
|
|
39608
40251
|
await init_spawn3();
|
|
39609
40252
|
await init_pipeline2();
|
|
40253
|
+
await init_ralph2();
|
|
39610
40254
|
import { realpathSync as realpathSync2 } from "node:fs";
|
|
39611
40255
|
import { pathToFileURL as pathToFileURL3 } from "node:url";
|
|
39612
40256
|
|
|
@@ -39715,7 +40359,7 @@ init_src5();
|
|
|
39715
40359
|
init_src4();
|
|
39716
40360
|
init_constants();
|
|
39717
40361
|
init_errors();
|
|
39718
|
-
import
|
|
40362
|
+
import path19 from "node:path";
|
|
39719
40363
|
import { Command } from "commander";
|
|
39720
40364
|
function parseMcpSpawnConfig(input) {
|
|
39721
40365
|
if (!input) {
|
|
@@ -39786,10 +40430,10 @@ function resolveWorkingDirectory(baseDir, candidate) {
|
|
|
39786
40430
|
if (!candidate || candidate.trim().length === 0) {
|
|
39787
40431
|
return void 0;
|
|
39788
40432
|
}
|
|
39789
|
-
if (
|
|
40433
|
+
if (path19.isAbsolute(candidate)) {
|
|
39790
40434
|
return candidate;
|
|
39791
40435
|
}
|
|
39792
|
-
return
|
|
40436
|
+
return path19.resolve(baseDir, candidate);
|
|
39793
40437
|
}
|
|
39794
40438
|
function createPoeAgentProgram() {
|
|
39795
40439
|
const program = new Command();
|
|
@@ -39892,6 +40536,7 @@ export {
|
|
|
39892
40536
|
main,
|
|
39893
40537
|
poeAgentMain,
|
|
39894
40538
|
runPipeline2 as runPipeline,
|
|
40539
|
+
runRalph2 as runRalph,
|
|
39895
40540
|
spawn5 as spawn
|
|
39896
40541
|
};
|
|
39897
40542
|
//# sourceMappingURL=index.js.map
|