poe-code 3.0.155 → 3.0.156
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/plan.d.ts +3 -0
- package/dist/cli/commands/plan.js +285 -0
- package/dist/cli/commands/plan.js.map +1 -0
- package/dist/cli/program.js +3 -0
- package/dist/cli/program.js.map +1 -1
- package/dist/index.js +1025 -175
- package/dist/index.js.map +4 -4
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -925,16 +925,16 @@ function getConfigFormat(pathOrFormat) {
|
|
|
925
925
|
}
|
|
926
926
|
return formatRegistry[formatName];
|
|
927
927
|
}
|
|
928
|
-
function detectFormat(
|
|
929
|
-
const ext = getExtension(
|
|
928
|
+
function detectFormat(path48) {
|
|
929
|
+
const ext = getExtension(path48);
|
|
930
930
|
return extensionMap[ext];
|
|
931
931
|
}
|
|
932
|
-
function getExtension(
|
|
933
|
-
const lastDot =
|
|
932
|
+
function getExtension(path48) {
|
|
933
|
+
const lastDot = path48.lastIndexOf(".");
|
|
934
934
|
if (lastDot === -1) {
|
|
935
935
|
return "";
|
|
936
936
|
}
|
|
937
|
-
return
|
|
937
|
+
return path48.slice(lastDot).toLowerCase();
|
|
938
938
|
}
|
|
939
939
|
var formatRegistry, extensionMap;
|
|
940
940
|
var init_formats = __esm({
|
|
@@ -1265,8 +1265,8 @@ async function applyChmod(mutation, context, options) {
|
|
|
1265
1265
|
};
|
|
1266
1266
|
}
|
|
1267
1267
|
try {
|
|
1268
|
-
const
|
|
1269
|
-
const currentMode = typeof
|
|
1268
|
+
const stat14 = await context.fs.stat(targetPath);
|
|
1269
|
+
const currentMode = typeof stat14.mode === "number" ? stat14.mode & 511 : null;
|
|
1270
1270
|
if (currentMode === mutation.mode) {
|
|
1271
1271
|
return {
|
|
1272
1272
|
outcome: { changed: false, effect: "none", detail: "noop" },
|
|
@@ -1989,38 +1989,38 @@ import { createTwoFilesPatch } from "diff";
|
|
|
1989
1989
|
import chalk from "chalk";
|
|
1990
1990
|
function createDryRunFileSystem(base, recorder) {
|
|
1991
1991
|
const proxy = {
|
|
1992
|
-
async readFile(
|
|
1992
|
+
async readFile(path48, encoding) {
|
|
1993
1993
|
if (encoding) {
|
|
1994
|
-
return base.readFile(
|
|
1994
|
+
return base.readFile(path48, encoding);
|
|
1995
1995
|
}
|
|
1996
|
-
return base.readFile(
|
|
1996
|
+
return base.readFile(path48);
|
|
1997
1997
|
},
|
|
1998
|
-
async writeFile(
|
|
1999
|
-
const previousContent = await tryReadText(base,
|
|
1998
|
+
async writeFile(path48, data, options) {
|
|
1999
|
+
const previousContent = await tryReadText(base, path48);
|
|
2000
2000
|
const nextContent = formatData(data, options?.encoding);
|
|
2001
2001
|
recorder.record({
|
|
2002
2002
|
type: "writeFile",
|
|
2003
|
-
path:
|
|
2003
|
+
path: path48,
|
|
2004
2004
|
nextContent,
|
|
2005
2005
|
previousContent
|
|
2006
2006
|
});
|
|
2007
2007
|
},
|
|
2008
|
-
async mkdir(
|
|
2009
|
-
recorder.record({ type: "mkdir", path:
|
|
2008
|
+
async mkdir(path48, options) {
|
|
2009
|
+
recorder.record({ type: "mkdir", path: path48, options });
|
|
2010
2010
|
},
|
|
2011
|
-
async stat(
|
|
2012
|
-
return base.stat(
|
|
2011
|
+
async stat(path48) {
|
|
2012
|
+
return base.stat(path48);
|
|
2013
2013
|
},
|
|
2014
|
-
async unlink(
|
|
2015
|
-
recorder.record({ type: "unlink", path:
|
|
2014
|
+
async unlink(path48) {
|
|
2015
|
+
recorder.record({ type: "unlink", path: path48 });
|
|
2016
2016
|
},
|
|
2017
|
-
async readdir(
|
|
2018
|
-
return base.readdir(
|
|
2017
|
+
async readdir(path48) {
|
|
2018
|
+
return base.readdir(path48);
|
|
2019
2019
|
}
|
|
2020
2020
|
};
|
|
2021
2021
|
if (typeof base.rm === "function") {
|
|
2022
|
-
proxy.rm = async (
|
|
2023
|
-
recorder.record({ type: "rm", path:
|
|
2022
|
+
proxy.rm = async (path48, options) => {
|
|
2023
|
+
recorder.record({ type: "rm", path: path48, options });
|
|
2024
2024
|
};
|
|
2025
2025
|
}
|
|
2026
2026
|
if (typeof base.copyFile === "function") {
|
|
@@ -2110,8 +2110,8 @@ function describeWriteChange(previous, next) {
|
|
|
2110
2110
|
}
|
|
2111
2111
|
return "update";
|
|
2112
2112
|
}
|
|
2113
|
-
function renderWriteCommand(
|
|
2114
|
-
const command = `cat > ${
|
|
2113
|
+
function renderWriteCommand(path48, change) {
|
|
2114
|
+
const command = `cat > ${path48}`;
|
|
2115
2115
|
if (change === "create") {
|
|
2116
2116
|
return renderOperationCommand(command, chalk.green, "# create");
|
|
2117
2117
|
}
|
|
@@ -2273,9 +2273,9 @@ function redactTomlLine(line) {
|
|
|
2273
2273
|
}
|
|
2274
2274
|
return line;
|
|
2275
2275
|
}
|
|
2276
|
-
async function tryReadText(base,
|
|
2276
|
+
async function tryReadText(base, path48) {
|
|
2277
2277
|
try {
|
|
2278
|
-
return await base.readFile(
|
|
2278
|
+
return await base.readFile(path48, "utf8");
|
|
2279
2279
|
} catch (error2) {
|
|
2280
2280
|
if (isNotFound(error2)) {
|
|
2281
2281
|
return null;
|
|
@@ -3404,6 +3404,9 @@ function resolveOutputFormat(env = process.env) {
|
|
|
3404
3404
|
cached = VALID_FORMATS.has(raw) ? raw : "terminal";
|
|
3405
3405
|
return cached;
|
|
3406
3406
|
}
|
|
3407
|
+
function withOutputFormat(format, fn) {
|
|
3408
|
+
return formatStorage.run(format, fn);
|
|
3409
|
+
}
|
|
3407
3410
|
function resetOutputFormatCache() {
|
|
3408
3411
|
cached = void 0;
|
|
3409
3412
|
}
|
|
@@ -7752,6 +7755,14 @@ async function text3(opts) {
|
|
|
7752
7755
|
async function confirm2(opts) {
|
|
7753
7756
|
return clack.confirm(opts);
|
|
7754
7757
|
}
|
|
7758
|
+
async function confirmOrCancel(opts) {
|
|
7759
|
+
const result = await confirm2(opts);
|
|
7760
|
+
if (Ct(result)) {
|
|
7761
|
+
cancel("Operation cancelled.");
|
|
7762
|
+
throw new PromptCancelledError();
|
|
7763
|
+
}
|
|
7764
|
+
return result === true;
|
|
7765
|
+
}
|
|
7755
7766
|
async function password2(opts) {
|
|
7756
7767
|
return clack.password(opts);
|
|
7757
7768
|
}
|
|
@@ -7818,6 +7829,7 @@ async function withSpinner(options) {
|
|
|
7818
7829
|
throw error2;
|
|
7819
7830
|
}
|
|
7820
7831
|
}
|
|
7832
|
+
var PromptCancelledError;
|
|
7821
7833
|
var init_prompts = __esm({
|
|
7822
7834
|
"packages/design-system/src/prompts/index.ts"() {
|
|
7823
7835
|
"use strict";
|
|
@@ -7829,6 +7841,15 @@ var init_prompts = __esm({
|
|
|
7829
7841
|
init_note();
|
|
7830
7842
|
init_outro();
|
|
7831
7843
|
init_spinner2();
|
|
7844
|
+
PromptCancelledError = class extends Error {
|
|
7845
|
+
constructor(message2 = "Operation cancelled.") {
|
|
7846
|
+
super(message2);
|
|
7847
|
+
this.name = "PromptCancelledError";
|
|
7848
|
+
if (Error.captureStackTrace) {
|
|
7849
|
+
Error.captureStackTrace(this, this.constructor);
|
|
7850
|
+
}
|
|
7851
|
+
}
|
|
7852
|
+
};
|
|
7832
7853
|
}
|
|
7833
7854
|
});
|
|
7834
7855
|
|
|
@@ -8089,21 +8110,21 @@ async function* adaptClaude(lines) {
|
|
|
8089
8110
|
if (blockType !== "tool_result") continue;
|
|
8090
8111
|
const kind = toolKindsById.get(item.tool_use_id);
|
|
8091
8112
|
toolKindsById.delete(item.tool_use_id);
|
|
8092
|
-
let
|
|
8113
|
+
let path48;
|
|
8093
8114
|
if (typeof item.content === "string") {
|
|
8094
|
-
|
|
8115
|
+
path48 = item.content;
|
|
8095
8116
|
} else {
|
|
8096
8117
|
try {
|
|
8097
|
-
|
|
8118
|
+
path48 = JSON.stringify(item.content);
|
|
8098
8119
|
} catch {
|
|
8099
|
-
|
|
8120
|
+
path48 = String(item.content);
|
|
8100
8121
|
}
|
|
8101
8122
|
}
|
|
8102
8123
|
yield {
|
|
8103
8124
|
event: "tool_complete",
|
|
8104
8125
|
id: item.tool_use_id,
|
|
8105
8126
|
kind,
|
|
8106
|
-
path:
|
|
8127
|
+
path: path48
|
|
8107
8128
|
};
|
|
8108
8129
|
}
|
|
8109
8130
|
}
|
|
@@ -8226,10 +8247,10 @@ async function* adaptCodex(lines) {
|
|
|
8226
8247
|
const kindFromStart = toolKindById.get(item.id);
|
|
8227
8248
|
const kind = kindFromStart ?? (itemType === "command_execution" ? "exec" : itemType === "file_edit" ? "edit" : "other");
|
|
8228
8249
|
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;
|
|
8229
|
-
const
|
|
8250
|
+
const path48 = titleFromEvent ?? toolTitleById.get(item.id) ?? "";
|
|
8230
8251
|
toolTitleById.delete(item.id);
|
|
8231
8252
|
toolKindById.delete(item.id);
|
|
8232
|
-
yield { event: "tool_complete", id: item.id, kind, path:
|
|
8253
|
+
yield { event: "tool_complete", id: item.id, kind, path: path48 };
|
|
8233
8254
|
}
|
|
8234
8255
|
}
|
|
8235
8256
|
}
|
|
@@ -9241,8 +9262,8 @@ function resourceNotFound(resource) {
|
|
|
9241
9262
|
`Resource not found: ${resource}`
|
|
9242
9263
|
);
|
|
9243
9264
|
}
|
|
9244
|
-
function assertAbsolutePath(
|
|
9245
|
-
if (!isAbsolute(
|
|
9265
|
+
function assertAbsolutePath(path48) {
|
|
9266
|
+
if (!isAbsolute(path48)) {
|
|
9246
9267
|
throw invalidParams('"path" must be an absolute path');
|
|
9247
9268
|
}
|
|
9248
9269
|
}
|
|
@@ -10354,7 +10375,7 @@ function updateSessionFromEvent(ctx, event, toolCallsById) {
|
|
|
10354
10375
|
}
|
|
10355
10376
|
const id = readString(event.id);
|
|
10356
10377
|
const kind = readString(event.kind);
|
|
10357
|
-
const
|
|
10378
|
+
const path48 = readString(event.path);
|
|
10358
10379
|
let toolCall = id ? toolCallsById.get(id) : void 0;
|
|
10359
10380
|
if (!toolCall) {
|
|
10360
10381
|
toolCall = {};
|
|
@@ -10369,8 +10390,8 @@ function updateSessionFromEvent(ctx, event, toolCallsById) {
|
|
|
10369
10390
|
if (kind) {
|
|
10370
10391
|
toolCall.kind = kind;
|
|
10371
10392
|
}
|
|
10372
|
-
if (
|
|
10373
|
-
toolCall.path =
|
|
10393
|
+
if (path48) {
|
|
10394
|
+
toolCall.path = path48;
|
|
10374
10395
|
}
|
|
10375
10396
|
}
|
|
10376
10397
|
var sessionCapture;
|
|
@@ -10859,14 +10880,14 @@ function parseDockerLocator(input) {
|
|
|
10859
10880
|
throw new Error(`Invalid docker workspace locator "${input}".`);
|
|
10860
10881
|
}
|
|
10861
10882
|
const container = input.slice(0, slashIndex);
|
|
10862
|
-
const
|
|
10863
|
-
if (container.length === 0 ||
|
|
10883
|
+
const path48 = input.slice(slashIndex);
|
|
10884
|
+
if (container.length === 0 || path48.length === 0) {
|
|
10864
10885
|
throw new Error(`Invalid docker workspace locator "${input}".`);
|
|
10865
10886
|
}
|
|
10866
10887
|
return {
|
|
10867
10888
|
scheme: "docker",
|
|
10868
10889
|
container,
|
|
10869
|
-
path:
|
|
10890
|
+
path: path48
|
|
10870
10891
|
};
|
|
10871
10892
|
}
|
|
10872
10893
|
function splitOnce(input, separator) {
|
|
@@ -12743,21 +12764,21 @@ function createSdkContainer(options) {
|
|
|
12743
12764
|
});
|
|
12744
12765
|
loggerFactory.setErrorLogger(errorLogger);
|
|
12745
12766
|
const asyncFs = {
|
|
12746
|
-
readFile: ((
|
|
12767
|
+
readFile: ((path48, encoding) => {
|
|
12747
12768
|
if (encoding) {
|
|
12748
|
-
return fs2.readFile(
|
|
12769
|
+
return fs2.readFile(path48, encoding);
|
|
12749
12770
|
}
|
|
12750
|
-
return fs2.readFile(
|
|
12771
|
+
return fs2.readFile(path48);
|
|
12751
12772
|
}),
|
|
12752
|
-
writeFile: (
|
|
12753
|
-
mkdir: (
|
|
12773
|
+
writeFile: (path48, data, opts) => fs2.writeFile(path48, data, opts),
|
|
12774
|
+
mkdir: (path48, opts) => fs2.mkdir(path48, opts).then(() => {
|
|
12754
12775
|
}),
|
|
12755
|
-
stat: (
|
|
12756
|
-
rm: (
|
|
12757
|
-
unlink: (
|
|
12758
|
-
readdir: (
|
|
12776
|
+
stat: (path48) => fs2.stat(path48),
|
|
12777
|
+
rm: (path48, opts) => fs2.rm(path48, opts),
|
|
12778
|
+
unlink: (path48) => fs2.unlink(path48),
|
|
12779
|
+
readdir: (path48) => fs2.readdir(path48),
|
|
12759
12780
|
copyFile: (src, dest) => fs2.copyFile(src, dest),
|
|
12760
|
-
chmod: (
|
|
12781
|
+
chmod: (path48, mode) => fs2.chmod(path48, mode)
|
|
12761
12782
|
};
|
|
12762
12783
|
const contextFactory = createCommandContextFactory({ fs: asyncFs });
|
|
12763
12784
|
const authFs = {
|
|
@@ -13390,11 +13411,11 @@ function createDefaultFs() {
|
|
|
13390
13411
|
readFile: fsPromises2.readFile,
|
|
13391
13412
|
readdir: fsPromises2.readdir,
|
|
13392
13413
|
stat: async (filePath) => {
|
|
13393
|
-
const
|
|
13414
|
+
const stat14 = await fsPromises2.stat(filePath);
|
|
13394
13415
|
return {
|
|
13395
|
-
isFile: () =>
|
|
13396
|
-
isDirectory: () =>
|
|
13397
|
-
mtimeMs:
|
|
13416
|
+
isFile: () => stat14.isFile(),
|
|
13417
|
+
isDirectory: () => stat14.isDirectory(),
|
|
13418
|
+
mtimeMs: stat14.mtimeMs
|
|
13398
13419
|
};
|
|
13399
13420
|
}
|
|
13400
13421
|
};
|
|
@@ -13421,8 +13442,8 @@ function countCompletedTasks(planPath, content) {
|
|
|
13421
13442
|
async function ensurePlanExists(fs3, cwd, planPath) {
|
|
13422
13443
|
const absolutePath = path15.isAbsolute(planPath) ? planPath : path15.resolve(cwd, planPath);
|
|
13423
13444
|
try {
|
|
13424
|
-
const
|
|
13425
|
-
if (!
|
|
13445
|
+
const stat14 = await fs3.stat(absolutePath);
|
|
13446
|
+
if (!stat14.isFile()) {
|
|
13426
13447
|
throw new Error(`Plan not found at "${planPath}".`);
|
|
13427
13448
|
}
|
|
13428
13449
|
} catch (error2) {
|
|
@@ -13448,8 +13469,8 @@ async function scanPlansDir(fs3, plansDir, displayPrefix) {
|
|
|
13448
13469
|
continue;
|
|
13449
13470
|
}
|
|
13450
13471
|
const absolutePath = path15.join(plansDir, entry);
|
|
13451
|
-
const
|
|
13452
|
-
if (!
|
|
13472
|
+
const stat14 = await fs3.stat(absolutePath);
|
|
13473
|
+
if (!stat14.isFile()) {
|
|
13453
13474
|
continue;
|
|
13454
13475
|
}
|
|
13455
13476
|
const displayPath = path15.join(displayPrefix, entry);
|
|
@@ -13491,8 +13512,8 @@ async function resolvePlanDirectory(options) {
|
|
|
13491
13512
|
const fs3 = options.fs ?? createDefaultFs();
|
|
13492
13513
|
const projectDir = path15.join(options.cwd, ".poe-code");
|
|
13493
13514
|
try {
|
|
13494
|
-
const
|
|
13495
|
-
if (
|
|
13515
|
+
const stat14 = await fs3.stat(projectDir);
|
|
13516
|
+
if (stat14.isDirectory()) {
|
|
13496
13517
|
return path15.join(options.cwd, ".poe-code", "pipeline", "plans");
|
|
13497
13518
|
}
|
|
13498
13519
|
} catch {
|
|
@@ -13707,11 +13728,11 @@ function createDefaultFs2() {
|
|
|
13707
13728
|
},
|
|
13708
13729
|
rmdir: fsPromises3.rmdir,
|
|
13709
13730
|
stat: async (filePath) => {
|
|
13710
|
-
const
|
|
13731
|
+
const stat14 = await fsPromises3.stat(filePath);
|
|
13711
13732
|
return {
|
|
13712
|
-
isFile: () =>
|
|
13713
|
-
isDirectory: () =>
|
|
13714
|
-
mtimeMs:
|
|
13733
|
+
isFile: () => stat14.isFile(),
|
|
13734
|
+
isDirectory: () => stat14.isDirectory(),
|
|
13735
|
+
mtimeMs: stat14.mtimeMs
|
|
13715
13736
|
};
|
|
13716
13737
|
}
|
|
13717
13738
|
};
|
|
@@ -13744,8 +13765,8 @@ async function lockFile(filePath, options = {}) {
|
|
|
13744
13765
|
if (!error2 || typeof error2 !== "object" || !("code" in error2) || error2.code !== "EEXIST") {
|
|
13745
13766
|
throw error2;
|
|
13746
13767
|
}
|
|
13747
|
-
const
|
|
13748
|
-
if (Date.now() -
|
|
13768
|
+
const stat14 = await fs3.stat(lockPath);
|
|
13769
|
+
if (Date.now() - stat14.mtimeMs > staleMs) {
|
|
13749
13770
|
await fs3.rmdir(lockPath);
|
|
13750
13771
|
continue;
|
|
13751
13772
|
}
|
|
@@ -13771,11 +13792,11 @@ function createDefaultFs3() {
|
|
|
13771
13792
|
writeFile: fsPromises4.writeFile,
|
|
13772
13793
|
readdir: fsPromises4.readdir,
|
|
13773
13794
|
stat: async (filePath) => {
|
|
13774
|
-
const
|
|
13795
|
+
const stat14 = await fsPromises4.stat(filePath);
|
|
13775
13796
|
return {
|
|
13776
|
-
isFile: () =>
|
|
13777
|
-
isDirectory: () =>
|
|
13778
|
-
mtimeMs:
|
|
13797
|
+
isFile: () => stat14.isFile(),
|
|
13798
|
+
isDirectory: () => stat14.isDirectory(),
|
|
13799
|
+
mtimeMs: stat14.mtimeMs
|
|
13779
13800
|
};
|
|
13780
13801
|
},
|
|
13781
13802
|
mkdir: async (filePath, options) => {
|
|
@@ -14237,8 +14258,8 @@ async function removeDirectory2(fs3, directoryPath) {
|
|
|
14237
14258
|
}
|
|
14238
14259
|
for (const entry of entries) {
|
|
14239
14260
|
const entryPath = path18.join(directoryPath, entry);
|
|
14240
|
-
const
|
|
14241
|
-
if (
|
|
14261
|
+
const stat14 = await fs3.stat(entryPath);
|
|
14262
|
+
if (stat14.isFile()) {
|
|
14242
14263
|
await fs3.rm(entryPath, { force: true });
|
|
14243
14264
|
continue;
|
|
14244
14265
|
}
|
|
@@ -14284,8 +14305,8 @@ function createStateStore(stateDir, fs3 = nodeFs2) {
|
|
|
14284
14305
|
for (const entry of [...entries].sort()) {
|
|
14285
14306
|
const entryPath = path18.join(stateDir, entry);
|
|
14286
14307
|
try {
|
|
14287
|
-
const
|
|
14288
|
-
if (
|
|
14308
|
+
const stat14 = await fs3.stat(entryPath);
|
|
14309
|
+
if (stat14.isFile()) {
|
|
14289
14310
|
continue;
|
|
14290
14311
|
}
|
|
14291
14312
|
} catch (error2) {
|
|
@@ -15691,8 +15712,8 @@ async function listIds(fs3, baseDir) {
|
|
|
15691
15712
|
for (const entry of entries) {
|
|
15692
15713
|
const entryPath = path22.join(baseDir, entry);
|
|
15693
15714
|
try {
|
|
15694
|
-
const
|
|
15695
|
-
if (!
|
|
15715
|
+
const stat14 = await fs3.stat(entryPath);
|
|
15716
|
+
if (!stat14.isFile()) {
|
|
15696
15717
|
ids.push(entry);
|
|
15697
15718
|
}
|
|
15698
15719
|
} catch (error2) {
|
|
@@ -15945,10 +15966,10 @@ function createDefaultFs4() {
|
|
|
15945
15966
|
return {
|
|
15946
15967
|
readdir: fsPromises5.readdir,
|
|
15947
15968
|
stat: async (filePath) => {
|
|
15948
|
-
const
|
|
15969
|
+
const stat14 = await fsPromises5.stat(filePath);
|
|
15949
15970
|
return {
|
|
15950
|
-
isFile: () =>
|
|
15951
|
-
mtimeMs:
|
|
15971
|
+
isFile: () => stat14.isFile(),
|
|
15972
|
+
mtimeMs: stat14.mtimeMs
|
|
15952
15973
|
};
|
|
15953
15974
|
}
|
|
15954
15975
|
};
|
|
@@ -15975,8 +15996,8 @@ async function scanDir(fs3, absoluteDir, displayDir) {
|
|
|
15975
15996
|
continue;
|
|
15976
15997
|
}
|
|
15977
15998
|
const absolutePath = path23.join(absoluteDir, entry);
|
|
15978
|
-
const
|
|
15979
|
-
if (!
|
|
15999
|
+
const stat14 = await fs3.stat(absolutePath);
|
|
16000
|
+
if (!stat14.isFile()) {
|
|
15980
16001
|
continue;
|
|
15981
16002
|
}
|
|
15982
16003
|
const displayPath = path23.join(displayDir, entry);
|
|
@@ -16149,10 +16170,10 @@ function createDefaultFs5() {
|
|
|
16149
16170
|
writeFile: (filePath, content) => fsPromises6.writeFile(filePath, content, "utf8"),
|
|
16150
16171
|
readdir: fsPromises6.readdir,
|
|
16151
16172
|
stat: async (filePath) => {
|
|
16152
|
-
const
|
|
16173
|
+
const stat14 = await fsPromises6.stat(filePath);
|
|
16153
16174
|
return {
|
|
16154
|
-
isFile: () =>
|
|
16155
|
-
mtimeMs:
|
|
16175
|
+
isFile: () => stat14.isFile(),
|
|
16176
|
+
mtimeMs: stat14.mtimeMs
|
|
16156
16177
|
};
|
|
16157
16178
|
},
|
|
16158
16179
|
mkdir: async (filePath, options) => {
|
|
@@ -16679,10 +16700,10 @@ function createDefaultFs6() {
|
|
|
16679
16700
|
writeFile: (filePath, content) => fsPromises7.writeFile(filePath, content, "utf8"),
|
|
16680
16701
|
readdir: fsPromises7.readdir,
|
|
16681
16702
|
stat: async (filePath) => {
|
|
16682
|
-
const
|
|
16703
|
+
const stat14 = await fsPromises7.stat(filePath);
|
|
16683
16704
|
return {
|
|
16684
|
-
isFile: () =>
|
|
16685
|
-
mtimeMs:
|
|
16705
|
+
isFile: () => stat14.isFile(),
|
|
16706
|
+
mtimeMs: stat14.mtimeMs
|
|
16686
16707
|
};
|
|
16687
16708
|
},
|
|
16688
16709
|
mkdir: async (filePath, options) => {
|
|
@@ -17000,10 +17021,10 @@ function createDefaultFs7() {
|
|
|
17000
17021
|
},
|
|
17001
17022
|
readdir: fsPromises8.readdir,
|
|
17002
17023
|
stat: async (filePath) => {
|
|
17003
|
-
const
|
|
17024
|
+
const stat14 = await fsPromises8.stat(filePath);
|
|
17004
17025
|
return {
|
|
17005
|
-
isFile: () =>
|
|
17006
|
-
mtimeMs:
|
|
17026
|
+
isFile: () => stat14.isFile(),
|
|
17027
|
+
mtimeMs: stat14.mtimeMs
|
|
17007
17028
|
};
|
|
17008
17029
|
},
|
|
17009
17030
|
mkdir: async (filePath, options) => {
|
|
@@ -23933,11 +23954,11 @@ function formatSegment(segment, casing) {
|
|
|
23933
23954
|
const separator = casing === "snake" ? "_" : "-";
|
|
23934
23955
|
return splitWords(segment).join(separator);
|
|
23935
23956
|
}
|
|
23936
|
-
function toOptionFlag(
|
|
23937
|
-
return `--${
|
|
23957
|
+
function toOptionFlag(path48, casing) {
|
|
23958
|
+
return `--${path48.map((segment) => formatSegment(segment, casing)).join(".")}`;
|
|
23938
23959
|
}
|
|
23939
|
-
function toOptionAttribute(
|
|
23940
|
-
return
|
|
23960
|
+
function toOptionAttribute(path48, casing) {
|
|
23961
|
+
return path48.map((segment) => {
|
|
23941
23962
|
const formatted = formatSegment(segment, casing);
|
|
23942
23963
|
if (casing === "snake") {
|
|
23943
23964
|
return formatted;
|
|
@@ -23948,13 +23969,13 @@ function toOptionAttribute(path43, casing) {
|
|
|
23948
23969
|
).join("");
|
|
23949
23970
|
}).join(".");
|
|
23950
23971
|
}
|
|
23951
|
-
function toDisplayPath(
|
|
23952
|
-
return
|
|
23972
|
+
function toDisplayPath(path48) {
|
|
23973
|
+
return path48.join(".");
|
|
23953
23974
|
}
|
|
23954
|
-
function collectFields(schema, casing,
|
|
23975
|
+
function collectFields(schema, casing, path48 = [], inheritedOptional = false) {
|
|
23955
23976
|
const fields = [];
|
|
23956
23977
|
for (const [key, rawChildSchema] of Object.entries(schema.shape)) {
|
|
23957
|
-
const nextPath = [...
|
|
23978
|
+
const nextPath = [...path48, key];
|
|
23958
23979
|
const optional = inheritedOptional || rawChildSchema.kind === "optional";
|
|
23959
23980
|
const childSchema = unwrapOptional(rawChildSchema);
|
|
23960
23981
|
if (childSchema.kind === "object") {
|
|
@@ -23977,9 +23998,9 @@ function collectFields(schema, casing, path43 = [], inheritedOptional = false) {
|
|
|
23977
23998
|
}
|
|
23978
23999
|
return fields;
|
|
23979
24000
|
}
|
|
23980
|
-
function toCommanderOptionAttribute(
|
|
23981
|
-
const optionAttribute = toOptionAttribute(
|
|
23982
|
-
const optionFlag = toOptionFlag(
|
|
24001
|
+
function toCommanderOptionAttribute(path48, casing) {
|
|
24002
|
+
const optionAttribute = toOptionAttribute(path48, casing);
|
|
24003
|
+
const optionFlag = toOptionFlag(path48, casing);
|
|
23983
24004
|
if (!GLOBAL_LONG_OPTION_FLAGS.has(optionFlag)) {
|
|
23984
24005
|
return optionAttribute;
|
|
23985
24006
|
}
|
|
@@ -24427,10 +24448,10 @@ function addGlobalOptions(command) {
|
|
|
24427
24448
|
throw new InvalidArgumentError('Invalid value for "--output". Expected one of: rich, md, json.');
|
|
24428
24449
|
}).option("--verbose", "Print stack traces for unexpected errors.");
|
|
24429
24450
|
}
|
|
24430
|
-
function setNestedValue(target,
|
|
24451
|
+
function setNestedValue(target, path48, value) {
|
|
24431
24452
|
let cursor = target;
|
|
24432
|
-
for (let index = 0; index <
|
|
24433
|
-
const segment =
|
|
24453
|
+
for (let index = 0; index < path48.length - 1; index += 1) {
|
|
24454
|
+
const segment = path48[index] ?? "";
|
|
24434
24455
|
const existing = cursor[segment];
|
|
24435
24456
|
if (typeof existing === "object" && existing !== null) {
|
|
24436
24457
|
cursor = existing;
|
|
@@ -24440,7 +24461,7 @@ function setNestedValue(target, path43, value) {
|
|
|
24440
24461
|
cursor[segment] = next;
|
|
24441
24462
|
cursor = next;
|
|
24442
24463
|
}
|
|
24443
|
-
const leaf =
|
|
24464
|
+
const leaf = path48[path48.length - 1];
|
|
24444
24465
|
if (leaf !== void 0) {
|
|
24445
24466
|
cursor[leaf] = value;
|
|
24446
24467
|
}
|
|
@@ -24530,13 +24551,13 @@ async function withOutputFormat2(output, fn) {
|
|
|
24530
24551
|
}
|
|
24531
24552
|
function createFs() {
|
|
24532
24553
|
return {
|
|
24533
|
-
readFile: async (
|
|
24534
|
-
writeFile: async (
|
|
24535
|
-
await writeFile7(
|
|
24554
|
+
readFile: async (path48, encoding = "utf8") => readFile12(path48, { encoding }),
|
|
24555
|
+
writeFile: async (path48, contents) => {
|
|
24556
|
+
await writeFile7(path48, contents);
|
|
24536
24557
|
},
|
|
24537
|
-
exists: async (
|
|
24558
|
+
exists: async (path48) => {
|
|
24538
24559
|
try {
|
|
24539
|
-
await access2(
|
|
24560
|
+
await access2(path48);
|
|
24540
24561
|
return true;
|
|
24541
24562
|
} catch {
|
|
24542
24563
|
return false;
|
|
@@ -24557,9 +24578,9 @@ function isPlainObject(value) {
|
|
|
24557
24578
|
function hasFieldValue(value) {
|
|
24558
24579
|
return value !== void 0;
|
|
24559
24580
|
}
|
|
24560
|
-
function hasNestedField(fields,
|
|
24581
|
+
function hasNestedField(fields, path48) {
|
|
24561
24582
|
return fields.some(
|
|
24562
|
-
(field) =>
|
|
24583
|
+
(field) => path48.length < field.path.length && path48.every((segment, index) => field.path[index] === segment)
|
|
24563
24584
|
);
|
|
24564
24585
|
}
|
|
24565
24586
|
function describeExpectedPresetValue(schema) {
|
|
@@ -24643,9 +24664,9 @@ async function loadPresetValues(fields, presetPath) {
|
|
|
24643
24664
|
}
|
|
24644
24665
|
const fieldByPath = new Map(fields.map((field) => [field.displayPath, field]));
|
|
24645
24666
|
const presetValues = {};
|
|
24646
|
-
function visitObject(current,
|
|
24667
|
+
function visitObject(current, path48) {
|
|
24647
24668
|
for (const [key, value] of Object.entries(current)) {
|
|
24648
|
-
const nextPath = [...
|
|
24669
|
+
const nextPath = [...path48, key];
|
|
24649
24670
|
const displayPath = toDisplayPath(nextPath);
|
|
24650
24671
|
const field = fieldByPath.get(displayPath);
|
|
24651
24672
|
if (field !== void 0) {
|
|
@@ -28899,23 +28920,24 @@ var init_configs3 = __esm({
|
|
|
28899
28920
|
}
|
|
28900
28921
|
});
|
|
28901
28922
|
|
|
28923
|
+
// packages/agent-skill-config/src/templates/poe-generate.md
|
|
28924
|
+
var poe_generate_default;
|
|
28925
|
+
var init_poe_generate = __esm({
|
|
28926
|
+
"packages/agent-skill-config/src/templates/poe-generate.md"() {
|
|
28927
|
+
poe_generate_default = '---\nname: poe-generate\ndescription: \'Poe code generation skill\'\n---\n\n# poe-code generate\n\nUse `poe-code generate` to create text, images, audio, or video via the Poe API.\n\n## Text generation\n\n```bash\npoe-code generate "Write a short function that parses a JSON string safely."\n```\n\nSpecify the model/bot:\n\n```bash\n# CLI option\npoe-code generate --model "gpt-4.1" "Summarize this codebase change."\n\n# Some agent runtimes call the model selector `--bot`\npoe-code generate --bot "gpt-4.1" "Summarize this codebase change."\n```\n\n## Media generation\n\nThe CLI supports media generation as subcommands:\n\n```bash\npoe-code generate image "A 3D render of a rubber duck wearing sunglasses" --model "gpt-image-1" -o duck.png\npoe-code generate video "A cinematic timelapse of a city at night" --model "veo" -o city.mp4\npoe-code generate audio "A calm 10 second lo-fi beat" --model "audio-model" -o beat.wav\n```\n\nSome agent runtimes expose the same media types as flags. If available, these are equivalent:\n\n```bash\npoe-code generate --image "A 3D render of a rubber duck wearing sunglasses" --bot "gpt-image-1" -o duck.png\npoe-code generate --video "A cinematic timelapse of a city at night" --bot "veo" -o city.mp4\npoe-code generate --audio "A calm 10 second lo-fi beat" --bot "audio-model" -o beat.wav\n```\n\n## Tips\n\n- Use `--param key=value` to pass provider/model parameters (repeatable).\n- Use `--output <path>` (or `-o`) for media outputs.\n';
|
|
28928
|
+
}
|
|
28929
|
+
});
|
|
28930
|
+
|
|
28931
|
+
// packages/agent-skill-config/src/templates/terminal-pilot.md
|
|
28932
|
+
var terminal_pilot_default;
|
|
28933
|
+
var init_terminal_pilot = __esm({
|
|
28934
|
+
"packages/agent-skill-config/src/templates/terminal-pilot.md"() {
|
|
28935
|
+
terminal_pilot_default = "---\nname: terminal-pilot\ndescription: 'Terminal automation skill using the terminal-pilot CLI'\n---\n\n# Terminal Pilot\n\nUse the `terminal-pilot` CLI when you need to automate or inspect interactive\nCLI applications through a real PTY session.\n\n## Commands\n\n- `terminal-pilot create-session` - start a PTY-backed command\n- `terminal-pilot fill` - paste text into a session\n- `terminal-pilot type` - type character-by-character for TUIs and readline\n- `terminal-pilot press-key` - send named keys such as `Enter` or `ArrowDown`\n- `terminal-pilot wait-for` - wait for terminal output to match a pattern\n- `terminal-pilot wait-for-exit` - block until a session exits\n- `terminal-pilot read-screen` - inspect the current visible terminal screen\n- `terminal-pilot read-history` - read scrollback output\n- `terminal-pilot list-sessions` - list active sessions\n- `terminal-pilot close-session` - close a session and return its exit code\n\n## Examples\n\n```bash\nterminal-pilot --help\nterminal-pilot create-session --help\nterminal-pilot read-screen --help\n```\n\nUse JSON output when another tool or script needs to read the result:\n\n```bash\nterminal-pilot list-sessions --output json\nterminal-pilot read-screen --session s1 --output json\n```\n\n## Tips\n\n- Use `fill` for pasted text and multi-line input.\n- Use `type` when the app reacts to individual keystrokes.\n- Use `press-key` for Enter, Tab, arrow keys, Escape, and control-key chords.\n- Use `wait-for --literal` for exact string matching.\n- Default terminal size is 120x40.\n";
|
|
28936
|
+
}
|
|
28937
|
+
});
|
|
28938
|
+
|
|
28902
28939
|
// packages/agent-skill-config/src/templates.ts
|
|
28903
|
-
import { readFile as readFile13 } from "node:fs/promises";
|
|
28904
|
-
async function getTemplates() {
|
|
28905
|
-
if (templatesCache) {
|
|
28906
|
-
return templatesCache;
|
|
28907
|
-
}
|
|
28908
|
-
const entries = await Promise.all(
|
|
28909
|
-
TEMPLATE_NAMES.map(async (name) => {
|
|
28910
|
-
const url = new URL(`./templates/${name}`, import.meta.url);
|
|
28911
|
-
return [name, await readFile13(url, "utf8")];
|
|
28912
|
-
})
|
|
28913
|
-
);
|
|
28914
|
-
templatesCache = Object.fromEntries(entries);
|
|
28915
|
-
return templatesCache;
|
|
28916
|
-
}
|
|
28917
28940
|
async function loadTemplate2(templateId) {
|
|
28918
|
-
const templates = await getTemplates();
|
|
28919
28941
|
const template = templates[templateId];
|
|
28920
28942
|
if (!template) {
|
|
28921
28943
|
throw new Error(`Template not found: ${templateId}`);
|
|
@@ -28925,12 +28947,16 @@ async function loadTemplate2(templateId) {
|
|
|
28925
28947
|
function createTemplateLoader() {
|
|
28926
28948
|
return loadTemplate2;
|
|
28927
28949
|
}
|
|
28928
|
-
var
|
|
28950
|
+
var templates;
|
|
28929
28951
|
var init_templates = __esm({
|
|
28930
28952
|
"packages/agent-skill-config/src/templates.ts"() {
|
|
28931
28953
|
"use strict";
|
|
28932
|
-
|
|
28933
|
-
|
|
28954
|
+
init_poe_generate();
|
|
28955
|
+
init_terminal_pilot();
|
|
28956
|
+
templates = {
|
|
28957
|
+
"poe-generate.md": poe_generate_default,
|
|
28958
|
+
"terminal-pilot.md": terminal_pilot_default
|
|
28959
|
+
};
|
|
28934
28960
|
}
|
|
28935
28961
|
});
|
|
28936
28962
|
|
|
@@ -29943,7 +29969,7 @@ var init_models2 = __esm({
|
|
|
29943
29969
|
|
|
29944
29970
|
// src/cli/commands/pipeline.ts
|
|
29945
29971
|
import path40 from "node:path";
|
|
29946
|
-
import { readFile as
|
|
29972
|
+
import { readFile as readFile13, stat as stat11 } from "node:fs/promises";
|
|
29947
29973
|
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
29948
29974
|
async function resolvePipelinePlanDirectory(container) {
|
|
29949
29975
|
const configDoc = await readMergedDocument(
|
|
@@ -30013,8 +30039,8 @@ async function loadPipelineTemplates() {
|
|
|
30013
30039
|
continue;
|
|
30014
30040
|
}
|
|
30015
30041
|
const [skillPlan, steps] = await Promise.all([
|
|
30016
|
-
|
|
30017
|
-
|
|
30042
|
+
readFile13(path40.join(templateRoot, "SKILL_plan.md"), "utf8"),
|
|
30043
|
+
readFile13(path40.join(templateRoot, "steps.yaml.hbs"), "utf8")
|
|
30018
30044
|
]);
|
|
30019
30045
|
pipelineTemplatesCache = { skillPlan, steps };
|
|
30020
30046
|
return pipelineTemplatesCache;
|
|
@@ -30348,12 +30374,12 @@ function registerPipelineCommand(program, container) {
|
|
|
30348
30374
|
scope = selected;
|
|
30349
30375
|
}
|
|
30350
30376
|
resources.logger.intro(`pipeline install (${support.id}, ${scope})`);
|
|
30351
|
-
const
|
|
30377
|
+
const templates2 = await loadPipelineTemplates();
|
|
30352
30378
|
const skillResult = await installSkill(
|
|
30353
30379
|
support.id,
|
|
30354
30380
|
{
|
|
30355
30381
|
name: "poe-code-pipeline-plan",
|
|
30356
|
-
content:
|
|
30382
|
+
content: templates2.skillPlan
|
|
30357
30383
|
},
|
|
30358
30384
|
{
|
|
30359
30385
|
fs: container.fs,
|
|
@@ -30394,7 +30420,7 @@ function registerPipelineCommand(program, container) {
|
|
|
30394
30420
|
await container.fs.mkdir(path40.dirname(pipelinePaths.stepsPath), {
|
|
30395
30421
|
recursive: true
|
|
30396
30422
|
});
|
|
30397
|
-
await container.fs.writeFile(pipelinePaths.stepsPath,
|
|
30423
|
+
await container.fs.writeFile(pipelinePaths.stepsPath, templates2.steps, {
|
|
30398
30424
|
encoding: "utf8"
|
|
30399
30425
|
});
|
|
30400
30426
|
resources.logger.info(
|
|
@@ -30429,8 +30455,828 @@ var init_pipeline3 = __esm({
|
|
|
30429
30455
|
}
|
|
30430
30456
|
});
|
|
30431
30457
|
|
|
30432
|
-
//
|
|
30458
|
+
// packages/plan-browser/src/format.ts
|
|
30433
30459
|
import path41 from "node:path";
|
|
30460
|
+
function isPipelineTaskDone(task) {
|
|
30461
|
+
if (typeof task.status === "string") {
|
|
30462
|
+
return task.status === "done";
|
|
30463
|
+
}
|
|
30464
|
+
return Object.values(task.status).every((status) => status === "done");
|
|
30465
|
+
}
|
|
30466
|
+
function formatPipelineProgress(content) {
|
|
30467
|
+
const plan = parsePlan(content);
|
|
30468
|
+
const done = plan.tasks.filter((task) => isPipelineTaskDone(task)).length;
|
|
30469
|
+
return `${done}/${plan.tasks.length} done`;
|
|
30470
|
+
}
|
|
30471
|
+
function formatRalphDetail(frontmatter) {
|
|
30472
|
+
const parts = [];
|
|
30473
|
+
if (frontmatter.agent !== void 0) {
|
|
30474
|
+
parts.push(Array.isArray(frontmatter.agent) ? frontmatter.agent.join(", ") : frontmatter.agent);
|
|
30475
|
+
}
|
|
30476
|
+
if (frontmatter.iterations !== void 0) {
|
|
30477
|
+
parts.push(`\xD7${frontmatter.iterations}`);
|
|
30478
|
+
}
|
|
30479
|
+
if (frontmatter.status.state !== "open" || frontmatter.status.iteration > 0) {
|
|
30480
|
+
parts.push(`${frontmatter.status.state} ${frontmatter.status.iteration}`);
|
|
30481
|
+
} else {
|
|
30482
|
+
parts.push("open");
|
|
30483
|
+
}
|
|
30484
|
+
return parts.join(" \xB7 ");
|
|
30485
|
+
}
|
|
30486
|
+
function formatExperimentDetail(frontmatter, state) {
|
|
30487
|
+
const parts = [];
|
|
30488
|
+
if (frontmatter.agent !== void 0) {
|
|
30489
|
+
parts.push(Array.isArray(frontmatter.agent) ? frontmatter.agent.join(", ") : frontmatter.agent);
|
|
30490
|
+
}
|
|
30491
|
+
const metrics = frontmatter.metric === void 0 ? [] : Array.isArray(frontmatter.metric) ? frontmatter.metric : [frontmatter.metric];
|
|
30492
|
+
if (metrics.length > 0) {
|
|
30493
|
+
const directions = Array.from(new Set(metrics.map((metric) => metric.direction)));
|
|
30494
|
+
parts.push(directions.join("/"));
|
|
30495
|
+
}
|
|
30496
|
+
parts.push(state);
|
|
30497
|
+
return parts.join(" \xB7 ");
|
|
30498
|
+
}
|
|
30499
|
+
function getLastExperimentState(journalContent) {
|
|
30500
|
+
const lines = journalContent.split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
|
|
30501
|
+
for (let index = lines.length - 1; index >= 0; index -= 1) {
|
|
30502
|
+
try {
|
|
30503
|
+
const parsed = JSON.parse(lines[index]);
|
|
30504
|
+
if (typeof parsed.status === "string" && parsed.status.length > 0) {
|
|
30505
|
+
return parsed.status;
|
|
30506
|
+
}
|
|
30507
|
+
} catch {
|
|
30508
|
+
continue;
|
|
30509
|
+
}
|
|
30510
|
+
}
|
|
30511
|
+
return "open";
|
|
30512
|
+
}
|
|
30513
|
+
function deriveMarkdownTitle(content, fallbackName) {
|
|
30514
|
+
const heading = content.split("\n").map((line) => line.trim()).find((line) => line.startsWith("# "));
|
|
30515
|
+
return heading ? heading.slice(2).trim() || fallbackName : fallbackName;
|
|
30516
|
+
}
|
|
30517
|
+
function formatPipelineTaskDetails(task) {
|
|
30518
|
+
if (typeof task.status === "string") {
|
|
30519
|
+
return null;
|
|
30520
|
+
}
|
|
30521
|
+
const entries = Object.entries(task.status).map(([name, status]) => `${name}=${status}`);
|
|
30522
|
+
return entries.length > 0 ? `Step status: ${entries.join(", ")}` : null;
|
|
30523
|
+
}
|
|
30524
|
+
function formatPipelinePlanMarkdown(options) {
|
|
30525
|
+
const plan = parsePlan(options.content);
|
|
30526
|
+
const lines = [
|
|
30527
|
+
`# ${options.title}`,
|
|
30528
|
+
"",
|
|
30529
|
+
`Status: ${formatPipelineProgress(options.content)}`,
|
|
30530
|
+
"",
|
|
30531
|
+
"## Tasks",
|
|
30532
|
+
""
|
|
30533
|
+
];
|
|
30534
|
+
for (const task of plan.tasks) {
|
|
30535
|
+
const mark = isPipelineTaskDone(task) ? "x" : " ";
|
|
30536
|
+
lines.push(`- [${mark}] ${task.title} (\`${task.id}\`)`);
|
|
30537
|
+
const detail = formatPipelineTaskDetails(task);
|
|
30538
|
+
if (detail) {
|
|
30539
|
+
lines.push(` - ${detail}`);
|
|
30540
|
+
}
|
|
30541
|
+
for (const promptLine of task.prompt.split("\n")) {
|
|
30542
|
+
lines.push(` > ${promptLine}`);
|
|
30543
|
+
}
|
|
30544
|
+
lines.push("");
|
|
30545
|
+
}
|
|
30546
|
+
return lines.join("\n").trimEnd();
|
|
30547
|
+
}
|
|
30548
|
+
function resolveExperimentJournalPath(absolutePath) {
|
|
30549
|
+
return path41.join(
|
|
30550
|
+
path41.dirname(absolutePath),
|
|
30551
|
+
`${path41.basename(absolutePath, path41.extname(absolutePath))}.journal.jsonl`
|
|
30552
|
+
);
|
|
30553
|
+
}
|
|
30554
|
+
async function readExperimentState(fs3, absolutePath) {
|
|
30555
|
+
try {
|
|
30556
|
+
const content = await fs3.readFile(resolveExperimentJournalPath(absolutePath), "utf8");
|
|
30557
|
+
return getLastExperimentState(content);
|
|
30558
|
+
} catch {
|
|
30559
|
+
return "open";
|
|
30560
|
+
}
|
|
30561
|
+
}
|
|
30562
|
+
async function loadPlanPreviewMarkdown(entry, fs3) {
|
|
30563
|
+
const content = await fs3.readFile(entry.absolutePath, "utf8");
|
|
30564
|
+
if (entry.source === "pipeline") {
|
|
30565
|
+
return formatPipelinePlanMarkdown({
|
|
30566
|
+
title: entry.title,
|
|
30567
|
+
content
|
|
30568
|
+
});
|
|
30569
|
+
}
|
|
30570
|
+
return content;
|
|
30571
|
+
}
|
|
30572
|
+
async function readPlanMetadata(options) {
|
|
30573
|
+
const content = await options.fs.readFile(options.absolutePath, "utf8");
|
|
30574
|
+
const fallbackName = path41.basename(options.path);
|
|
30575
|
+
if (options.source === "pipeline") {
|
|
30576
|
+
return {
|
|
30577
|
+
title: fallbackName,
|
|
30578
|
+
status: formatPipelineProgress(content),
|
|
30579
|
+
format: "yaml"
|
|
30580
|
+
};
|
|
30581
|
+
}
|
|
30582
|
+
if (options.source === "ralph") {
|
|
30583
|
+
const parsed2 = parseFrontmatter(content);
|
|
30584
|
+
return {
|
|
30585
|
+
title: deriveMarkdownTitle(parsed2.body, fallbackName),
|
|
30586
|
+
status: formatRalphDetail(parsed2.data),
|
|
30587
|
+
format: "markdown"
|
|
30588
|
+
};
|
|
30589
|
+
}
|
|
30590
|
+
const parsed = parseExperimentFrontmatter(content);
|
|
30591
|
+
const state = await readExperimentState(options.fs, options.absolutePath);
|
|
30592
|
+
return {
|
|
30593
|
+
title: deriveMarkdownTitle(parsed.body, fallbackName),
|
|
30594
|
+
status: formatExperimentDetail(parsed.frontmatter, state),
|
|
30595
|
+
format: "markdown"
|
|
30596
|
+
};
|
|
30597
|
+
}
|
|
30598
|
+
var init_format = __esm({
|
|
30599
|
+
"packages/plan-browser/src/format.ts"() {
|
|
30600
|
+
"use strict";
|
|
30601
|
+
init_src10();
|
|
30602
|
+
init_src14();
|
|
30603
|
+
init_src13();
|
|
30604
|
+
}
|
|
30605
|
+
});
|
|
30606
|
+
|
|
30607
|
+
// packages/plan-browser/src/discovery.ts
|
|
30608
|
+
import path42 from "node:path";
|
|
30609
|
+
import * as fsPromises10 from "node:fs/promises";
|
|
30610
|
+
function createDefaultFs8() {
|
|
30611
|
+
return {
|
|
30612
|
+
readFile: fsPromises10.readFile,
|
|
30613
|
+
writeFile: fsPromises10.writeFile,
|
|
30614
|
+
readdir: fsPromises10.readdir,
|
|
30615
|
+
stat: async (filePath) => {
|
|
30616
|
+
const stat14 = await fsPromises10.stat(filePath);
|
|
30617
|
+
return {
|
|
30618
|
+
isFile: () => stat14.isFile(),
|
|
30619
|
+
isDirectory: () => stat14.isDirectory(),
|
|
30620
|
+
mtimeMs: stat14.mtimeMs
|
|
30621
|
+
};
|
|
30622
|
+
},
|
|
30623
|
+
mkdir: async (directoryPath, mkdirOptions) => {
|
|
30624
|
+
await fsPromises10.mkdir(directoryPath, mkdirOptions);
|
|
30625
|
+
},
|
|
30626
|
+
rename: fsPromises10.rename,
|
|
30627
|
+
unlink: fsPromises10.unlink
|
|
30628
|
+
};
|
|
30629
|
+
}
|
|
30630
|
+
function isNotFound4(error2) {
|
|
30631
|
+
return !!error2 && typeof error2 === "object" && "code" in error2 && error2.code === "ENOENT";
|
|
30632
|
+
}
|
|
30633
|
+
function resolveAbsoluteDirectory3(dir, cwd, homeDir) {
|
|
30634
|
+
if (dir.startsWith("~/")) {
|
|
30635
|
+
return path42.join(homeDir, dir.slice(2));
|
|
30636
|
+
}
|
|
30637
|
+
return path42.isAbsolute(dir) ? dir : path42.resolve(cwd, dir);
|
|
30638
|
+
}
|
|
30639
|
+
function resolveAbsoluteDisplayPath(displayPath, cwd, homeDir) {
|
|
30640
|
+
if (displayPath.startsWith("~/")) {
|
|
30641
|
+
return path42.join(homeDir, displayPath.slice(2));
|
|
30642
|
+
}
|
|
30643
|
+
return path42.isAbsolute(displayPath) ? displayPath : path42.resolve(cwd, displayPath);
|
|
30644
|
+
}
|
|
30645
|
+
function isPipelinePlanFile(name) {
|
|
30646
|
+
const lower = name.toLowerCase();
|
|
30647
|
+
return lower.startsWith("plan") && (lower.endsWith(".yaml") || lower.endsWith(".yml"));
|
|
30648
|
+
}
|
|
30649
|
+
function isMarkdownFile2(name) {
|
|
30650
|
+
return name.toLowerCase().endsWith(".md");
|
|
30651
|
+
}
|
|
30652
|
+
async function resolvePlanDirectorySetting(options) {
|
|
30653
|
+
const envValue = options.variables?.[options.envName]?.trim();
|
|
30654
|
+
if (envValue) {
|
|
30655
|
+
return envValue;
|
|
30656
|
+
}
|
|
30657
|
+
const document = await readMergedDocument(
|
|
30658
|
+
options.fs,
|
|
30659
|
+
options.configPath,
|
|
30660
|
+
options.projectConfigPath
|
|
30661
|
+
);
|
|
30662
|
+
const configured = document[options.scope]?.plan_directory;
|
|
30663
|
+
return typeof configured === "string" && configured.trim().length > 0 ? configured.trim() : void 0;
|
|
30664
|
+
}
|
|
30665
|
+
async function scanDirectory(options) {
|
|
30666
|
+
let entries;
|
|
30667
|
+
try {
|
|
30668
|
+
entries = await options.fs.readdir(options.absoluteDir);
|
|
30669
|
+
} catch (error2) {
|
|
30670
|
+
if (isNotFound4(error2)) {
|
|
30671
|
+
return [];
|
|
30672
|
+
}
|
|
30673
|
+
throw error2;
|
|
30674
|
+
}
|
|
30675
|
+
const plans = [];
|
|
30676
|
+
for (const name of entries) {
|
|
30677
|
+
if (!options.include(name)) {
|
|
30678
|
+
continue;
|
|
30679
|
+
}
|
|
30680
|
+
const absolutePath = path42.join(options.absoluteDir, name);
|
|
30681
|
+
const stat14 = await options.fs.stat(absolutePath);
|
|
30682
|
+
if (!stat14.isFile()) {
|
|
30683
|
+
continue;
|
|
30684
|
+
}
|
|
30685
|
+
const displayPath = path42.join(options.displayDir, name);
|
|
30686
|
+
const metadata = await readPlanMetadata({
|
|
30687
|
+
source: options.source,
|
|
30688
|
+
absolutePath,
|
|
30689
|
+
path: displayPath,
|
|
30690
|
+
fs: options.fs
|
|
30691
|
+
});
|
|
30692
|
+
plans.push({
|
|
30693
|
+
path: displayPath,
|
|
30694
|
+
absolutePath: resolveAbsoluteDisplayPath(displayPath, options.cwd, options.homeDir),
|
|
30695
|
+
source: options.source,
|
|
30696
|
+
format: metadata.format,
|
|
30697
|
+
title: metadata.title,
|
|
30698
|
+
status: metadata.status,
|
|
30699
|
+
updatedAt: stat14.mtimeMs
|
|
30700
|
+
});
|
|
30701
|
+
}
|
|
30702
|
+
return plans;
|
|
30703
|
+
}
|
|
30704
|
+
async function discoverPipelinePlans(options) {
|
|
30705
|
+
const configuredDir = await resolvePlanDirectorySetting({
|
|
30706
|
+
fs: options.fs,
|
|
30707
|
+
configPath: options.configPath,
|
|
30708
|
+
projectConfigPath: options.projectConfigPath,
|
|
30709
|
+
scope: "pipeline",
|
|
30710
|
+
envName: "POE_PIPELINE_PLAN_DIRECTORY",
|
|
30711
|
+
variables: options.variables
|
|
30712
|
+
});
|
|
30713
|
+
const targets = configuredDir ? [{
|
|
30714
|
+
absoluteDir: resolveAbsoluteDirectory3(configuredDir, options.cwd, options.homeDir),
|
|
30715
|
+
displayDir: configuredDir
|
|
30716
|
+
}] : [
|
|
30717
|
+
{
|
|
30718
|
+
absoluteDir: path42.join(options.cwd, ".poe-code", "pipeline", "plans"),
|
|
30719
|
+
displayDir: ".poe-code/pipeline/plans"
|
|
30720
|
+
},
|
|
30721
|
+
{
|
|
30722
|
+
absoluteDir: path42.join(options.homeDir, ".poe-code", "pipeline", "plans"),
|
|
30723
|
+
displayDir: "~/.poe-code/pipeline/plans"
|
|
30724
|
+
}
|
|
30725
|
+
];
|
|
30726
|
+
const plans = await Promise.all(
|
|
30727
|
+
targets.map(
|
|
30728
|
+
(target) => scanDirectory({
|
|
30729
|
+
...target,
|
|
30730
|
+
fs: options.fs,
|
|
30731
|
+
source: "pipeline",
|
|
30732
|
+
include: isPipelinePlanFile,
|
|
30733
|
+
cwd: options.cwd,
|
|
30734
|
+
homeDir: options.homeDir
|
|
30735
|
+
})
|
|
30736
|
+
)
|
|
30737
|
+
);
|
|
30738
|
+
return plans.flat();
|
|
30739
|
+
}
|
|
30740
|
+
async function discoverExperimentPlans(options) {
|
|
30741
|
+
const configuredDir = await resolvePlanDirectorySetting({
|
|
30742
|
+
fs: options.fs,
|
|
30743
|
+
configPath: options.configPath,
|
|
30744
|
+
projectConfigPath: options.projectConfigPath,
|
|
30745
|
+
scope: "experiment",
|
|
30746
|
+
envName: "POE_EXPERIMENT_PLAN_DIRECTORY",
|
|
30747
|
+
variables: options.variables
|
|
30748
|
+
});
|
|
30749
|
+
const targets = configuredDir ? [{
|
|
30750
|
+
absoluteDir: resolveAbsoluteDirectory3(configuredDir, options.cwd, options.homeDir),
|
|
30751
|
+
displayDir: configuredDir
|
|
30752
|
+
}] : [
|
|
30753
|
+
{
|
|
30754
|
+
absoluteDir: path42.join(options.cwd, ".poe-code", "experiments"),
|
|
30755
|
+
displayDir: ".poe-code/experiments"
|
|
30756
|
+
},
|
|
30757
|
+
{
|
|
30758
|
+
absoluteDir: path42.join(options.homeDir, ".poe-code", "experiments"),
|
|
30759
|
+
displayDir: "~/.poe-code/experiments"
|
|
30760
|
+
}
|
|
30761
|
+
];
|
|
30762
|
+
const plans = await Promise.all(
|
|
30763
|
+
targets.map(
|
|
30764
|
+
(target) => scanDirectory({
|
|
30765
|
+
...target,
|
|
30766
|
+
fs: options.fs,
|
|
30767
|
+
source: "experiment",
|
|
30768
|
+
include: isMarkdownFile2,
|
|
30769
|
+
cwd: options.cwd,
|
|
30770
|
+
homeDir: options.homeDir
|
|
30771
|
+
})
|
|
30772
|
+
)
|
|
30773
|
+
);
|
|
30774
|
+
return plans.flat();
|
|
30775
|
+
}
|
|
30776
|
+
async function discoverRalphPlans(options) {
|
|
30777
|
+
const configuredDir = await resolvePlanDirectorySetting({
|
|
30778
|
+
fs: options.fs,
|
|
30779
|
+
configPath: options.configPath,
|
|
30780
|
+
projectConfigPath: options.projectConfigPath,
|
|
30781
|
+
scope: "ralph",
|
|
30782
|
+
envName: "POE_RALPH_PLAN_DIRECTORY",
|
|
30783
|
+
variables: options.variables
|
|
30784
|
+
});
|
|
30785
|
+
const docs = await discoverDocs({
|
|
30786
|
+
cwd: options.cwd,
|
|
30787
|
+
homeDir: options.homeDir,
|
|
30788
|
+
planDirectory: configuredDir,
|
|
30789
|
+
fs: {
|
|
30790
|
+
readdir: options.fs.readdir,
|
|
30791
|
+
stat: async (filePath) => {
|
|
30792
|
+
const stat14 = await options.fs.stat(filePath);
|
|
30793
|
+
return {
|
|
30794
|
+
isFile: () => stat14.isFile(),
|
|
30795
|
+
mtimeMs: stat14.mtimeMs
|
|
30796
|
+
};
|
|
30797
|
+
}
|
|
30798
|
+
}
|
|
30799
|
+
});
|
|
30800
|
+
const plans = await Promise.all(
|
|
30801
|
+
docs.map(async (doc) => {
|
|
30802
|
+
const absolutePath = resolveAbsoluteDisplayPath(doc.path, options.cwd, options.homeDir);
|
|
30803
|
+
const stat14 = await options.fs.stat(absolutePath);
|
|
30804
|
+
const metadata = await readPlanMetadata({
|
|
30805
|
+
source: "ralph",
|
|
30806
|
+
absolutePath,
|
|
30807
|
+
path: doc.path,
|
|
30808
|
+
fs: options.fs
|
|
30809
|
+
});
|
|
30810
|
+
return {
|
|
30811
|
+
path: doc.path,
|
|
30812
|
+
absolutePath,
|
|
30813
|
+
source: "ralph",
|
|
30814
|
+
format: metadata.format,
|
|
30815
|
+
title: metadata.title,
|
|
30816
|
+
status: metadata.status,
|
|
30817
|
+
updatedAt: stat14.mtimeMs
|
|
30818
|
+
};
|
|
30819
|
+
})
|
|
30820
|
+
);
|
|
30821
|
+
return plans;
|
|
30822
|
+
}
|
|
30823
|
+
async function discoverAllPlans(options) {
|
|
30824
|
+
const fs3 = options.fs ?? createDefaultFs8();
|
|
30825
|
+
const discoverers = {
|
|
30826
|
+
pipeline: () => discoverPipelinePlans({ ...options, fs: fs3 }),
|
|
30827
|
+
experiment: () => discoverExperimentPlans({ ...options, fs: fs3 }),
|
|
30828
|
+
ralph: () => discoverRalphPlans({ ...options, fs: fs3 })
|
|
30829
|
+
};
|
|
30830
|
+
const sources = options.source ? [options.source] : Object.keys(discoverers);
|
|
30831
|
+
const results = (await Promise.all(sources.map((source) => discoverers[source]()))).flat();
|
|
30832
|
+
const deduped = /* @__PURE__ */ new Map();
|
|
30833
|
+
for (const result of results) {
|
|
30834
|
+
if (!deduped.has(result.absolutePath)) {
|
|
30835
|
+
deduped.set(result.absolutePath, result);
|
|
30836
|
+
}
|
|
30837
|
+
}
|
|
30838
|
+
return [...deduped.values()].sort((left, right) => {
|
|
30839
|
+
if (right.updatedAt !== left.updatedAt) {
|
|
30840
|
+
return right.updatedAt - left.updatedAt;
|
|
30841
|
+
}
|
|
30842
|
+
return left.path.localeCompare(right.path);
|
|
30843
|
+
});
|
|
30844
|
+
}
|
|
30845
|
+
var init_discovery3 = __esm({
|
|
30846
|
+
"packages/plan-browser/src/discovery.ts"() {
|
|
30847
|
+
"use strict";
|
|
30848
|
+
init_src13();
|
|
30849
|
+
init_src4();
|
|
30850
|
+
init_format();
|
|
30851
|
+
}
|
|
30852
|
+
});
|
|
30853
|
+
|
|
30854
|
+
// packages/plan-browser/src/actions.ts
|
|
30855
|
+
import path43 from "node:path";
|
|
30856
|
+
import { spawnSync as nodeSpawnSync } from "node:child_process";
|
|
30857
|
+
function resolveEditor2(env = process.env) {
|
|
30858
|
+
const editor = env.EDITOR?.trim() || env.VISUAL?.trim() || "vi";
|
|
30859
|
+
return editor.length > 0 ? editor : "vi";
|
|
30860
|
+
}
|
|
30861
|
+
function editPlan(absolutePath, options = {}) {
|
|
30862
|
+
const editor = resolveEditor2(options.env);
|
|
30863
|
+
const spawnSync3 = options.spawnSync ?? nodeSpawnSync;
|
|
30864
|
+
spawnSync3(editor, [absolutePath], { stdio: "inherit" });
|
|
30865
|
+
}
|
|
30866
|
+
async function archivePlan3(entry, fs3) {
|
|
30867
|
+
const archiveDir = path43.join(path43.dirname(entry.absolutePath), "archive");
|
|
30868
|
+
const archivedPath = path43.join(archiveDir, path43.basename(entry.absolutePath));
|
|
30869
|
+
await fs3.mkdir(archiveDir, { recursive: true });
|
|
30870
|
+
await fs3.rename(entry.absolutePath, archivedPath);
|
|
30871
|
+
return archivedPath;
|
|
30872
|
+
}
|
|
30873
|
+
async function deletePlan(entry, fs3) {
|
|
30874
|
+
await fs3.unlink(entry.absolutePath);
|
|
30875
|
+
}
|
|
30876
|
+
var init_actions = __esm({
|
|
30877
|
+
"packages/plan-browser/src/actions.ts"() {
|
|
30878
|
+
"use strict";
|
|
30879
|
+
}
|
|
30880
|
+
});
|
|
30881
|
+
|
|
30882
|
+
// packages/plan-browser/src/browser.ts
|
|
30883
|
+
import path44 from "node:path";
|
|
30884
|
+
async function runPlanBrowser(options) {
|
|
30885
|
+
const renderPlanPreview = async (entry) => {
|
|
30886
|
+
const markdown = await loadPlanPreviewMarkdown(entry, options.fs);
|
|
30887
|
+
process.stdout.write(`${renderMarkdown(markdown).trimEnd()}
|
|
30888
|
+
`);
|
|
30889
|
+
};
|
|
30890
|
+
while (true) {
|
|
30891
|
+
const plans = await discoverAllPlans({
|
|
30892
|
+
cwd: options.cwd,
|
|
30893
|
+
homeDir: options.homeDir,
|
|
30894
|
+
configPath: options.configPath,
|
|
30895
|
+
projectConfigPath: options.projectConfigPath,
|
|
30896
|
+
fs: options.fs,
|
|
30897
|
+
source: options.source,
|
|
30898
|
+
variables: options.variables
|
|
30899
|
+
});
|
|
30900
|
+
if (plans.length === 0) {
|
|
30901
|
+
process.stdout.write("No plans found.\n");
|
|
30902
|
+
return;
|
|
30903
|
+
}
|
|
30904
|
+
if (options.assumeYes) {
|
|
30905
|
+
const selectedPlan2 = plans[0];
|
|
30906
|
+
await renderPlanPreview(selectedPlan2);
|
|
30907
|
+
return;
|
|
30908
|
+
}
|
|
30909
|
+
const selectedPath = await select2({
|
|
30910
|
+
message: "Select a plan",
|
|
30911
|
+
options: plans.map((plan) => ({
|
|
30912
|
+
label: text.selectLabel(path44.basename(plan.path), plan.status),
|
|
30913
|
+
hint: plan.source,
|
|
30914
|
+
value: plan.absolutePath
|
|
30915
|
+
}))
|
|
30916
|
+
});
|
|
30917
|
+
if (Ct(selectedPath)) {
|
|
30918
|
+
return;
|
|
30919
|
+
}
|
|
30920
|
+
const selectedPlan = plans.find((plan) => plan.absolutePath === selectedPath);
|
|
30921
|
+
if (!selectedPlan) {
|
|
30922
|
+
cancel("Plan selection cancelled.");
|
|
30923
|
+
return;
|
|
30924
|
+
}
|
|
30925
|
+
await renderPlanPreview(selectedPlan);
|
|
30926
|
+
process.stdout.write("\n");
|
|
30927
|
+
const action = await select2({
|
|
30928
|
+
message: "Action",
|
|
30929
|
+
options: [
|
|
30930
|
+
{ label: "Back to list", value: "back" },
|
|
30931
|
+
{ label: "Edit in $EDITOR", value: "edit" },
|
|
30932
|
+
{ label: "Archive", value: "archive" },
|
|
30933
|
+
{ label: "Delete", value: "delete" }
|
|
30934
|
+
]
|
|
30935
|
+
});
|
|
30936
|
+
if (Ct(action) || action === "back") {
|
|
30937
|
+
continue;
|
|
30938
|
+
}
|
|
30939
|
+
if (action === "edit") {
|
|
30940
|
+
editPlan(selectedPlan.absolutePath, {
|
|
30941
|
+
env: options.variables ?? process.env
|
|
30942
|
+
});
|
|
30943
|
+
continue;
|
|
30944
|
+
}
|
|
30945
|
+
if (action === "archive") {
|
|
30946
|
+
try {
|
|
30947
|
+
const confirmed = options.assumeYes || await confirmOrCancel({
|
|
30948
|
+
message: `Archive ${path44.basename(selectedPlan.path)}?`,
|
|
30949
|
+
initialValue: true
|
|
30950
|
+
});
|
|
30951
|
+
if (confirmed) {
|
|
30952
|
+
await archivePlan3(selectedPlan, options.fs);
|
|
30953
|
+
}
|
|
30954
|
+
} catch (error2) {
|
|
30955
|
+
if (!(error2 instanceof PromptCancelledError)) {
|
|
30956
|
+
throw error2;
|
|
30957
|
+
}
|
|
30958
|
+
}
|
|
30959
|
+
continue;
|
|
30960
|
+
}
|
|
30961
|
+
try {
|
|
30962
|
+
const confirmed = options.assumeYes || await confirmOrCancel({
|
|
30963
|
+
message: `Permanently delete ${path44.basename(selectedPlan.path)}?`,
|
|
30964
|
+
initialValue: true
|
|
30965
|
+
});
|
|
30966
|
+
if (confirmed) {
|
|
30967
|
+
await deletePlan(selectedPlan, options.fs);
|
|
30968
|
+
}
|
|
30969
|
+
} catch (error2) {
|
|
30970
|
+
if (!(error2 instanceof PromptCancelledError)) {
|
|
30971
|
+
throw error2;
|
|
30972
|
+
}
|
|
30973
|
+
}
|
|
30974
|
+
}
|
|
30975
|
+
}
|
|
30976
|
+
var init_browser = __esm({
|
|
30977
|
+
"packages/plan-browser/src/browser.ts"() {
|
|
30978
|
+
"use strict";
|
|
30979
|
+
init_src5();
|
|
30980
|
+
init_src5();
|
|
30981
|
+
init_actions();
|
|
30982
|
+
init_discovery3();
|
|
30983
|
+
init_format();
|
|
30984
|
+
}
|
|
30985
|
+
});
|
|
30986
|
+
|
|
30987
|
+
// packages/plan-browser/src/index.ts
|
|
30988
|
+
var init_src23 = __esm({
|
|
30989
|
+
"packages/plan-browser/src/index.ts"() {
|
|
30990
|
+
"use strict";
|
|
30991
|
+
init_discovery3();
|
|
30992
|
+
init_actions();
|
|
30993
|
+
init_format();
|
|
30994
|
+
init_browser();
|
|
30995
|
+
}
|
|
30996
|
+
});
|
|
30997
|
+
|
|
30998
|
+
// src/cli/commands/plan.ts
|
|
30999
|
+
import path45 from "node:path";
|
|
31000
|
+
function resolvePlanCommandOptions(command) {
|
|
31001
|
+
const localOptions = command.opts();
|
|
31002
|
+
const parentOptions = command.parent?.opts() ?? {};
|
|
31003
|
+
return {
|
|
31004
|
+
source: localOptions.source ?? parentOptions.source,
|
|
31005
|
+
output: localOptions.output ?? parentOptions.output
|
|
31006
|
+
};
|
|
31007
|
+
}
|
|
31008
|
+
function resolveOutputOption(value) {
|
|
31009
|
+
if (!value || value.trim().length === 0) {
|
|
31010
|
+
return "terminal";
|
|
31011
|
+
}
|
|
31012
|
+
const normalized = value.trim().toLowerCase();
|
|
31013
|
+
if (normalized === "json") {
|
|
31014
|
+
return "json";
|
|
31015
|
+
}
|
|
31016
|
+
if (normalized === "md" || normalized === "markdown") {
|
|
31017
|
+
return "markdown";
|
|
31018
|
+
}
|
|
31019
|
+
if (normalized === "terminal") {
|
|
31020
|
+
return "terminal";
|
|
31021
|
+
}
|
|
31022
|
+
throw new ValidationError(`Invalid --output value "${value}". Expected one of: terminal, md, json.`);
|
|
31023
|
+
}
|
|
31024
|
+
function resolveSource(value) {
|
|
31025
|
+
if (!value || value.trim().length === 0) {
|
|
31026
|
+
return void 0;
|
|
31027
|
+
}
|
|
31028
|
+
if (value === "pipeline" || value === "experiment" || value === "ralph") {
|
|
31029
|
+
return value;
|
|
31030
|
+
}
|
|
31031
|
+
throw new ValidationError(`Invalid --source value "${value}". Expected pipeline, experiment, or ralph.`);
|
|
31032
|
+
}
|
|
31033
|
+
function formatDate2(timestamp) {
|
|
31034
|
+
return new Date(timestamp).toISOString().slice(0, 10);
|
|
31035
|
+
}
|
|
31036
|
+
async function discoverPlans(container, source) {
|
|
31037
|
+
return discoverAllPlans({
|
|
31038
|
+
cwd: container.env.cwd,
|
|
31039
|
+
homeDir: container.env.homeDir,
|
|
31040
|
+
configPath: container.env.configPath,
|
|
31041
|
+
projectConfigPath: container.env.projectConfigPath,
|
|
31042
|
+
fs: container.fs,
|
|
31043
|
+
source,
|
|
31044
|
+
variables: container.env.variables
|
|
31045
|
+
});
|
|
31046
|
+
}
|
|
31047
|
+
async function resolveSelectedPlan(options) {
|
|
31048
|
+
const providedPath = options.providedPath?.trim();
|
|
31049
|
+
if (providedPath) {
|
|
31050
|
+
const resolvedAbsolute = providedPath.startsWith("~/") ? path45.join(options.container.env.homeDir, providedPath.slice(2)) : path45.isAbsolute(providedPath) ? providedPath : path45.resolve(options.container.env.cwd, providedPath);
|
|
31051
|
+
const matched2 = options.plans.find(
|
|
31052
|
+
(plan) => plan.path === providedPath || plan.absolutePath === providedPath || plan.absolutePath === resolvedAbsolute
|
|
31053
|
+
);
|
|
31054
|
+
if (!matched2) {
|
|
31055
|
+
throw new ValidationError(`Plan not found: ${providedPath}`);
|
|
31056
|
+
}
|
|
31057
|
+
return matched2;
|
|
31058
|
+
}
|
|
31059
|
+
if (options.plans.length === 0) {
|
|
31060
|
+
throw new ValidationError("No plans found.");
|
|
31061
|
+
}
|
|
31062
|
+
if (options.assumeYes) {
|
|
31063
|
+
return options.plans[0];
|
|
31064
|
+
}
|
|
31065
|
+
const selected = await select2({
|
|
31066
|
+
message: options.promptMessage,
|
|
31067
|
+
options: options.plans.map((plan) => ({
|
|
31068
|
+
label: text.selectLabel(path45.basename(plan.path), plan.status),
|
|
31069
|
+
hint: plan.source,
|
|
31070
|
+
value: plan.absolutePath
|
|
31071
|
+
}))
|
|
31072
|
+
});
|
|
31073
|
+
if (Ct(selected)) {
|
|
31074
|
+
throw new ValidationError("Plan selection cancelled.");
|
|
31075
|
+
}
|
|
31076
|
+
const matched = options.plans.find((plan) => plan.absolutePath === selected);
|
|
31077
|
+
if (!matched) {
|
|
31078
|
+
throw new ValidationError("Plan selection cancelled.");
|
|
31079
|
+
}
|
|
31080
|
+
return matched;
|
|
31081
|
+
}
|
|
31082
|
+
function writeOutput(format, value) {
|
|
31083
|
+
if (format === "terminal") {
|
|
31084
|
+
process.stdout.write(value.endsWith("\n") ? value : `${value}
|
|
31085
|
+
`);
|
|
31086
|
+
return;
|
|
31087
|
+
}
|
|
31088
|
+
const scopedFormat = format === "markdown" ? "markdown" : "json";
|
|
31089
|
+
withOutputFormat(scopedFormat, () => {
|
|
31090
|
+
process.stdout.write(value.endsWith("\n") ? value : `${value}
|
|
31091
|
+
`);
|
|
31092
|
+
});
|
|
31093
|
+
}
|
|
31094
|
+
async function renderPlanList(container, options) {
|
|
31095
|
+
const format = resolveOutputOption(options.output);
|
|
31096
|
+
const source = resolveSource(options.source);
|
|
31097
|
+
const plans = await discoverPlans(container, source);
|
|
31098
|
+
if (format === "json") {
|
|
31099
|
+
writeOutput(
|
|
31100
|
+
format,
|
|
31101
|
+
JSON.stringify(
|
|
31102
|
+
plans.map((plan) => ({
|
|
31103
|
+
source: plan.source,
|
|
31104
|
+
name: path45.basename(plan.path),
|
|
31105
|
+
path: plan.path,
|
|
31106
|
+
detail: plan.status,
|
|
31107
|
+
updated: formatDate2(plan.updatedAt)
|
|
31108
|
+
})),
|
|
31109
|
+
null,
|
|
31110
|
+
2
|
|
31111
|
+
)
|
|
31112
|
+
);
|
|
31113
|
+
return;
|
|
31114
|
+
}
|
|
31115
|
+
const table = withOutputFormat(
|
|
31116
|
+
format,
|
|
31117
|
+
() => renderTable({
|
|
31118
|
+
theme: getTheme(),
|
|
31119
|
+
columns: [
|
|
31120
|
+
{ name: "source", title: "Source", alignment: "left", maxLen: 12 },
|
|
31121
|
+
{ name: "name", title: "Name", alignment: "left", maxLen: 32 },
|
|
31122
|
+
{ name: "detail", title: "Detail", alignment: "left", maxLen: 40 },
|
|
31123
|
+
{ name: "updated", title: "Updated", alignment: "left", maxLen: 12 }
|
|
31124
|
+
],
|
|
31125
|
+
rows: plans.map((plan) => ({
|
|
31126
|
+
source: plan.source,
|
|
31127
|
+
name: path45.basename(plan.path),
|
|
31128
|
+
detail: plan.status,
|
|
31129
|
+
updated: formatDate2(plan.updatedAt)
|
|
31130
|
+
}))
|
|
31131
|
+
})
|
|
31132
|
+
);
|
|
31133
|
+
writeOutput(format, table);
|
|
31134
|
+
}
|
|
31135
|
+
async function executePlanAction(options) {
|
|
31136
|
+
intro(`plan ${options.action}`);
|
|
31137
|
+
const flags = resolveCommandFlags(options.program);
|
|
31138
|
+
const format = resolveOutputOption(options.output);
|
|
31139
|
+
const plans = await discoverPlans(options.container, resolveSource(options.source));
|
|
31140
|
+
const plan = await resolveSelectedPlan({
|
|
31141
|
+
container: options.container,
|
|
31142
|
+
plans,
|
|
31143
|
+
providedPath: options.pathArg,
|
|
31144
|
+
assumeYes: flags.assumeYes,
|
|
31145
|
+
promptMessage: `Select a plan to ${options.action}`
|
|
31146
|
+
});
|
|
31147
|
+
if (options.action === "edit") {
|
|
31148
|
+
editPlan(plan.absolutePath, {
|
|
31149
|
+
env: options.container.env.variables
|
|
31150
|
+
});
|
|
31151
|
+
writeOutput(
|
|
31152
|
+
format,
|
|
31153
|
+
format === "json" ? JSON.stringify({ action: "edit", path: plan.path }, null, 2) : `Edited ${plan.path}`
|
|
31154
|
+
);
|
|
31155
|
+
return;
|
|
31156
|
+
}
|
|
31157
|
+
if (!flags.assumeYes) {
|
|
31158
|
+
const confirmed = await confirmOrCancel({
|
|
31159
|
+
message: options.action === "archive" ? `Archive ${path45.basename(plan.path)}?` : `Permanently delete ${path45.basename(plan.path)}?`,
|
|
31160
|
+
initialValue: true
|
|
31161
|
+
});
|
|
31162
|
+
if (!confirmed) {
|
|
31163
|
+
return;
|
|
31164
|
+
}
|
|
31165
|
+
}
|
|
31166
|
+
if (options.action === "archive") {
|
|
31167
|
+
const archivedPath = await archivePlan3(
|
|
31168
|
+
plan,
|
|
31169
|
+
options.container.fs
|
|
31170
|
+
);
|
|
31171
|
+
writeOutput(
|
|
31172
|
+
format,
|
|
31173
|
+
format === "json" ? JSON.stringify({ action: "archive", path: plan.path, archivedPath }, null, 2) : `Archived ${plan.path}`
|
|
31174
|
+
);
|
|
31175
|
+
return;
|
|
31176
|
+
}
|
|
31177
|
+
await deletePlan(
|
|
31178
|
+
plan,
|
|
31179
|
+
options.container.fs
|
|
31180
|
+
);
|
|
31181
|
+
writeOutput(
|
|
31182
|
+
format,
|
|
31183
|
+
format === "json" ? JSON.stringify({ action: "delete", path: plan.path }, null, 2) : `Deleted ${plan.path}`
|
|
31184
|
+
);
|
|
31185
|
+
}
|
|
31186
|
+
function registerPlanCommand(program, container) {
|
|
31187
|
+
const plan = program.command("plan").description("Browse, view, and manage plans across pipeline, experiment, and Ralph.").option("--source <source>", "Filter by plan source: pipeline, experiment, or ralph").action(async function() {
|
|
31188
|
+
const opts = this.opts();
|
|
31189
|
+
const flags = resolveCommandFlags(this);
|
|
31190
|
+
intro("plan browser");
|
|
31191
|
+
await runPlanBrowser({
|
|
31192
|
+
cwd: container.env.cwd,
|
|
31193
|
+
homeDir: container.env.homeDir,
|
|
31194
|
+
configPath: container.env.configPath,
|
|
31195
|
+
projectConfigPath: container.env.projectConfigPath,
|
|
31196
|
+
fs: container.fs,
|
|
31197
|
+
source: resolveSource(opts.source),
|
|
31198
|
+
variables: container.env.variables,
|
|
31199
|
+
assumeYes: flags.assumeYes
|
|
31200
|
+
});
|
|
31201
|
+
});
|
|
31202
|
+
plan.command("list").description("List plans across all plan systems.").option("--source <source>", "Filter by plan source: pipeline, experiment, or ralph").option("--output <format>", "Output format: terminal, md, or json").action(async function() {
|
|
31203
|
+
intro("plan list");
|
|
31204
|
+
await renderPlanList(container, resolvePlanCommandOptions(this));
|
|
31205
|
+
});
|
|
31206
|
+
plan.command("view").description("Render a single plan to the terminal.").argument("[path]", "Plan path").option("--source <source>", "Filter by plan source: pipeline, experiment, or ralph").option("--output <format>", "Output format: terminal, md, or json").action(async function(pathArg) {
|
|
31207
|
+
intro("plan view");
|
|
31208
|
+
const flags = resolveCommandFlags(program);
|
|
31209
|
+
const options = resolvePlanCommandOptions(this);
|
|
31210
|
+
const format = resolveOutputOption(options.output);
|
|
31211
|
+
const plans = await discoverPlans(container, resolveSource(options.source));
|
|
31212
|
+
const plan2 = await resolveSelectedPlan({
|
|
31213
|
+
container,
|
|
31214
|
+
plans,
|
|
31215
|
+
providedPath: pathArg,
|
|
31216
|
+
assumeYes: flags.assumeYes,
|
|
31217
|
+
promptMessage: "Select a plan to view"
|
|
31218
|
+
});
|
|
31219
|
+
const markdown = await loadPlanPreviewMarkdown(plan2, container.fs);
|
|
31220
|
+
if (format === "json") {
|
|
31221
|
+
writeOutput(
|
|
31222
|
+
format,
|
|
31223
|
+
JSON.stringify(
|
|
31224
|
+
{
|
|
31225
|
+
source: plan2.source,
|
|
31226
|
+
path: plan2.path,
|
|
31227
|
+
title: plan2.title,
|
|
31228
|
+
detail: plan2.status,
|
|
31229
|
+
content: markdown
|
|
31230
|
+
},
|
|
31231
|
+
null,
|
|
31232
|
+
2
|
|
31233
|
+
)
|
|
31234
|
+
);
|
|
31235
|
+
return;
|
|
31236
|
+
}
|
|
31237
|
+
const output = format === "markdown" ? markdown : renderMarkdown(markdown);
|
|
31238
|
+
writeOutput(format, output.trimEnd());
|
|
31239
|
+
});
|
|
31240
|
+
plan.command("edit").description("Open a plan in $EDITOR.").argument("[path]", "Plan path").option("--source <source>", "Filter by plan source: pipeline, experiment, or ralph").option("--output <format>", "Output format: terminal, md, or json").action(async function(pathArg) {
|
|
31241
|
+
await executePlanAction({
|
|
31242
|
+
program,
|
|
31243
|
+
container,
|
|
31244
|
+
action: "edit",
|
|
31245
|
+
pathArg,
|
|
31246
|
+
...resolvePlanCommandOptions(this)
|
|
31247
|
+
});
|
|
31248
|
+
});
|
|
31249
|
+
plan.command("archive").description("Move a plan into archive/.").argument("[path]", "Plan path").option("--source <source>", "Filter by plan source: pipeline, experiment, or ralph").option("--output <format>", "Output format: terminal, md, or json").action(async function(pathArg) {
|
|
31250
|
+
await executePlanAction({
|
|
31251
|
+
program,
|
|
31252
|
+
container,
|
|
31253
|
+
action: "archive",
|
|
31254
|
+
pathArg,
|
|
31255
|
+
...resolvePlanCommandOptions(this)
|
|
31256
|
+
});
|
|
31257
|
+
});
|
|
31258
|
+
plan.command("delete").description("Delete a plan file.").argument("[path]", "Plan path").option("--source <source>", "Filter by plan source: pipeline, experiment, or ralph").option("--output <format>", "Output format: terminal, md, or json").action(async function(pathArg) {
|
|
31259
|
+
await executePlanAction({
|
|
31260
|
+
program,
|
|
31261
|
+
container,
|
|
31262
|
+
action: "delete",
|
|
31263
|
+
pathArg,
|
|
31264
|
+
...resolvePlanCommandOptions(this)
|
|
31265
|
+
});
|
|
31266
|
+
});
|
|
31267
|
+
}
|
|
31268
|
+
var init_plan = __esm({
|
|
31269
|
+
"src/cli/commands/plan.ts"() {
|
|
31270
|
+
"use strict";
|
|
31271
|
+
init_src5();
|
|
31272
|
+
init_src23();
|
|
31273
|
+
init_errors();
|
|
31274
|
+
init_shared();
|
|
31275
|
+
}
|
|
31276
|
+
});
|
|
31277
|
+
|
|
31278
|
+
// src/cli/commands/ralph.ts
|
|
31279
|
+
import path46 from "node:path";
|
|
30434
31280
|
function formatDuration2(ms) {
|
|
30435
31281
|
const totalSeconds = Math.round(ms / 1e3);
|
|
30436
31282
|
const minutes = Math.floor(totalSeconds / 60);
|
|
@@ -30466,9 +31312,9 @@ function normalizeConfiguredIterations(value) {
|
|
|
30466
31312
|
}
|
|
30467
31313
|
function resolveAbsoluteDocPath4(container, docPath) {
|
|
30468
31314
|
if (docPath.startsWith("~/")) {
|
|
30469
|
-
return
|
|
31315
|
+
return path46.join(container.env.homeDir, docPath.slice(2));
|
|
30470
31316
|
}
|
|
30471
|
-
return
|
|
31317
|
+
return path46.isAbsolute(docPath) ? docPath : path46.resolve(container.env.cwd, docPath);
|
|
30472
31318
|
}
|
|
30473
31319
|
async function resolvePlanDirectory2(container) {
|
|
30474
31320
|
const configDoc = await readMergedDocument(
|
|
@@ -30839,11 +31685,11 @@ var init_ralph3 = __esm({
|
|
|
30839
31685
|
});
|
|
30840
31686
|
|
|
30841
31687
|
// src/cli/commands/experiment.ts
|
|
30842
|
-
import
|
|
30843
|
-
import { readFile as readFile15, stat as
|
|
31688
|
+
import path47 from "node:path";
|
|
31689
|
+
import { readFile as readFile15, stat as stat13 } from "node:fs/promises";
|
|
30844
31690
|
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
30845
31691
|
function resolveExperimentPaths(scope, cwd, homeDir) {
|
|
30846
|
-
const rootPath = scope === "global" ?
|
|
31692
|
+
const rootPath = scope === "global" ? path47.join(homeDir, ".poe-code", "experiments") : path47.join(cwd, ".poe-code", "experiments");
|
|
30847
31693
|
const displayRoot = scope === "global" ? "~/.poe-code/experiments" : ".poe-code/experiments";
|
|
30848
31694
|
return {
|
|
30849
31695
|
experimentsPath: rootPath,
|
|
@@ -30852,7 +31698,7 @@ function resolveExperimentPaths(scope, cwd, homeDir) {
|
|
|
30852
31698
|
}
|
|
30853
31699
|
async function pathExistsOnDisk2(targetPath) {
|
|
30854
31700
|
try {
|
|
30855
|
-
await
|
|
31701
|
+
await stat13(targetPath);
|
|
30856
31702
|
return true;
|
|
30857
31703
|
} catch (error2) {
|
|
30858
31704
|
if (error2 && typeof error2 === "object" && "code" in error2 && error2.code === "ENOENT") {
|
|
@@ -30862,12 +31708,12 @@ async function pathExistsOnDisk2(targetPath) {
|
|
|
30862
31708
|
}
|
|
30863
31709
|
}
|
|
30864
31710
|
async function findPackageRoot2(entryFilePath) {
|
|
30865
|
-
let currentPath =
|
|
31711
|
+
let currentPath = path47.dirname(entryFilePath);
|
|
30866
31712
|
while (true) {
|
|
30867
|
-
if (await pathExistsOnDisk2(
|
|
31713
|
+
if (await pathExistsOnDisk2(path47.join(currentPath, "package.json"))) {
|
|
30868
31714
|
return currentPath;
|
|
30869
31715
|
}
|
|
30870
|
-
const parentPath =
|
|
31716
|
+
const parentPath = path47.dirname(currentPath);
|
|
30871
31717
|
if (parentPath === currentPath) {
|
|
30872
31718
|
throw new Error("Unable to locate package root for Experiment templates.");
|
|
30873
31719
|
}
|
|
@@ -30880,16 +31726,16 @@ async function loadExperimentTemplates() {
|
|
|
30880
31726
|
}
|
|
30881
31727
|
const packageRoot = await findPackageRoot2(fileURLToPath8(import.meta.url));
|
|
30882
31728
|
const templateRoots = [
|
|
30883
|
-
|
|
30884
|
-
|
|
31729
|
+
path47.join(packageRoot, "src", "templates", "experiment"),
|
|
31730
|
+
path47.join(packageRoot, "dist", "templates", "experiment")
|
|
30885
31731
|
];
|
|
30886
31732
|
for (const templateRoot of templateRoots) {
|
|
30887
31733
|
if (!await pathExistsOnDisk2(templateRoot)) {
|
|
30888
31734
|
continue;
|
|
30889
31735
|
}
|
|
30890
31736
|
const [skillPlan, runYaml] = await Promise.all([
|
|
30891
|
-
readFile15(
|
|
30892
|
-
readFile15(
|
|
31737
|
+
readFile15(path47.join(templateRoot, "SKILL_experiment.md"), "utf8"),
|
|
31738
|
+
readFile15(path47.join(templateRoot, "run.yaml.hbs"), "utf8")
|
|
30893
31739
|
]);
|
|
30894
31740
|
experimentTemplatesCache = { skillPlan, runYaml };
|
|
30895
31741
|
return experimentTemplatesCache;
|
|
@@ -30976,15 +31822,15 @@ async function resolveExperimentPlanDirectory(container) {
|
|
|
30976
31822
|
}
|
|
30977
31823
|
function resolveAbsoluteDocPath5(container, docPath) {
|
|
30978
31824
|
if (docPath.startsWith("~/")) {
|
|
30979
|
-
return
|
|
31825
|
+
return path47.join(container.env.homeDir, docPath.slice(2));
|
|
30980
31826
|
}
|
|
30981
|
-
return
|
|
31827
|
+
return path47.isAbsolute(docPath) ? docPath : path47.resolve(container.env.cwd, docPath);
|
|
30982
31828
|
}
|
|
30983
|
-
function
|
|
31829
|
+
function resolveAbsoluteDirectory4(dir, cwd, homeDir) {
|
|
30984
31830
|
if (dir.startsWith("~/")) {
|
|
30985
|
-
return
|
|
31831
|
+
return path47.join(homeDir, dir.slice(2));
|
|
30986
31832
|
}
|
|
30987
|
-
return
|
|
31833
|
+
return path47.isAbsolute(dir) ? dir : path47.resolve(cwd, dir);
|
|
30988
31834
|
}
|
|
30989
31835
|
async function scanExperimentDir(container, absoluteDir, displayDir) {
|
|
30990
31836
|
let names;
|
|
@@ -31001,12 +31847,12 @@ async function scanExperimentDir(container, absoluteDir, displayDir) {
|
|
|
31001
31847
|
if (!name.endsWith(".md")) {
|
|
31002
31848
|
continue;
|
|
31003
31849
|
}
|
|
31004
|
-
const absolutePath =
|
|
31850
|
+
const absolutePath = path47.join(absoluteDir, name);
|
|
31005
31851
|
const fileStat = await container.fs.stat(absolutePath);
|
|
31006
31852
|
if (!fileStat.isFile()) {
|
|
31007
31853
|
continue;
|
|
31008
31854
|
}
|
|
31009
|
-
const displayPath =
|
|
31855
|
+
const displayPath = path47.join(displayDir, name);
|
|
31010
31856
|
docs.push({ path: displayPath, displayPath });
|
|
31011
31857
|
}
|
|
31012
31858
|
return docs;
|
|
@@ -31014,12 +31860,12 @@ async function scanExperimentDir(container, absoluteDir, displayDir) {
|
|
|
31014
31860
|
async function discoverExperimentDocs(container, planDirectory) {
|
|
31015
31861
|
const customDir = planDirectory?.trim();
|
|
31016
31862
|
if (customDir) {
|
|
31017
|
-
const absoluteDir =
|
|
31863
|
+
const absoluteDir = resolveAbsoluteDirectory4(customDir, container.env.cwd, container.env.homeDir);
|
|
31018
31864
|
return scanExperimentDir(container, absoluteDir, customDir);
|
|
31019
31865
|
}
|
|
31020
31866
|
return scanExperimentDir(
|
|
31021
31867
|
container,
|
|
31022
|
-
|
|
31868
|
+
path47.join(container.env.cwd, EXPERIMENTS_DIRECTORY),
|
|
31023
31869
|
EXPERIMENTS_DIRECTORY
|
|
31024
31870
|
);
|
|
31025
31871
|
}
|
|
@@ -31396,12 +32242,12 @@ function registerExperimentCommand(program, container) {
|
|
|
31396
32242
|
scope = selected;
|
|
31397
32243
|
}
|
|
31398
32244
|
resources.logger.intro(`experiment install (${support.id}, ${scope})`);
|
|
31399
|
-
const
|
|
32245
|
+
const templates2 = await loadExperimentTemplates();
|
|
31400
32246
|
const skillResult = await installSkill(
|
|
31401
32247
|
support.id,
|
|
31402
32248
|
{
|
|
31403
32249
|
name: "poe-code-experiment-plan",
|
|
31404
|
-
content:
|
|
32250
|
+
content: templates2.skillPlan
|
|
31405
32251
|
},
|
|
31406
32252
|
{
|
|
31407
32253
|
fs: container.fs,
|
|
@@ -31435,13 +32281,13 @@ function registerExperimentCommand(program, container) {
|
|
|
31435
32281
|
);
|
|
31436
32282
|
}
|
|
31437
32283
|
}
|
|
31438
|
-
const runYamlPath =
|
|
31439
|
-
const runYamlDisplayPath =
|
|
32284
|
+
const runYamlPath = path47.join(experimentPaths.experimentsPath, "run.yaml");
|
|
32285
|
+
const runYamlDisplayPath = path47.join(experimentPaths.displayExperimentsPath, "run.yaml");
|
|
31440
32286
|
if (!await pathExists4(container.fs, runYamlPath)) {
|
|
31441
32287
|
if (flags.dryRun) {
|
|
31442
32288
|
resources.logger.dryRun(`Would create: ${runYamlDisplayPath}`);
|
|
31443
32289
|
} else {
|
|
31444
|
-
await container.fs.writeFile(runYamlPath,
|
|
32290
|
+
await container.fs.writeFile(runYamlPath, templates2.runYaml);
|
|
31445
32291
|
resources.logger.info(`Create: ${runYamlDisplayPath}`);
|
|
31446
32292
|
}
|
|
31447
32293
|
}
|
|
@@ -31470,7 +32316,7 @@ var init_experiment2 = __esm({
|
|
|
31470
32316
|
init_src4();
|
|
31471
32317
|
DEFAULT_EXPERIMENT_AGENT = "claude-code";
|
|
31472
32318
|
DEFAULT_EXPERIMENT_SCOPE = "local";
|
|
31473
|
-
EXPERIMENTS_DIRECTORY =
|
|
32319
|
+
EXPERIMENTS_DIRECTORY = path47.join(".poe-code", "experiments");
|
|
31474
32320
|
experimentTemplatesCache = null;
|
|
31475
32321
|
}
|
|
31476
32322
|
});
|
|
@@ -31902,7 +32748,7 @@ var init_package = __esm({
|
|
|
31902
32748
|
"package.json"() {
|
|
31903
32749
|
package_default = {
|
|
31904
32750
|
name: "poe-code",
|
|
31905
|
-
version: "3.0.
|
|
32751
|
+
version: "3.0.156",
|
|
31906
32752
|
description: "CLI tool to configure Poe API for developer workflows.",
|
|
31907
32753
|
type: "module",
|
|
31908
32754
|
main: "./dist/index.js",
|
|
@@ -32010,6 +32856,7 @@ var init_package = __esm({
|
|
|
32010
32856
|
"@poe-code/e2e-docker-test-runner": "*",
|
|
32011
32857
|
"@poe-code/experiment-loop": "*",
|
|
32012
32858
|
"@poe-code/github-workflows": "*",
|
|
32859
|
+
"@poe-code/plan-browser": "*",
|
|
32013
32860
|
"@poe-code/pipeline": "*",
|
|
32014
32861
|
"@poe-code/poe-acp-client": "*",
|
|
32015
32862
|
"@poe-code/poe-agent": "*",
|
|
@@ -32077,22 +32924,22 @@ function formatCommandHeader(cmd) {
|
|
|
32077
32924
|
}
|
|
32078
32925
|
return `Poe - ${parts.reverse().join(" ")}`;
|
|
32079
32926
|
}
|
|
32080
|
-
function findCommandByPath(root,
|
|
32927
|
+
function findCommandByPath(root, path48) {
|
|
32081
32928
|
let current = root;
|
|
32082
|
-
for (const segment of
|
|
32929
|
+
for (const segment of path48) {
|
|
32083
32930
|
const next = current.commands.find(
|
|
32084
32931
|
(command) => Reflect.get(command, "_hidden") !== true && command.name() === segment
|
|
32085
32932
|
);
|
|
32086
32933
|
if (!next) {
|
|
32087
|
-
throw new Error(`Root help command is missing: ${
|
|
32934
|
+
throw new Error(`Root help command is missing: ${path48.join(" ")}`);
|
|
32088
32935
|
}
|
|
32089
32936
|
current = next;
|
|
32090
32937
|
}
|
|
32091
32938
|
return current;
|
|
32092
32939
|
}
|
|
32093
|
-
function formatRootHelpCommandName(
|
|
32940
|
+
function formatRootHelpCommandName(path48, command) {
|
|
32094
32941
|
const leaf = [command.name(), ...command.aliases()].join(", ");
|
|
32095
|
-
return
|
|
32942
|
+
return path48.length > 1 ? [...path48.slice(0, -1), leaf].join(" ") : leaf;
|
|
32096
32943
|
}
|
|
32097
32944
|
function splitUsageParts(usage) {
|
|
32098
32945
|
return usage.split(" ").map((part) => part.trim()).filter((part) => part.length > 0);
|
|
@@ -32309,6 +33156,7 @@ function bootstrapProgram(container) {
|
|
|
32309
33156
|
registerMcpCommand(program, container);
|
|
32310
33157
|
registerSkillCommand(program, container);
|
|
32311
33158
|
registerPipelineCommand(program, container);
|
|
33159
|
+
registerPlanCommand(program, container);
|
|
32312
33160
|
registerRalphCommand(program, container);
|
|
32313
33161
|
registerExperimentCommand(program, container);
|
|
32314
33162
|
registerLaunchCommand(program, container);
|
|
@@ -32381,6 +33229,7 @@ var init_program = __esm({
|
|
|
32381
33229
|
init_usage();
|
|
32382
33230
|
init_models2();
|
|
32383
33231
|
await init_pipeline3();
|
|
33232
|
+
init_plan();
|
|
32384
33233
|
await init_ralph3();
|
|
32385
33234
|
await init_experiment2();
|
|
32386
33235
|
init_launch2();
|
|
@@ -32407,6 +33256,7 @@ var init_program = __esm({
|
|
|
32407
33256
|
{ path: ["pipeline", "install"] },
|
|
32408
33257
|
{ path: ["pipeline", "run"] },
|
|
32409
33258
|
{ path: ["pipeline", "validate"] },
|
|
33259
|
+
{ path: ["plan"] },
|
|
32410
33260
|
{ path: ["experiment", "install"] },
|
|
32411
33261
|
{ path: ["experiment", "run"] },
|
|
32412
33262
|
{ path: ["experiment", "journal"] },
|