poe-code 3.0.114 → 3.0.115
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/pipeline.js +24 -1
- package/dist/cli/commands/pipeline.js.map +1 -1
- package/dist/cli/commands/ralph.js +241 -62
- package/dist/cli/commands/ralph.js.map +1 -1
- package/dist/cli/program.js +6 -1
- package/dist/cli/program.js.map +1 -1
- package/dist/index.js +635 -229
- package/dist/index.js.map +4 -4
- package/dist/providers/claude-code.js.map +1 -1
- package/dist/providers/codex.js.map +1 -1
- package/dist/providers/kimi.js.map +1 -1
- package/dist/providers/opencode.js.map +1 -1
- package/dist/sdk/pipeline.d.ts +1 -0
- package/dist/sdk/pipeline.js +1 -0
- package/dist/sdk/pipeline.js.map +1 -1
- package/dist/sdk/ralph.d.ts +1 -1
- package/dist/sdk/ralph.js.map +1 -1
- package/dist/services/config.d.ts +30 -0
- package/dist/services/config.js +17 -1
- package/dist/services/config.js.map +1 -1
- package/dist/templates/pipeline/SKILL_plan.md +5 -6
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -891,16 +891,16 @@ function getConfigFormat(pathOrFormat) {
|
|
|
891
891
|
}
|
|
892
892
|
return formatRegistry[formatName];
|
|
893
893
|
}
|
|
894
|
-
function detectFormat(
|
|
895
|
-
const ext = getExtension(
|
|
894
|
+
function detectFormat(path29) {
|
|
895
|
+
const ext = getExtension(path29);
|
|
896
896
|
return extensionMap[ext];
|
|
897
897
|
}
|
|
898
|
-
function getExtension(
|
|
899
|
-
const lastDot =
|
|
898
|
+
function getExtension(path29) {
|
|
899
|
+
const lastDot = path29.lastIndexOf(".");
|
|
900
900
|
if (lastDot === -1) {
|
|
901
901
|
return "";
|
|
902
902
|
}
|
|
903
|
-
return
|
|
903
|
+
return path29.slice(lastDot).toLowerCase();
|
|
904
904
|
}
|
|
905
905
|
var formatRegistry, extensionMap;
|
|
906
906
|
var init_formats = __esm({
|
|
@@ -1750,6 +1750,61 @@ var init_store = __esm({
|
|
|
1750
1750
|
});
|
|
1751
1751
|
|
|
1752
1752
|
// packages/poe-code-config/src/resolve.ts
|
|
1753
|
+
function resolveScope(schema, fileValues, env = {}) {
|
|
1754
|
+
const resolved = {};
|
|
1755
|
+
for (const key of Object.keys(schema)) {
|
|
1756
|
+
const field = schema[key];
|
|
1757
|
+
const envValue = resolveEnvValue(field, env);
|
|
1758
|
+
const fileValue = resolveFileValue(field, fileValues?.[key]);
|
|
1759
|
+
resolved[key] = envValue ?? fileValue ?? field.default;
|
|
1760
|
+
}
|
|
1761
|
+
return resolved;
|
|
1762
|
+
}
|
|
1763
|
+
function resolveEnvValue(field, env) {
|
|
1764
|
+
if (!field.env) {
|
|
1765
|
+
return void 0;
|
|
1766
|
+
}
|
|
1767
|
+
const raw = env[field.env];
|
|
1768
|
+
if (raw === void 0) {
|
|
1769
|
+
return void 0;
|
|
1770
|
+
}
|
|
1771
|
+
return coerceValue(field, raw);
|
|
1772
|
+
}
|
|
1773
|
+
function resolveFileValue(field, value) {
|
|
1774
|
+
return coerceValue(field, value);
|
|
1775
|
+
}
|
|
1776
|
+
function coerceValue(field, value) {
|
|
1777
|
+
switch (field.type) {
|
|
1778
|
+
case "string":
|
|
1779
|
+
return typeof value === "string" ? value : void 0;
|
|
1780
|
+
case "number":
|
|
1781
|
+
return coerceNumber(value);
|
|
1782
|
+
case "boolean":
|
|
1783
|
+
return coerceBoolean(value);
|
|
1784
|
+
}
|
|
1785
|
+
}
|
|
1786
|
+
function coerceNumber(value) {
|
|
1787
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
1788
|
+
return value;
|
|
1789
|
+
}
|
|
1790
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
1791
|
+
return void 0;
|
|
1792
|
+
}
|
|
1793
|
+
const parsed = Number(value);
|
|
1794
|
+
return Number.isNaN(parsed) ? void 0 : parsed;
|
|
1795
|
+
}
|
|
1796
|
+
function coerceBoolean(value) {
|
|
1797
|
+
if (typeof value === "boolean") {
|
|
1798
|
+
return value;
|
|
1799
|
+
}
|
|
1800
|
+
if (value === "true" || value === "1") {
|
|
1801
|
+
return true;
|
|
1802
|
+
}
|
|
1803
|
+
if (value === "false" || value === "0") {
|
|
1804
|
+
return false;
|
|
1805
|
+
}
|
|
1806
|
+
return void 0;
|
|
1807
|
+
}
|
|
1753
1808
|
var init_resolve = __esm({
|
|
1754
1809
|
"packages/poe-code-config/src/resolve.ts"() {
|
|
1755
1810
|
"use strict";
|
|
@@ -1900,38 +1955,38 @@ import { createTwoFilesPatch } from "diff";
|
|
|
1900
1955
|
import chalk from "chalk";
|
|
1901
1956
|
function createDryRunFileSystem(base, recorder) {
|
|
1902
1957
|
const proxy = {
|
|
1903
|
-
async readFile(
|
|
1958
|
+
async readFile(path29, encoding) {
|
|
1904
1959
|
if (encoding) {
|
|
1905
|
-
return base.readFile(
|
|
1960
|
+
return base.readFile(path29, encoding);
|
|
1906
1961
|
}
|
|
1907
|
-
return base.readFile(
|
|
1962
|
+
return base.readFile(path29);
|
|
1908
1963
|
},
|
|
1909
|
-
async writeFile(
|
|
1910
|
-
const previousContent = await tryReadText(base,
|
|
1964
|
+
async writeFile(path29, data, options) {
|
|
1965
|
+
const previousContent = await tryReadText(base, path29);
|
|
1911
1966
|
const nextContent = formatData(data, options?.encoding);
|
|
1912
1967
|
recorder.record({
|
|
1913
1968
|
type: "writeFile",
|
|
1914
|
-
path:
|
|
1969
|
+
path: path29,
|
|
1915
1970
|
nextContent,
|
|
1916
1971
|
previousContent
|
|
1917
1972
|
});
|
|
1918
1973
|
},
|
|
1919
|
-
async mkdir(
|
|
1920
|
-
recorder.record({ type: "mkdir", path:
|
|
1974
|
+
async mkdir(path29, options) {
|
|
1975
|
+
recorder.record({ type: "mkdir", path: path29, options });
|
|
1921
1976
|
},
|
|
1922
|
-
async stat(
|
|
1923
|
-
return base.stat(
|
|
1977
|
+
async stat(path29) {
|
|
1978
|
+
return base.stat(path29);
|
|
1924
1979
|
},
|
|
1925
|
-
async unlink(
|
|
1926
|
-
recorder.record({ type: "unlink", path:
|
|
1980
|
+
async unlink(path29) {
|
|
1981
|
+
recorder.record({ type: "unlink", path: path29 });
|
|
1927
1982
|
},
|
|
1928
|
-
async readdir(
|
|
1929
|
-
return base.readdir(
|
|
1983
|
+
async readdir(path29) {
|
|
1984
|
+
return base.readdir(path29);
|
|
1930
1985
|
}
|
|
1931
1986
|
};
|
|
1932
1987
|
if (typeof base.rm === "function") {
|
|
1933
|
-
proxy.rm = async (
|
|
1934
|
-
recorder.record({ type: "rm", path:
|
|
1988
|
+
proxy.rm = async (path29, options) => {
|
|
1989
|
+
recorder.record({ type: "rm", path: path29, options });
|
|
1935
1990
|
};
|
|
1936
1991
|
}
|
|
1937
1992
|
if (typeof base.copyFile === "function") {
|
|
@@ -2021,8 +2076,8 @@ function describeWriteChange(previous, next) {
|
|
|
2021
2076
|
}
|
|
2022
2077
|
return "update";
|
|
2023
2078
|
}
|
|
2024
|
-
function renderWriteCommand(
|
|
2025
|
-
const command = `cat > ${
|
|
2079
|
+
function renderWriteCommand(path29, change) {
|
|
2080
|
+
const command = `cat > ${path29}`;
|
|
2026
2081
|
if (change === "create") {
|
|
2027
2082
|
return renderOperationCommand(command, chalk.green, "# create");
|
|
2028
2083
|
}
|
|
@@ -2184,9 +2239,9 @@ function redactTomlLine(line) {
|
|
|
2184
2239
|
}
|
|
2185
2240
|
return line;
|
|
2186
2241
|
}
|
|
2187
|
-
async function tryReadText(base,
|
|
2242
|
+
async function tryReadText(base, path29) {
|
|
2188
2243
|
try {
|
|
2189
|
-
return await base.readFile(
|
|
2244
|
+
return await base.readFile(path29, "utf8");
|
|
2190
2245
|
} catch (error2) {
|
|
2191
2246
|
if (isNotFound(error2)) {
|
|
2192
2247
|
return null;
|
|
@@ -3324,6 +3379,12 @@ var init_text = __esm({
|
|
|
3324
3379
|
badge(content) {
|
|
3325
3380
|
const theme = getTheme();
|
|
3326
3381
|
return theme.badge(content);
|
|
3382
|
+
},
|
|
3383
|
+
selectLabel(label, detail) {
|
|
3384
|
+
if (!detail) {
|
|
3385
|
+
return label;
|
|
3386
|
+
}
|
|
3387
|
+
return `${label} ${typography.dim("\u2014")} ${typography.dim(detail)}`;
|
|
3327
3388
|
}
|
|
3328
3389
|
};
|
|
3329
3390
|
}
|
|
@@ -4028,21 +4089,21 @@ async function* adaptClaude(lines) {
|
|
|
4028
4089
|
if (blockType !== "tool_result") continue;
|
|
4029
4090
|
const kind = toolKindsById.get(item.tool_use_id);
|
|
4030
4091
|
toolKindsById.delete(item.tool_use_id);
|
|
4031
|
-
let
|
|
4092
|
+
let path29;
|
|
4032
4093
|
if (typeof item.content === "string") {
|
|
4033
|
-
|
|
4094
|
+
path29 = item.content;
|
|
4034
4095
|
} else {
|
|
4035
4096
|
try {
|
|
4036
|
-
|
|
4097
|
+
path29 = JSON.stringify(item.content);
|
|
4037
4098
|
} catch {
|
|
4038
|
-
|
|
4099
|
+
path29 = String(item.content);
|
|
4039
4100
|
}
|
|
4040
4101
|
}
|
|
4041
4102
|
yield {
|
|
4042
4103
|
event: "tool_complete",
|
|
4043
4104
|
id: item.tool_use_id,
|
|
4044
4105
|
kind,
|
|
4045
|
-
path:
|
|
4106
|
+
path: path29
|
|
4046
4107
|
};
|
|
4047
4108
|
}
|
|
4048
4109
|
}
|
|
@@ -4164,10 +4225,10 @@ async function* adaptCodex(lines) {
|
|
|
4164
4225
|
const kindFromStart = toolKindById.get(item.id);
|
|
4165
4226
|
const kind = kindFromStart ?? (itemType === "command_execution" ? "exec" : itemType === "file_edit" ? "edit" : "other");
|
|
4166
4227
|
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;
|
|
4167
|
-
const
|
|
4228
|
+
const path29 = titleFromEvent ?? toolTitleById.get(item.id) ?? "";
|
|
4168
4229
|
toolTitleById.delete(item.id);
|
|
4169
4230
|
toolKindById.delete(item.id);
|
|
4170
|
-
yield { event: "tool_complete", id: item.id, kind, path:
|
|
4231
|
+
yield { event: "tool_complete", id: item.id, kind, path: path29 };
|
|
4171
4232
|
}
|
|
4172
4233
|
}
|
|
4173
4234
|
}
|
|
@@ -4616,7 +4677,7 @@ function updateSessionFromEvent(ctx, event, toolCallsById) {
|
|
|
4616
4677
|
}
|
|
4617
4678
|
const id = readString(event.id);
|
|
4618
4679
|
const kind = readString(event.kind);
|
|
4619
|
-
const
|
|
4680
|
+
const path29 = readString(event.path);
|
|
4620
4681
|
let toolCall = id ? toolCallsById.get(id) : void 0;
|
|
4621
4682
|
if (!toolCall) {
|
|
4622
4683
|
toolCall = {};
|
|
@@ -4631,8 +4692,8 @@ function updateSessionFromEvent(ctx, event, toolCallsById) {
|
|
|
4631
4692
|
if (kind) {
|
|
4632
4693
|
toolCall.kind = kind;
|
|
4633
4694
|
}
|
|
4634
|
-
if (
|
|
4635
|
-
toolCall.path =
|
|
4695
|
+
if (path29) {
|
|
4696
|
+
toolCall.path = path29;
|
|
4636
4697
|
}
|
|
4637
4698
|
}
|
|
4638
4699
|
var sessionCapture;
|
|
@@ -6630,21 +6691,21 @@ function createSdkContainer(options) {
|
|
|
6630
6691
|
});
|
|
6631
6692
|
loggerFactory.setErrorLogger(errorLogger);
|
|
6632
6693
|
const asyncFs = {
|
|
6633
|
-
readFile: ((
|
|
6694
|
+
readFile: ((path29, encoding) => {
|
|
6634
6695
|
if (encoding) {
|
|
6635
|
-
return fs2.readFile(
|
|
6696
|
+
return fs2.readFile(path29, encoding);
|
|
6636
6697
|
}
|
|
6637
|
-
return fs2.readFile(
|
|
6698
|
+
return fs2.readFile(path29);
|
|
6638
6699
|
}),
|
|
6639
|
-
writeFile: (
|
|
6640
|
-
mkdir: (
|
|
6700
|
+
writeFile: (path29, data, opts) => fs2.writeFile(path29, data, opts),
|
|
6701
|
+
mkdir: (path29, opts) => fs2.mkdir(path29, opts).then(() => {
|
|
6641
6702
|
}),
|
|
6642
|
-
stat: (
|
|
6643
|
-
rm: (
|
|
6644
|
-
unlink: (
|
|
6645
|
-
readdir: (
|
|
6703
|
+
stat: (path29) => fs2.stat(path29),
|
|
6704
|
+
rm: (path29, opts) => fs2.rm(path29, opts),
|
|
6705
|
+
unlink: (path29) => fs2.unlink(path29),
|
|
6706
|
+
readdir: (path29) => fs2.readdir(path29),
|
|
6646
6707
|
copyFile: (src, dest) => fs2.copyFile(src, dest),
|
|
6647
|
-
chmod: (
|
|
6708
|
+
chmod: (path29, mode) => fs2.chmod(path29, mode)
|
|
6648
6709
|
};
|
|
6649
6710
|
const contextFactory = createCommandContextFactory({ fs: asyncFs });
|
|
6650
6711
|
const authFs = {
|
|
@@ -7189,16 +7250,46 @@ async function scanPlansDir(fs3, plansDir, displayPrefix) {
|
|
|
7189
7250
|
}
|
|
7190
7251
|
return candidates;
|
|
7191
7252
|
}
|
|
7192
|
-
async function listPlanCandidates(fs3, cwd, homeDir) {
|
|
7253
|
+
async function listPlanCandidates(fs3, cwd, homeDir, planDirectory) {
|
|
7254
|
+
const customDir = planDirectory?.trim();
|
|
7255
|
+
const candidates = customDir ? await scanCustomPlanDir(fs3, customDir, cwd, homeDir) : await scanDefaultPlanDirs(fs3, cwd, homeDir);
|
|
7256
|
+
candidates.sort((left, right) => left.path.localeCompare(right.path));
|
|
7257
|
+
return candidates;
|
|
7258
|
+
}
|
|
7259
|
+
async function scanCustomPlanDir(fs3, planDirectory, cwd, homeDir) {
|
|
7260
|
+
const absoluteDir = resolveAbsoluteDirectory(planDirectory, cwd, homeDir);
|
|
7261
|
+
return scanPlansDir(fs3, absoluteDir, planDirectory);
|
|
7262
|
+
}
|
|
7263
|
+
async function scanDefaultPlanDirs(fs3, cwd, homeDir) {
|
|
7193
7264
|
const projectDir = path13.join(cwd, ".poe-code", "pipeline", "plans");
|
|
7194
7265
|
const globalDir = path13.join(homeDir, ".poe-code", "pipeline", "plans");
|
|
7195
7266
|
const [projectCandidates, globalCandidates] = await Promise.all([
|
|
7196
7267
|
scanPlansDir(fs3, projectDir, ".poe-code/pipeline/plans"),
|
|
7197
7268
|
scanPlansDir(fs3, globalDir, "~/.poe-code/pipeline/plans")
|
|
7198
7269
|
]);
|
|
7199
|
-
|
|
7200
|
-
|
|
7201
|
-
|
|
7270
|
+
return [...projectCandidates, ...globalCandidates];
|
|
7271
|
+
}
|
|
7272
|
+
function resolveAbsoluteDirectory(dir, cwd, homeDir) {
|
|
7273
|
+
if (dir.startsWith("~/")) {
|
|
7274
|
+
return path13.join(homeDir, dir.slice(2));
|
|
7275
|
+
}
|
|
7276
|
+
return path13.isAbsolute(dir) ? dir : path13.resolve(cwd, dir);
|
|
7277
|
+
}
|
|
7278
|
+
async function resolvePlanDirectory(options) {
|
|
7279
|
+
const customDir = options.planDirectory?.trim();
|
|
7280
|
+
if (customDir) {
|
|
7281
|
+
return resolveAbsoluteDirectory(customDir, options.cwd, options.homeDir);
|
|
7282
|
+
}
|
|
7283
|
+
const fs3 = options.fs ?? createDefaultFs();
|
|
7284
|
+
const projectDir = path13.join(options.cwd, ".poe-code");
|
|
7285
|
+
try {
|
|
7286
|
+
const stat8 = await fs3.stat(projectDir);
|
|
7287
|
+
if (stat8.isDirectory()) {
|
|
7288
|
+
return path13.join(options.cwd, ".poe-code", "pipeline", "plans");
|
|
7289
|
+
}
|
|
7290
|
+
} catch {
|
|
7291
|
+
}
|
|
7292
|
+
return path13.join(options.homeDir, ".poe-code", "pipeline", "plans");
|
|
7202
7293
|
}
|
|
7203
7294
|
function resolveAbsolutePlanPath(planPath, cwd, homeDir) {
|
|
7204
7295
|
if (planPath.startsWith("~/")) {
|
|
@@ -7222,7 +7313,7 @@ async function resolvePlanPath(options) {
|
|
|
7222
7313
|
await ensurePlanExists(fs3, options.cwd, config2.planPath);
|
|
7223
7314
|
return config2.planPath;
|
|
7224
7315
|
}
|
|
7225
|
-
const candidates = await listPlanCandidates(fs3, options.cwd, options.homeDir);
|
|
7316
|
+
const candidates = await listPlanCandidates(fs3, options.cwd, options.homeDir, options.planDirectory);
|
|
7226
7317
|
if (candidates.length >= 1) {
|
|
7227
7318
|
if (options.assumeYes) {
|
|
7228
7319
|
return candidates[0].path;
|
|
@@ -7507,6 +7598,7 @@ async function runPipeline(options) {
|
|
|
7507
7598
|
cwd: options.cwd,
|
|
7508
7599
|
homeDir: options.homeDir,
|
|
7509
7600
|
plan: options.plan,
|
|
7601
|
+
planDirectory: options.planDirectory,
|
|
7510
7602
|
assumeYes: options.assumeYes,
|
|
7511
7603
|
fs: fs3,
|
|
7512
7604
|
selectPlan: options.selectPlan,
|
|
@@ -7755,51 +7847,134 @@ var init_pipeline2 = __esm({
|
|
|
7755
7847
|
init_src8();
|
|
7756
7848
|
init_src6();
|
|
7757
7849
|
await init_spawn3();
|
|
7850
|
+
init_src8();
|
|
7758
7851
|
}
|
|
7759
7852
|
});
|
|
7760
7853
|
|
|
7761
7854
|
// packages/ralph/src/frontmatter/frontmatter.ts
|
|
7762
|
-
import {
|
|
7855
|
+
import { parse as parse6, stringify } from "yaml";
|
|
7763
7856
|
function parseFrontmatter(content) {
|
|
7764
|
-
const defaults = { status: "pending", iteration: 0 };
|
|
7765
7857
|
if (!content.startsWith(`${FENCE}
|
|
7766
7858
|
`)) {
|
|
7767
|
-
return {
|
|
7859
|
+
return {
|
|
7860
|
+
data: createDefaultFrontmatter(),
|
|
7861
|
+
body: content
|
|
7862
|
+
};
|
|
7768
7863
|
}
|
|
7769
7864
|
const closingIndex = content.indexOf(`
|
|
7770
7865
|
${FENCE}
|
|
7771
7866
|
`, FENCE.length);
|
|
7772
7867
|
if (closingIndex === -1) {
|
|
7773
|
-
return {
|
|
7868
|
+
return {
|
|
7869
|
+
data: createDefaultFrontmatter(),
|
|
7870
|
+
body: content
|
|
7871
|
+
};
|
|
7774
7872
|
}
|
|
7775
7873
|
const yamlBlock = content.slice(FENCE.length + 1, closingIndex);
|
|
7776
7874
|
const body = content.slice(closingIndex + FENCE.length + 2);
|
|
7777
7875
|
const parsed = parse6(yamlBlock);
|
|
7778
7876
|
return {
|
|
7779
|
-
data:
|
|
7780
|
-
status: isValidStatus(parsed?.status) ? parsed.status : defaults.status,
|
|
7781
|
-
iteration: typeof parsed?.iteration === "number" ? parsed.iteration : defaults.iteration
|
|
7782
|
-
},
|
|
7877
|
+
data: parseFrontmatterData(parsed),
|
|
7783
7878
|
body
|
|
7784
7879
|
};
|
|
7785
7880
|
}
|
|
7786
7881
|
function writeFrontmatter(data, body) {
|
|
7787
|
-
const
|
|
7882
|
+
const serialized = {
|
|
7883
|
+
...data.agent !== void 0 ? { agent: data.agent } : {},
|
|
7884
|
+
...data.iterations !== void 0 ? { iterations: data.iterations } : {},
|
|
7885
|
+
status: {
|
|
7886
|
+
state: data.status.state,
|
|
7887
|
+
iteration: data.status.iteration
|
|
7888
|
+
}
|
|
7889
|
+
};
|
|
7890
|
+
const yaml = stringify(serialized).trimEnd();
|
|
7788
7891
|
return `${FENCE}
|
|
7789
7892
|
${yaml}
|
|
7790
7893
|
${FENCE}
|
|
7791
7894
|
${body}`;
|
|
7792
7895
|
}
|
|
7793
|
-
function
|
|
7794
|
-
return
|
|
7795
|
-
|
|
7796
|
-
|
|
7896
|
+
function createDefaultFrontmatter() {
|
|
7897
|
+
return {
|
|
7898
|
+
status: {
|
|
7899
|
+
state: DEFAULT_STATUS.state,
|
|
7900
|
+
iteration: DEFAULT_STATUS.iteration
|
|
7901
|
+
}
|
|
7902
|
+
};
|
|
7903
|
+
}
|
|
7904
|
+
function parseFrontmatterData(value) {
|
|
7905
|
+
const defaults = createDefaultFrontmatter();
|
|
7906
|
+
const parsed = isRecord4(value) ? value : void 0;
|
|
7907
|
+
const parsedStatus = isRecord4(parsed?.status) ? parsed.status : void 0;
|
|
7908
|
+
const state = parsePlanStatus(parsedStatus?.state) ?? parseLegacyStatus(parsed?.status) ?? defaults.status.state;
|
|
7909
|
+
const iteration = parseNonNegativeInteger(parsedStatus?.iteration) ?? parseNonNegativeInteger(parsed?.iteration) ?? defaults.status.iteration;
|
|
7910
|
+
const agent2 = parseAgent(parsed?.agent);
|
|
7911
|
+
const iterations = parsePositiveInteger(parsed?.iterations);
|
|
7912
|
+
return {
|
|
7913
|
+
...agent2 !== void 0 ? { agent: agent2 } : {},
|
|
7914
|
+
...iterations !== void 0 ? { iterations } : {},
|
|
7915
|
+
status: {
|
|
7916
|
+
state,
|
|
7917
|
+
iteration
|
|
7918
|
+
}
|
|
7919
|
+
};
|
|
7920
|
+
}
|
|
7921
|
+
function parseAgent(value) {
|
|
7922
|
+
if (typeof value === "string") {
|
|
7923
|
+
const trimmed = value.trim();
|
|
7924
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
7925
|
+
}
|
|
7926
|
+
if (!Array.isArray(value)) {
|
|
7927
|
+
return void 0;
|
|
7928
|
+
}
|
|
7929
|
+
if (value.length === 0) {
|
|
7930
|
+
return [];
|
|
7931
|
+
}
|
|
7932
|
+
const agents = [];
|
|
7933
|
+
for (const item of value) {
|
|
7934
|
+
if (typeof item !== "string") {
|
|
7935
|
+
return void 0;
|
|
7936
|
+
}
|
|
7937
|
+
const trimmed = item.trim();
|
|
7938
|
+
if (trimmed.length === 0) {
|
|
7939
|
+
return void 0;
|
|
7940
|
+
}
|
|
7941
|
+
agents.push(trimmed);
|
|
7942
|
+
}
|
|
7943
|
+
return agents;
|
|
7944
|
+
}
|
|
7945
|
+
function parsePlanStatus(value) {
|
|
7946
|
+
if (value === "open" || value === "in_progress" || value === "completed") {
|
|
7947
|
+
return value;
|
|
7948
|
+
}
|
|
7949
|
+
return void 0;
|
|
7950
|
+
}
|
|
7951
|
+
function parseLegacyStatus(value) {
|
|
7952
|
+
if (value === "in_progress" || value === "completed") {
|
|
7953
|
+
return value;
|
|
7954
|
+
}
|
|
7955
|
+
if (value === "open" || value === "pending" || value === "cancelled" || value === "overbake_abort") {
|
|
7956
|
+
return "open";
|
|
7957
|
+
}
|
|
7958
|
+
return void 0;
|
|
7959
|
+
}
|
|
7960
|
+
function parseNonNegativeInteger(value) {
|
|
7961
|
+
return typeof value === "number" && Number.isInteger(value) && value >= 0 ? value : void 0;
|
|
7797
7962
|
}
|
|
7798
|
-
|
|
7963
|
+
function parsePositiveInteger(value) {
|
|
7964
|
+
return typeof value === "number" && Number.isInteger(value) && value >= 1 ? value : void 0;
|
|
7965
|
+
}
|
|
7966
|
+
function isRecord4(value) {
|
|
7967
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7968
|
+
}
|
|
7969
|
+
var FENCE, DEFAULT_STATUS;
|
|
7799
7970
|
var init_frontmatter = __esm({
|
|
7800
7971
|
"packages/ralph/src/frontmatter/frontmatter.ts"() {
|
|
7801
7972
|
"use strict";
|
|
7802
7973
|
FENCE = "---";
|
|
7974
|
+
DEFAULT_STATUS = {
|
|
7975
|
+
state: "open",
|
|
7976
|
+
iteration: 0
|
|
7977
|
+
};
|
|
7803
7978
|
}
|
|
7804
7979
|
});
|
|
7805
7980
|
|
|
@@ -7854,23 +8029,39 @@ async function scanDir(fs3, absoluteDir, displayDir) {
|
|
|
7854
8029
|
}
|
|
7855
8030
|
async function discoverDocs(options) {
|
|
7856
8031
|
const fs3 = options.fs ?? createDefaultFs4();
|
|
8032
|
+
const customDir = options.planDirectory?.trim();
|
|
8033
|
+
const docs = customDir ? await scanCustomDir(fs3, customDir, options.cwd, options.homeDir) : await scanDefaultDirs(fs3, options.cwd, options.homeDir);
|
|
8034
|
+
return docs.sort((left, right) => {
|
|
8035
|
+
const leftName = path15.basename(left.displayPath).toLowerCase();
|
|
8036
|
+
const rightName = path15.basename(right.displayPath).toLowerCase();
|
|
8037
|
+
return leftName === rightName ? left.displayPath.localeCompare(right.displayPath) : leftName.localeCompare(rightName);
|
|
8038
|
+
});
|
|
8039
|
+
}
|
|
8040
|
+
async function scanCustomDir(fs3, planDirectory, cwd, homeDir) {
|
|
8041
|
+
const absoluteDir = resolveAbsoluteDirectory2(planDirectory, cwd, homeDir);
|
|
8042
|
+
const displayDir = planDirectory;
|
|
8043
|
+
return scanDir(fs3, absoluteDir, displayDir);
|
|
8044
|
+
}
|
|
8045
|
+
async function scanDefaultDirs(fs3, cwd, homeDir) {
|
|
7857
8046
|
const [localDocs, globalDocs] = await Promise.all([
|
|
7858
8047
|
scanDir(
|
|
7859
8048
|
fs3,
|
|
7860
|
-
path15.join(
|
|
8049
|
+
path15.join(cwd, ".poe-code", "ralph", "plans"),
|
|
7861
8050
|
".poe-code/ralph/plans"
|
|
7862
8051
|
),
|
|
7863
8052
|
scanDir(
|
|
7864
8053
|
fs3,
|
|
7865
|
-
path15.join(
|
|
8054
|
+
path15.join(homeDir, ".poe-code", "ralph", "plans"),
|
|
7866
8055
|
"~/.poe-code/ralph/plans"
|
|
7867
8056
|
)
|
|
7868
8057
|
]);
|
|
7869
|
-
return [...localDocs, ...globalDocs]
|
|
7870
|
-
|
|
7871
|
-
|
|
7872
|
-
|
|
7873
|
-
|
|
8058
|
+
return [...localDocs, ...globalDocs];
|
|
8059
|
+
}
|
|
8060
|
+
function resolveAbsoluteDirectory2(dir, cwd, homeDir) {
|
|
8061
|
+
if (dir.startsWith("~/")) {
|
|
8062
|
+
return path15.join(homeDir, dir.slice(2));
|
|
8063
|
+
}
|
|
8064
|
+
return path15.isAbsolute(dir) ? dir : path15.resolve(cwd, dir);
|
|
7874
8065
|
}
|
|
7875
8066
|
var init_discovery2 = __esm({
|
|
7876
8067
|
"packages/ralph/src/discovery/discovery.ts"() {
|
|
@@ -7878,37 +8069,6 @@ var init_discovery2 = __esm({
|
|
|
7878
8069
|
}
|
|
7879
8070
|
});
|
|
7880
8071
|
|
|
7881
|
-
// packages/ralph/src/overbaking/detector.ts
|
|
7882
|
-
var OverbakingDetector;
|
|
7883
|
-
var init_detector = __esm({
|
|
7884
|
-
"packages/ralph/src/overbaking/detector.ts"() {
|
|
7885
|
-
"use strict";
|
|
7886
|
-
OverbakingDetector = class {
|
|
7887
|
-
threshold;
|
|
7888
|
-
consecutiveFailures = 0;
|
|
7889
|
-
constructor(threshold) {
|
|
7890
|
-
this.threshold = threshold;
|
|
7891
|
-
}
|
|
7892
|
-
record(_success) {
|
|
7893
|
-
if (_success) {
|
|
7894
|
-
this.consecutiveFailures = 0;
|
|
7895
|
-
return {
|
|
7896
|
-
consecutiveFailures: 0,
|
|
7897
|
-
overbaked: false,
|
|
7898
|
-
shouldWarn: false
|
|
7899
|
-
};
|
|
7900
|
-
}
|
|
7901
|
-
this.consecutiveFailures += 1;
|
|
7902
|
-
return {
|
|
7903
|
-
consecutiveFailures: this.consecutiveFailures,
|
|
7904
|
-
overbaked: this.consecutiveFailures >= this.threshold,
|
|
7905
|
-
shouldWarn: this.consecutiveFailures === this.threshold
|
|
7906
|
-
};
|
|
7907
|
-
}
|
|
7908
|
-
};
|
|
7909
|
-
}
|
|
7910
|
-
});
|
|
7911
|
-
|
|
7912
8072
|
// packages/ralph/src/run/ralph.ts
|
|
7913
8073
|
import path16 from "node:path";
|
|
7914
8074
|
import * as fsPromises5 from "node:fs/promises";
|
|
@@ -7921,27 +8081,31 @@ async function runRalph(options) {
|
|
|
7921
8081
|
if (!Number.isInteger(options.maxIterations) || options.maxIterations < 1) {
|
|
7922
8082
|
throw new Error("maxIterations must be a positive integer.");
|
|
7923
8083
|
}
|
|
7924
|
-
const
|
|
7925
|
-
if (!Number.isInteger(threshold) || threshold < 1) {
|
|
7926
|
-
throw new Error("maxFailures must be a positive integer.");
|
|
7927
|
-
}
|
|
8084
|
+
const agents = normalizeAgents(options.agent);
|
|
7928
8085
|
const absoluteDocPath = resolveAbsoluteDocPath(
|
|
7929
8086
|
options.docPath,
|
|
7930
8087
|
options.cwd,
|
|
7931
8088
|
options.homeDir
|
|
7932
8089
|
);
|
|
7933
8090
|
const rawContent = await fs3.readFile(absoluteDocPath, "utf8");
|
|
7934
|
-
const { body: prompt } = parseFrontmatter(rawContent);
|
|
7935
|
-
const detector = new OverbakingDetector(threshold);
|
|
8091
|
+
const { data: frontmatter, body: prompt } = parseFrontmatter(rawContent);
|
|
7936
8092
|
const startTime = Date.now();
|
|
7937
8093
|
let iterationsCompleted = 0;
|
|
7938
|
-
await updateFrontmatter(
|
|
8094
|
+
await updateFrontmatter(
|
|
8095
|
+
fs3,
|
|
8096
|
+
absoluteDocPath,
|
|
8097
|
+
prompt,
|
|
8098
|
+
frontmatter,
|
|
8099
|
+
"in_progress",
|
|
8100
|
+
0
|
|
8101
|
+
);
|
|
7939
8102
|
async function finalize2(stopReason) {
|
|
7940
8103
|
const status = stopReasonToStatus(stopReason);
|
|
7941
8104
|
await updateFrontmatter(
|
|
7942
8105
|
fs3,
|
|
7943
8106
|
absoluteDocPath,
|
|
7944
8107
|
prompt,
|
|
8108
|
+
frontmatter,
|
|
7945
8109
|
status,
|
|
7946
8110
|
iterationsCompleted
|
|
7947
8111
|
);
|
|
@@ -7958,12 +8122,13 @@ async function runRalph(options) {
|
|
|
7958
8122
|
try {
|
|
7959
8123
|
for (let iteration = 1; iteration <= options.maxIterations; iteration += 1) {
|
|
7960
8124
|
assertNotAborted2(options.signal);
|
|
7961
|
-
|
|
8125
|
+
const currentAgent = agents[(iteration - 1) % agents.length];
|
|
8126
|
+
options.onIterationStart?.(iteration, options.maxIterations, currentAgent);
|
|
7962
8127
|
const iterationStart = Date.now();
|
|
7963
8128
|
let result;
|
|
7964
8129
|
try {
|
|
7965
8130
|
result = await runAgent({
|
|
7966
|
-
agent:
|
|
8131
|
+
agent: currentAgent,
|
|
7967
8132
|
prompt,
|
|
7968
8133
|
cwd: options.cwd,
|
|
7969
8134
|
...options.model ? { model: options.model } : {},
|
|
@@ -7981,6 +8146,7 @@ async function runRalph(options) {
|
|
|
7981
8146
|
fs3,
|
|
7982
8147
|
absoluteDocPath,
|
|
7983
8148
|
prompt,
|
|
8149
|
+
frontmatter,
|
|
7984
8150
|
"in_progress",
|
|
7985
8151
|
iterationsCompleted
|
|
7986
8152
|
);
|
|
@@ -7989,21 +8155,6 @@ async function runRalph(options) {
|
|
|
7989
8155
|
Date.now() - iterationStart,
|
|
7990
8156
|
success2
|
|
7991
8157
|
);
|
|
7992
|
-
const overbake = detector.record(success2);
|
|
7993
|
-
if (!overbake.shouldWarn) {
|
|
7994
|
-
continue;
|
|
7995
|
-
}
|
|
7996
|
-
options.onOverbakeWarning?.(
|
|
7997
|
-
overbake.consecutiveFailures,
|
|
7998
|
-
threshold
|
|
7999
|
-
);
|
|
8000
|
-
const action = options.promptOverbake ? await options.promptOverbake({
|
|
8001
|
-
consecutiveFailures: overbake.consecutiveFailures,
|
|
8002
|
-
threshold
|
|
8003
|
-
}) : "abort";
|
|
8004
|
-
if (action === "abort") {
|
|
8005
|
-
return finalize2("overbake_abort");
|
|
8006
|
-
}
|
|
8007
8158
|
}
|
|
8008
8159
|
} catch (error2) {
|
|
8009
8160
|
if (isAbortError2(error2)) {
|
|
@@ -8031,6 +8182,23 @@ function createDefaultFs5() {
|
|
|
8031
8182
|
rename: fsPromises5.rename
|
|
8032
8183
|
};
|
|
8033
8184
|
}
|
|
8185
|
+
function normalizeAgents(agent2) {
|
|
8186
|
+
if (typeof agent2 === "string") {
|
|
8187
|
+
const trimmed = agent2.trim();
|
|
8188
|
+
if (trimmed.length === 0) {
|
|
8189
|
+
throw new Error("agent must contain at least one entry.");
|
|
8190
|
+
}
|
|
8191
|
+
return [trimmed];
|
|
8192
|
+
}
|
|
8193
|
+
if (agent2.length === 0) {
|
|
8194
|
+
throw new Error("agent must contain at least one entry.");
|
|
8195
|
+
}
|
|
8196
|
+
const agents = agent2.map((entry) => entry.trim());
|
|
8197
|
+
if (agents.some((entry) => entry.length === 0)) {
|
|
8198
|
+
throw new Error("agent entries must be non-empty strings.");
|
|
8199
|
+
}
|
|
8200
|
+
return agents;
|
|
8201
|
+
}
|
|
8034
8202
|
function resolveAbsoluteDocPath(docPath, cwd, homeDir) {
|
|
8035
8203
|
if (docPath.startsWith("~/")) {
|
|
8036
8204
|
return path16.join(homeDir, docPath.slice(2));
|
|
@@ -8051,8 +8219,18 @@ function createAbortError4() {
|
|
|
8051
8219
|
function isAbortError2(error2) {
|
|
8052
8220
|
return error2 instanceof Error && error2.name === "AbortError";
|
|
8053
8221
|
}
|
|
8054
|
-
async function updateFrontmatter(fs3, absoluteDocPath, body,
|
|
8055
|
-
const content = writeFrontmatter(
|
|
8222
|
+
async function updateFrontmatter(fs3, absoluteDocPath, body, frontmatter, state, iteration) {
|
|
8223
|
+
const content = writeFrontmatter(
|
|
8224
|
+
{
|
|
8225
|
+
...frontmatter.agent !== void 0 ? { agent: frontmatter.agent } : {},
|
|
8226
|
+
...frontmatter.iterations !== void 0 ? { iterations: frontmatter.iterations } : {},
|
|
8227
|
+
status: {
|
|
8228
|
+
state,
|
|
8229
|
+
iteration
|
|
8230
|
+
}
|
|
8231
|
+
},
|
|
8232
|
+
body
|
|
8233
|
+
);
|
|
8056
8234
|
await fs3.writeFile(absoluteDocPath, content);
|
|
8057
8235
|
}
|
|
8058
8236
|
async function archivePlan2(fs3, absoluteDocPath) {
|
|
@@ -8067,16 +8245,13 @@ function stopReasonToStatus(stopReason) {
|
|
|
8067
8245
|
case "completed":
|
|
8068
8246
|
case "max_iterations":
|
|
8069
8247
|
return "completed";
|
|
8070
|
-
case "overbake_abort":
|
|
8071
|
-
return "overbake_abort";
|
|
8072
8248
|
case "cancelled":
|
|
8073
|
-
return "
|
|
8249
|
+
return "open";
|
|
8074
8250
|
}
|
|
8075
8251
|
}
|
|
8076
8252
|
var init_ralph = __esm({
|
|
8077
8253
|
"packages/ralph/src/run/ralph.ts"() {
|
|
8078
8254
|
"use strict";
|
|
8079
|
-
init_detector();
|
|
8080
8255
|
init_frontmatter();
|
|
8081
8256
|
}
|
|
8082
8257
|
});
|
|
@@ -8087,7 +8262,6 @@ var init_src9 = __esm({
|
|
|
8087
8262
|
"use strict";
|
|
8088
8263
|
init_frontmatter();
|
|
8089
8264
|
init_discovery2();
|
|
8090
|
-
init_detector();
|
|
8091
8265
|
init_ralph();
|
|
8092
8266
|
}
|
|
8093
8267
|
});
|
|
@@ -8182,13 +8356,13 @@ async function readErrorBody(response) {
|
|
|
8182
8356
|
}
|
|
8183
8357
|
}
|
|
8184
8358
|
function extractTextContent(data) {
|
|
8185
|
-
if (!
|
|
8359
|
+
if (!isRecord5(data)) return void 0;
|
|
8186
8360
|
const choices = data.choices;
|
|
8187
8361
|
if (!Array.isArray(choices) || choices.length === 0) return void 0;
|
|
8188
8362
|
const first = choices[0];
|
|
8189
|
-
if (!
|
|
8363
|
+
if (!isRecord5(first)) return void 0;
|
|
8190
8364
|
const message = first.message;
|
|
8191
|
-
if (!
|
|
8365
|
+
if (!isRecord5(message)) return void 0;
|
|
8192
8366
|
return typeof message.content === "string" ? message.content : void 0;
|
|
8193
8367
|
}
|
|
8194
8368
|
function extractMediaFromCompletion(data) {
|
|
@@ -8196,14 +8370,14 @@ function extractMediaFromCompletion(data) {
|
|
|
8196
8370
|
if (!content) return {};
|
|
8197
8371
|
try {
|
|
8198
8372
|
const parsed = JSON.parse(content);
|
|
8199
|
-
if (
|
|
8373
|
+
if (isRecord5(parsed) && typeof parsed.url === "string") {
|
|
8200
8374
|
return {
|
|
8201
8375
|
url: parsed.url,
|
|
8202
8376
|
mimeType: typeof parsed.mimeType === "string" ? parsed.mimeType : void 0,
|
|
8203
8377
|
data: typeof parsed.data === "string" ? parsed.data : void 0
|
|
8204
8378
|
};
|
|
8205
8379
|
}
|
|
8206
|
-
if (
|
|
8380
|
+
if (isRecord5(parsed) && typeof parsed.data === "string") {
|
|
8207
8381
|
return {
|
|
8208
8382
|
data: parsed.data,
|
|
8209
8383
|
mimeType: typeof parsed.mimeType === "string" ? parsed.mimeType : void 0
|
|
@@ -8237,7 +8411,7 @@ function isValidUrl(value) {
|
|
|
8237
8411
|
return false;
|
|
8238
8412
|
}
|
|
8239
8413
|
}
|
|
8240
|
-
function
|
|
8414
|
+
function isRecord5(value) {
|
|
8241
8415
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
8242
8416
|
}
|
|
8243
8417
|
var init_llm_client = __esm({
|
|
@@ -8876,8 +9050,8 @@ function resourceNotFound(resource) {
|
|
|
8876
9050
|
`Resource not found: ${resource}`
|
|
8877
9051
|
);
|
|
8878
9052
|
}
|
|
8879
|
-
function assertAbsolutePath(
|
|
8880
|
-
if (!isAbsolute(
|
|
9053
|
+
function assertAbsolutePath(path29) {
|
|
9054
|
+
if (!isAbsolute(path29)) {
|
|
8881
9055
|
throw invalidParams('"path" must be an absolute path');
|
|
8882
9056
|
}
|
|
8883
9057
|
}
|
|
@@ -14348,7 +14522,7 @@ function parseLegacyConfigDocument(raw) {
|
|
|
14348
14522
|
}
|
|
14349
14523
|
}
|
|
14350
14524
|
function normalizeLegacyConfigDocument(value) {
|
|
14351
|
-
if (!
|
|
14525
|
+
if (!isRecord6(value)) {
|
|
14352
14526
|
return {};
|
|
14353
14527
|
}
|
|
14354
14528
|
const document = {};
|
|
@@ -14362,12 +14536,12 @@ function normalizeLegacyConfigDocument(value) {
|
|
|
14362
14536
|
return document;
|
|
14363
14537
|
}
|
|
14364
14538
|
function normalizeConfiguredServices(value) {
|
|
14365
|
-
if (!
|
|
14539
|
+
if (!isRecord6(value)) {
|
|
14366
14540
|
return {};
|
|
14367
14541
|
}
|
|
14368
14542
|
const entries = {};
|
|
14369
14543
|
for (const [key, entry] of Object.entries(value)) {
|
|
14370
|
-
if (!
|
|
14544
|
+
if (!isRecord6(entry)) {
|
|
14371
14545
|
continue;
|
|
14372
14546
|
}
|
|
14373
14547
|
entries[key] = normalizeConfiguredServiceMetadata({
|
|
@@ -14386,10 +14560,10 @@ function createInvalidBackupPath2(filePath) {
|
|
|
14386
14560
|
const baseName = path21.basename(filePath);
|
|
14387
14561
|
return path21.join(directory, `${baseName}.invalid-${createTimestamp()}.json`);
|
|
14388
14562
|
}
|
|
14389
|
-
function
|
|
14563
|
+
function isRecord6(value) {
|
|
14390
14564
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
14391
14565
|
}
|
|
14392
|
-
var coreConfigScope, knownConfigScopes, CORE_SCOPE, configuredServicesScope, EMPTY_DOCUMENT3;
|
|
14566
|
+
var coreConfigScope, ralphConfigScope, pipelineConfigScope, knownConfigScopes, CORE_SCOPE, configuredServicesScope, EMPTY_DOCUMENT3;
|
|
14393
14567
|
var init_config3 = __esm({
|
|
14394
14568
|
"src/services/config.ts"() {
|
|
14395
14569
|
"use strict";
|
|
@@ -14409,7 +14583,23 @@ var init_config3 = __esm({
|
|
|
14409
14583
|
doc: "Poe API base URL"
|
|
14410
14584
|
}
|
|
14411
14585
|
});
|
|
14412
|
-
|
|
14586
|
+
ralphConfigScope = defineScope("ralph", {
|
|
14587
|
+
plan_directory: {
|
|
14588
|
+
type: "string",
|
|
14589
|
+
default: "",
|
|
14590
|
+
env: "POE_RALPH_PLAN_DIRECTORY",
|
|
14591
|
+
doc: "Custom directory for Ralph plan documents"
|
|
14592
|
+
}
|
|
14593
|
+
});
|
|
14594
|
+
pipelineConfigScope = defineScope("pipeline", {
|
|
14595
|
+
plan_directory: {
|
|
14596
|
+
type: "string",
|
|
14597
|
+
default: "",
|
|
14598
|
+
env: "POE_PIPELINE_PLAN_DIRECTORY",
|
|
14599
|
+
doc: "Custom directory for Pipeline plan files"
|
|
14600
|
+
}
|
|
14601
|
+
});
|
|
14602
|
+
knownConfigScopes = [coreConfigScope, ralphConfigScope, pipelineConfigScope];
|
|
14413
14603
|
CORE_SCOPE = coreConfigScope.scope;
|
|
14414
14604
|
configuredServicesScope = "configured_services";
|
|
14415
14605
|
EMPTY_DOCUMENT3 = `${JSON.stringify({}, null, 2)}
|
|
@@ -17663,8 +17853,8 @@ var init_parseUtil = __esm({
|
|
|
17663
17853
|
init_errors3();
|
|
17664
17854
|
init_en();
|
|
17665
17855
|
makeIssue = (params) => {
|
|
17666
|
-
const { data, path:
|
|
17667
|
-
const fullPath = [...
|
|
17856
|
+
const { data, path: path29, errorMaps, issueData } = params;
|
|
17857
|
+
const fullPath = [...path29, ...issueData.path || []];
|
|
17668
17858
|
const fullIssue = {
|
|
17669
17859
|
...issueData,
|
|
17670
17860
|
path: fullPath
|
|
@@ -17944,11 +18134,11 @@ var init_types4 = __esm({
|
|
|
17944
18134
|
init_parseUtil();
|
|
17945
18135
|
init_util();
|
|
17946
18136
|
ParseInputLazyPath = class {
|
|
17947
|
-
constructor(parent, value,
|
|
18137
|
+
constructor(parent, value, path29, key) {
|
|
17948
18138
|
this._cachedPath = [];
|
|
17949
18139
|
this.parent = parent;
|
|
17950
18140
|
this.data = value;
|
|
17951
|
-
this._path =
|
|
18141
|
+
this._path = path29;
|
|
17952
18142
|
this._key = key;
|
|
17953
18143
|
}
|
|
17954
18144
|
get path() {
|
|
@@ -21452,10 +21642,10 @@ function mergeDefs(...defs) {
|
|
|
21452
21642
|
function cloneDef(schema) {
|
|
21453
21643
|
return mergeDefs(schema._zod.def);
|
|
21454
21644
|
}
|
|
21455
|
-
function getElementAtPath(obj,
|
|
21456
|
-
if (!
|
|
21645
|
+
function getElementAtPath(obj, path29) {
|
|
21646
|
+
if (!path29)
|
|
21457
21647
|
return obj;
|
|
21458
|
-
return
|
|
21648
|
+
return path29.reduce((acc, key) => acc?.[key], obj);
|
|
21459
21649
|
}
|
|
21460
21650
|
function promiseAllObject(promisesObj) {
|
|
21461
21651
|
const keys = Object.keys(promisesObj);
|
|
@@ -21767,11 +21957,11 @@ function aborted(x, startIndex = 0) {
|
|
|
21767
21957
|
}
|
|
21768
21958
|
return false;
|
|
21769
21959
|
}
|
|
21770
|
-
function prefixIssues(
|
|
21960
|
+
function prefixIssues(path29, issues) {
|
|
21771
21961
|
return issues.map((iss) => {
|
|
21772
21962
|
var _a2;
|
|
21773
21963
|
(_a2 = iss).path ?? (_a2.path = []);
|
|
21774
|
-
iss.path.unshift(
|
|
21964
|
+
iss.path.unshift(path29);
|
|
21775
21965
|
return iss;
|
|
21776
21966
|
});
|
|
21777
21967
|
}
|
|
@@ -33932,8 +34122,8 @@ var require_utils = __commonJS({
|
|
|
33932
34122
|
}
|
|
33933
34123
|
return ind;
|
|
33934
34124
|
}
|
|
33935
|
-
function removeDotSegments(
|
|
33936
|
-
let input =
|
|
34125
|
+
function removeDotSegments(path29) {
|
|
34126
|
+
let input = path29;
|
|
33937
34127
|
const output = [];
|
|
33938
34128
|
let nextSlash = -1;
|
|
33939
34129
|
let len = 0;
|
|
@@ -34132,8 +34322,8 @@ var require_schemes = __commonJS({
|
|
|
34132
34322
|
wsComponent.secure = void 0;
|
|
34133
34323
|
}
|
|
34134
34324
|
if (wsComponent.resourceName) {
|
|
34135
|
-
const [
|
|
34136
|
-
wsComponent.path =
|
|
34325
|
+
const [path29, query] = wsComponent.resourceName.split("?");
|
|
34326
|
+
wsComponent.path = path29 && path29 !== "/" ? path29 : void 0;
|
|
34137
34327
|
wsComponent.query = query;
|
|
34138
34328
|
wsComponent.resourceName = void 0;
|
|
34139
34329
|
}
|
|
@@ -39427,6 +39617,20 @@ var init_models2 = __esm({
|
|
|
39427
39617
|
import path27 from "node:path";
|
|
39428
39618
|
import { readFile as readFile7, stat as stat7 } from "node:fs/promises";
|
|
39429
39619
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
39620
|
+
async function resolvePipelinePlanDirectory(container) {
|
|
39621
|
+
const configDoc = await readMergedDocument(
|
|
39622
|
+
container.fs,
|
|
39623
|
+
container.env.configPath,
|
|
39624
|
+
container.env.projectConfigPath
|
|
39625
|
+
);
|
|
39626
|
+
const pipelineConfig = resolveScope(
|
|
39627
|
+
pipelineConfigScope.schema,
|
|
39628
|
+
configDoc[pipelineConfigScope.scope],
|
|
39629
|
+
container.env.variables
|
|
39630
|
+
);
|
|
39631
|
+
const dir = pipelineConfig.plan_directory?.trim();
|
|
39632
|
+
return dir || void 0;
|
|
39633
|
+
}
|
|
39430
39634
|
function formatDuration(ms) {
|
|
39431
39635
|
const totalSeconds = Math.round(ms / 1e3);
|
|
39432
39636
|
const minutes = Math.floor(totalSeconds / 60);
|
|
@@ -39553,10 +39757,12 @@ function registerPipelineCommand(program, container) {
|
|
|
39553
39757
|
}
|
|
39554
39758
|
agent2 = resolvePipelineAgent(selected);
|
|
39555
39759
|
}
|
|
39760
|
+
const planDirectory = await resolvePipelinePlanDirectory(container);
|
|
39556
39761
|
const result = await runPipeline2({
|
|
39557
39762
|
agent: agent2,
|
|
39558
39763
|
cwd: container.env.cwd,
|
|
39559
39764
|
homeDir: container.env.homeDir,
|
|
39765
|
+
...planDirectory ? { planDirectory } : {},
|
|
39560
39766
|
...options.model ? { model: options.model } : {},
|
|
39561
39767
|
...options.task ? { task: options.task } : {},
|
|
39562
39768
|
...options.plan ? { plan: options.plan } : {},
|
|
@@ -39682,6 +39888,17 @@ function registerPipelineCommand(program, container) {
|
|
|
39682
39888
|
resources.context.finalize();
|
|
39683
39889
|
}
|
|
39684
39890
|
});
|
|
39891
|
+
pipeline.command("plan-path").description("Print the directory where pipeline plan files should be placed.").action(async function() {
|
|
39892
|
+
const planDirectory = await resolvePipelinePlanDirectory(container);
|
|
39893
|
+
const resolvedPath = await resolvePlanDirectory({
|
|
39894
|
+
cwd: container.env.cwd,
|
|
39895
|
+
homeDir: container.env.homeDir,
|
|
39896
|
+
planDirectory,
|
|
39897
|
+
fs: container.fs
|
|
39898
|
+
});
|
|
39899
|
+
process.stdout.write(`${resolvedPath}
|
|
39900
|
+
`);
|
|
39901
|
+
});
|
|
39685
39902
|
pipeline.command("install").description("Install the Pipeline /plan skill and scaffold pipeline files.").option("--agent <name>", "Agent to install the Pipeline skill for").option("--local", "Install project-local skill and pipeline files").option("--global", "Install user-global skill and pipeline files").option("--force", "Overwrite an existing steps.yaml scaffold").action(async function() {
|
|
39686
39903
|
const flags = resolveCommandFlags(program);
|
|
39687
39904
|
const resources = createExecutionResources(
|
|
@@ -39808,6 +40025,8 @@ var init_pipeline4 = __esm({
|
|
|
39808
40025
|
init_src5();
|
|
39809
40026
|
init_src2();
|
|
39810
40027
|
init_src15();
|
|
40028
|
+
init_src4();
|
|
40029
|
+
init_config3();
|
|
39811
40030
|
init_errors();
|
|
39812
40031
|
init_shared();
|
|
39813
40032
|
await init_pipeline2();
|
|
@@ -39819,19 +40038,20 @@ var init_pipeline4 = __esm({
|
|
|
39819
40038
|
});
|
|
39820
40039
|
|
|
39821
40040
|
// src/cli/commands/ralph.ts
|
|
40041
|
+
import path28 from "node:path";
|
|
39822
40042
|
function formatDuration2(ms) {
|
|
39823
40043
|
const totalSeconds = Math.round(ms / 1e3);
|
|
39824
40044
|
const minutes = Math.floor(totalSeconds / 60);
|
|
39825
40045
|
const seconds = totalSeconds % 60;
|
|
39826
40046
|
return minutes > 0 ? `${minutes}m ${seconds}s` : `${seconds}s`;
|
|
39827
40047
|
}
|
|
39828
|
-
function resolveRalphAgent(value) {
|
|
40048
|
+
function resolveRalphAgent(value, sourceLabel = "agent") {
|
|
39829
40049
|
if (!value || value.trim().length === 0) {
|
|
39830
40050
|
return DEFAULT_RALPH_AGENT;
|
|
39831
40051
|
}
|
|
39832
40052
|
const resolved = resolveAgentId(value.trim());
|
|
39833
40053
|
if (!resolved) {
|
|
39834
|
-
throw new ValidationError(`Unsupported
|
|
40054
|
+
throw new ValidationError(`Unsupported ${sourceLabel}: ${value}`);
|
|
39835
40055
|
}
|
|
39836
40056
|
return resolved;
|
|
39837
40057
|
}
|
|
@@ -39847,26 +40067,54 @@ function parsePositiveInt(value, fieldName) {
|
|
|
39847
40067
|
}
|
|
39848
40068
|
return parsed;
|
|
39849
40069
|
}
|
|
39850
|
-
|
|
39851
|
-
|
|
39852
|
-
|
|
40070
|
+
function normalizeConfiguredIterations(value) {
|
|
40071
|
+
return typeof value === "number" && Number.isInteger(value) && value >= 1 ? value : void 0;
|
|
40072
|
+
}
|
|
40073
|
+
function resolveAbsoluteDocPath2(container, docPath) {
|
|
40074
|
+
if (docPath.startsWith("~/")) {
|
|
40075
|
+
return path28.join(container.env.homeDir, docPath.slice(2));
|
|
39853
40076
|
}
|
|
39854
|
-
|
|
39855
|
-
|
|
39856
|
-
|
|
40077
|
+
return path28.isAbsolute(docPath) ? docPath : path28.resolve(container.env.cwd, docPath);
|
|
40078
|
+
}
|
|
40079
|
+
async function resolvePlanDirectory2(container) {
|
|
40080
|
+
const configDoc = await readMergedDocument(
|
|
40081
|
+
container.fs,
|
|
40082
|
+
container.env.configPath,
|
|
40083
|
+
container.env.projectConfigPath
|
|
40084
|
+
);
|
|
40085
|
+
const ralphConfig = resolveScope(
|
|
40086
|
+
ralphConfigScope.schema,
|
|
40087
|
+
configDoc[ralphConfigScope.scope],
|
|
40088
|
+
container.env.variables
|
|
40089
|
+
);
|
|
40090
|
+
const configDir = ralphConfig.plan_directory?.trim();
|
|
40091
|
+
return configDir || void 0;
|
|
40092
|
+
}
|
|
40093
|
+
function formatDocHint(frontmatter) {
|
|
40094
|
+
const parts = [];
|
|
40095
|
+
if (frontmatter.agent !== void 0) {
|
|
40096
|
+
const agents = Array.isArray(frontmatter.agent) ? frontmatter.agent : [frontmatter.agent];
|
|
40097
|
+
if (agents.length > 0) {
|
|
40098
|
+
parts.push(agents.join(", "));
|
|
40099
|
+
}
|
|
39857
40100
|
}
|
|
39858
|
-
|
|
39859
|
-
|
|
39860
|
-
|
|
39861
|
-
|
|
39862
|
-
|
|
39863
|
-
|
|
39864
|
-
|
|
39865
|
-
|
|
39866
|
-
|
|
39867
|
-
|
|
40101
|
+
if (frontmatter.iterations !== void 0) {
|
|
40102
|
+
parts.push(`\xD7${frontmatter.iterations}`);
|
|
40103
|
+
}
|
|
40104
|
+
if (frontmatter.status.state !== "open" || frontmatter.status.iteration > 0) {
|
|
40105
|
+
parts.push(`${frontmatter.status.state} ${frontmatter.status.iteration}`);
|
|
40106
|
+
}
|
|
40107
|
+
return parts.length > 0 ? parts.join(" \xB7 ") : void 0;
|
|
40108
|
+
}
|
|
40109
|
+
async function readDocHint(container, docPath) {
|
|
40110
|
+
const absolutePath = resolveAbsoluteDocPath2(container, docPath);
|
|
40111
|
+
try {
|
|
40112
|
+
const content = await container.fs.readFile(absolutePath, "utf8");
|
|
40113
|
+
const { data } = parseFrontmatter(content);
|
|
40114
|
+
return formatDocHint(data);
|
|
40115
|
+
} catch {
|
|
40116
|
+
return void 0;
|
|
39868
40117
|
}
|
|
39869
|
-
return resolveRalphAgent(typeof selected === "string" ? selected : void 0);
|
|
39870
40118
|
}
|
|
39871
40119
|
async function resolveDocPath(options) {
|
|
39872
40120
|
if (options.providedDoc && options.providedDoc.trim().length > 0) {
|
|
@@ -39875,6 +40123,7 @@ async function resolveDocPath(options) {
|
|
|
39875
40123
|
const docs = await discoverDocs({
|
|
39876
40124
|
cwd: options.container.env.cwd,
|
|
39877
40125
|
homeDir: options.container.env.homeDir,
|
|
40126
|
+
planDirectory: options.planDirectory,
|
|
39878
40127
|
fs: options.container.fs
|
|
39879
40128
|
});
|
|
39880
40129
|
if (docs.length === 0) {
|
|
@@ -39886,10 +40135,13 @@ async function resolveDocPath(options) {
|
|
|
39886
40135
|
if (flags.assumeYes) {
|
|
39887
40136
|
return docs[0].path;
|
|
39888
40137
|
}
|
|
40138
|
+
const hints = await Promise.all(
|
|
40139
|
+
docs.map((doc) => readDocHint(options.container, doc.path))
|
|
40140
|
+
);
|
|
39889
40141
|
const selected = await select2({
|
|
39890
40142
|
message: "Select the Ralph markdown doc to run:",
|
|
39891
|
-
options: docs.map((doc) => ({
|
|
39892
|
-
label: doc.displayPath,
|
|
40143
|
+
options: docs.map((doc, index) => ({
|
|
40144
|
+
label: text.selectLabel(doc.displayPath, hints[index]),
|
|
39893
40145
|
value: doc.path
|
|
39894
40146
|
}))
|
|
39895
40147
|
});
|
|
@@ -39899,7 +40151,61 @@ async function resolveDocPath(options) {
|
|
|
39899
40151
|
}
|
|
39900
40152
|
return typeof selected === "string" ? selected : null;
|
|
39901
40153
|
}
|
|
39902
|
-
async function
|
|
40154
|
+
async function readRalphDoc(container, docPath) {
|
|
40155
|
+
const absolutePath = resolveAbsoluteDocPath2(container, docPath);
|
|
40156
|
+
try {
|
|
40157
|
+
const content = await container.fs.readFile(absolutePath, "utf8");
|
|
40158
|
+
const parsed = parseFrontmatter(content);
|
|
40159
|
+
return {
|
|
40160
|
+
absolutePath,
|
|
40161
|
+
body: parsed.body,
|
|
40162
|
+
data: parsed.data
|
|
40163
|
+
};
|
|
40164
|
+
} catch {
|
|
40165
|
+
throw new ValidationError(`Ralph doc not found: ${docPath}`);
|
|
40166
|
+
}
|
|
40167
|
+
}
|
|
40168
|
+
function resolveConfiguredAgents(value) {
|
|
40169
|
+
if (value === void 0) {
|
|
40170
|
+
return void 0;
|
|
40171
|
+
}
|
|
40172
|
+
if (typeof value === "string") {
|
|
40173
|
+
return resolveRalphAgent(value, "frontmatter agent");
|
|
40174
|
+
}
|
|
40175
|
+
if (value.length === 0) {
|
|
40176
|
+
throw new ValidationError("Frontmatter agent array must not be empty.");
|
|
40177
|
+
}
|
|
40178
|
+
return value.map((entry) => resolveRalphAgent(entry, "frontmatter agent"));
|
|
40179
|
+
}
|
|
40180
|
+
async function promptForAgent(program) {
|
|
40181
|
+
const flags = resolveCommandFlags(program);
|
|
40182
|
+
if (flags.assumeYes) {
|
|
40183
|
+
return DEFAULT_RALPH_AGENT;
|
|
40184
|
+
}
|
|
40185
|
+
const selected = await select2({
|
|
40186
|
+
message: "Select agent to run Ralph with:",
|
|
40187
|
+
options: allSpawnConfigs.map((config2) => ({
|
|
40188
|
+
label: config2.agentId,
|
|
40189
|
+
value: config2.agentId
|
|
40190
|
+
}))
|
|
40191
|
+
});
|
|
40192
|
+
if (isCancel2(selected)) {
|
|
40193
|
+
cancel2("Ralph run cancelled.");
|
|
40194
|
+
return null;
|
|
40195
|
+
}
|
|
40196
|
+
return resolveRalphAgent(typeof selected === "string" ? selected : void 0);
|
|
40197
|
+
}
|
|
40198
|
+
async function resolveRunAgent(options) {
|
|
40199
|
+
if (options.providedAgent) {
|
|
40200
|
+
return resolveRalphAgent(options.providedAgent);
|
|
40201
|
+
}
|
|
40202
|
+
const configured = resolveConfiguredAgents(options.frontmatterAgent);
|
|
40203
|
+
if (configured !== void 0) {
|
|
40204
|
+
return configured;
|
|
40205
|
+
}
|
|
40206
|
+
return promptForAgent(options.program);
|
|
40207
|
+
}
|
|
40208
|
+
async function resolveRunIterations(options) {
|
|
39903
40209
|
const explicitIterations = parsePositiveInt(
|
|
39904
40210
|
options.providedIterations,
|
|
39905
40211
|
"iterations"
|
|
@@ -39907,11 +40213,15 @@ async function resolveIterations(options) {
|
|
|
39907
40213
|
if (explicitIterations != null) {
|
|
39908
40214
|
return explicitIterations;
|
|
39909
40215
|
}
|
|
40216
|
+
const configuredIterations = normalizeConfiguredIterations(
|
|
40217
|
+
options.frontmatterIterations
|
|
40218
|
+
);
|
|
40219
|
+
if (configuredIterations != null) {
|
|
40220
|
+
return configuredIterations;
|
|
40221
|
+
}
|
|
39910
40222
|
const flags = resolveCommandFlags(options.program);
|
|
39911
40223
|
if (flags.assumeYes) {
|
|
39912
|
-
|
|
39913
|
-
"Iterations are required when using --yes. Provide poe-code ralph run <iterations> [doc]."
|
|
39914
|
-
);
|
|
40224
|
+
return DEFAULT_RALPH_ITERATIONS;
|
|
39915
40225
|
}
|
|
39916
40226
|
const entered = await text3({
|
|
39917
40227
|
message: "How many Ralph iterations should run?"
|
|
@@ -39925,43 +40235,157 @@ async function resolveIterations(options) {
|
|
|
39925
40235
|
"iterations"
|
|
39926
40236
|
) ?? null;
|
|
39927
40237
|
}
|
|
40238
|
+
async function resolveInitAgent(options) {
|
|
40239
|
+
if (options.providedAgent) {
|
|
40240
|
+
return resolveRalphAgent(options.providedAgent);
|
|
40241
|
+
}
|
|
40242
|
+
return promptForAgent(options.program);
|
|
40243
|
+
}
|
|
40244
|
+
async function resolveInitIterations(options) {
|
|
40245
|
+
const explicitIterations = parsePositiveInt(
|
|
40246
|
+
options.providedIterations,
|
|
40247
|
+
"iterations"
|
|
40248
|
+
);
|
|
40249
|
+
if (explicitIterations != null) {
|
|
40250
|
+
return explicitIterations;
|
|
40251
|
+
}
|
|
40252
|
+
const flags = resolveCommandFlags(options.program);
|
|
40253
|
+
if (flags.assumeYes) {
|
|
40254
|
+
return DEFAULT_RALPH_ITERATIONS;
|
|
40255
|
+
}
|
|
40256
|
+
const entered = await text3({
|
|
40257
|
+
message: "How many Ralph iterations should run?"
|
|
40258
|
+
});
|
|
40259
|
+
if (isCancel2(entered)) {
|
|
40260
|
+
cancel2("Ralph init cancelled.");
|
|
40261
|
+
return null;
|
|
40262
|
+
}
|
|
40263
|
+
return parsePositiveInt(
|
|
40264
|
+
typeof entered === "string" ? entered.trim() : void 0,
|
|
40265
|
+
"iterations"
|
|
40266
|
+
) ?? null;
|
|
40267
|
+
}
|
|
40268
|
+
function formatCurrentConfig(frontmatter) {
|
|
40269
|
+
if (frontmatter.agent === void 0 && frontmatter.iterations === void 0) {
|
|
40270
|
+
return null;
|
|
40271
|
+
}
|
|
40272
|
+
const items = [];
|
|
40273
|
+
if (frontmatter.iterations !== void 0) {
|
|
40274
|
+
items.push(String(frontmatter.iterations));
|
|
40275
|
+
}
|
|
40276
|
+
const agentList = expandAgentList(frontmatter.agent, frontmatter.iterations);
|
|
40277
|
+
if (agentList.length > 0) {
|
|
40278
|
+
items.push(...agentList);
|
|
40279
|
+
}
|
|
40280
|
+
return items.length > 0 ? `Current: ${items.join(", ")}` : null;
|
|
40281
|
+
}
|
|
40282
|
+
function expandAgentList(agent2, iterations) {
|
|
40283
|
+
if (agent2 === void 0) {
|
|
40284
|
+
return [];
|
|
40285
|
+
}
|
|
40286
|
+
if (typeof agent2 === "string") {
|
|
40287
|
+
const count2 = normalizeConfiguredIterations(iterations) ?? 1;
|
|
40288
|
+
return Array.from({ length: count2 }, () => agent2);
|
|
40289
|
+
}
|
|
40290
|
+
if (agent2.length === 0) {
|
|
40291
|
+
return [];
|
|
40292
|
+
}
|
|
40293
|
+
const count = normalizeConfiguredIterations(iterations) ?? agent2.length;
|
|
40294
|
+
return Array.from({ length: count }, (_, index) => agent2[index % agent2.length]);
|
|
40295
|
+
}
|
|
39928
40296
|
function registerRalphCommand(program, container) {
|
|
39929
40297
|
const ralph = program.command("ralph").description("Run a simple iterative markdown loop.");
|
|
39930
|
-
ralph.command("
|
|
39931
|
-
|
|
39932
|
-
|
|
39933
|
-
|
|
40298
|
+
ralph.command("init").description("Write Ralph config into an existing markdown doc frontmatter.").argument("[doc]", "Markdown doc path").option("--agent <name>", "Agent to write into frontmatter").option("--iterations <n>", "Number of iterations to write into frontmatter").action(async function(docArg) {
|
|
40299
|
+
const flags = resolveCommandFlags(program);
|
|
40300
|
+
const resources = createExecutionResources(container, flags, "ralph:init");
|
|
40301
|
+
const options = this.opts();
|
|
40302
|
+
resources.logger.intro("ralph init");
|
|
40303
|
+
try {
|
|
40304
|
+
const planDirectory = await resolvePlanDirectory2(container);
|
|
40305
|
+
const docPath = await resolveDocPath({
|
|
40306
|
+
container,
|
|
40307
|
+
program,
|
|
40308
|
+
providedDoc: docArg,
|
|
40309
|
+
planDirectory
|
|
40310
|
+
});
|
|
40311
|
+
if (!docPath) {
|
|
40312
|
+
return;
|
|
40313
|
+
}
|
|
40314
|
+
const doc = await readRalphDoc(container, docPath);
|
|
40315
|
+
const currentConfig = formatCurrentConfig(doc.data);
|
|
40316
|
+
if (!options.agent && !options.iterations && !flags.assumeYes && currentConfig) {
|
|
40317
|
+
resources.logger.info(currentConfig);
|
|
40318
|
+
}
|
|
40319
|
+
const agent2 = await resolveInitAgent({
|
|
40320
|
+
program,
|
|
40321
|
+
providedAgent: options.agent
|
|
40322
|
+
});
|
|
40323
|
+
if (!agent2) {
|
|
40324
|
+
return;
|
|
40325
|
+
}
|
|
40326
|
+
const iterations = await resolveInitIterations({
|
|
40327
|
+
program,
|
|
40328
|
+
providedIterations: options.iterations
|
|
40329
|
+
});
|
|
40330
|
+
if (iterations == null) {
|
|
40331
|
+
return;
|
|
40332
|
+
}
|
|
40333
|
+
const updated = writeFrontmatter(
|
|
40334
|
+
{
|
|
40335
|
+
agent: agent2,
|
|
40336
|
+
iterations,
|
|
40337
|
+
status: {
|
|
40338
|
+
state: doc.data.status.state,
|
|
40339
|
+
iteration: doc.data.status.iteration
|
|
40340
|
+
}
|
|
40341
|
+
},
|
|
40342
|
+
doc.body
|
|
40343
|
+
);
|
|
40344
|
+
await container.fs.writeFile(doc.absolutePath, updated, { encoding: "utf8" });
|
|
40345
|
+
resources.logger.resolved(
|
|
40346
|
+
"Initialized Ralph config",
|
|
40347
|
+
`Doc: ${docPath}
|
|
40348
|
+
Agent: ${agent2}
|
|
40349
|
+
Iterations: ${iterations}`
|
|
40350
|
+
);
|
|
40351
|
+
resources.logger.success("Ralph config saved.");
|
|
40352
|
+
} finally {
|
|
40353
|
+
resources.context.finalize();
|
|
40354
|
+
}
|
|
40355
|
+
});
|
|
40356
|
+
ralph.command("run").description("Run the selected markdown doc through repeated agent iterations.").argument("[doc]", "Markdown doc path").option("--agent <name>", "Override the agent from frontmatter").option("--iterations <n>", "Override iterations from frontmatter").option("--model <model>", "Model override passed to the agent").action(async function(docArg) {
|
|
39934
40357
|
const flags = resolveCommandFlags(program);
|
|
39935
40358
|
const resources = createExecutionResources(container, flags, "ralph:run");
|
|
39936
40359
|
const options = this.opts();
|
|
39937
40360
|
resources.logger.intro("ralph run");
|
|
39938
40361
|
try {
|
|
40362
|
+
const planDirectory = await resolvePlanDirectory2(container);
|
|
39939
40363
|
const docPath = await resolveDocPath({
|
|
39940
40364
|
container,
|
|
39941
40365
|
program,
|
|
39942
|
-
providedDoc: docArg
|
|
40366
|
+
providedDoc: docArg,
|
|
40367
|
+
planDirectory
|
|
39943
40368
|
});
|
|
39944
40369
|
if (!docPath) {
|
|
39945
40370
|
return;
|
|
39946
40371
|
}
|
|
39947
|
-
const
|
|
40372
|
+
const doc = await readRalphDoc(container, docPath);
|
|
40373
|
+
const agent2 = await resolveRunAgent({
|
|
39948
40374
|
program,
|
|
39949
|
-
providedAgent: options.agent
|
|
40375
|
+
providedAgent: options.agent,
|
|
40376
|
+
frontmatterAgent: doc.data.agent
|
|
39950
40377
|
});
|
|
39951
40378
|
if (!agent2) {
|
|
39952
40379
|
return;
|
|
39953
40380
|
}
|
|
39954
|
-
const maxIterations = await
|
|
40381
|
+
const maxIterations = await resolveRunIterations({
|
|
39955
40382
|
program,
|
|
39956
|
-
providedIterations:
|
|
40383
|
+
providedIterations: options.iterations,
|
|
40384
|
+
frontmatterIterations: doc.data.iterations
|
|
39957
40385
|
});
|
|
39958
40386
|
if (maxIterations == null) {
|
|
39959
40387
|
return;
|
|
39960
40388
|
}
|
|
39961
|
-
const maxFailures = parsePositiveInt(
|
|
39962
|
-
options.maxFailures,
|
|
39963
|
-
"max-failures"
|
|
39964
|
-
);
|
|
39965
40389
|
const result = await runRalph2({
|
|
39966
40390
|
agent: agent2,
|
|
39967
40391
|
cwd: container.env.cwd,
|
|
@@ -39969,34 +40393,14 @@ function registerRalphCommand(program, container) {
|
|
|
39969
40393
|
docPath,
|
|
39970
40394
|
maxIterations,
|
|
39971
40395
|
...options.model ? { model: options.model } : {},
|
|
39972
|
-
|
|
39973
|
-
|
|
39974
|
-
const selected = await select2({
|
|
39975
|
-
message: `Ralph hit ${input.consecutiveFailures} consecutive failures (threshold ${input.threshold}). What should happen next?`,
|
|
39976
|
-
options: [
|
|
39977
|
-
{ label: "Continue", value: "continue" },
|
|
39978
|
-
{ label: "Abort", value: "abort" }
|
|
39979
|
-
]
|
|
39980
|
-
});
|
|
39981
|
-
if (isCancel2(selected)) {
|
|
39982
|
-
cancel2("Ralph run cancelled.");
|
|
39983
|
-
return "abort";
|
|
39984
|
-
}
|
|
39985
|
-
return selected === "continue" ? "continue" : "abort";
|
|
39986
|
-
},
|
|
39987
|
-
onIterationStart(iteration, total) {
|
|
39988
|
-
resources.logger.info(`Iteration ${iteration}/${total}`);
|
|
40396
|
+
onIterationStart(iteration, total, currentAgent) {
|
|
40397
|
+
resources.logger.info(`Iteration ${iteration}/${total} (${currentAgent})`);
|
|
39989
40398
|
},
|
|
39990
40399
|
onIterationComplete(iteration, durationMs, success2) {
|
|
39991
40400
|
const status = success2 ? "done" : "failed";
|
|
39992
40401
|
resources.logger.info(
|
|
39993
40402
|
`Iteration ${iteration} ${status} in ${formatDuration2(durationMs)}`
|
|
39994
40403
|
);
|
|
39995
|
-
},
|
|
39996
|
-
onOverbakeWarning(consecutiveFailures, threshold) {
|
|
39997
|
-
resources.logger.warn(
|
|
39998
|
-
`Overbake protection triggered at ${consecutiveFailures} consecutive failures (threshold ${threshold}).`
|
|
39999
|
-
);
|
|
40000
40404
|
}
|
|
40001
40405
|
});
|
|
40002
40406
|
const summary = [
|
|
@@ -40010,12 +40414,6 @@ function registerRalphCommand(program, container) {
|
|
|
40010
40414
|
resources.logger.resolved("Run summary", summary);
|
|
40011
40415
|
return;
|
|
40012
40416
|
}
|
|
40013
|
-
if (result.stopReason === "overbake_abort") {
|
|
40014
|
-
process.exitCode = 1;
|
|
40015
|
-
resources.logger.warn("Ralph stopped after repeated failures.");
|
|
40016
|
-
resources.logger.resolved("Run summary", summary);
|
|
40017
|
-
return;
|
|
40018
|
-
}
|
|
40019
40417
|
resources.logger.resolved("Run summary", summary);
|
|
40020
40418
|
resources.logger.success("Ralph run finished.");
|
|
40021
40419
|
} finally {
|
|
@@ -40023,7 +40421,7 @@ function registerRalphCommand(program, container) {
|
|
|
40023
40421
|
}
|
|
40024
40422
|
});
|
|
40025
40423
|
}
|
|
40026
|
-
var DEFAULT_RALPH_AGENT;
|
|
40424
|
+
var DEFAULT_RALPH_AGENT, DEFAULT_RALPH_ITERATIONS;
|
|
40027
40425
|
var init_ralph3 = __esm({
|
|
40028
40426
|
async "src/cli/commands/ralph.ts"() {
|
|
40029
40427
|
"use strict";
|
|
@@ -40031,10 +40429,13 @@ var init_ralph3 = __esm({
|
|
|
40031
40429
|
init_src2();
|
|
40032
40430
|
init_src6();
|
|
40033
40431
|
init_src9();
|
|
40432
|
+
init_src4();
|
|
40433
|
+
init_config3();
|
|
40034
40434
|
init_errors();
|
|
40035
40435
|
init_shared();
|
|
40036
40436
|
await init_ralph2();
|
|
40037
40437
|
DEFAULT_RALPH_AGENT = "claude-code";
|
|
40438
|
+
DEFAULT_RALPH_ITERATIONS = 3;
|
|
40038
40439
|
}
|
|
40039
40440
|
});
|
|
40040
40441
|
|
|
@@ -40044,7 +40445,7 @@ var init_package = __esm({
|
|
|
40044
40445
|
"package.json"() {
|
|
40045
40446
|
package_default = {
|
|
40046
40447
|
name: "poe-code",
|
|
40047
|
-
version: "3.0.
|
|
40448
|
+
version: "3.0.115",
|
|
40048
40449
|
description: "CLI tool to configure Poe API for developer workflows.",
|
|
40049
40450
|
type: "module",
|
|
40050
40451
|
main: "./dist/index.js",
|
|
@@ -40262,9 +40663,14 @@ function formatHelpText(input) {
|
|
|
40262
40663
|
args: "",
|
|
40263
40664
|
description: "Run a fixed-step task pipeline plan"
|
|
40264
40665
|
},
|
|
40666
|
+
{
|
|
40667
|
+
name: "ralph init",
|
|
40668
|
+
args: "[doc]",
|
|
40669
|
+
description: "Write Ralph config into a markdown doc frontmatter"
|
|
40670
|
+
},
|
|
40265
40671
|
{
|
|
40266
40672
|
name: "ralph run",
|
|
40267
|
-
args: "[
|
|
40673
|
+
args: "[doc]",
|
|
40268
40674
|
description: "Run a markdown doc through repeated agent iterations"
|
|
40269
40675
|
},
|
|
40270
40676
|
{
|