poe-code 3.0.129 → 3.0.130

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/index.js CHANGED
@@ -8154,7 +8154,7 @@ function interpolate(template, values) {
8154
8154
  }
8155
8155
  return output;
8156
8156
  }
8157
- async function resolveFileIncludes(template, cwd, readFile14) {
8157
+ async function resolveFileIncludes(template, cwd, readFile15) {
8158
8158
  const matches = [...template.matchAll(FILE_INCLUDE_PATTERN)];
8159
8159
  if (matches.length === 0) {
8160
8160
  return template;
@@ -8162,7 +8162,7 @@ async function resolveFileIncludes(template, cwd, readFile14) {
8162
8162
  let result = template;
8163
8163
  for (const match of matches) {
8164
8164
  const absolutePath = path14.resolve(cwd, match[1]);
8165
- const content = await readFile14(absolutePath, "utf8");
8165
+ const content = await readFile15(absolutePath, "utf8");
8166
8166
  result = result.replace(match[0], content);
8167
8167
  }
8168
8168
  return result;
@@ -8288,10 +8288,10 @@ function createDefaultFs3() {
8288
8288
  function isAbortError(error2) {
8289
8289
  return error2 instanceof Error && error2.name === "AbortError";
8290
8290
  }
8291
- async function resolveVars(vars, cwd, readFile14) {
8291
+ async function resolveVars(vars, cwd, readFile15) {
8292
8292
  const resolved = {};
8293
8293
  for (const [key, value] of Object.entries(vars)) {
8294
- resolved[key] = await resolveFileIncludes(value, cwd, readFile14);
8294
+ resolved[key] = await resolveFileIncludes(value, cwd, readFile15);
8295
8295
  }
8296
8296
  return resolved;
8297
8297
  }
@@ -10640,12 +10640,6 @@ function parseExperimentFrontmatter(content) {
10640
10640
  body: parsed.content
10641
10641
  };
10642
10642
  }
10643
- async function writeExperimentFrontmatter(docPath, frontmatter, body, fs3) {
10644
- await fs3.mkdir(dirname(docPath), { recursive: true });
10645
- const serialized = matter.stringify(body, serializeFrontmatter(frontmatter));
10646
- const content = body.endsWith("\n") || !serialized.endsWith("\n") ? serialized : serialized.slice(0, -1);
10647
- await fs3.writeFile(docPath, content);
10648
- }
10649
10643
  function parseFrontmatterData2(value) {
10650
10644
  const parsed = isRecord5(value) ? value : void 0;
10651
10645
  const agent2 = parseAgent2(parsed?.agent);
@@ -10657,22 +10651,7 @@ function parseFrontmatterData2(value) {
10657
10651
  ...metric !== void 0 ? { metric } : {},
10658
10652
  baseline: parseBaseline(parsed?.baseline),
10659
10653
  ...maxExperiments !== void 0 ? { maxExperiments } : {},
10660
- ...metricTimeout !== void 0 ? { metricTimeout } : {},
10661
- status: parseStatus(parsed?.status)
10662
- };
10663
- }
10664
- function serializeFrontmatter(frontmatter) {
10665
- return {
10666
- ...frontmatter.agent !== void 0 ? { agent: frontmatter.agent } : {},
10667
- ...frontmatter.metric !== void 0 ? { metric: frontmatter.metric } : {},
10668
- baseline: frontmatter.baseline,
10669
- ...frontmatter.maxExperiments !== void 0 ? { maxExperiments: frontmatter.maxExperiments } : {},
10670
- ...frontmatter.metricTimeout !== void 0 ? { metricTimeout: frontmatter.metricTimeout } : {},
10671
- status: {
10672
- state: frontmatter.status.state,
10673
- experiment: frontmatter.status.experiment,
10674
- kept: frontmatter.status.kept
10675
- }
10654
+ ...metricTimeout !== void 0 ? { metricTimeout } : {}
10676
10655
  };
10677
10656
  }
10678
10657
  function parseMetric(value) {
@@ -10716,14 +10695,6 @@ function parseBaseline(value) {
10716
10695
  }).filter((entry) => entry !== void 0);
10717
10696
  return baselineEntries.length === Object.keys(value).length ? Object.fromEntries(baselineEntries) : null;
10718
10697
  }
10719
- function parseStatus(value) {
10720
- const parsed = isRecord5(value) ? value : void 0;
10721
- return {
10722
- state: parseString(parsed?.state) ?? DEFAULT_STATUS2.state,
10723
- experiment: parseNonNegativeInteger2(parsed?.experiment) ?? DEFAULT_STATUS2.experiment,
10724
- kept: parseNonNegativeInteger2(parsed?.kept) ?? DEFAULT_STATUS2.kept
10725
- };
10726
- }
10727
10698
  function parseAgent2(value) {
10728
10699
  if (typeof value === "string") {
10729
10700
  return parseString(value);
@@ -10754,20 +10725,23 @@ function parseNonNegativeInteger2(value) {
10754
10725
  function isRecord5(value) {
10755
10726
  return typeof value === "object" && value !== null && !Array.isArray(value);
10756
10727
  }
10757
- var DEFAULT_STATUS2;
10758
10728
  var init_frontmatter2 = __esm({
10759
10729
  "packages/experiment-loop/src/frontmatter/frontmatter.ts"() {
10760
10730
  "use strict";
10761
- DEFAULT_STATUS2 = {
10762
- state: "open",
10763
- experiment: 0,
10764
- kept: 0
10765
- };
10766
10731
  }
10767
10732
  });
10768
10733
 
10769
10734
  // packages/experiment-loop/src/journal/journal.ts
10770
10735
  import { dirname as dirname2 } from "node:path";
10736
+ function baselineFromEntry(metrics, entry) {
10737
+ if (entry.scores) {
10738
+ return entry.scores;
10739
+ }
10740
+ if (entry.score !== null && metrics.length === 1) {
10741
+ return { [metrics[0].name]: entry.score };
10742
+ }
10743
+ return null;
10744
+ }
10771
10745
  function parseLine(line) {
10772
10746
  try {
10773
10747
  return [JSON.parse(line)];
@@ -10833,6 +10807,20 @@ var init_journal = __esm({
10833
10807
  }
10834
10808
  return content.split("\n").filter((line) => line.length > 0).flatMap((line) => parseLine(line));
10835
10809
  }
10810
+ async updateLast(updates) {
10811
+ const entries = await this.readAll();
10812
+ if (entries.length === 0) {
10813
+ return null;
10814
+ }
10815
+ const last = entries[entries.length - 1];
10816
+ const updated = { ...last, ...updates };
10817
+ entries[entries.length - 1] = updated;
10818
+ await this.fs.writeFile(
10819
+ this.journalPath,
10820
+ entries.map((e) => JSON.stringify(e)).join("\n") + "\n"
10821
+ );
10822
+ return updated;
10823
+ }
10836
10824
  async format() {
10837
10825
  const entries = await this.readAll();
10838
10826
  return [
@@ -10919,20 +10907,6 @@ async function readCurrentHash(exec3, cwd) {
10919
10907
  }
10920
10908
  function createDefaultGit(exec3) {
10921
10909
  return {
10922
- async commitAll(message2, cwd) {
10923
- await runOrThrow(exec3, `git add -A -- . ':!${EXPERIMENT_DOCS_PATH}'`, cwd);
10924
- const diffResult = await exec3("git diff --cached --quiet", { cwd });
10925
- if (diffResult.exitCode === 0) {
10926
- return readCurrentHash(exec3, cwd);
10927
- }
10928
- if (diffResult.exitCode !== 1) {
10929
- throw new Error(
10930
- diffResult.stderr || diffResult.stdout || "Failed to detect staged git changes"
10931
- );
10932
- }
10933
- await runOrThrow(exec3, `git commit -m ${shellEscape(message2)}`, cwd);
10934
- return readCurrentHash(exec3, cwd);
10935
- },
10936
10910
  async reset(commitHash, cwd) {
10937
10911
  const stashResult = await exec3(
10938
10912
  `git stash push -q --include-untracked -- ${EXPERIMENT_DOCS_PATH}`,
@@ -10959,6 +10933,8 @@ var init_git = __esm({
10959
10933
 
10960
10934
  // packages/experiment-loop/src/config/loader.ts
10961
10935
  import path23 from "node:path";
10936
+ import { readFile as readFile5 } from "node:fs/promises";
10937
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
10962
10938
  import { parse as parse7 } from "yaml";
10963
10939
  function isRecord6(value) {
10964
10940
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -10996,8 +10972,20 @@ function parseRunConfigDocument(filePath, content) {
10996
10972
  }
10997
10973
  return { prompt };
10998
10974
  }
10999
- function defaultRunConfig() {
11000
- return { prompt: DEFAULT_PROMPT };
10975
+ async function readBundledFile(name) {
10976
+ const filePath = fileURLToPath2(new URL(`./${name}`, import.meta.url));
10977
+ return readFile5(filePath, "utf8");
10978
+ }
10979
+ async function readDefaultRunConfig() {
10980
+ const content = await readBundledFile("default-run.yaml");
10981
+ const config = parseRunConfigDocument("default-run.yaml", content);
10982
+ if (!config) {
10983
+ throw new Error("default-run.yaml is empty or invalid.");
10984
+ }
10985
+ return config;
10986
+ }
10987
+ async function loadInstructions() {
10988
+ return readBundledFile("default-instructions.md");
11001
10989
  }
11002
10990
  async function loadRunConfig(options) {
11003
10991
  const projectPath = path23.join(options.cwd, ".poe-code", "experiments", "run.yaml");
@@ -11016,26 +11004,11 @@ async function loadRunConfig(options) {
11016
11004
  return config;
11017
11005
  }
11018
11006
  }
11019
- return defaultRunConfig();
11007
+ return readDefaultRunConfig();
11020
11008
  }
11021
- var DEFAULT_PROMPT;
11022
11009
  var init_loader2 = __esm({
11023
11010
  "packages/experiment-loop/src/config/loader.ts"() {
11024
11011
  "use strict";
11025
- DEFAULT_PROMPT = `{{body}}
11026
-
11027
- ## Metrics
11028
-
11029
- {{metrics}}
11030
-
11031
- ## Journal
11032
-
11033
- {{journal}}
11034
-
11035
- {{crash_output}}
11036
-
11037
- You are autonomous, do not stop or ask for input.
11038
- Do not write to the journal file or commit changes. Both are managed automatically after your run completes.`;
11039
11012
  }
11040
11013
  });
11041
11014
 
@@ -11135,9 +11108,6 @@ function createAbortError5() {
11135
11108
  function isAbortError3(error2) {
11136
11109
  return error2 instanceof Error && error2.name === "AbortError";
11137
11110
  }
11138
- function combineOutput(stdout, stderr) {
11139
- return `${stdout}${stderr}`;
11140
- }
11141
11111
  function interpolate2(template, values) {
11142
11112
  let output = template;
11143
11113
  for (const [key, value] of Object.entries(values)) {
@@ -11160,41 +11130,25 @@ function formatMetrics(metrics, baseline) {
11160
11130
  }).join("\n");
11161
11131
  }
11162
11132
  function buildPrompt(options) {
11163
- return interpolate2(options.runConfig.prompt, {
11133
+ const vars = {
11164
11134
  body: options.body.trim(),
11165
11135
  journal: options.journal,
11166
11136
  metrics: formatMetrics(options.metrics, options.baseline),
11167
- crash_output: options.lastCrashOutput ? `## Last crash output
11168
-
11169
- ${options.lastCrashOutput.trim()}` : "",
11170
11137
  experiment_index: String(options.experimentIndex),
11171
- baseline: options.baseline ? JSON.stringify(options.baseline) : ""
11172
- }).trim();
11138
+ baseline: options.baseline ? JSON.stringify(options.baseline) : "",
11139
+ doc_path: options.docPath,
11140
+ doc_name: options.docName
11141
+ };
11142
+ const context = interpolate2(options.runConfig.prompt, vars).trim();
11143
+ const instructions = interpolate2(options.instructions, vars).trim();
11144
+ return `${context}
11145
+
11146
+ ${instructions}`;
11173
11147
  }
11174
11148
  function allMetricsPassed(metrics, results) {
11175
11149
  return results.length === metrics.length && results.every((result) => result.passed);
11176
11150
  }
11177
- function allScoresImproved(metrics, results, baseline) {
11178
- return metrics.every((metric, index) => {
11179
- const score = results[index]?.score;
11180
- if (score === null || score === void 0) {
11181
- return false;
11182
- }
11183
- const baselineScore = baseline?.[metric.name];
11184
- if (baselineScore === void 0) {
11185
- return true;
11186
- }
11187
- const delta = metric.delta;
11188
- if (metric.direction === "stable") {
11189
- return delta !== void 0 ? Math.abs(score - baselineScore) <= delta : score === baselineScore;
11190
- }
11191
- if (metric.direction === "maximize") {
11192
- return delta !== void 0 ? score >= baselineScore - delta : score > baselineScore;
11193
- }
11194
- return delta !== void 0 ? score <= baselineScore + delta : score < baselineScore;
11195
- });
11196
- }
11197
- function updateBaseline(metrics, results) {
11151
+ function baselineFromResults(metrics, results) {
11198
11152
  return Object.fromEntries(
11199
11153
  metrics.map((metric, index) => {
11200
11154
  const score = results[index]?.score;
@@ -11205,53 +11159,16 @@ function updateBaseline(metrics, results) {
11205
11159
  })
11206
11160
  );
11207
11161
  }
11208
- function formatEvaluationOutput(metrics, results) {
11209
- return metrics.map((metric, index) => {
11210
- const result = results[index];
11211
- if (!result) {
11212
- return `${metric.name}: not_run`;
11213
- }
11214
- return [
11215
- `${metric.name}: score=${result.score === null ? "null" : result.score}, passed=${String(result.passed)}`,
11216
- result.output.trim()
11217
- ].filter((entry) => entry.length > 0).join("\n");
11218
- }).join("\n\n");
11219
- }
11220
- function selectJournalScore(metrics, results) {
11221
- if (metrics.length !== 1) {
11222
- return null;
11223
- }
11224
- return results[0]?.score ?? null;
11225
- }
11226
- function createEntry(options) {
11162
+ function deriveStateFromJournal(entries, metrics) {
11163
+ const keepEntries = entries.filter((e) => e.status === "keep");
11164
+ const lastKeep = keepEntries[keepEntries.length - 1];
11227
11165
  return {
11228
- commit: options.commit,
11229
- status: options.status,
11230
- score: options.score,
11231
- output: options.output,
11232
- agentOutput: options.agentOutput,
11233
- durationMs: options.durationMs,
11234
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
11166
+ experimentsCompleted: entries.length,
11167
+ experimentsKept: keepEntries.length,
11168
+ baseline: lastKeep ? baselineFromEntry(metrics, lastKeep) : null,
11169
+ baselineHash: lastKeep?.commit
11235
11170
  };
11236
11171
  }
11237
- async function persistDoc(options) {
11238
- const rawContent = await options.fs.readFile(options.docPath, "utf8");
11239
- const { frontmatter, body } = parseExperimentFrontmatter(rawContent);
11240
- await writeExperimentFrontmatter(
11241
- options.docPath,
11242
- {
11243
- ...frontmatter,
11244
- baseline: options.baseline,
11245
- status: {
11246
- ...frontmatter.status,
11247
- experiment: options.experimentsCompleted,
11248
- kept: options.experimentsKept
11249
- }
11250
- },
11251
- body,
11252
- options.fs
11253
- );
11254
- }
11255
11172
  async function runExperimentLoop(options) {
11256
11173
  const fs3 = options.fs ?? createDefaultFs6();
11257
11174
  const exec3 = options.exec ?? createDefaultExec();
@@ -11263,35 +11180,35 @@ async function runExperimentLoop(options) {
11263
11180
  const absoluteDocPath = resolveAbsoluteDocPath2(options.docPath, options.cwd, options.homeDir);
11264
11181
  const journal = new ExperimentJournal(resolveJournalPath(absoluteDocPath), fs3);
11265
11182
  await journal.init();
11266
- const runConfig = await loadRunConfig({ cwd: options.cwd, homeDir: options.homeDir, fs: fs3 });
11183
+ const [runConfig, instructions] = await Promise.all([
11184
+ loadRunConfig({ cwd: options.cwd, homeDir: options.homeDir, fs: fs3 }),
11185
+ loadInstructions()
11186
+ ]);
11267
11187
  const startTime = Date.now();
11268
11188
  async function readDoc() {
11269
11189
  const rawContent = await fs3.readFile(absoluteDocPath, "utf8");
11270
11190
  return parseExperimentFrontmatter(rawContent);
11271
11191
  }
11272
- let { frontmatter, body } = await readDoc();
11273
- let experimentsCompleted = 0;
11274
- let experimentsKept = 0;
11275
- let lastCrashOutput;
11276
- let baselineHash;
11277
- if (frontmatter.baseline === null) {
11278
- const metrics = normalizeMetrics(frontmatter.metric);
11279
- const metricTimeoutMs = frontmatter.metricTimeout ? frontmatter.metricTimeout * 1e3 : void 0;
11280
- const baselineResults = await evaluateChain(metrics, options.cwd, exec3, options.onMetricResult, metricTimeoutMs);
11281
- if (allMetricsPassed(metrics, baselineResults)) {
11282
- const baseline = updateBaseline(metrics, baselineResults);
11192
+ const { frontmatter: initialFrontmatter } = await readDoc();
11193
+ const initialMetrics = normalizeMetrics(initialFrontmatter.metric);
11194
+ const journalEntries = await journal.readAll();
11195
+ const journalState = deriveStateFromJournal(journalEntries, initialMetrics);
11196
+ let experimentsCompleted = journalState.experimentsCompleted;
11197
+ let experimentsKept = journalState.experimentsKept;
11198
+ let baselineHash = journalState.baselineHash;
11199
+ let baseline = journalState.baseline ?? initialFrontmatter.baseline;
11200
+ if (baseline === null) {
11201
+ const metricTimeoutMs = initialFrontmatter.metricTimeout ? initialFrontmatter.metricTimeout * 1e3 : void 0;
11202
+ const baselineResults = await evaluateChain(
11203
+ initialMetrics,
11204
+ options.cwd,
11205
+ exec3,
11206
+ options.onMetricResult,
11207
+ metricTimeoutMs
11208
+ );
11209
+ if (allMetricsPassed(initialMetrics, baselineResults)) {
11210
+ baseline = baselineFromResults(initialMetrics, baselineResults);
11283
11211
  options.onBaselineCollected?.(baseline);
11284
- frontmatter = {
11285
- ...frontmatter,
11286
- baseline
11287
- };
11288
- await persistDoc({
11289
- fs: fs3,
11290
- docPath: absoluteDocPath,
11291
- baseline: frontmatter.baseline,
11292
- experimentsCompleted,
11293
- experimentsKept
11294
- });
11295
11212
  }
11296
11213
  }
11297
11214
  async function finalize(stopReason) {
@@ -11307,8 +11224,7 @@ async function runExperimentLoop(options) {
11307
11224
  while (true) {
11308
11225
  assertNotAborted3(options.signal);
11309
11226
  const doc = await readDoc();
11310
- body = doc.body;
11311
- frontmatter = doc.frontmatter;
11227
+ const { body, frontmatter } = doc;
11312
11228
  const maxExperiments = validateMaxExperiments(
11313
11229
  options.maxExperiments ?? frontmatter.maxExperiments
11314
11230
  );
@@ -11317,20 +11233,21 @@ async function runExperimentLoop(options) {
11317
11233
  }
11318
11234
  const metrics = normalizeMetrics(frontmatter.metric);
11319
11235
  const agents = normalizeAgents2(options.agent ?? frontmatter.agent);
11320
- const metricTimeoutMs = frontmatter.metricTimeout ? frontmatter.metricTimeout * 1e3 : void 0;
11321
11236
  const experimentIndex = experimentsCompleted + 1;
11237
+ baselineHash ??= await git.currentHash(options.cwd);
11238
+ const preExperimentHash = baselineHash;
11239
+ const journalLengthBefore = (await journal.readAll()).length;
11322
11240
  const prompt = buildPrompt({
11323
11241
  runConfig,
11242
+ instructions,
11324
11243
  body,
11325
11244
  journal: await journal.format(),
11326
11245
  metrics,
11327
11246
  experimentIndex,
11328
- baseline: frontmatter.baseline,
11329
- ...lastCrashOutput ? { lastCrashOutput } : {}
11247
+ baseline,
11248
+ docPath: options.docPath,
11249
+ docName: path24.basename(absoluteDocPath, path24.extname(absoluteDocPath))
11330
11250
  });
11331
- baselineHash ??= await git.currentHash(options.cwd);
11332
- const preExperimentHash = baselineHash;
11333
- const experimentStart = Date.now();
11334
11251
  const currentSpecifier = agents[(experimentIndex - 1) % agents.length];
11335
11252
  const model = currentSpecifier.model;
11336
11253
  options.onExperimentStart?.(experimentIndex, currentSpecifier.agent);
@@ -11349,108 +11266,39 @@ async function runExperimentLoop(options) {
11349
11266
  }
11350
11267
  throw error2;
11351
11268
  }
11352
- const agentOutput = combineOutput(agentResult.stdout, agentResult.stderr);
11353
- if (agentResult.exitCode !== 0) {
11354
- const entry2 = createEntry({
11355
- commit: preExperimentHash,
11356
- status: "crash",
11357
- score: null,
11358
- output: agentOutput,
11359
- agentOutput,
11360
- durationMs: Date.now() - experimentStart
11361
- });
11362
- experimentsCompleted += 1;
11363
- lastCrashOutput = entry2.output;
11364
- await journal.log(entry2);
11365
- await git.reset(preExperimentHash, options.cwd);
11366
- options.onReset?.(preExperimentHash);
11367
- options.onExperimentComplete?.(experimentIndex, entry2);
11368
- await persistDoc({
11369
- fs: fs3,
11370
- docPath: absoluteDocPath,
11371
- baseline: frontmatter.baseline,
11372
- experimentsCompleted,
11373
- experimentsKept
11374
- });
11375
- continue;
11376
- }
11377
- const commitMessage = `experiment-loop: ${path24.basename(absoluteDocPath, path24.extname(absoluteDocPath))} #${experimentIndex}`;
11378
- let commitHash;
11379
- try {
11380
- commitHash = await git.commitAll(commitMessage, options.cwd);
11381
- } catch (commitError) {
11382
- const errorMessage = commitError instanceof Error ? commitError.message : String(commitError);
11383
- options.onRecoveryAttempt?.(errorMessage);
11384
- const recoveryResult = await runAgent({
11385
- agent: currentSpecifier.agent,
11386
- prompt: `A git command failed. Fix the issue so the commit can succeed.
11387
-
11388
- Error:
11389
- ${errorMessage}`,
11390
- cwd: options.cwd,
11391
- ...model ? { model } : {},
11392
- ...options.signal ? { signal: options.signal } : {}
11393
- });
11394
- if (recoveryResult.exitCode !== 0) {
11395
- const entry2 = createEntry({
11396
- commit: preExperimentHash,
11397
- status: "crash",
11398
- score: null,
11399
- output: errorMessage,
11400
- agentOutput,
11401
- durationMs: Date.now() - experimentStart
11402
- });
11403
- experimentsCompleted += 1;
11404
- lastCrashOutput = entry2.output;
11405
- await journal.log(entry2);
11269
+ const journalAfter = await journal.readAll();
11270
+ let newEntry = journalAfter.length > journalLengthBefore ? journalAfter[journalAfter.length - 1] : null;
11271
+ experimentsCompleted += 1;
11272
+ if (newEntry && newEntry.score === null && !newEntry.scores && metrics.length > 0) {
11273
+ const metricTimeoutMs = frontmatter.metricTimeout ? frontmatter.metricTimeout * 1e3 : void 0;
11274
+ const results = await evaluateChain(
11275
+ metrics,
11276
+ options.cwd,
11277
+ exec3,
11278
+ options.onMetricResult,
11279
+ metricTimeoutMs
11280
+ );
11281
+ if (allMetricsPassed(metrics, results)) {
11282
+ const scores = baselineFromResults(metrics, results);
11283
+ const score = metrics.length === 1 ? results[0].score : null;
11284
+ newEntry = await journal.updateLast({ score, scores }) ?? newEntry;
11285
+ }
11286
+ }
11287
+ if (newEntry) {
11288
+ if (newEntry.status === "keep") {
11289
+ experimentsKept += 1;
11290
+ baselineHash = newEntry.commit;
11291
+ baseline = baselineFromEntry(metrics, newEntry) ?? baseline;
11292
+ options.onCommit?.(newEntry.commit);
11293
+ } else {
11406
11294
  await git.reset(preExperimentHash, options.cwd);
11407
11295
  options.onReset?.(preExperimentHash);
11408
- options.onExperimentComplete?.(experimentIndex, entry2);
11409
- await persistDoc({
11410
- fs: fs3,
11411
- docPath: absoluteDocPath,
11412
- baseline: frontmatter.baseline,
11413
- experimentsCompleted,
11414
- experimentsKept
11415
- });
11416
- continue;
11417
11296
  }
11418
- commitHash = await git.commitAll(commitMessage, options.cwd);
11419
- }
11420
- options.onCommit?.(commitHash);
11421
- const evaluationResults = await evaluateChain(metrics, options.cwd, exec3, options.onMetricResult, metricTimeoutMs);
11422
- const keep = allMetricsPassed(metrics, evaluationResults) && allScoresImproved(metrics, evaluationResults, frontmatter.baseline);
11423
- const entry = createEntry({
11424
- commit: commitHash,
11425
- status: keep ? "keep" : "discard",
11426
- score: selectJournalScore(metrics, evaluationResults),
11427
- output: formatEvaluationOutput(metrics, evaluationResults),
11428
- agentOutput,
11429
- durationMs: Date.now() - experimentStart
11430
- });
11431
- experimentsCompleted += 1;
11432
- await journal.log(entry);
11433
- if (keep) {
11434
- experimentsKept += 1;
11435
- frontmatter = {
11436
- ...frontmatter,
11437
- baseline: updateBaseline(metrics, evaluationResults)
11438
- };
11439
- baselineHash = commitHash;
11440
- lastCrashOutput = void 0;
11297
+ options.onExperimentComplete?.(experimentIndex, newEntry);
11441
11298
  } else {
11442
11299
  await git.reset(preExperimentHash, options.cwd);
11443
11300
  options.onReset?.(preExperimentHash);
11444
- lastCrashOutput = void 0;
11445
11301
  }
11446
- options.onExperimentComplete?.(experimentIndex, entry);
11447
- await persistDoc({
11448
- fs: fs3,
11449
- docPath: absoluteDocPath,
11450
- baseline: frontmatter.baseline,
11451
- experimentsCompleted,
11452
- experimentsKept
11453
- });
11454
11302
  }
11455
11303
  } catch (error2) {
11456
11304
  if (isAbortError3(error2)) {
@@ -11545,6 +11393,13 @@ async function readExperimentJournal(options) {
11545
11393
  const journal = new ExperimentJournal(resolveJournalPath2(absoluteDocPath), fs3);
11546
11394
  return await journal.readAll();
11547
11395
  }
11396
+ async function appendExperimentJournalEntry(options) {
11397
+ const fs3 = options.fs ?? createDefaultFs7();
11398
+ const absoluteDocPath = resolveAbsoluteDocPath3(options.docPath, options.cwd, options.homeDir);
11399
+ const journal = new ExperimentJournal(resolveJournalPath2(absoluteDocPath), fs3);
11400
+ await journal.init();
11401
+ await journal.log(options.entry);
11402
+ }
11548
11403
  var init_experiment = __esm({
11549
11404
  async "src/sdk/experiment.ts"() {
11550
11405
  "use strict";
@@ -11804,7 +11659,7 @@ var init_frontmatter3 = __esm({
11804
11659
  });
11805
11660
 
11806
11661
  // packages/github-workflows/src/discover.ts
11807
- import { readdir as readdir9, readFile as readFile7 } from "node:fs/promises";
11662
+ import { readdir as readdir9, readFile as readFile8 } from "node:fs/promises";
11808
11663
  import { join } from "node:path";
11809
11664
  async function discoverAutomations(builtInDir, projectDir) {
11810
11665
  const automationsByName = /* @__PURE__ */ new Map();
@@ -11845,7 +11700,7 @@ async function listMarkdownFiles(dir) {
11845
11700
  }
11846
11701
  }
11847
11702
  async function readAutomation(dir, fileName) {
11848
- const content = await readFile7(join(dir, fileName), "utf8");
11703
+ const content = await readFile8(join(dir, fileName), "utf8");
11849
11704
  const { frontmatter, body } = parseFrontmatter2(content);
11850
11705
  const name = fileName.slice(0, -3);
11851
11706
  return {
@@ -12042,7 +11897,7 @@ var init_src13 = __esm({
12042
11897
  });
12043
11898
 
12044
11899
  // packages/cmdkit/src/index.ts
12045
- import { fileURLToPath as fileURLToPath2 } from "node:url";
11900
+ import { fileURLToPath as fileURLToPath3 } from "node:url";
12046
11901
  function cloneScope(scope) {
12047
11902
  return scope === void 0 ? void 0 : [...scope];
12048
11903
  }
@@ -12074,7 +11929,7 @@ function cloneRequires(requires) {
12074
11929
  function parseStackPath(candidate) {
12075
11930
  if (candidate.startsWith("file://")) {
12076
11931
  try {
12077
- return fileURLToPath2(candidate);
11932
+ return fileURLToPath3(candidate);
12078
11933
  } catch {
12079
11934
  return void 0;
12080
11935
  }
@@ -12470,9 +12325,9 @@ var init_require_comment_prefix = __esm({
12470
12325
  });
12471
12326
 
12472
12327
  // packages/github-workflows/src/commands.ts
12473
- import { access, mkdir as mkdir8, readFile as readFile8, unlink as unlink2, writeFile as writeFile6 } from "node:fs/promises";
12328
+ import { access, mkdir as mkdir8, readFile as readFile9, unlink as unlink2, writeFile as writeFile6 } from "node:fs/promises";
12474
12329
  import path26 from "node:path";
12475
- import { fileURLToPath as fileURLToPath3 } from "node:url";
12330
+ import { fileURLToPath as fileURLToPath4 } from "node:url";
12476
12331
  import Mustache3 from "mustache";
12477
12332
  function formatLabel(name) {
12478
12333
  const capitalize = (s) => s.charAt(0).toUpperCase() + s.slice(1);
@@ -12490,7 +12345,7 @@ async function loadNamedAutomation(name, cwd) {
12490
12345
  }
12491
12346
  async function readBuiltInPromptFile(name) {
12492
12347
  try {
12493
- return await readFile8(path26.join(await resolveBuiltInPromptsDir(), `${name}.md`), "utf8");
12348
+ return await readFile9(path26.join(await resolveBuiltInPromptsDir(), `${name}.md`), "utf8");
12494
12349
  } catch (error2) {
12495
12350
  if (isMissingPathError2(error2)) {
12496
12351
  throw new UserError(`Automation "${name}" was not found.`);
@@ -12501,7 +12356,7 @@ async function readBuiltInPromptFile(name) {
12501
12356
  async function readBuiltInWorkflowTemplate(name, variant) {
12502
12357
  const templatePath = path26.join(await resolveBuiltInWorkflowTemplatesDir(), `${name}.${variant}.yml`);
12503
12358
  try {
12504
- const content = await readFile8(templatePath, "utf8");
12359
+ const content = await readFile9(templatePath, "utf8");
12505
12360
  const header = variant === "ejected" ? `# Auto-generated by: poe-code github-workflows install ${name}
12506
12361
  # Edit .poe-code/github-workflows/poe-code-${name}.md to customize the prompt.
12507
12362
  ` : `# Auto-generated by: poe-code github-workflows install ${name}
@@ -12718,12 +12573,12 @@ var init_commands = __esm({
12718
12573
  init_require_comment_prefix();
12719
12574
  UPSTREAM_REPO = "poe-platform/poe-code";
12720
12575
  builtInPromptsDirCandidates = [
12721
- fileURLToPath3(new URL("./prompts", import.meta.url)),
12722
- fileURLToPath3(new URL("../src/prompts", import.meta.url))
12576
+ fileURLToPath4(new URL("./prompts", import.meta.url)),
12577
+ fileURLToPath4(new URL("../src/prompts", import.meta.url))
12723
12578
  ];
12724
12579
  builtInWorkflowTemplatesDirCandidates = [
12725
- fileURLToPath3(new URL("./workflow-templates", import.meta.url)),
12726
- fileURLToPath3(new URL("../src/workflow-templates", import.meta.url))
12580
+ fileURLToPath4(new URL("./workflow-templates", import.meta.url)),
12581
+ fileURLToPath4(new URL("../src/workflow-templates", import.meta.url))
12727
12582
  ];
12728
12583
  originalMustacheEscape = Mustache3.escape;
12729
12584
  installableAutomations = [
@@ -13001,7 +12856,7 @@ var init_src15 = __esm({
13001
12856
 
13002
12857
  // src/utils/execution-context.ts
13003
12858
  import { basename as basename2, dirname as dirname3 } from "node:path";
13004
- import { fileURLToPath as fileURLToPath4 } from "node:url";
12859
+ import { fileURLToPath as fileURLToPath5 } from "node:url";
13005
12860
  function detectExecutionContext(input) {
13006
12861
  const { argv, env, moduleUrl } = input;
13007
12862
  if (isDevelopmentMode(argv, env)) {
@@ -13060,7 +12915,7 @@ function detectNpxVersion(env) {
13060
12915
  return "default";
13061
12916
  }
13062
12917
  function createDevelopmentContext(moduleUrl) {
13063
- const modulePath = fileURLToPath4(moduleUrl);
12918
+ const modulePath = fileURLToPath5(moduleUrl);
13064
12919
  const srcIndex = modulePath.lastIndexOf("/src/");
13065
12920
  const projectRoot = srcIndex !== -1 ? modulePath.substring(0, srcIndex) : dirname3(dirname3(modulePath));
13066
12921
  return {
@@ -15920,8 +15775,8 @@ var init_poe_agent_plugin_shell = __esm({
15920
15775
 
15921
15776
  // packages/poe-agent/src/system-prompt.ts
15922
15777
  import { readFileSync } from "node:fs";
15923
- import { readFile as readFile9 } from "node:fs/promises";
15924
- import { fileURLToPath as fileURLToPath5 } from "node:url";
15778
+ import { readFile as readFile10 } from "node:fs/promises";
15779
+ import { fileURLToPath as fileURLToPath6 } from "node:url";
15925
15780
  function loadSystemPromptSync() {
15926
15781
  return readFileSync(SYSTEM_PROMPT_PATH, "utf8");
15927
15782
  }
@@ -15929,7 +15784,7 @@ var SYSTEM_PROMPT_PATH;
15929
15784
  var init_system_prompt = __esm({
15930
15785
  "packages/poe-agent/src/system-prompt.ts"() {
15931
15786
  "use strict";
15932
- SYSTEM_PROMPT_PATH = fileURLToPath5(new URL("./SYSTEM_PROMPT.md", import.meta.url));
15787
+ SYSTEM_PROMPT_PATH = fileURLToPath6(new URL("./SYSTEM_PROMPT.md", import.meta.url));
15933
15788
  }
15934
15789
  });
15935
15790
 
@@ -19241,7 +19096,7 @@ var init_renderer2 = __esm({
19241
19096
  });
19242
19097
 
19243
19098
  // packages/cmdkit/src/cli.ts
19244
- import { access as access2, readFile as readFile10, writeFile as writeFile7 } from "node:fs/promises";
19099
+ import { access as access2, readFile as readFile11, writeFile as writeFile7 } from "node:fs/promises";
19245
19100
  import path32 from "node:path";
19246
19101
  import { Command as CommanderCommand, CommanderError, InvalidArgumentError, Option } from "commander";
19247
19102
  function unwrapOptional(schema) {
@@ -19817,7 +19672,7 @@ async function withOutputFormat2(output, fn) {
19817
19672
  }
19818
19673
  function createFs() {
19819
19674
  return {
19820
- readFile: async (path42, encoding = "utf8") => readFile10(path42, { encoding }),
19675
+ readFile: async (path42, encoding = "utf8") => readFile11(path42, { encoding }),
19821
19676
  writeFile: async (path42, contents) => {
19822
19677
  await writeFile7(path42, contents);
19823
19678
  },
@@ -19909,7 +19764,7 @@ function validatePresetFieldValue(value, field, presetPath) {
19909
19764
  async function loadPresetValues(fields, presetPath) {
19910
19765
  let rawPreset;
19911
19766
  try {
19912
- rawPreset = await readFile10(presetPath, {
19767
+ rawPreset = await readFile11(presetPath, {
19913
19768
  encoding: "utf8"
19914
19769
  });
19915
19770
  } catch (error2) {
@@ -20158,7 +20013,7 @@ async function loadFixtureScenario(command, selector) {
20158
20013
  const fixturePath = resolveFixturePath(commandPath);
20159
20014
  let rawFixture;
20160
20015
  try {
20161
- rawFixture = await readFile10(fixturePath, {
20016
+ rawFixture = await readFile11(fixturePath, {
20162
20017
  encoding: "utf8"
20163
20018
  });
20164
20019
  } catch {
@@ -24564,7 +24419,7 @@ var init_configs3 = __esm({
24564
24419
  });
24565
24420
 
24566
24421
  // packages/agent-skill-config/src/templates.ts
24567
- import { readFile as readFile11 } from "node:fs/promises";
24422
+ import { readFile as readFile12 } from "node:fs/promises";
24568
24423
  async function getTemplates() {
24569
24424
  if (templatesCache) {
24570
24425
  return templatesCache;
@@ -24573,7 +24428,7 @@ async function getTemplates() {
24573
24428
  "./templates/poe-generate.md",
24574
24429
  import.meta.url
24575
24430
  );
24576
- const poeGenerateTemplate = await readFile11(poeGenerateTemplateUrl, "utf8");
24431
+ const poeGenerateTemplate = await readFile12(poeGenerateTemplateUrl, "utf8");
24577
24432
  templatesCache = {
24578
24433
  "poe-generate.md": poeGenerateTemplate
24579
24434
  };
@@ -25615,8 +25470,8 @@ var init_models2 = __esm({
25615
25470
 
25616
25471
  // src/cli/commands/pipeline.ts
25617
25472
  import path39 from "node:path";
25618
- import { readFile as readFile12, stat as stat9 } from "node:fs/promises";
25619
- import { fileURLToPath as fileURLToPath6 } from "node:url";
25473
+ import { readFile as readFile13, stat as stat9 } from "node:fs/promises";
25474
+ import { fileURLToPath as fileURLToPath7 } from "node:url";
25620
25475
  async function resolvePipelinePlanDirectory(container) {
25621
25476
  const configDoc = await readMergedDocument(
25622
25477
  container.fs,
@@ -25675,7 +25530,7 @@ async function loadPipelineTemplates() {
25675
25530
  if (pipelineTemplatesCache) {
25676
25531
  return pipelineTemplatesCache;
25677
25532
  }
25678
- const packageRoot = await findPackageRoot(fileURLToPath6(import.meta.url));
25533
+ const packageRoot = await findPackageRoot(fileURLToPath7(import.meta.url));
25679
25534
  const templateRoots = [
25680
25535
  path39.join(packageRoot, "src", "templates", "pipeline"),
25681
25536
  path39.join(packageRoot, "dist", "templates", "pipeline")
@@ -25685,8 +25540,8 @@ async function loadPipelineTemplates() {
25685
25540
  continue;
25686
25541
  }
25687
25542
  const [skillPlan, steps] = await Promise.all([
25688
- readFile12(path39.join(templateRoot, "SKILL_plan.md"), "utf8"),
25689
- readFile12(path39.join(templateRoot, "steps.yaml.hbs"), "utf8")
25543
+ readFile13(path39.join(templateRoot, "SKILL_plan.md"), "utf8"),
25544
+ readFile13(path39.join(templateRoot, "steps.yaml.hbs"), "utf8")
25690
25545
  ]);
25691
25546
  pipelineTemplatesCache = { skillPlan, steps };
25692
25547
  return pipelineTemplatesCache;
@@ -25897,16 +25752,16 @@ function registerPipelineCommand(program, container) {
25897
25752
  resources.logger.success("Plan is valid.");
25898
25753
  const opts = this.opts();
25899
25754
  if (opts.preview) {
25900
- const readFile14 = container.fs.readFile.bind(container.fs);
25755
+ const readFile15 = container.fs.readFile.bind(container.fs);
25901
25756
  const resolvedVars = {};
25902
25757
  for (const [key, value] of Object.entries(plan.vars ?? {})) {
25903
- resolvedVars[key] = await resolveFileIncludes(value, container.env.cwd, readFile14);
25758
+ resolvedVars[key] = await resolveFileIncludes(value, container.env.cwd, readFile15);
25904
25759
  }
25905
25760
  const resolvedSetup = plan.setup === null ? void 0 : plan.setup ?? steps.setup;
25906
25761
  const resolvedTeardown = plan.teardown === null ? void 0 : plan.teardown ?? steps.teardown;
25907
25762
  if (resolvedSetup) {
25908
25763
  const raw = Object.keys(resolvedVars).length > 0 ? interpolate(resolvedSetup.prompt, resolvedVars) : resolvedSetup.prompt;
25909
- const expanded = await resolveFileIncludes(raw, container.env.cwd, readFile14);
25764
+ const expanded = await resolveFileIncludes(raw, container.env.cwd, readFile15);
25910
25765
  resources.logger.resolved("setup", expanded);
25911
25766
  }
25912
25767
  for (const task of plan.tasks) {
@@ -25914,7 +25769,7 @@ function registerPipelineCommand(program, container) {
25914
25769
  const expanded = await resolveFileIncludes(
25915
25770
  buildExecutionPrompt({ selection: { kind: "run", task }, steps: steps.steps, planPath: file, vars: resolvedVars }),
25916
25771
  container.env.cwd,
25917
- readFile14
25772
+ readFile15
25918
25773
  );
25919
25774
  resources.logger.resolved(`task: ${task.id} \u2014 ${task.title}`, expanded);
25920
25775
  } else {
@@ -25922,7 +25777,7 @@ function registerPipelineCommand(program, container) {
25922
25777
  const expanded = await resolveFileIncludes(
25923
25778
  buildExecutionPrompt({ selection: { kind: "run", task, stepName }, steps: steps.steps, planPath: file, vars: resolvedVars }),
25924
25779
  container.env.cwd,
25925
- readFile14
25780
+ readFile15
25926
25781
  );
25927
25782
  resources.logger.resolved(`task: ${task.id} / ${stepName}`, expanded);
25928
25783
  }
@@ -25930,7 +25785,7 @@ function registerPipelineCommand(program, container) {
25930
25785
  }
25931
25786
  if (resolvedTeardown) {
25932
25787
  const raw = Object.keys(resolvedVars).length > 0 ? interpolate(resolvedTeardown.prompt, resolvedVars) : resolvedTeardown.prompt;
25933
- const expanded = await resolveFileIncludes(raw, container.env.cwd, readFile14);
25788
+ const expanded = await resolveFileIncludes(raw, container.env.cwd, readFile15);
25934
25789
  resources.logger.resolved("teardown", expanded);
25935
25790
  }
25936
25791
  }
@@ -26498,8 +26353,8 @@ var init_ralph3 = __esm({
26498
26353
 
26499
26354
  // src/cli/commands/experiment.ts
26500
26355
  import path41 from "node:path";
26501
- import { readFile as readFile13, stat as stat10 } from "node:fs/promises";
26502
- import { fileURLToPath as fileURLToPath7 } from "node:url";
26356
+ import { readFile as readFile14, stat as stat10 } from "node:fs/promises";
26357
+ import { fileURLToPath as fileURLToPath8 } from "node:url";
26503
26358
  function resolveExperimentPaths(scope, cwd, homeDir) {
26504
26359
  const rootPath = scope === "global" ? path41.join(homeDir, ".poe-code", "experiments") : path41.join(cwd, ".poe-code", "experiments");
26505
26360
  const displayRoot = scope === "global" ? "~/.poe-code/experiments" : ".poe-code/experiments";
@@ -26536,7 +26391,7 @@ async function loadExperimentTemplates() {
26536
26391
  if (experimentTemplatesCache) {
26537
26392
  return experimentTemplatesCache;
26538
26393
  }
26539
- const packageRoot = await findPackageRoot2(fileURLToPath7(import.meta.url));
26394
+ const packageRoot = await findPackageRoot2(fileURLToPath8(import.meta.url));
26540
26395
  const templateRoots = [
26541
26396
  path41.join(packageRoot, "src", "templates", "experiment"),
26542
26397
  path41.join(packageRoot, "dist", "templates", "experiment")
@@ -26546,8 +26401,8 @@ async function loadExperimentTemplates() {
26546
26401
  continue;
26547
26402
  }
26548
26403
  const [skillPlan, runYaml] = await Promise.all([
26549
- readFile13(path41.join(templateRoot, "SKILL_experiment.md"), "utf8"),
26550
- readFile13(path41.join(templateRoot, "run.yaml.hbs"), "utf8")
26404
+ readFile14(path41.join(templateRoot, "SKILL_experiment.md"), "utf8"),
26405
+ readFile14(path41.join(templateRoot, "run.yaml.hbs"), "utf8")
26551
26406
  ]);
26552
26407
  experimentTemplatesCache = { skillPlan, runYaml };
26553
26408
  return experimentTemplatesCache;
@@ -26588,11 +26443,6 @@ function validateExperimentDoc(frontmatter) {
26588
26443
  }
26589
26444
  }
26590
26445
  }
26591
- if (frontmatter.status.kept > frontmatter.status.experiment) {
26592
- errors.push(
26593
- `Status inconsistency: kept (${frontmatter.status.kept}) exceeds experiment count (${frontmatter.status.experiment})`
26594
- );
26595
- }
26596
26446
  return errors;
26597
26447
  }
26598
26448
  function formatDuration3(ms) {
@@ -26821,7 +26671,7 @@ function registerExperimentCommand(program, container) {
26821
26671
  resources.context.finalize();
26822
26672
  }
26823
26673
  });
26824
- experiment.command("journal").description("Display the experiment journal as a table.").argument("[doc]", "Experiment doc path").action(async function(docArg) {
26674
+ const journalCommand = experiment.command("journal").description("Display the experiment journal as a table.").argument("[doc]", "Experiment doc path").action(async function(docArg) {
26825
26675
  const flags = resolveCommandFlags(program);
26826
26676
  const resources = createExecutionResources(container, flags, "experiment:journal");
26827
26677
  resources.logger.intro("experiment journal");
@@ -26872,6 +26722,60 @@ function registerExperimentCommand(program, container) {
26872
26722
  resources.context.finalize();
26873
26723
  }
26874
26724
  });
26725
+ journalCommand.command("log").description("Append an entry to the experiment journal.").argument("[doc]", "Experiment doc path").requiredOption("--status <status>", "Entry status: keep or discard").requiredOption("--commit <hash>", "Git commit hash").option("--score <number>", "Metric score (for single-metric display)").option("--scores <json>", `Multi-metric scores as JSON object, e.g. '{"tests":2}'`).option("--output <text>", "Metric output text", "").option("--duration-ms <number>", "Duration in milliseconds", "0").action(async function(docArg) {
26726
+ const flags = resolveCommandFlags(program);
26727
+ const resources = createExecutionResources(container, flags, "experiment:journal:log");
26728
+ const opts = this.opts();
26729
+ try {
26730
+ const docPath = await resolveDocPath2({
26731
+ container,
26732
+ program,
26733
+ providedDoc: docArg,
26734
+ selectMessage: "Select the experiment doc to log to:",
26735
+ cancelMessage: "Journal log cancelled."
26736
+ });
26737
+ if (!docPath) {
26738
+ return;
26739
+ }
26740
+ const status = opts.status;
26741
+ if (status !== "keep" && status !== "discard") {
26742
+ throw new ValidationError(`Invalid status "${opts.status}". Must be keep or discard.`);
26743
+ }
26744
+ const score = opts.score !== void 0 ? Number.parseFloat(opts.score) : null;
26745
+ let scores;
26746
+ if (opts.scores) {
26747
+ try {
26748
+ scores = JSON.parse(opts.scores);
26749
+ } catch {
26750
+ throw new ValidationError(`Invalid --scores JSON: ${opts.scores}`);
26751
+ }
26752
+ }
26753
+ const entry = {
26754
+ commit: opts.commit,
26755
+ status,
26756
+ score: score !== null && Number.isFinite(score) ? score : null,
26757
+ ...scores ? { scores } : {},
26758
+ output: opts.output,
26759
+ agentOutput: "",
26760
+ durationMs: Number.parseInt(opts.durationMs, 10) || 0,
26761
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
26762
+ };
26763
+ if (!flags.dryRun) {
26764
+ await appendExperimentJournalEntry({
26765
+ cwd: container.env.cwd,
26766
+ homeDir: container.env.homeDir,
26767
+ docPath,
26768
+ entry
26769
+ });
26770
+ }
26771
+ resources.context.complete({
26772
+ success: `Logged ${status} entry (commit: ${opts.commit})`,
26773
+ dry: `Would log ${status} entry (commit: ${opts.commit})`
26774
+ });
26775
+ } finally {
26776
+ resources.context.finalize();
26777
+ }
26778
+ });
26875
26779
  experiment.command("validate").description("Validate an experiment doc without running it.").argument("[doc]", "Experiment doc path").action(async function(docArg) {
26876
26780
  const flags = resolveCommandFlags(program);
26877
26781
  const resources = createExecutionResources(
@@ -27475,7 +27379,7 @@ var init_package = __esm({
27475
27379
  "package.json"() {
27476
27380
  package_default = {
27477
27381
  name: "poe-code",
27478
- version: "3.0.129",
27382
+ version: "3.0.130",
27479
27383
  description: "CLI tool to configure Poe API for developer workflows.",
27480
27384
  type: "module",
27481
27385
  main: "./dist/index.js",