poe-code 3.0.101 → 3.0.102

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
@@ -714,16 +714,16 @@ function getConfigFormat(pathOrFormat) {
714
714
  }
715
715
  return formatRegistry[formatName];
716
716
  }
717
- function detectFormat(path24) {
718
- const ext = getExtension(path24);
717
+ function detectFormat(path27) {
718
+ const ext = getExtension(path27);
719
719
  return extensionMap[ext];
720
720
  }
721
- function getExtension(path24) {
722
- const lastDot = path24.lastIndexOf(".");
721
+ function getExtension(path27) {
722
+ const lastDot = path27.lastIndexOf(".");
723
723
  if (lastDot === -1) {
724
724
  return "";
725
725
  }
726
- return path24.slice(lastDot).toLowerCase();
726
+ return path27.slice(lastDot).toLowerCase();
727
727
  }
728
728
  var formatRegistry, extensionMap;
729
729
  var init_formats = __esm({
@@ -1054,8 +1054,8 @@ async function applyChmod(mutation, context, options) {
1054
1054
  };
1055
1055
  }
1056
1056
  try {
1057
- const stat6 = await context.fs.stat(targetPath);
1058
- const currentMode = typeof stat6.mode === "number" ? stat6.mode & 511 : null;
1057
+ const stat8 = await context.fs.stat(targetPath);
1058
+ const currentMode = typeof stat8.mode === "number" ? stat8.mode & 511 : null;
1059
1059
  if (currentMode === mutation.mode) {
1060
1060
  return {
1061
1061
  outcome: { changed: false, effect: "none", detail: "noop" },
@@ -1450,38 +1450,38 @@ import { createTwoFilesPatch } from "diff";
1450
1450
  import chalk from "chalk";
1451
1451
  function createDryRunFileSystem(base, recorder) {
1452
1452
  const proxy = {
1453
- async readFile(path24, encoding) {
1453
+ async readFile(path27, encoding) {
1454
1454
  if (encoding) {
1455
- return base.readFile(path24, encoding);
1455
+ return base.readFile(path27, encoding);
1456
1456
  }
1457
- return base.readFile(path24);
1457
+ return base.readFile(path27);
1458
1458
  },
1459
- async writeFile(path24, data, options) {
1460
- const previousContent = await tryReadText(base, path24);
1459
+ async writeFile(path27, data, options) {
1460
+ const previousContent = await tryReadText(base, path27);
1461
1461
  const nextContent = formatData(data, options?.encoding);
1462
1462
  recorder.record({
1463
1463
  type: "writeFile",
1464
- path: path24,
1464
+ path: path27,
1465
1465
  nextContent,
1466
1466
  previousContent
1467
1467
  });
1468
1468
  },
1469
- async mkdir(path24, options) {
1470
- recorder.record({ type: "mkdir", path: path24, options });
1469
+ async mkdir(path27, options) {
1470
+ recorder.record({ type: "mkdir", path: path27, options });
1471
1471
  },
1472
- async stat(path24) {
1473
- return base.stat(path24);
1472
+ async stat(path27) {
1473
+ return base.stat(path27);
1474
1474
  },
1475
- async unlink(path24) {
1476
- recorder.record({ type: "unlink", path: path24 });
1475
+ async unlink(path27) {
1476
+ recorder.record({ type: "unlink", path: path27 });
1477
1477
  },
1478
- async readdir(path24) {
1479
- return base.readdir(path24);
1478
+ async readdir(path27) {
1479
+ return base.readdir(path27);
1480
1480
  }
1481
1481
  };
1482
1482
  if (typeof base.rm === "function") {
1483
- proxy.rm = async (path24, options) => {
1484
- recorder.record({ type: "rm", path: path24, options });
1483
+ proxy.rm = async (path27, options) => {
1484
+ recorder.record({ type: "rm", path: path27, options });
1485
1485
  };
1486
1486
  }
1487
1487
  if (typeof base.copyFile === "function") {
@@ -1571,8 +1571,8 @@ function describeWriteChange(previous, next) {
1571
1571
  }
1572
1572
  return "update";
1573
1573
  }
1574
- function renderWriteCommand(path24, change) {
1575
- const command = `cat > ${path24}`;
1574
+ function renderWriteCommand(path27, change) {
1575
+ const command = `cat > ${path27}`;
1576
1576
  if (change === "create") {
1577
1577
  return renderOperationCommand(command, chalk.green, "# create");
1578
1578
  }
@@ -1734,9 +1734,9 @@ function redactTomlLine(line) {
1734
1734
  }
1735
1735
  return line;
1736
1736
  }
1737
- async function tryReadText(base, path24) {
1737
+ async function tryReadText(base, path27) {
1738
1738
  try {
1739
- return await base.readFile(path24, "utf8");
1739
+ return await base.readFile(path27, "utf8");
1740
1740
  } catch (error2) {
1741
1741
  if (isNotFound(error2)) {
1742
1742
  return null;
@@ -3730,21 +3730,21 @@ async function* adaptClaude(lines) {
3730
3730
  if (blockType !== "tool_result") continue;
3731
3731
  const kind = toolKindsById.get(item.tool_use_id);
3732
3732
  toolKindsById.delete(item.tool_use_id);
3733
- let path24;
3733
+ let path27;
3734
3734
  if (typeof item.content === "string") {
3735
- path24 = item.content;
3735
+ path27 = item.content;
3736
3736
  } else {
3737
3737
  try {
3738
- path24 = JSON.stringify(item.content);
3738
+ path27 = JSON.stringify(item.content);
3739
3739
  } catch {
3740
- path24 = String(item.content);
3740
+ path27 = String(item.content);
3741
3741
  }
3742
3742
  }
3743
3743
  yield {
3744
3744
  event: "tool_complete",
3745
3745
  id: item.tool_use_id,
3746
3746
  kind,
3747
- path: path24
3747
+ path: path27
3748
3748
  };
3749
3749
  }
3750
3750
  }
@@ -3866,10 +3866,10 @@ async function* adaptCodex(lines) {
3866
3866
  const kindFromStart = toolKindById.get(item.id);
3867
3867
  const kind = kindFromStart ?? (itemType === "command_execution" ? "exec" : itemType === "file_edit" ? "edit" : "other");
3868
3868
  const titleFromEvent = isNonEmptyString(item.path) ? item.path : itemType === "mcp_tool_call" ? `${isNonEmptyString(item.server) ? item.server : "unknown"}.${isNonEmptyString(item.tool) ? item.tool : "unknown"}` : void 0;
3869
- const path24 = titleFromEvent ?? toolTitleById.get(item.id) ?? "";
3869
+ const path27 = titleFromEvent ?? toolTitleById.get(item.id) ?? "";
3870
3870
  toolTitleById.delete(item.id);
3871
3871
  toolKindById.delete(item.id);
3872
- yield { event: "tool_complete", id: item.id, kind, path: path24 };
3872
+ yield { event: "tool_complete", id: item.id, kind, path: path27 };
3873
3873
  }
3874
3874
  }
3875
3875
  }
@@ -4311,7 +4311,7 @@ function updateSessionFromEvent(ctx, event, toolCallsById) {
4311
4311
  }
4312
4312
  const id = readString(event.id);
4313
4313
  const kind = readString(event.kind);
4314
- const path24 = readString(event.path);
4314
+ const path27 = readString(event.path);
4315
4315
  let toolCall = id ? toolCallsById.get(id) : void 0;
4316
4316
  if (!toolCall) {
4317
4317
  toolCall = {};
@@ -4326,8 +4326,8 @@ function updateSessionFromEvent(ctx, event, toolCallsById) {
4326
4326
  if (kind) {
4327
4327
  toolCall.kind = kind;
4328
4328
  }
4329
- if (path24) {
4330
- toolCall.path = path24;
4329
+ if (path27) {
4330
+ toolCall.path = path27;
4331
4331
  }
4332
4332
  }
4333
4333
  var sessionCapture;
@@ -4835,15 +4835,142 @@ var init_spawn_core = __esm({
4835
4835
  }
4836
4836
  });
4837
4837
 
4838
- // src/cli/environment.ts
4838
+ // packages/poe-code-config/src/schema.ts
4839
+ var init_schema = __esm({
4840
+ "packages/poe-code-config/src/schema.ts"() {
4841
+ "use strict";
4842
+ }
4843
+ });
4844
+
4845
+ // packages/poe-code-config/src/store.ts
4839
4846
  import path7 from "node:path";
4847
+ async function readDocument(fs3, filePath) {
4848
+ try {
4849
+ const raw = await fs3.readFile(filePath, "utf8");
4850
+ return await parseDocument(fs3, filePath, raw);
4851
+ } catch (error2) {
4852
+ if (isNotFound(error2)) {
4853
+ return {};
4854
+ }
4855
+ throw error2;
4856
+ }
4857
+ }
4858
+ async function writeScope(fs3, filePath, scope, values) {
4859
+ const document = await readDocument(fs3, filePath);
4860
+ const normalizedValues = normalizeScopeValues(values);
4861
+ if (Object.keys(normalizedValues).length === 0) {
4862
+ delete document[scope];
4863
+ } else {
4864
+ document[scope] = normalizedValues;
4865
+ }
4866
+ await writeDocument(fs3, filePath, document);
4867
+ }
4868
+ async function parseDocument(fs3, filePath, raw) {
4869
+ try {
4870
+ return normalizeDocument(JSON.parse(raw));
4871
+ } catch (error2) {
4872
+ if (error2 instanceof SyntaxError) {
4873
+ await recoverInvalidDocument(fs3, filePath, raw);
4874
+ return {};
4875
+ }
4876
+ throw error2;
4877
+ }
4878
+ }
4879
+ function normalizeDocument(value) {
4880
+ if (!isRecord2(value)) {
4881
+ return {};
4882
+ }
4883
+ const document = {};
4884
+ for (const [scope, scopeValues] of Object.entries(value)) {
4885
+ const normalizedValues = normalizeScopeValues(scopeValues);
4886
+ if (Object.keys(normalizedValues).length > 0) {
4887
+ document[scope] = normalizedValues;
4888
+ }
4889
+ }
4890
+ return document;
4891
+ }
4892
+ function normalizeScopeValues(value) {
4893
+ if (!isRecord2(value)) {
4894
+ return {};
4895
+ }
4896
+ const normalized = {};
4897
+ for (const [key, entry] of Object.entries(value)) {
4898
+ if (entry !== void 0) {
4899
+ normalized[key] = entry;
4900
+ }
4901
+ }
4902
+ return normalized;
4903
+ }
4904
+ async function writeDocument(fs3, filePath, document) {
4905
+ await fs3.mkdir(path7.dirname(filePath), { recursive: true });
4906
+ await fs3.writeFile(filePath, `${JSON.stringify(document, null, 2)}
4907
+ `, {
4908
+ encoding: "utf8"
4909
+ });
4910
+ }
4911
+ async function recoverInvalidDocument(fs3, filePath, content) {
4912
+ await fs3.mkdir(path7.dirname(filePath), { recursive: true });
4913
+ const backupPath = createInvalidBackupPath(filePath);
4914
+ await fs3.writeFile(backupPath, content, { encoding: "utf8" });
4915
+ await fs3.writeFile(filePath, EMPTY_DOCUMENT, { encoding: "utf8" });
4916
+ }
4917
+ function createInvalidBackupPath(filePath) {
4918
+ const directory = path7.dirname(filePath);
4919
+ const baseName = path7.basename(filePath);
4920
+ return path7.join(directory, `${baseName}.invalid-${createTimestamp()}.json`);
4921
+ }
4922
+ function isRecord2(value) {
4923
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
4924
+ }
4925
+ function resolveConfigPath(homeDir) {
4926
+ return path7.join(homeDir, ".poe-code", "config.json");
4927
+ }
4928
+ var EMPTY_DOCUMENT;
4929
+ var init_store = __esm({
4930
+ "packages/poe-code-config/src/store.ts"() {
4931
+ "use strict";
4932
+ init_src2();
4933
+ EMPTY_DOCUMENT = `${JSON.stringify({}, null, 2)}
4934
+ `;
4935
+ }
4936
+ });
4937
+
4938
+ // packages/poe-code-config/src/resolve.ts
4939
+ var init_resolve = __esm({
4940
+ "packages/poe-code-config/src/resolve.ts"() {
4941
+ "use strict";
4942
+ }
4943
+ });
4944
+
4945
+ // packages/poe-code-config/src/config.ts
4946
+ var init_config = __esm({
4947
+ "packages/poe-code-config/src/config.ts"() {
4948
+ "use strict";
4949
+ init_store();
4950
+ init_resolve();
4951
+ }
4952
+ });
4953
+
4954
+ // packages/poe-code-config/src/index.ts
4955
+ var init_src6 = __esm({
4956
+ "packages/poe-code-config/src/index.ts"() {
4957
+ "use strict";
4958
+ init_schema();
4959
+ init_config();
4960
+ init_resolve();
4961
+ init_store();
4962
+ }
4963
+ });
4964
+
4965
+ // src/cli/environment.ts
4966
+ import path8 from "node:path";
4840
4967
  function createCliEnvironment(init) {
4841
4968
  const platform = init.platform ?? process.platform;
4842
4969
  const variables = init.variables ?? process.env;
4843
4970
  const configPath = resolveConfigPath(init.homeDir);
4844
4971
  const logDir = resolveLogDir(init.homeDir);
4845
4972
  const { poeApiBaseUrl, poeBaseUrl } = resolvePoeBaseUrls(variables);
4846
- const resolveHomePath = (...segments) => path7.join(init.homeDir, ...segments);
4973
+ const resolveHomePath = (...segments) => path8.join(init.homeDir, ...segments);
4847
4974
  const getVariable = (name) => variables[name];
4848
4975
  return {
4849
4976
  cwd: init.cwd,
@@ -4858,11 +4985,8 @@ function createCliEnvironment(init) {
4858
4985
  getVariable
4859
4986
  };
4860
4987
  }
4861
- function resolveConfigPath(homeDir) {
4862
- return path7.join(homeDir, ".poe-code", "config.json");
4863
- }
4864
4988
  function resolveLogDir(homeDir) {
4865
- return path7.join(homeDir, ".poe-code", "logs");
4989
+ return path8.join(homeDir, ".poe-code", "logs");
4866
4990
  }
4867
4991
  function resolvePoeBaseUrls(variables) {
4868
4992
  const raw = variables.POE_BASE_URL;
@@ -4941,6 +5065,7 @@ var DEFAULT_POE_API_BASE_URL;
4941
5065
  var init_environment = __esm({
4942
5066
  "src/cli/environment.ts"() {
4943
5067
  "use strict";
5068
+ init_src6();
4944
5069
  DEFAULT_POE_API_BASE_URL = "https://api.poe.com/v1";
4945
5070
  }
4946
5071
  });
@@ -5555,7 +5680,7 @@ var init_logger2 = __esm({
5555
5680
  });
5556
5681
 
5557
5682
  // src/cli/error-logger.ts
5558
- import path8 from "node:path";
5683
+ import path9 from "node:path";
5559
5684
  var DEFAULT_MAX_SIZE, DEFAULT_MAX_BACKUPS, ErrorLogger;
5560
5685
  var init_error_logger = __esm({
5561
5686
  "src/cli/error-logger.ts"() {
@@ -5572,7 +5697,7 @@ var init_error_logger = __esm({
5572
5697
  fileLoggingAvailable;
5573
5698
  constructor(options) {
5574
5699
  this.fs = options.fs;
5575
- this.logFilePath = path8.join(options.logDir, "errors.log");
5700
+ this.logFilePath = path9.join(options.logDir, "errors.log");
5576
5701
  this.logToStderr = options.logToStderr ?? true;
5577
5702
  this.maxSize = options.maxSize ?? DEFAULT_MAX_SIZE;
5578
5703
  this.maxBackups = options.maxBackups ?? DEFAULT_MAX_BACKUPS;
@@ -5691,7 +5816,7 @@ ${entry.stack}`);
5691
5816
  return `${this.logFilePath}.${index}`;
5692
5817
  }
5693
5818
  ensureLogDirectory() {
5694
- const directory = path8.dirname(this.logFilePath);
5819
+ const directory = path9.dirname(this.logFilePath);
5695
5820
  try {
5696
5821
  if (!this.fs.existsSync(directory)) {
5697
5822
  this.fs.mkdirSync(directory, { recursive: true });
@@ -5709,7 +5834,7 @@ ${entry.stack}`);
5709
5834
  });
5710
5835
 
5711
5836
  // src/providers/index.ts
5712
- import path9 from "node:path";
5837
+ import path10 from "node:path";
5713
5838
  import { readdir } from "node:fs/promises";
5714
5839
  import { fileURLToPath, pathToFileURL } from "node:url";
5715
5840
  function isProviderModule(filename) {
@@ -5736,7 +5861,7 @@ async function loadProviders() {
5736
5861
  for (const entry of entries) {
5737
5862
  if (!entry.isFile()) continue;
5738
5863
  if (!isProviderModule(entry.name)) continue;
5739
- const moduleUrl = pathToFileURL(path9.join(currentDir, entry.name)).href;
5864
+ const moduleUrl = pathToFileURL(path10.join(currentDir, entry.name)).href;
5740
5865
  const moduleExports = await import(moduleUrl);
5741
5866
  if (!moduleExports.provider) {
5742
5867
  throw new Error(`Provider module "${entry.name}" must export "provider".`);
@@ -5752,8 +5877,8 @@ var moduleDir, currentDir, defaultProviders;
5752
5877
  var init_providers = __esm({
5753
5878
  async "src/providers/index.ts"() {
5754
5879
  "use strict";
5755
- moduleDir = path9.dirname(fileURLToPath(import.meta.url));
5756
- currentDir = path9.basename(moduleDir) === "providers" ? moduleDir : path9.join(moduleDir, "providers");
5880
+ moduleDir = path10.dirname(fileURLToPath(import.meta.url));
5881
+ currentDir = path10.basename(moduleDir) === "providers" ? moduleDir : path10.join(moduleDir, "providers");
5757
5882
  defaultProviders = await loadProviders();
5758
5883
  }
5759
5884
  });
@@ -6095,21 +6220,21 @@ function createSdkContainer(options) {
6095
6220
  });
6096
6221
  loggerFactory.setErrorLogger(errorLogger);
6097
6222
  const asyncFs = {
6098
- readFile: ((path24, encoding) => {
6223
+ readFile: ((path27, encoding) => {
6099
6224
  if (encoding) {
6100
- return fs2.readFile(path24, encoding);
6225
+ return fs2.readFile(path27, encoding);
6101
6226
  }
6102
- return fs2.readFile(path24);
6227
+ return fs2.readFile(path27);
6103
6228
  }),
6104
- writeFile: (path24, data, opts) => fs2.writeFile(path24, data, opts),
6105
- mkdir: (path24, opts) => fs2.mkdir(path24, opts).then(() => {
6229
+ writeFile: (path27, data, opts) => fs2.writeFile(path27, data, opts),
6230
+ mkdir: (path27, opts) => fs2.mkdir(path27, opts).then(() => {
6106
6231
  }),
6107
- stat: (path24) => fs2.stat(path24),
6108
- rm: (path24, opts) => fs2.rm(path24, opts),
6109
- unlink: (path24) => fs2.unlink(path24),
6110
- readdir: (path24) => fs2.readdir(path24),
6232
+ stat: (path27) => fs2.stat(path27),
6233
+ rm: (path27, opts) => fs2.rm(path27, opts),
6234
+ unlink: (path27) => fs2.unlink(path27),
6235
+ readdir: (path27) => fs2.readdir(path27),
6111
6236
  copyFile: (src, dest) => fs2.copyFile(src, dest),
6112
- chmod: (path24, mode) => fs2.chmod(path24, mode)
6237
+ chmod: (path27, mode) => fs2.chmod(path27, mode)
6113
6238
  };
6114
6239
  const contextFactory = createCommandContextFactory({ fs: asyncFs });
6115
6240
  const authFs = {
@@ -6811,8 +6936,8 @@ function resourceNotFound(resource) {
6811
6936
  `Resource not found: ${resource}`
6812
6937
  );
6813
6938
  }
6814
- function assertAbsolutePath(path24) {
6815
- if (!isAbsolute(path24)) {
6939
+ function assertAbsolutePath(path27) {
6940
+ if (!isAbsolute(path27)) {
6816
6941
  throw invalidParams('"path" must be an absolute path');
6817
6942
  }
6818
6943
  }
@@ -7546,7 +7671,7 @@ var init_run_report = __esm({
7546
7671
  });
7547
7672
 
7548
7673
  // packages/poe-acp-client/src/index.ts
7549
- var init_src6 = __esm({
7674
+ var init_src7 = __esm({
7550
7675
  "packages/poe-acp-client/src/index.ts"() {
7551
7676
  "use strict";
7552
7677
  init_acp_client();
@@ -8573,7 +8698,7 @@ var init_acp_core = __esm({
8573
8698
  });
8574
8699
 
8575
8700
  // packages/poe-agent/src/plugins/plugin-args.ts
8576
- import path10 from "node:path";
8701
+ import path11 from "node:path";
8577
8702
  function isObjectRecord3(value) {
8578
8703
  return typeof value === "object" && value !== null && !Array.isArray(value);
8579
8704
  }
@@ -8604,13 +8729,13 @@ function getOptionalString(args, key) {
8604
8729
  return value;
8605
8730
  }
8606
8731
  function resolveAllowedPath(cwd, allowedPaths, inputPath) {
8607
- const resolvedPath = path10.resolve(cwd, inputPath);
8732
+ const resolvedPath = path11.resolve(cwd, inputPath);
8608
8733
  const isAllowed = allowedPaths.some((allowedPath) => {
8609
8734
  if (allowedPath === resolvedPath) {
8610
8735
  return true;
8611
8736
  }
8612
- const rel = path10.relative(allowedPath, resolvedPath);
8613
- return rel.length > 0 && !rel.startsWith("..") && !path10.isAbsolute(rel);
8737
+ const rel = path11.relative(allowedPath, resolvedPath);
8738
+ return rel.length > 0 && !rel.startsWith("..") && !path11.isAbsolute(rel);
8614
8739
  });
8615
8740
  if (!isAllowed) {
8616
8741
  throw new Error(`Path is outside allowed paths: ${inputPath}`);
@@ -8625,7 +8750,7 @@ var init_plugin_args = __esm({
8625
8750
 
8626
8751
  // packages/poe-agent/src/plugins/poe-agent-plugin-files.ts
8627
8752
  import fsPromises2 from "node:fs/promises";
8628
- import path11 from "node:path";
8753
+ import path12 from "node:path";
8629
8754
  async function fileExists(fs3, filePath) {
8630
8755
  try {
8631
8756
  await fs3.readFile(filePath, "utf8");
@@ -8649,9 +8774,9 @@ var init_poe_agent_plugin_files = __esm({
8649
8774
  "use strict";
8650
8775
  init_plugin_args();
8651
8776
  filesPlugin = (options = {}) => {
8652
- const cwd = path11.resolve(options.cwd ?? process.cwd());
8777
+ const cwd = path12.resolve(options.cwd ?? process.cwd());
8653
8778
  const allowedPaths = (options.allowedPaths ?? [cwd]).map(
8654
- (allowedPath) => path11.resolve(cwd, allowedPath)
8779
+ (allowedPath) => path12.resolve(cwd, allowedPath)
8655
8780
  );
8656
8781
  const fs3 = options.fs ?? fsPromises2;
8657
8782
  const readFileTool = {
@@ -8705,7 +8830,7 @@ var init_poe_agent_plugin_files = __esm({
8705
8830
  async call(args) {
8706
8831
  const command = getRequiredString(args, "command");
8707
8832
  const filePath = resolveAllowedPath(cwd, allowedPaths, getRequiredString(args, "path"));
8708
- const displayedPath = path11.relative(cwd, filePath) || path11.basename(filePath);
8833
+ const displayedPath = path12.relative(cwd, filePath) || path12.basename(filePath);
8709
8834
  if (command === "str_replace") {
8710
8835
  const oldStr = getRequiredString(args, "old_str", true);
8711
8836
  const newStr = getRequiredString(args, "new_str", true);
@@ -8725,7 +8850,7 @@ var init_poe_agent_plugin_files = __esm({
8725
8850
  if (await fileExists(fs3, filePath)) {
8726
8851
  throw new Error("File already exists \u2014 use str_replace to edit");
8727
8852
  }
8728
- await fs3.mkdir(path11.dirname(filePath), { recursive: true });
8853
+ await fs3.mkdir(path12.dirname(filePath), { recursive: true });
8729
8854
  await fs3.writeFile(filePath, fileText, "utf8");
8730
8855
  return `Created file: ${displayedPath}`;
8731
8856
  }
@@ -8766,7 +8891,7 @@ var init_poe_agent_plugin_files = __esm({
8766
8891
 
8767
8892
  // packages/poe-agent/src/plugins/poe-agent-plugin-shell.ts
8768
8893
  import { exec as execCallback } from "node:child_process";
8769
- import path12 from "node:path";
8894
+ import path13 from "node:path";
8770
8895
  import { promisify } from "node:util";
8771
8896
  async function defaultRunCommand(command, cwd) {
8772
8897
  try {
@@ -8799,9 +8924,9 @@ var init_poe_agent_plugin_shell = __esm({
8799
8924
  init_plugin_args();
8800
8925
  exec = promisify(execCallback);
8801
8926
  shellPlugin = (options = {}) => {
8802
- const cwd = path12.resolve(options.cwd ?? process.cwd());
8927
+ const cwd = path13.resolve(options.cwd ?? process.cwd());
8803
8928
  const allowedPaths = (options.allowedPaths ?? [cwd]).map(
8804
- (allowedPath) => path12.resolve(cwd, allowedPath)
8929
+ (allowedPath) => path13.resolve(cwd, allowedPath)
8805
8930
  );
8806
8931
  const runCommand2 = options.runCommand ?? defaultRunCommand;
8807
8932
  const runCommandTool = {
@@ -9585,7 +9710,7 @@ var AgentHost;
9585
9710
  var init_agent_host = __esm({
9586
9711
  "packages/poe-agent/src/runtime/agent-host.ts"() {
9587
9712
  "use strict";
9588
- init_src6();
9713
+ init_src7();
9589
9714
  init_agent_session();
9590
9715
  init_acp_core();
9591
9716
  init_run_context();
@@ -9945,7 +10070,7 @@ function readDependencies(plugin) {
9945
10070
  }
9946
10071
  return normalized;
9947
10072
  }
9948
- var init_config = __esm({
10073
+ var init_config2 = __esm({
9949
10074
  "packages/poe-agent/src/runtime/config.ts"() {
9950
10075
  "use strict";
9951
10076
  }
@@ -10872,7 +10997,7 @@ var init_internal = __esm({
10872
10997
  });
10873
10998
 
10874
10999
  // packages/tiny-mcp-client/src/index.ts
10875
- var init_src7 = __esm({
11000
+ var init_src8 = __esm({
10876
11001
  "packages/tiny-mcp-client/src/index.ts"() {
10877
11002
  "use strict";
10878
11003
  init_internal();
@@ -10921,7 +11046,7 @@ var DEFAULT_MCP_CLIENT_INFO, PluginApiImpl;
10921
11046
  var init_plugin_api_impl = __esm({
10922
11047
  "packages/poe-agent/src/runtime/plugin-api-impl.ts"() {
10923
11048
  "use strict";
10924
- init_src7();
11049
+ init_src8();
10925
11050
  init_hooks();
10926
11051
  DEFAULT_MCP_CLIENT_INFO = {
10927
11052
  name: "poe-agent",
@@ -11252,7 +11377,7 @@ var init_agent = __esm({
11252
11377
  init_acp_core();
11253
11378
  init_agent_host();
11254
11379
  init_hooks();
11255
- init_config();
11380
+ init_config2();
11256
11381
  init_plugin_setup();
11257
11382
  init_run_context();
11258
11383
  ImmutableAgentBuilder = class _ImmutableAgentBuilder {
@@ -11488,7 +11613,7 @@ __export(src_exports, {
11488
11613
  agent: () => agent,
11489
11614
  createAgentSession: () => createAgentSession
11490
11615
  });
11491
- var init_src8 = __esm({
11616
+ var init_src9 = __esm({
11492
11617
  "packages/poe-agent/src/index.ts"() {
11493
11618
  "use strict";
11494
11619
  init_agent();
@@ -11826,7 +11951,7 @@ function createInMemoryAcpTransport2(options) {
11826
11951
  }
11827
11952
  if (method === "session/new") {
11828
11953
  const request = params;
11829
- const { createAgentSession: createAgentSession2 } = await Promise.resolve().then(() => (init_src8(), src_exports));
11954
+ const { createAgentSession: createAgentSession2 } = await Promise.resolve().then(() => (init_src9(), src_exports));
11830
11955
  const session = await createAgentSession2({
11831
11956
  model: options.model,
11832
11957
  cwd: request.cwd || options.cwd,
@@ -11976,7 +12101,7 @@ var init_poe_agent = __esm({
11976
12101
  "src/providers/poe-agent.ts"() {
11977
12102
  "use strict";
11978
12103
  init_constants();
11979
- init_src6();
12104
+ init_src7();
11980
12105
  init_create_provider();
11981
12106
  poeAgentService = createProvider({
11982
12107
  id: "poe-agent",
@@ -12145,7 +12270,7 @@ var init_spawn3 = __esm({
12145
12270
  });
12146
12271
 
12147
12272
  // packages/pipeline/src/utils.ts
12148
- function isRecord2(value) {
12273
+ function isRecord3(value) {
12149
12274
  return typeof value === "object" && value !== null && !Array.isArray(value);
12150
12275
  }
12151
12276
  function isNotFound2(error2) {
@@ -12179,7 +12304,7 @@ var init_utils2 = __esm({
12179
12304
  });
12180
12305
 
12181
12306
  // packages/pipeline/src/config/loader.ts
12182
- import path13 from "node:path";
12307
+ import path14 from "node:path";
12183
12308
  import { parse as parse4 } from "yaml";
12184
12309
  function asStepMode(value) {
12185
12310
  if (value === void 0 || value === null) {
@@ -12203,19 +12328,19 @@ function parseStepConfigDocument(filePath, content) {
12203
12328
  if (document === null || document === void 0) {
12204
12329
  return {};
12205
12330
  }
12206
- if (!isRecord2(document)) {
12331
+ if (!isRecord3(document)) {
12207
12332
  throw new Error(`Invalid pipeline step config in "${filePath}": expected a top-level object.`);
12208
12333
  }
12209
12334
  const stepsValue = document.steps;
12210
12335
  if (stepsValue === void 0 || stepsValue === null) {
12211
12336
  return {};
12212
12337
  }
12213
- if (!isRecord2(stepsValue)) {
12338
+ if (!isRecord3(stepsValue)) {
12214
12339
  throw new Error(`Invalid pipeline step config in "${filePath}": "steps" must be an object.`);
12215
12340
  }
12216
12341
  const steps = {};
12217
12342
  for (const [stepName, value] of Object.entries(stepsValue)) {
12218
- if (!isRecord2(value)) {
12343
+ if (!isRecord3(value)) {
12219
12344
  throw new Error(`Invalid step "${stepName}" in "${filePath}": expected an object.`);
12220
12345
  }
12221
12346
  const instruction = value.instruction;
@@ -12237,7 +12362,7 @@ function parseConfigDocument(filePath, content) {
12237
12362
  if (document === null || document === void 0) {
12238
12363
  return {};
12239
12364
  }
12240
- if (!isRecord2(document)) {
12365
+ if (!isRecord3(document)) {
12241
12366
  throw new Error(`Invalid pipeline config in "${filePath}": expected a top-level object.`);
12242
12367
  }
12243
12368
  const planPath = document.planPath;
@@ -12263,8 +12388,8 @@ async function loadStepsFile(fs3, filePath) {
12263
12388
  return parseStepConfigDocument(filePath, content);
12264
12389
  }
12265
12390
  async function loadPipelineConfig(options) {
12266
- const globalPath = path13.join(options.homeDir, ".poe-code", "pipeline", "config.yaml");
12267
- const projectPath = path13.join(options.cwd, ".poe-code", "pipeline", "config.yaml");
12391
+ const globalPath = path14.join(options.homeDir, ".poe-code", "pipeline", "config.yaml");
12392
+ const projectPath = path14.join(options.cwd, ".poe-code", "pipeline", "config.yaml");
12268
12393
  const [globalConfig2, projectConfig] = await Promise.all([
12269
12394
  loadConfigFile(options.fs, globalPath),
12270
12395
  loadConfigFile(options.fs, projectPath)
@@ -12275,8 +12400,8 @@ async function loadPipelineConfig(options) {
12275
12400
  };
12276
12401
  }
12277
12402
  async function loadResolvedSteps(options) {
12278
- const globalPath = path13.join(options.homeDir, ".poe-code", "pipeline", "steps.yaml");
12279
- const projectPath = path13.join(options.cwd, ".poe-code", "pipeline", "steps.yaml");
12403
+ const globalPath = path14.join(options.homeDir, ".poe-code", "pipeline", "steps.yaml");
12404
+ const projectPath = path14.join(options.cwd, ".poe-code", "pipeline", "steps.yaml");
12280
12405
  const [globalSteps, projectSteps] = await Promise.all([
12281
12406
  loadStepsFile(options.fs, globalPath),
12282
12407
  loadStepsFile(options.fs, projectPath)
@@ -12315,7 +12440,7 @@ function parseTaskStatus(value, availableSteps, taskId) {
12315
12440
  if (typeof value === "string") {
12316
12441
  return normalizeStatus(value, "task status");
12317
12442
  }
12318
- if (!isRecord2(value)) {
12443
+ if (!isRecord3(value)) {
12319
12444
  throw new Error(`Invalid status for task "${taskId}": expected a string or step-status map.`);
12320
12445
  }
12321
12446
  const statusMap = {};
@@ -12335,7 +12460,7 @@ function parsePlan(yamlContent, options = {}) {
12335
12460
  const message = error2 instanceof Error ? error2.message : String(error2);
12336
12461
  throw new Error(`Invalid plan YAML: ${message}`);
12337
12462
  }
12338
- if (!isRecord2(document)) {
12463
+ if (!isRecord3(document)) {
12339
12464
  throw new Error("Invalid plan YAML: expected a top-level object.");
12340
12465
  }
12341
12466
  const tasksValue = document.tasks;
@@ -12344,7 +12469,7 @@ function parsePlan(yamlContent, options = {}) {
12344
12469
  }
12345
12470
  const ids = /* @__PURE__ */ new Set();
12346
12471
  const tasks = tasksValue.map((value, index) => {
12347
- if (!isRecord2(value)) {
12472
+ if (!isRecord3(value)) {
12348
12473
  throw new Error(`Invalid tasks[${index}]: expected an object.`);
12349
12474
  }
12350
12475
  const id = asRequiredString(value.id, `tasks[${index}].id`);
@@ -12369,18 +12494,18 @@ var init_parser = __esm({
12369
12494
  });
12370
12495
 
12371
12496
  // packages/pipeline/src/plan/discovery.ts
12372
- import path14 from "node:path";
12497
+ import path15 from "node:path";
12373
12498
  import * as fsPromises3 from "node:fs/promises";
12374
12499
  function createDefaultFs() {
12375
12500
  return {
12376
12501
  readFile: fsPromises3.readFile,
12377
12502
  readdir: fsPromises3.readdir,
12378
12503
  stat: async (filePath) => {
12379
- const stat6 = await fsPromises3.stat(filePath);
12504
+ const stat8 = await fsPromises3.stat(filePath);
12380
12505
  return {
12381
- isFile: () => stat6.isFile(),
12382
- isDirectory: () => stat6.isDirectory(),
12383
- mtimeMs: stat6.mtimeMs
12506
+ isFile: () => stat8.isFile(),
12507
+ isDirectory: () => stat8.isDirectory(),
12508
+ mtimeMs: stat8.mtimeMs
12384
12509
  };
12385
12510
  }
12386
12511
  };
@@ -12405,10 +12530,10 @@ function countCompletedTasks(planPath, content) {
12405
12530
  };
12406
12531
  }
12407
12532
  async function ensurePlanExists(fs3, cwd, planPath) {
12408
- const absolutePath = path14.isAbsolute(planPath) ? planPath : path14.resolve(cwd, planPath);
12533
+ const absolutePath = path15.isAbsolute(planPath) ? planPath : path15.resolve(cwd, planPath);
12409
12534
  try {
12410
- const stat6 = await fs3.stat(absolutePath);
12411
- if (!stat6.isFile()) {
12535
+ const stat8 = await fs3.stat(absolutePath);
12536
+ if (!stat8.isFile()) {
12412
12537
  throw new Error(`Plan not found at "${planPath}".`);
12413
12538
  }
12414
12539
  } catch (error2) {
@@ -12433,20 +12558,20 @@ async function scanPlansDir(fs3, plansDir, displayPrefix) {
12433
12558
  if (!isPlanCandidateFile(entry)) {
12434
12559
  continue;
12435
12560
  }
12436
- const absolutePath = path14.join(plansDir, entry);
12437
- const stat6 = await fs3.stat(absolutePath);
12438
- if (!stat6.isFile()) {
12561
+ const absolutePath = path15.join(plansDir, entry);
12562
+ const stat8 = await fs3.stat(absolutePath);
12563
+ if (!stat8.isFile()) {
12439
12564
  continue;
12440
12565
  }
12441
- const displayPath = path14.join(displayPrefix, entry);
12566
+ const displayPath = path15.join(displayPrefix, entry);
12442
12567
  const content = await fs3.readFile(absolutePath, "utf8");
12443
12568
  candidates.push(countCompletedTasks(displayPath, content));
12444
12569
  }
12445
12570
  return candidates;
12446
12571
  }
12447
12572
  async function listPlanCandidates(fs3, cwd, homeDir) {
12448
- const projectDir = path14.join(cwd, ".poe-code", "pipeline", "plans");
12449
- const globalDir = path14.join(homeDir, ".poe-code", "pipeline", "plans");
12573
+ const projectDir = path15.join(cwd, ".poe-code", "pipeline", "plans");
12574
+ const globalDir = path15.join(homeDir, ".poe-code", "pipeline", "plans");
12450
12575
  const [projectCandidates, globalCandidates] = await Promise.all([
12451
12576
  scanPlansDir(fs3, projectDir, ".poe-code/pipeline/plans"),
12452
12577
  scanPlansDir(fs3, globalDir, "~/.poe-code/pipeline/plans")
@@ -12457,9 +12582,9 @@ async function listPlanCandidates(fs3, cwd, homeDir) {
12457
12582
  }
12458
12583
  function resolveAbsolutePlanPath(planPath, cwd, homeDir) {
12459
12584
  if (planPath.startsWith("~/")) {
12460
- return path14.join(homeDir, planPath.slice(2));
12585
+ return path15.join(homeDir, planPath.slice(2));
12461
12586
  }
12462
- return path14.isAbsolute(planPath) ? planPath : path14.resolve(cwd, planPath);
12587
+ return path15.isAbsolute(planPath) ? planPath : path15.resolve(cwd, planPath);
12463
12588
  }
12464
12589
  async function resolvePlanPath(options) {
12465
12590
  const fs3 = options.fs ?? createDefaultFs();
@@ -12516,7 +12641,7 @@ var init_discovery = __esm({
12516
12641
  });
12517
12642
 
12518
12643
  // packages/pipeline/src/plan/writer.ts
12519
- import { parseDocument, isMap, isSeq } from "yaml";
12644
+ import { parseDocument as parseDocument2, isMap, isSeq } from "yaml";
12520
12645
  function getTasksNode(document) {
12521
12646
  const tasksNode = document.get("tasks", true);
12522
12647
  if (!tasksNode || !isSeq(tasksNode)) {
@@ -12540,7 +12665,7 @@ async function readPlanFile(fs3, planPath) {
12540
12665
  }
12541
12666
  async function writeTaskStatus(options) {
12542
12667
  const content = await readPlanFile(options.fs, options.planPath);
12543
- const document = parseDocument(content);
12668
+ const document = parseDocument2(content);
12544
12669
  const tasksNode = getTasksNode(document);
12545
12670
  const taskNode = getTaskNode(tasksNode, options.taskId);
12546
12671
  if (options.stepName) {
@@ -12646,11 +12771,11 @@ function createDefaultFs2() {
12646
12771
  },
12647
12772
  rmdir: fsPromises4.rmdir,
12648
12773
  stat: async (filePath) => {
12649
- const stat6 = await fsPromises4.stat(filePath);
12774
+ const stat8 = await fsPromises4.stat(filePath);
12650
12775
  return {
12651
- isFile: () => stat6.isFile(),
12652
- isDirectory: () => stat6.isDirectory(),
12653
- mtimeMs: stat6.mtimeMs
12776
+ isFile: () => stat8.isFile(),
12777
+ isDirectory: () => stat8.isDirectory(),
12778
+ mtimeMs: stat8.mtimeMs
12654
12779
  };
12655
12780
  }
12656
12781
  };
@@ -12683,8 +12808,8 @@ async function lockFile(filePath, options = {}) {
12683
12808
  if (!error2 || typeof error2 !== "object" || !("code" in error2) || error2.code !== "EEXIST") {
12684
12809
  throw error2;
12685
12810
  }
12686
- const stat6 = await fs3.stat(lockPath);
12687
- if (Date.now() - stat6.mtimeMs > staleMs) {
12811
+ const stat8 = await fs3.stat(lockPath);
12812
+ if (Date.now() - stat8.mtimeMs > staleMs) {
12688
12813
  await fs3.rmdir(lockPath);
12689
12814
  continue;
12690
12815
  }
@@ -12702,7 +12827,7 @@ var init_lock = __esm({
12702
12827
  });
12703
12828
 
12704
12829
  // packages/pipeline/src/run/pipeline.ts
12705
- import path15 from "node:path";
12830
+ import path16 from "node:path";
12706
12831
  import * as fsPromises5 from "node:fs/promises";
12707
12832
  function createDefaultFs3() {
12708
12833
  return {
@@ -12710,11 +12835,11 @@ function createDefaultFs3() {
12710
12835
  writeFile: fsPromises5.writeFile,
12711
12836
  readdir: fsPromises5.readdir,
12712
12837
  stat: async (filePath) => {
12713
- const stat6 = await fsPromises5.stat(filePath);
12838
+ const stat8 = await fsPromises5.stat(filePath);
12714
12839
  return {
12715
- isFile: () => stat6.isFile(),
12716
- isDirectory: () => stat6.isDirectory(),
12717
- mtimeMs: stat6.mtimeMs
12840
+ isFile: () => stat8.isFile(),
12841
+ isDirectory: () => stat8.isDirectory(),
12842
+ mtimeMs: stat8.mtimeMs
12718
12843
  };
12719
12844
  },
12720
12845
  mkdir: async (filePath, options) => {
@@ -12738,9 +12863,9 @@ function resolveMode(stepName, steps) {
12738
12863
  return step.mode;
12739
12864
  }
12740
12865
  async function archivePlan(fs3, absolutePlanPath) {
12741
- const dir = path15.dirname(absolutePlanPath);
12742
- const archiveDir = path15.join(dir, "archive");
12743
- const archivePath = path15.join(archiveDir, path15.basename(absolutePlanPath));
12866
+ const dir = path16.dirname(absolutePlanPath);
12867
+ const archiveDir = path16.join(dir, "archive");
12868
+ const archivePath = path16.join(archiveDir, path16.basename(absolutePlanPath));
12744
12869
  await fs3.mkdir(archiveDir, { recursive: true });
12745
12870
  await fs3.rename(absolutePlanPath, archivePath);
12746
12871
  }
@@ -12975,7 +13100,7 @@ var init_pipeline = __esm({
12975
13100
  });
12976
13101
 
12977
13102
  // packages/pipeline/src/index.ts
12978
- var init_src9 = __esm({
13103
+ var init_src10 = __esm({
12979
13104
  "packages/pipeline/src/index.ts"() {
12980
13105
  "use strict";
12981
13106
  init_loader();
@@ -13007,7 +13132,286 @@ async function runPipeline2(options) {
13007
13132
  var init_pipeline2 = __esm({
13008
13133
  async "src/sdk/pipeline.ts"() {
13009
13134
  "use strict";
13010
- init_src9();
13135
+ init_src10();
13136
+ init_src5();
13137
+ await init_spawn3();
13138
+ }
13139
+ });
13140
+
13141
+ // packages/ralph/src/discovery/discovery.ts
13142
+ import path17 from "node:path";
13143
+ import * as fsPromises6 from "node:fs/promises";
13144
+ function createDefaultFs4() {
13145
+ return {
13146
+ readFile: fsPromises6.readFile,
13147
+ readdir: fsPromises6.readdir,
13148
+ stat: async (filePath) => {
13149
+ const stat8 = await fsPromises6.stat(filePath);
13150
+ return {
13151
+ isFile: () => stat8.isFile(),
13152
+ mtimeMs: stat8.mtimeMs
13153
+ };
13154
+ }
13155
+ };
13156
+ }
13157
+ function isNotFound3(error2) {
13158
+ return !!error2 && typeof error2 === "object" && "code" in error2 && error2.code === "ENOENT";
13159
+ }
13160
+ function isMarkdownFile(entry) {
13161
+ return entry.toLowerCase().endsWith(".md");
13162
+ }
13163
+ async function scanDir(fs3, absoluteDir, displayDir) {
13164
+ let entries;
13165
+ try {
13166
+ entries = await fs3.readdir(absoluteDir);
13167
+ } catch (error2) {
13168
+ if (isNotFound3(error2)) {
13169
+ return [];
13170
+ }
13171
+ throw error2;
13172
+ }
13173
+ const docs = [];
13174
+ for (const entry of entries) {
13175
+ if (!isMarkdownFile(entry)) {
13176
+ continue;
13177
+ }
13178
+ const absolutePath = path17.join(absoluteDir, entry);
13179
+ const stat8 = await fs3.stat(absolutePath);
13180
+ if (!stat8.isFile()) {
13181
+ continue;
13182
+ }
13183
+ const displayPath = path17.join(displayDir, entry);
13184
+ docs.push({
13185
+ path: displayPath,
13186
+ displayPath
13187
+ });
13188
+ }
13189
+ return docs;
13190
+ }
13191
+ async function discoverDocs(options) {
13192
+ const fs3 = options.fs ?? createDefaultFs4();
13193
+ const [localDocs, globalDocs] = await Promise.all([
13194
+ scanDir(
13195
+ fs3,
13196
+ path17.join(options.cwd, ".poe-code", "ralph", "plans"),
13197
+ ".poe-code/ralph/plans"
13198
+ ),
13199
+ scanDir(
13200
+ fs3,
13201
+ path17.join(options.homeDir, ".poe-code", "ralph", "plans"),
13202
+ "~/.poe-code/ralph/plans"
13203
+ )
13204
+ ]);
13205
+ return [...localDocs, ...globalDocs].sort((left, right) => {
13206
+ const leftName = path17.basename(left.displayPath).toLowerCase();
13207
+ const rightName = path17.basename(right.displayPath).toLowerCase();
13208
+ return leftName === rightName ? left.displayPath.localeCompare(right.displayPath) : leftName.localeCompare(rightName);
13209
+ });
13210
+ }
13211
+ var init_discovery2 = __esm({
13212
+ "packages/ralph/src/discovery/discovery.ts"() {
13213
+ "use strict";
13214
+ }
13215
+ });
13216
+
13217
+ // packages/ralph/src/overbaking/detector.ts
13218
+ var OverbakingDetector;
13219
+ var init_detector = __esm({
13220
+ "packages/ralph/src/overbaking/detector.ts"() {
13221
+ "use strict";
13222
+ OverbakingDetector = class {
13223
+ threshold;
13224
+ consecutiveFailures = 0;
13225
+ constructor(threshold) {
13226
+ this.threshold = threshold;
13227
+ }
13228
+ record(_success) {
13229
+ if (_success) {
13230
+ this.consecutiveFailures = 0;
13231
+ return {
13232
+ consecutiveFailures: 0,
13233
+ overbaked: false,
13234
+ shouldWarn: false
13235
+ };
13236
+ }
13237
+ this.consecutiveFailures += 1;
13238
+ return {
13239
+ consecutiveFailures: this.consecutiveFailures,
13240
+ overbaked: this.consecutiveFailures >= this.threshold,
13241
+ shouldWarn: this.consecutiveFailures === this.threshold
13242
+ };
13243
+ }
13244
+ };
13245
+ }
13246
+ });
13247
+
13248
+ // packages/ralph/src/run/ralph.ts
13249
+ import path18 from "node:path";
13250
+ import * as fsPromises7 from "node:fs/promises";
13251
+ async function runRalph(options) {
13252
+ const fs3 = options.fs ?? createDefaultFs5();
13253
+ const runAgent = options.runAgent;
13254
+ if (!runAgent) {
13255
+ throw new Error("runRalph requires a runAgent implementation.");
13256
+ }
13257
+ if (!Number.isInteger(options.maxIterations) || options.maxIterations < 1) {
13258
+ throw new Error("maxIterations must be a positive integer.");
13259
+ }
13260
+ const threshold = options.maxFailures ?? 3;
13261
+ if (!Number.isInteger(threshold) || threshold < 1) {
13262
+ throw new Error("maxFailures must be a positive integer.");
13263
+ }
13264
+ const absoluteDocPath = resolveAbsoluteDocPath(
13265
+ options.docPath,
13266
+ options.cwd,
13267
+ options.homeDir
13268
+ );
13269
+ const prompt = await fs3.readFile(absoluteDocPath, "utf8");
13270
+ const detector = new OverbakingDetector(threshold);
13271
+ const startTime = Date.now();
13272
+ let iterationsCompleted = 0;
13273
+ try {
13274
+ for (let iteration = 1; iteration <= options.maxIterations; iteration += 1) {
13275
+ assertNotAborted5(options.signal);
13276
+ options.onIterationStart?.(iteration, options.maxIterations);
13277
+ const iterationStart = Date.now();
13278
+ let result;
13279
+ try {
13280
+ result = await runAgent({
13281
+ agent: options.agent,
13282
+ prompt,
13283
+ cwd: options.cwd,
13284
+ ...options.model ? { model: options.model } : {},
13285
+ ...options.signal ? { signal: options.signal } : {}
13286
+ });
13287
+ } catch (error2) {
13288
+ if (isAbortError2(error2)) {
13289
+ return {
13290
+ stopReason: "cancelled",
13291
+ docPath: options.docPath,
13292
+ iterationsCompleted,
13293
+ totalDurationMs: Date.now() - startTime
13294
+ };
13295
+ }
13296
+ throw error2;
13297
+ }
13298
+ const success2 = result.exitCode === 0;
13299
+ iterationsCompleted += 1;
13300
+ options.onIterationComplete?.(
13301
+ iteration,
13302
+ Date.now() - iterationStart,
13303
+ success2
13304
+ );
13305
+ const overbake = detector.record(success2);
13306
+ if (!overbake.shouldWarn) {
13307
+ continue;
13308
+ }
13309
+ options.onOverbakeWarning?.(
13310
+ overbake.consecutiveFailures,
13311
+ threshold
13312
+ );
13313
+ const action = options.promptOverbake ? await options.promptOverbake({
13314
+ consecutiveFailures: overbake.consecutiveFailures,
13315
+ threshold
13316
+ }) : "abort";
13317
+ if (action === "abort") {
13318
+ return {
13319
+ stopReason: "overbake_abort",
13320
+ docPath: options.docPath,
13321
+ iterationsCompleted,
13322
+ totalDurationMs: Date.now() - startTime
13323
+ };
13324
+ }
13325
+ }
13326
+ } catch (error2) {
13327
+ if (isAbortError2(error2)) {
13328
+ return {
13329
+ stopReason: "cancelled",
13330
+ docPath: options.docPath,
13331
+ iterationsCompleted,
13332
+ totalDurationMs: Date.now() - startTime
13333
+ };
13334
+ }
13335
+ throw error2;
13336
+ }
13337
+ return {
13338
+ stopReason: "max_iterations",
13339
+ docPath: options.docPath,
13340
+ iterationsCompleted,
13341
+ totalDurationMs: Date.now() - startTime
13342
+ };
13343
+ }
13344
+ function createDefaultFs5() {
13345
+ return {
13346
+ readFile: fsPromises7.readFile,
13347
+ readdir: fsPromises7.readdir,
13348
+ stat: async (filePath) => {
13349
+ const stat8 = await fsPromises7.stat(filePath);
13350
+ return {
13351
+ isFile: () => stat8.isFile(),
13352
+ mtimeMs: stat8.mtimeMs
13353
+ };
13354
+ }
13355
+ };
13356
+ }
13357
+ function resolveAbsoluteDocPath(docPath, cwd, homeDir) {
13358
+ if (docPath.startsWith("~/")) {
13359
+ return path18.join(homeDir, docPath.slice(2));
13360
+ }
13361
+ return path18.isAbsolute(docPath) ? docPath : path18.resolve(cwd, docPath);
13362
+ }
13363
+ function assertNotAborted5(signal) {
13364
+ if (!signal?.aborted) {
13365
+ return;
13366
+ }
13367
+ throw createAbortError4();
13368
+ }
13369
+ function createAbortError4() {
13370
+ const error2 = new Error("Ralph run cancelled");
13371
+ error2.name = "AbortError";
13372
+ return error2;
13373
+ }
13374
+ function isAbortError2(error2) {
13375
+ return error2 instanceof Error && error2.name === "AbortError";
13376
+ }
13377
+ var init_ralph = __esm({
13378
+ "packages/ralph/src/run/ralph.ts"() {
13379
+ "use strict";
13380
+ init_detector();
13381
+ }
13382
+ });
13383
+
13384
+ // packages/ralph/src/index.ts
13385
+ var init_src11 = __esm({
13386
+ "packages/ralph/src/index.ts"() {
13387
+ "use strict";
13388
+ init_discovery2();
13389
+ init_detector();
13390
+ init_ralph();
13391
+ }
13392
+ });
13393
+
13394
+ // src/sdk/ralph.ts
13395
+ async function runRalph2(options) {
13396
+ return runRalph({
13397
+ ...options,
13398
+ runAgent: async (input) => {
13399
+ const { events, result } = spawn5(input.agent, {
13400
+ prompt: input.prompt,
13401
+ cwd: input.cwd,
13402
+ model: input.model,
13403
+ mode: "yolo",
13404
+ ...input.signal ? { signal: input.signal } : {}
13405
+ });
13406
+ await renderAcpStream(events);
13407
+ return result;
13408
+ }
13409
+ });
13410
+ }
13411
+ var init_ralph2 = __esm({
13412
+ async "src/sdk/ralph.ts"() {
13413
+ "use strict";
13414
+ init_src11();
13011
13415
  init_src5();
13012
13416
  await init_spawn3();
13013
13417
  }
@@ -13077,13 +13481,13 @@ async function readErrorBody(response) {
13077
13481
  }
13078
13482
  }
13079
13483
  function extractTextContent(data) {
13080
- if (!isRecord3(data)) return void 0;
13484
+ if (!isRecord4(data)) return void 0;
13081
13485
  const choices = data.choices;
13082
13486
  if (!Array.isArray(choices) || choices.length === 0) return void 0;
13083
13487
  const first = choices[0];
13084
- if (!isRecord3(first)) return void 0;
13488
+ if (!isRecord4(first)) return void 0;
13085
13489
  const message = first.message;
13086
- if (!isRecord3(message)) return void 0;
13490
+ if (!isRecord4(message)) return void 0;
13087
13491
  return typeof message.content === "string" ? message.content : void 0;
13088
13492
  }
13089
13493
  function extractMediaFromCompletion(data) {
@@ -13091,14 +13495,14 @@ function extractMediaFromCompletion(data) {
13091
13495
  if (!content) return {};
13092
13496
  try {
13093
13497
  const parsed = JSON.parse(content);
13094
- if (isRecord3(parsed) && typeof parsed.url === "string") {
13498
+ if (isRecord4(parsed) && typeof parsed.url === "string") {
13095
13499
  return {
13096
13500
  url: parsed.url,
13097
13501
  mimeType: typeof parsed.mimeType === "string" ? parsed.mimeType : void 0,
13098
13502
  data: typeof parsed.data === "string" ? parsed.data : void 0
13099
13503
  };
13100
13504
  }
13101
- if (isRecord3(parsed) && typeof parsed.data === "string") {
13505
+ if (isRecord4(parsed) && typeof parsed.data === "string") {
13102
13506
  return {
13103
13507
  data: parsed.data,
13104
13508
  mimeType: typeof parsed.mimeType === "string" ? parsed.mimeType : void 0
@@ -13132,7 +13536,7 @@ function isValidUrl(value) {
13132
13536
  return false;
13133
13537
  }
13134
13538
  }
13135
- function isRecord3(value) {
13539
+ function isRecord4(value) {
13136
13540
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
13137
13541
  }
13138
13542
  var init_llm_client = __esm({
@@ -13375,7 +13779,7 @@ var init_oauth_client = __esm({
13375
13779
  });
13376
13780
 
13377
13781
  // packages/poe-oauth/src/index.ts
13378
- var init_src10 = __esm({
13782
+ var init_src12 = __esm({
13379
13783
  "packages/poe-oauth/src/index.ts"() {
13380
13784
  "use strict";
13381
13785
  init_check_auth();
@@ -13426,7 +13830,7 @@ function openInBrowser(url2) {
13426
13830
  var init_oauth_login = __esm({
13427
13831
  "src/cli/oauth-login.ts"() {
13428
13832
  "use strict";
13429
- init_src10();
13833
+ init_src12();
13430
13834
  init_src4();
13431
13835
  }
13432
13836
  });
@@ -13557,7 +13961,7 @@ var init_container2 = __esm({
13557
13961
  });
13558
13962
 
13559
13963
  // src/services/config.ts
13560
- import path17 from "node:path";
13964
+ import path20 from "node:path";
13561
13965
  async function deleteConfig(options) {
13562
13966
  const { fs: fs3, filePath } = options;
13563
13967
  try {
@@ -13572,31 +13976,32 @@ async function deleteConfig(options) {
13572
13976
  }
13573
13977
  async function loadConfiguredServices(options) {
13574
13978
  const { fs: fs3, filePath } = options;
13575
- const document = await readConfigDocument(fs3, filePath);
13576
- return { ...document.configured_services ?? {} };
13979
+ await migrateLegacyCredentialsIfNeeded(fs3, filePath);
13980
+ const document = await readDocument(fs3, filePath);
13981
+ return normalizeConfiguredServices(document[configuredServicesScope]);
13577
13982
  }
13578
13983
  async function saveConfiguredService(options) {
13579
13984
  const { fs: fs3, filePath, service, metadata } = options;
13580
- const document = await readConfigDocument(fs3, filePath);
13581
- const normalized = normalizeConfiguredServiceMetadata(metadata);
13582
- document.configured_services = {
13583
- ...document.configured_services ?? {},
13584
- [service]: normalized
13585
- };
13586
- await writeConfigDocument(fs3, filePath, document);
13985
+ await migrateLegacyConfigIfNeeded(fs3, filePath);
13986
+ const document = await readDocument(fs3, filePath);
13987
+ const services = normalizeConfiguredServices(
13988
+ document[configuredServicesScope]
13989
+ );
13990
+ services[service] = normalizeConfiguredServiceMetadata(metadata);
13991
+ await writeScope(fs3, filePath, configuredServicesScope, services);
13587
13992
  }
13588
13993
  async function unconfigureService(options) {
13589
13994
  const { fs: fs3, filePath, service } = options;
13590
- const document = await readConfigDocument(fs3, filePath);
13591
- const services = document.configured_services;
13592
- if (!services || !(service in services)) {
13995
+ await migrateLegacyConfigIfNeeded(fs3, filePath);
13996
+ const document = await readDocument(fs3, filePath);
13997
+ const services = normalizeConfiguredServices(
13998
+ document[configuredServicesScope]
13999
+ );
14000
+ if (!(service in services)) {
13593
14001
  return false;
13594
14002
  }
13595
14003
  delete services[service];
13596
- if (Object.keys(services).length === 0) {
13597
- delete document.configured_services;
13598
- }
13599
- await writeConfigDocument(fs3, filePath, document);
14004
+ await writeScope(fs3, filePath, configuredServicesScope, services);
13600
14005
  return true;
13601
14006
  }
13602
14007
  function normalizeConfiguredServiceMetadata(metadata) {
@@ -13611,47 +14016,78 @@ function normalizeConfiguredServiceMetadata(metadata) {
13611
14016
  seen.add(entry);
13612
14017
  }
13613
14018
  }
13614
- return {
13615
- files
13616
- };
14019
+ return { files };
13617
14020
  }
13618
- async function readConfigDocument(fs3, filePath) {
13619
- try {
13620
- const raw = await fs3.readFile(filePath, "utf8");
13621
- return await parseConfigDocument2(fs3, filePath, raw);
13622
- } catch (error2) {
13623
- if (isNotFound(error2)) {
13624
- return migrateLegacyCredentialsFile(fs3, filePath);
13625
- }
13626
- throw error2;
14021
+ async function migrateLegacyConfigIfNeeded(fs3, filePath) {
14022
+ await migrateLegacyCredentialsIfNeeded(fs3, filePath);
14023
+ const currentRaw = await readFileIfExists(fs3, filePath);
14024
+ if (currentRaw === null) {
14025
+ return;
14026
+ }
14027
+ const legacyDocument = normalizeLegacyConfigDocument(
14028
+ parseLegacyConfigDocument(currentRaw)
14029
+ );
14030
+ if (!legacyDocument.apiKey) {
14031
+ return;
13627
14032
  }
14033
+ const document = await readDocument(fs3, filePath);
14034
+ const existingCore = document[CORE_SCOPE] ?? {};
14035
+ if (typeof existingCore.apiKey === "string" && existingCore.apiKey.length > 0) {
14036
+ return;
14037
+ }
14038
+ await writeScope(fs3, filePath, CORE_SCOPE, {
14039
+ ...existingCore,
14040
+ apiKey: legacyDocument.apiKey
14041
+ });
13628
14042
  }
13629
- async function migrateLegacyCredentialsFile(fs3, configPath) {
13630
- const legacyPath = path17.join(path17.dirname(configPath), "credentials.json");
13631
- try {
13632
- const raw = await fs3.readFile(legacyPath, "utf8");
13633
- const document = await parseConfigDocument2(fs3, legacyPath, raw);
13634
- await writeConfigDocument(fs3, configPath, document);
13635
- await fs3.unlink(legacyPath);
13636
- return document;
13637
- } catch {
13638
- return {};
14043
+ async function migrateLegacyCredentialsIfNeeded(fs3, filePath) {
14044
+ const currentRaw = await readFileIfExists(fs3, filePath);
14045
+ if (currentRaw !== null) {
14046
+ return;
13639
14047
  }
14048
+ await migrateLegacyCredentialsFile(fs3, filePath);
13640
14049
  }
13641
- async function parseConfigDocument2(fs3, filePath, raw) {
14050
+ async function migrateLegacyCredentialsFile(fs3, configPath) {
14051
+ const legacyPath = path20.join(path20.dirname(configPath), "credentials.json");
14052
+ const raw = await readFileIfExists(fs3, legacyPath);
14053
+ if (raw === null) {
14054
+ return;
14055
+ }
14056
+ let legacyDocument;
13642
14057
  try {
13643
- const parsed = JSON.parse(raw);
13644
- return normalizeConfigDocument(parsed);
14058
+ legacyDocument = normalizeLegacyConfigDocument(JSON.parse(raw));
13645
14059
  } catch (error2) {
13646
14060
  if (error2 instanceof SyntaxError) {
13647
- await recoverInvalidConfig(fs3, filePath, raw);
13648
- return {};
14061
+ await recoverInvalidConfig(fs3, legacyPath, raw);
14062
+ await fs3.unlink(legacyPath);
14063
+ return;
13649
14064
  }
13650
14065
  throw error2;
13651
14066
  }
14067
+ if (legacyDocument.configured_services) {
14068
+ await writeScope(
14069
+ fs3,
14070
+ configPath,
14071
+ configuredServicesScope,
14072
+ legacyDocument.configured_services
14073
+ );
14074
+ }
14075
+ if (legacyDocument.apiKey) {
14076
+ await writeScope(fs3, configPath, CORE_SCOPE, {
14077
+ apiKey: legacyDocument.apiKey
14078
+ });
14079
+ }
14080
+ await fs3.unlink(legacyPath);
14081
+ }
14082
+ function parseLegacyConfigDocument(raw) {
14083
+ try {
14084
+ return JSON.parse(raw);
14085
+ } catch {
14086
+ return null;
14087
+ }
13652
14088
  }
13653
- function normalizeConfigDocument(value) {
13654
- if (!isRecord4(value)) {
14089
+ function normalizeLegacyConfigDocument(value) {
14090
+ if (!isRecord5(value)) {
13655
14091
  return {};
13656
14092
  }
13657
14093
  const document = {};
@@ -13665,55 +14101,42 @@ function normalizeConfigDocument(value) {
13665
14101
  return document;
13666
14102
  }
13667
14103
  function normalizeConfiguredServices(value) {
13668
- if (!isRecord4(value)) {
14104
+ if (!isRecord5(value)) {
13669
14105
  return {};
13670
14106
  }
13671
14107
  const entries = {};
13672
14108
  for (const [key, entry] of Object.entries(value)) {
13673
- if (!isRecord4(entry)) {
14109
+ if (!isRecord5(entry)) {
13674
14110
  continue;
13675
14111
  }
13676
- const normalized = normalizeConfiguredServiceMetadata({
14112
+ entries[key] = normalizeConfiguredServiceMetadata({
13677
14113
  files: Array.isArray(entry.files) ? entry.files : []
13678
14114
  });
13679
- entries[key] = normalized;
13680
14115
  }
13681
14116
  return entries;
13682
14117
  }
13683
- async function writeConfigDocument(fs3, filePath, document) {
13684
- await fs3.mkdir(path17.dirname(filePath), { recursive: true });
13685
- const payload = {};
13686
- if (document.apiKey) {
13687
- payload.apiKey = document.apiKey;
13688
- }
13689
- if (document.configured_services) {
13690
- payload.configured_services = document.configured_services;
13691
- }
13692
- await fs3.writeFile(filePath, `${JSON.stringify(payload, null, 2)}
13693
- `, {
13694
- encoding: "utf8"
13695
- });
13696
- }
13697
14118
  async function recoverInvalidConfig(fs3, filePath, content) {
13698
- const backupPath = createInvalidBackupPath(filePath);
14119
+ const backupPath = createInvalidBackupPath2(filePath);
13699
14120
  await fs3.writeFile(backupPath, content, { encoding: "utf8" });
13700
- await fs3.writeFile(filePath, EMPTY_DOCUMENT, { encoding: "utf8" });
14121
+ await fs3.writeFile(filePath, EMPTY_DOCUMENT2, { encoding: "utf8" });
13701
14122
  }
13702
- function createInvalidBackupPath(filePath) {
13703
- const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
13704
- const dir = path17.dirname(filePath);
13705
- const base = path17.basename(filePath);
13706
- return path17.join(dir, `${base}.invalid-${timestamp}.json`);
14123
+ function createInvalidBackupPath2(filePath) {
14124
+ const directory = path20.dirname(filePath);
14125
+ const baseName = path20.basename(filePath);
14126
+ return path20.join(directory, `${baseName}.invalid-${createTimestamp()}.json`);
13707
14127
  }
13708
- function isRecord4(value) {
14128
+ function isRecord5(value) {
13709
14129
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
13710
14130
  }
13711
- var EMPTY_DOCUMENT;
13712
- var init_config2 = __esm({
14131
+ var CORE_SCOPE, configuredServicesScope, EMPTY_DOCUMENT2;
14132
+ var init_config3 = __esm({
13713
14133
  "src/services/config.ts"() {
13714
14134
  "use strict";
13715
14135
  init_src2();
13716
- EMPTY_DOCUMENT = `${JSON.stringify({}, null, 2)}
14136
+ init_src6();
14137
+ CORE_SCOPE = "core";
14138
+ configuredServicesScope = "configured_services";
14139
+ EMPTY_DOCUMENT2 = `${JSON.stringify({}, null, 2)}
13717
14140
  `;
13718
14141
  }
13719
14142
  });
@@ -13882,7 +14305,7 @@ var init_configure = __esm({
13882
14305
  "use strict";
13883
14306
  init_shared();
13884
14307
  init_errors();
13885
- init_config2();
14308
+ init_config3();
13886
14309
  init_mutation_events();
13887
14310
  init_configure_payload();
13888
14311
  serviceSelectionPrompt = (action) => `Pick an agent to ${action}:`;
@@ -13906,7 +14329,7 @@ function registerAgentCommand(program, container) {
13906
14329
  }
13907
14330
  let session;
13908
14331
  try {
13909
- const { createAgentSession: createAgentSession2 } = await Promise.resolve().then(() => (init_src8(), src_exports));
14332
+ const { createAgentSession: createAgentSession2 } = await Promise.resolve().then(() => (init_src9(), src_exports));
13910
14333
  session = await createAgentSession2({
13911
14334
  model: options.model,
13912
14335
  apiKey: options.apiKey,
@@ -13965,7 +14388,7 @@ var init_agent2 = __esm({
13965
14388
  });
13966
14389
 
13967
14390
  // src/cli/commands/spawn.ts
13968
- import path18 from "node:path";
14391
+ import path21 from "node:path";
13969
14392
  function registerSpawnCommand(program, container, options = {}) {
13970
14393
  const spawnServices = container.registry.list().filter((service) => typeof service.spawn === "function" || getSpawnConfig(service.name)).map((service) => service.name);
13971
14394
  const extraServices = options.extraServices ?? [];
@@ -14176,10 +14599,10 @@ function resolveSpawnWorkingDirectory2(baseDir, candidate) {
14176
14599
  if (!candidate || candidate.trim().length === 0) {
14177
14600
  return void 0;
14178
14601
  }
14179
- if (path18.isAbsolute(candidate)) {
14602
+ if (path21.isAbsolute(candidate)) {
14180
14603
  return candidate;
14181
14604
  }
14182
- return path18.resolve(baseDir, candidate);
14605
+ return path21.resolve(baseDir, candidate);
14183
14606
  }
14184
14607
  function parseMcpSpawnConfig2(input) {
14185
14608
  if (!input) {
@@ -14290,7 +14713,7 @@ var init_spawn4 = __esm({
14290
14713
  init_src5();
14291
14714
  init_src3();
14292
14715
  init_src4();
14293
- init_config2();
14716
+ init_config3();
14294
14717
  init_shared();
14295
14718
  init_spawn_core();
14296
14719
  await init_spawn3();
@@ -14299,7 +14722,7 @@ var init_spawn4 = __esm({
14299
14722
  });
14300
14723
 
14301
14724
  // src/sdk/research.ts
14302
- import path19 from "node:path";
14725
+ import path22 from "node:path";
14303
14726
  async function research(container, options) {
14304
14727
  const logger2 = options.logger;
14305
14728
  const source = await resolveSource({
@@ -14334,7 +14757,7 @@ async function research(container, options) {
14334
14757
  markdown: markdownOutput
14335
14758
  });
14336
14759
  outputPath = buildOutputPath(container.env.homeDir, options.prompt);
14337
- await ensureDirectory2(container.fs, path19.dirname(outputPath));
14760
+ await ensureDirectory2(container.fs, path22.dirname(outputPath));
14338
14761
  await container.fs.writeFile(outputPath, document, {
14339
14762
  encoding: "utf8"
14340
14763
  });
@@ -14409,7 +14832,7 @@ function buildResearchDocument(input) {
14409
14832
  }
14410
14833
  function buildClonePath(homeDir, github) {
14411
14834
  const slug = extractRepoSlug(github);
14412
- return path19.join(homeDir, ".poe-code", "repos", slug);
14835
+ return path22.join(homeDir, ".poe-code", "repos", slug);
14413
14836
  }
14414
14837
  function extractRepoSlug(value) {
14415
14838
  const trimmed = value.trim();
@@ -14447,7 +14870,7 @@ function extractRepoSlug(value) {
14447
14870
  function buildOutputPath(homeDir, prompt, now = /* @__PURE__ */ new Date()) {
14448
14871
  const timestamp = formatTimestamp2(now);
14449
14872
  const slug = buildSlug(prompt);
14450
- return path19.join(
14873
+ return path22.join(
14451
14874
  homeDir,
14452
14875
  ".poe-code",
14453
14876
  "research",
@@ -14468,7 +14891,7 @@ async function resolveSource(input) {
14468
14891
  if (options.github) {
14469
14892
  const cloneUrl = resolveGithubCloneUrl(options.github);
14470
14893
  const clonePath = buildClonePath(container.env.homeDir, options.github);
14471
- await ensureDirectory2(container.fs, path19.dirname(clonePath));
14894
+ await ensureDirectory2(container.fs, path22.dirname(clonePath));
14472
14895
  const exists = await pathExists2(container.fs, clonePath);
14473
14896
  if (!exists) {
14474
14897
  const cloneResult = await container.commandRunner(
@@ -14566,10 +14989,10 @@ function formatYamlString(value) {
14566
14989
  return JSON.stringify(value);
14567
14990
  }
14568
14991
  function resolvePath2(baseDir, candidate) {
14569
- if (path19.isAbsolute(candidate)) {
14992
+ if (path22.isAbsolute(candidate)) {
14570
14993
  return candidate;
14571
14994
  }
14572
- return path19.resolve(baseDir, candidate);
14995
+ return path22.resolve(baseDir, candidate);
14573
14996
  }
14574
14997
  function teeAcpStream(events) {
14575
14998
  const chunks = [];
@@ -14629,7 +15052,7 @@ async function removePathFallback(fs3, target) {
14629
15052
  if (stats && typeof stats.isDirectory === "function" && stats.isDirectory()) {
14630
15053
  const entries = await fs3.readdir(target);
14631
15054
  for (const entry of entries) {
14632
- await removePathFallback(fs3, path19.join(target, entry));
15055
+ await removePathFallback(fs3, path22.join(target, entry));
14633
15056
  }
14634
15057
  }
14635
15058
  try {
@@ -14796,7 +15219,7 @@ var init_research2 = __esm({
14796
15219
  async "src/cli/commands/research.ts"() {
14797
15220
  "use strict";
14798
15221
  init_src5();
14799
- init_config2();
15222
+ init_config3();
14800
15223
  await init_research();
14801
15224
  init_errors();
14802
15225
  init_shared();
@@ -15026,7 +15449,7 @@ var init_login = __esm({
15026
15449
  "use strict";
15027
15450
  init_shared();
15028
15451
  init_errors();
15029
- init_config2();
15452
+ init_config3();
15030
15453
  init_mutation_events();
15031
15454
  }
15032
15455
  });
@@ -15151,7 +15574,7 @@ function formatUnconfigureMessages(service, label, unconfigured, _payload) {
15151
15574
  var init_unconfigure = __esm({
15152
15575
  "src/cli/commands/unconfigure.ts"() {
15153
15576
  "use strict";
15154
- init_config2();
15577
+ init_config3();
15155
15578
  init_mutation_events();
15156
15579
  init_isolated_env();
15157
15580
  init_shared();
@@ -15205,7 +15628,7 @@ async function executeLogout(program, container) {
15205
15628
  var init_logout = __esm({
15206
15629
  "src/cli/commands/logout.ts"() {
15207
15630
  "use strict";
15208
- init_config2();
15631
+ init_config3();
15209
15632
  init_shared();
15210
15633
  init_unconfigure();
15211
15634
  }
@@ -15305,7 +15728,7 @@ var init_auth = __esm({
15305
15728
  "src/cli/commands/auth.ts"() {
15306
15729
  "use strict";
15307
15730
  init_errors();
15308
- init_config2();
15731
+ init_config3();
15309
15732
  init_shared();
15310
15733
  init_login();
15311
15734
  init_logout();
@@ -15508,7 +15931,7 @@ var init_media_download = __esm({
15508
15931
  });
15509
15932
 
15510
15933
  // src/cli/commands/generate.ts
15511
- import path20 from "node:path";
15934
+ import path23 from "node:path";
15512
15935
  function registerGenerateCommand(program, container) {
15513
15936
  const generate2 = program.command("generate").description("Generate content via Poe API").option("--model <model>", `Model identifier (default: ${DEFAULT_TEXT_MODEL})`).option(
15514
15937
  "--param <key=value>",
@@ -15774,11 +16197,11 @@ function getDefaultMimeType(type) {
15774
16197
  return defaults[type];
15775
16198
  }
15776
16199
  function resolveOutputPath(filename, cwd) {
15777
- if (path20.isAbsolute(filename)) {
16200
+ if (path23.isAbsolute(filename)) {
15778
16201
  return { path: filename, label: filename };
15779
16202
  }
15780
16203
  return {
15781
- path: path20.join(cwd, filename),
16204
+ path: path23.join(cwd, filename),
15782
16205
  label: `./${filename}`
15783
16206
  };
15784
16207
  }
@@ -16471,7 +16894,7 @@ function defineSchema(definition) {
16471
16894
  required: required2
16472
16895
  };
16473
16896
  }
16474
- var init_schema = __esm({
16897
+ var init_schema2 = __esm({
16475
16898
  "packages/tiny-stdio-mcp-server/src/schema.ts"() {
16476
16899
  "use strict";
16477
16900
  }
@@ -16882,8 +17305,8 @@ var init_parseUtil = __esm({
16882
17305
  init_errors3();
16883
17306
  init_en();
16884
17307
  makeIssue = (params) => {
16885
- const { data, path: path24, errorMaps, issueData } = params;
16886
- const fullPath = [...path24, ...issueData.path || []];
17308
+ const { data, path: path27, errorMaps, issueData } = params;
17309
+ const fullPath = [...path27, ...issueData.path || []];
16887
17310
  const fullIssue = {
16888
17311
  ...issueData,
16889
17312
  path: fullPath
@@ -17163,11 +17586,11 @@ var init_types4 = __esm({
17163
17586
  init_parseUtil();
17164
17587
  init_util();
17165
17588
  ParseInputLazyPath = class {
17166
- constructor(parent, value, path24, key) {
17589
+ constructor(parent, value, path27, key) {
17167
17590
  this._cachedPath = [];
17168
17591
  this.parent = parent;
17169
17592
  this.data = value;
17170
- this._path = path24;
17593
+ this._path = path27;
17171
17594
  this._key = key;
17172
17595
  }
17173
17596
  get path() {
@@ -20671,10 +21094,10 @@ function mergeDefs(...defs) {
20671
21094
  function cloneDef(schema) {
20672
21095
  return mergeDefs(schema._zod.def);
20673
21096
  }
20674
- function getElementAtPath(obj, path24) {
20675
- if (!path24)
21097
+ function getElementAtPath(obj, path27) {
21098
+ if (!path27)
20676
21099
  return obj;
20677
- return path24.reduce((acc, key) => acc?.[key], obj);
21100
+ return path27.reduce((acc, key) => acc?.[key], obj);
20678
21101
  }
20679
21102
  function promiseAllObject(promisesObj) {
20680
21103
  const keys = Object.keys(promisesObj);
@@ -20986,11 +21409,11 @@ function aborted(x, startIndex = 0) {
20986
21409
  }
20987
21410
  return false;
20988
21411
  }
20989
- function prefixIssues(path24, issues) {
21412
+ function prefixIssues(path27, issues) {
20990
21413
  return issues.map((iss) => {
20991
21414
  var _a2;
20992
21415
  (_a2 = iss).path ?? (_a2.path = []);
20993
- iss.path.unshift(path24);
21416
+ iss.path.unshift(path27);
20994
21417
  return iss;
20995
21418
  });
20996
21419
  }
@@ -33151,8 +33574,8 @@ var require_utils = __commonJS({
33151
33574
  }
33152
33575
  return ind;
33153
33576
  }
33154
- function removeDotSegments(path24) {
33155
- let input = path24;
33577
+ function removeDotSegments(path27) {
33578
+ let input = path27;
33156
33579
  const output = [];
33157
33580
  let nextSlash = -1;
33158
33581
  let len = 0;
@@ -33351,8 +33774,8 @@ var require_schemes = __commonJS({
33351
33774
  wsComponent.secure = void 0;
33352
33775
  }
33353
33776
  if (wsComponent.resourceName) {
33354
- const [path24, query] = wsComponent.resourceName.split("?");
33355
- wsComponent.path = path24 && path24 !== "/" ? path24 : void 0;
33777
+ const [path27, query] = wsComponent.resourceName.split("?");
33778
+ wsComponent.path = path27 && path27 !== "/" ? path27 : void 0;
33356
33779
  wsComponent.query = query;
33357
33780
  wsComponent.resourceName = void 0;
33358
33781
  }
@@ -36585,11 +37008,11 @@ var init_content = __esm({
36585
37008
  });
36586
37009
 
36587
37010
  // packages/tiny-stdio-mcp-server/src/index.ts
36588
- var init_src11 = __esm({
37011
+ var init_src13 = __esm({
36589
37012
  "packages/tiny-stdio-mcp-server/src/index.ts"() {
36590
37013
  "use strict";
36591
37014
  init_server();
36592
- init_schema();
37015
+ init_schema2();
36593
37016
  init_testing();
36594
37017
  init_content();
36595
37018
  init_types3();
@@ -36889,7 +37312,7 @@ var generateTextSchema, generateImageSchema, generateVideoSchema, generateAudioS
36889
37312
  var init_mcp_server = __esm({
36890
37313
  "src/cli/mcp-server.ts"() {
36891
37314
  "use strict";
36892
- init_src11();
37315
+ init_src13();
36893
37316
  init_client_instance();
36894
37317
  init_constants();
36895
37318
  generateTextSchema = defineSchema({
@@ -37295,9 +37718,9 @@ var init_shapes = __esm({
37295
37718
  });
37296
37719
 
37297
37720
  // packages/agent-mcp-config/src/apply.ts
37298
- import path21 from "node:path";
37721
+ import path24 from "node:path";
37299
37722
  function getConfigDirectory(configPath) {
37300
- return path21.dirname(configPath);
37723
+ return path24.dirname(configPath);
37301
37724
  }
37302
37725
  function isConfigObject5(value) {
37303
37726
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
@@ -37399,7 +37822,7 @@ var init_apply = __esm({
37399
37822
  });
37400
37823
 
37401
37824
  // packages/agent-mcp-config/src/index.ts
37402
- var init_src12 = __esm({
37825
+ var init_src14 = __esm({
37403
37826
  "packages/agent-mcp-config/src/index.ts"() {
37404
37827
  "use strict";
37405
37828
  init_configs2();
@@ -37579,7 +38002,7 @@ var init_mcp2 = __esm({
37579
38002
  init_shared();
37580
38003
  init_mcp_output_format();
37581
38004
  init_command_not_found();
37582
- init_src12();
38005
+ init_src14();
37583
38006
  init_execution_context();
37584
38007
  DEFAULT_MCP_AGENT = "claude-code";
37585
38008
  }
@@ -37587,7 +38010,7 @@ var init_mcp2 = __esm({
37587
38010
 
37588
38011
  // packages/agent-skill-config/src/configs.ts
37589
38012
  import os2 from "node:os";
37590
- import path22 from "node:path";
38013
+ import path25 from "node:path";
37591
38014
  function resolveAgentSupport2(input, registry2 = agentSkillConfigs) {
37592
38015
  const resolvedId = resolveAgentId(input);
37593
38016
  if (!resolvedId) {
@@ -37623,7 +38046,7 @@ var init_configs3 = __esm({
37623
38046
  });
37624
38047
 
37625
38048
  // packages/agent-skill-config/src/templates.ts
37626
- import { readFile as readFile5 } from "node:fs/promises";
38049
+ import { readFile as readFile7 } from "node:fs/promises";
37627
38050
  async function getTemplates() {
37628
38051
  if (templatesCache) {
37629
38052
  return templatesCache;
@@ -37632,7 +38055,7 @@ async function getTemplates() {
37632
38055
  "./templates/poe-generate.md",
37633
38056
  import.meta.url
37634
38057
  );
37635
- const poeGenerateTemplate = await readFile5(poeGenerateTemplateUrl, "utf8");
38058
+ const poeGenerateTemplate = await readFile7(poeGenerateTemplateUrl, "utf8");
37636
38059
  templatesCache = {
37637
38060
  "poe-generate.md": poeGenerateTemplate
37638
38061
  };
@@ -37779,7 +38202,7 @@ var init_apply2 = __esm({
37779
38202
  });
37780
38203
 
37781
38204
  // packages/agent-skill-config/src/index.ts
37782
- var init_src13 = __esm({
38205
+ var init_src15 = __esm({
37783
38206
  "packages/agent-skill-config/src/index.ts"() {
37784
38207
  "use strict";
37785
38208
  init_configs3();
@@ -38004,7 +38427,7 @@ var init_skill = __esm({
38004
38427
  "src/cli/commands/skill.ts"() {
38005
38428
  "use strict";
38006
38429
  init_src4();
38007
- init_src13();
38430
+ init_src15();
38008
38431
  init_shared();
38009
38432
  init_command_not_found();
38010
38433
  DEFAULT_SKILL_AGENT = "claude-code";
@@ -38598,8 +39021,8 @@ var init_models = __esm({
38598
39021
  });
38599
39022
 
38600
39023
  // src/cli/commands/pipeline.ts
38601
- import path23 from "node:path";
38602
- import { readFile as readFile6, stat as stat5 } from "node:fs/promises";
39024
+ import path26 from "node:path";
39025
+ import { readFile as readFile8, stat as stat7 } from "node:fs/promises";
38603
39026
  import { fileURLToPath as fileURLToPath4 } from "node:url";
38604
39027
  function formatDuration(ms) {
38605
39028
  const totalSeconds = Math.round(ms / 1e3);
@@ -38630,11 +39053,11 @@ function resolveMaxRuns(value) {
38630
39053
  return parsed;
38631
39054
  }
38632
39055
  function resolvePipelinePaths(scope, cwd, homeDir) {
38633
- const rootPath = scope === "global" ? path23.join(homeDir, ".poe-code", "pipeline") : path23.join(cwd, ".poe-code", "pipeline");
39056
+ const rootPath = scope === "global" ? path26.join(homeDir, ".poe-code", "pipeline") : path26.join(cwd, ".poe-code", "pipeline");
38634
39057
  const displayRoot = scope === "global" ? "~/.poe-code/pipeline" : ".poe-code/pipeline";
38635
39058
  return {
38636
- plansPath: path23.join(rootPath, "plans"),
38637
- stepsPath: path23.join(rootPath, "steps.yaml"),
39059
+ plansPath: path26.join(rootPath, "plans"),
39060
+ stepsPath: path26.join(rootPath, "steps.yaml"),
38638
39061
  displayPlansPath: `${displayRoot}/plans`,
38639
39062
  displayStepsPath: `${displayRoot}/steps.yaml`
38640
39063
  };
@@ -38645,16 +39068,16 @@ async function loadPipelineTemplates() {
38645
39068
  }
38646
39069
  const packageRoot = await findPackageRoot(fileURLToPath4(import.meta.url));
38647
39070
  const templateRoots = [
38648
- path23.join(packageRoot, "src", "templates", "pipeline"),
38649
- path23.join(packageRoot, "dist", "templates", "pipeline")
39071
+ path26.join(packageRoot, "src", "templates", "pipeline"),
39072
+ path26.join(packageRoot, "dist", "templates", "pipeline")
38650
39073
  ];
38651
39074
  for (const templateRoot of templateRoots) {
38652
39075
  if (!await pathExistsOnDisk(templateRoot)) {
38653
39076
  continue;
38654
39077
  }
38655
39078
  const [skillPlan, steps] = await Promise.all([
38656
- readFile6(path23.join(templateRoot, "SKILL_plan.md"), "utf8"),
38657
- readFile6(path23.join(templateRoot, "steps.yaml.hbs"), "utf8")
39079
+ readFile8(path26.join(templateRoot, "SKILL_plan.md"), "utf8"),
39080
+ readFile8(path26.join(templateRoot, "steps.yaml.hbs"), "utf8")
38658
39081
  ]);
38659
39082
  pipelineTemplatesCache = { skillPlan, steps };
38660
39083
  return pipelineTemplatesCache;
@@ -38663,7 +39086,7 @@ async function loadPipelineTemplates() {
38663
39086
  }
38664
39087
  async function pathExistsOnDisk(targetPath) {
38665
39088
  try {
38666
- await stat5(targetPath);
39089
+ await stat7(targetPath);
38667
39090
  return true;
38668
39091
  } catch (error2) {
38669
39092
  if (error2 && typeof error2 === "object" && "code" in error2 && error2.code === "ENOENT") {
@@ -38673,12 +39096,12 @@ async function pathExistsOnDisk(targetPath) {
38673
39096
  }
38674
39097
  }
38675
39098
  async function findPackageRoot(entryFilePath) {
38676
- let currentPath = path23.dirname(entryFilePath);
39099
+ let currentPath = path26.dirname(entryFilePath);
38677
39100
  while (true) {
38678
- if (await pathExistsOnDisk(path23.join(currentPath, "package.json"))) {
39101
+ if (await pathExistsOnDisk(path26.join(currentPath, "package.json"))) {
38679
39102
  return currentPath;
38680
39103
  }
38681
- const parentPath = path23.dirname(currentPath);
39104
+ const parentPath = path26.dirname(currentPath);
38682
39105
  if (parentPath === currentPath) {
38683
39106
  throw new Error("Unable to locate package root for Pipeline templates.");
38684
39107
  }
@@ -38956,7 +39379,7 @@ function registerPipelineCommand(program, container) {
38956
39379
  `Would ${stepsExists ? "overwrite" : "create"}: ${pipelinePaths.displayStepsPath}`
38957
39380
  );
38958
39381
  } else {
38959
- await container.fs.mkdir(path23.dirname(pipelinePaths.stepsPath), {
39382
+ await container.fs.mkdir(path26.dirname(pipelinePaths.stepsPath), {
38960
39383
  recursive: true
38961
39384
  });
38962
39385
  await container.fs.writeFile(pipelinePaths.stepsPath, templates.steps, {
@@ -38981,24 +39404,244 @@ var init_pipeline4 = __esm({
38981
39404
  "use strict";
38982
39405
  init_src4();
38983
39406
  init_src3();
38984
- init_src13();
39407
+ init_src15();
38985
39408
  init_errors();
38986
39409
  init_shared();
38987
39410
  await init_pipeline2();
38988
- init_src9();
39411
+ init_src10();
38989
39412
  DEFAULT_PIPELINE_AGENT = "claude-code";
38990
39413
  DEFAULT_PIPELINE_SCOPE = "local";
38991
39414
  pipelineTemplatesCache = null;
38992
39415
  }
38993
39416
  });
38994
39417
 
39418
+ // src/cli/commands/ralph.ts
39419
+ function formatDuration2(ms) {
39420
+ const totalSeconds = Math.round(ms / 1e3);
39421
+ const minutes = Math.floor(totalSeconds / 60);
39422
+ const seconds = totalSeconds % 60;
39423
+ return minutes > 0 ? `${minutes}m ${seconds}s` : `${seconds}s`;
39424
+ }
39425
+ function resolveRalphAgent(value) {
39426
+ if (!value || value.trim().length === 0) {
39427
+ return DEFAULT_RALPH_AGENT;
39428
+ }
39429
+ const resolved = resolveAgentId(value.trim());
39430
+ if (!resolved) {
39431
+ throw new ValidationError(`Unsupported agent: ${value}`);
39432
+ }
39433
+ return resolved;
39434
+ }
39435
+ function parsePositiveInt(value, fieldName) {
39436
+ if (value == null) {
39437
+ return void 0;
39438
+ }
39439
+ const parsed = Number.parseInt(value, 10);
39440
+ if (!Number.isFinite(parsed) || parsed < 1) {
39441
+ throw new ValidationError(
39442
+ `Invalid ${fieldName} "${value}". Expected a positive integer.`
39443
+ );
39444
+ }
39445
+ return parsed;
39446
+ }
39447
+ async function resolveAgent(options) {
39448
+ if (options.providedAgent) {
39449
+ return resolveRalphAgent(options.providedAgent);
39450
+ }
39451
+ const flags = resolveCommandFlags(options.program);
39452
+ if (flags.assumeYes) {
39453
+ return DEFAULT_RALPH_AGENT;
39454
+ }
39455
+ const selected = await select2({
39456
+ message: "Select agent to run Ralph with:",
39457
+ options: allSpawnConfigs.map((config2) => ({
39458
+ label: config2.agentId,
39459
+ value: config2.agentId
39460
+ }))
39461
+ });
39462
+ if (isCancel2(selected)) {
39463
+ cancel2("Ralph run cancelled.");
39464
+ return null;
39465
+ }
39466
+ return resolveRalphAgent(typeof selected === "string" ? selected : void 0);
39467
+ }
39468
+ async function resolveDocPath(options) {
39469
+ if (options.providedDoc && options.providedDoc.trim().length > 0) {
39470
+ return options.providedDoc.trim();
39471
+ }
39472
+ const docs = await discoverDocs({
39473
+ cwd: options.container.env.cwd,
39474
+ homeDir: options.container.env.homeDir,
39475
+ fs: options.container.fs
39476
+ });
39477
+ if (docs.length === 0) {
39478
+ throw new ValidationError(
39479
+ "No markdown doc found under .poe-code/ralph/plans/ or ~/.poe-code/ralph/plans/. Provide a doc path."
39480
+ );
39481
+ }
39482
+ const flags = resolveCommandFlags(options.program);
39483
+ if (flags.assumeYes) {
39484
+ return docs[0].path;
39485
+ }
39486
+ const selected = await select2({
39487
+ message: "Select the Ralph markdown doc to run:",
39488
+ options: docs.map((doc) => ({
39489
+ label: doc.displayPath,
39490
+ value: doc.path
39491
+ }))
39492
+ });
39493
+ if (isCancel2(selected)) {
39494
+ cancel2("Ralph run cancelled.");
39495
+ return null;
39496
+ }
39497
+ return typeof selected === "string" ? selected : null;
39498
+ }
39499
+ async function resolveIterations(options) {
39500
+ const explicitIterations = parsePositiveInt(
39501
+ options.providedIterations,
39502
+ "iterations"
39503
+ );
39504
+ if (explicitIterations != null) {
39505
+ return explicitIterations;
39506
+ }
39507
+ const flags = resolveCommandFlags(options.program);
39508
+ if (flags.assumeYes) {
39509
+ throw new ValidationError(
39510
+ "Iterations are required when using --yes. Provide poe-code ralph run <iterations> [doc]."
39511
+ );
39512
+ }
39513
+ const entered = await text3({
39514
+ message: "How many Ralph iterations should run?"
39515
+ });
39516
+ if (isCancel2(entered)) {
39517
+ cancel2("Ralph run cancelled.");
39518
+ return null;
39519
+ }
39520
+ return parsePositiveInt(
39521
+ typeof entered === "string" ? entered.trim() : void 0,
39522
+ "iterations"
39523
+ ) ?? null;
39524
+ }
39525
+ function registerRalphCommand(program, container) {
39526
+ const ralph = program.command("ralph").description("Run a simple iterative markdown loop.");
39527
+ ralph.command("run").description("Run the selected markdown doc through repeated agent iterations.").argument("[iterations]", "Number of Ralph iterations to run").argument("[doc]", "Markdown doc path").option("--agent <name>", "Agent to run each iteration with").option("--model <model>", "Model override passed to the agent").option(
39528
+ "--max-failures <n>",
39529
+ "Consecutive failure threshold before overbake protection prompts"
39530
+ ).action(async function(iterationsArg, docArg) {
39531
+ const flags = resolveCommandFlags(program);
39532
+ const resources = createExecutionResources(container, flags, "ralph:run");
39533
+ const options = this.opts();
39534
+ resources.logger.intro("ralph run");
39535
+ try {
39536
+ const docPath = await resolveDocPath({
39537
+ container,
39538
+ program,
39539
+ providedDoc: docArg
39540
+ });
39541
+ if (!docPath) {
39542
+ return;
39543
+ }
39544
+ const agent2 = await resolveAgent({
39545
+ program,
39546
+ providedAgent: options.agent
39547
+ });
39548
+ if (!agent2) {
39549
+ return;
39550
+ }
39551
+ const maxIterations = await resolveIterations({
39552
+ program,
39553
+ providedIterations: iterationsArg
39554
+ });
39555
+ if (maxIterations == null) {
39556
+ return;
39557
+ }
39558
+ const maxFailures = parsePositiveInt(
39559
+ options.maxFailures,
39560
+ "max-failures"
39561
+ );
39562
+ const result = await runRalph2({
39563
+ agent: agent2,
39564
+ cwd: container.env.cwd,
39565
+ homeDir: container.env.homeDir,
39566
+ docPath,
39567
+ maxIterations,
39568
+ ...options.model ? { model: options.model } : {},
39569
+ ...maxFailures != null ? { maxFailures } : {},
39570
+ promptOverbake: async (input) => {
39571
+ const selected = await select2({
39572
+ message: `Ralph hit ${input.consecutiveFailures} consecutive failures (threshold ${input.threshold}). What should happen next?`,
39573
+ options: [
39574
+ { label: "Continue", value: "continue" },
39575
+ { label: "Abort", value: "abort" }
39576
+ ]
39577
+ });
39578
+ if (isCancel2(selected)) {
39579
+ cancel2("Ralph run cancelled.");
39580
+ return "abort";
39581
+ }
39582
+ return selected === "continue" ? "continue" : "abort";
39583
+ },
39584
+ onIterationStart(iteration, total) {
39585
+ resources.logger.info(`Iteration ${iteration}/${total}`);
39586
+ },
39587
+ onIterationComplete(iteration, durationMs, success2) {
39588
+ const status = success2 ? "done" : "failed";
39589
+ resources.logger.info(
39590
+ `Iteration ${iteration} ${status} in ${formatDuration2(durationMs)}`
39591
+ );
39592
+ },
39593
+ onOverbakeWarning(consecutiveFailures, threshold) {
39594
+ resources.logger.warn(
39595
+ `Overbake protection triggered at ${consecutiveFailures} consecutive failures (threshold ${threshold}).`
39596
+ );
39597
+ }
39598
+ });
39599
+ const summary = [
39600
+ `Iterations: ${result.iterationsCompleted}/${maxIterations}`,
39601
+ `Doc: ${result.docPath}`,
39602
+ `Duration: ${formatDuration2(result.totalDurationMs)}`
39603
+ ].join("\n ");
39604
+ if (result.stopReason === "cancelled") {
39605
+ process.exitCode = 130;
39606
+ resources.logger.warn("Ralph run cancelled.");
39607
+ resources.logger.resolved("Run summary", summary);
39608
+ return;
39609
+ }
39610
+ if (result.stopReason === "overbake_abort") {
39611
+ process.exitCode = 1;
39612
+ resources.logger.warn("Ralph stopped after repeated failures.");
39613
+ resources.logger.resolved("Run summary", summary);
39614
+ return;
39615
+ }
39616
+ resources.logger.resolved("Run summary", summary);
39617
+ resources.logger.success("Ralph run finished.");
39618
+ } finally {
39619
+ resources.context.finalize();
39620
+ }
39621
+ });
39622
+ }
39623
+ var DEFAULT_RALPH_AGENT;
39624
+ var init_ralph3 = __esm({
39625
+ async "src/cli/commands/ralph.ts"() {
39626
+ "use strict";
39627
+ init_src4();
39628
+ init_src3();
39629
+ init_src5();
39630
+ init_src11();
39631
+ init_errors();
39632
+ init_shared();
39633
+ await init_ralph2();
39634
+ DEFAULT_RALPH_AGENT = "claude-code";
39635
+ }
39636
+ });
39637
+
38995
39638
  // package.json
38996
39639
  var package_default;
38997
39640
  var init_package = __esm({
38998
39641
  "package.json"() {
38999
39642
  package_default = {
39000
39643
  name: "poe-code",
39001
- version: "3.0.101",
39644
+ version: "3.0.102",
39002
39645
  description: "CLI tool to configure Poe API for developer workflows.",
39003
39646
  type: "module",
39004
39647
  main: "./dist/index.js",
@@ -39091,6 +39734,8 @@ var init_package = __esm({
39091
39734
  "@poe-code/freeze-cli": "*",
39092
39735
  "@poe-code/pipeline": "*",
39093
39736
  "@poe-code/poe-acp-client": "*",
39737
+ "@poe-code/poe-code-config": "*",
39738
+ "@poe-code/ralph": "*",
39094
39739
  "@types/mustache": "^4.2.6",
39095
39740
  "@types/node": "^25.2.2",
39096
39741
  "@types/semver": "^7.7.1",
@@ -39214,6 +39859,11 @@ function formatHelpText(input) {
39214
39859
  args: "",
39215
39860
  description: "Run a fixed-step task pipeline plan"
39216
39861
  },
39862
+ {
39863
+ name: "ralph run",
39864
+ args: "[iterations] [doc]",
39865
+ description: "Run a markdown doc through repeated agent iterations"
39866
+ },
39217
39867
  {
39218
39868
  name: "usage",
39219
39869
  args: "",
@@ -39223,11 +39873,6 @@ function formatHelpText(input) {
39223
39873
  name: "usage list",
39224
39874
  args: "",
39225
39875
  description: "Display usage history"
39226
- },
39227
- {
39228
- name: "pipeline run",
39229
- args: "",
39230
- description: "Run a fixed-step task pipeline plan"
39231
39876
  }
39232
39877
  ];
39233
39878
  const nameWidth = Math.max(0, ...commandRows.map((row) => row.name.length));
@@ -39377,6 +40022,7 @@ function bootstrapProgram(container) {
39377
40022
  registerMcpCommand(program, container);
39378
40023
  registerSkillCommand(program, container);
39379
40024
  registerPipelineCommand(program, container);
40025
+ registerRalphCommand(program, container);
39380
40026
  registerUsageCommand(program, container);
39381
40027
  registerModelsCommand(program, container);
39382
40028
  program.allowExcessArguments().action(function() {
@@ -39434,6 +40080,7 @@ var init_program = __esm({
39434
40080
  init_usage();
39435
40081
  init_models();
39436
40082
  await init_pipeline4();
40083
+ await init_ralph3();
39437
40084
  init_package();
39438
40085
  init_command_not_found();
39439
40086
  init_execution_context();
@@ -39607,6 +40254,7 @@ var init_bootstrap = __esm({
39607
40254
  // src/index.ts
39608
40255
  await init_spawn3();
39609
40256
  await init_pipeline2();
40257
+ await init_ralph2();
39610
40258
  import { realpathSync as realpathSync2 } from "node:fs";
39611
40259
  import { pathToFileURL as pathToFileURL3 } from "node:url";
39612
40260
 
@@ -39715,7 +40363,7 @@ init_src5();
39715
40363
  init_src4();
39716
40364
  init_constants();
39717
40365
  init_errors();
39718
- import path16 from "node:path";
40366
+ import path19 from "node:path";
39719
40367
  import { Command } from "commander";
39720
40368
  function parseMcpSpawnConfig(input) {
39721
40369
  if (!input) {
@@ -39786,10 +40434,10 @@ function resolveWorkingDirectory(baseDir, candidate) {
39786
40434
  if (!candidate || candidate.trim().length === 0) {
39787
40435
  return void 0;
39788
40436
  }
39789
- if (path16.isAbsolute(candidate)) {
40437
+ if (path19.isAbsolute(candidate)) {
39790
40438
  return candidate;
39791
40439
  }
39792
- return path16.resolve(baseDir, candidate);
40440
+ return path19.resolve(baseDir, candidate);
39793
40441
  }
39794
40442
  function createPoeAgentProgram() {
39795
40443
  const program = new Command();
@@ -39892,6 +40540,7 @@ export {
39892
40540
  main,
39893
40541
  poeAgentMain,
39894
40542
  runPipeline2 as runPipeline,
40543
+ runRalph2 as runRalph,
39895
40544
  spawn5 as spawn
39896
40545
  };
39897
40546
  //# sourceMappingURL=index.js.map