poe-code 3.0.60 → 3.0.61

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
@@ -352,16 +352,16 @@ function getConfigFormat(pathOrFormat) {
352
352
  }
353
353
  return formatRegistry[formatName];
354
354
  }
355
- function detectFormat(path19) {
356
- const ext = getExtension(path19);
355
+ function detectFormat(path20) {
356
+ const ext = getExtension(path20);
357
357
  return extensionMap[ext];
358
358
  }
359
- function getExtension(path19) {
360
- const lastDot = path19.lastIndexOf(".");
359
+ function getExtension(path20) {
360
+ const lastDot = path20.lastIndexOf(".");
361
361
  if (lastDot === -1) {
362
362
  return "";
363
363
  }
364
- return path19.slice(lastDot).toLowerCase();
364
+ return path20.slice(lastDot).toLowerCase();
365
365
  }
366
366
  var formatRegistry, extensionMap;
367
367
  var init_formats = __esm({
@@ -1077,9 +1077,6 @@ var init_render = __esm({
1077
1077
  });
1078
1078
 
1079
1079
  // packages/config-mutations/src/types.ts
1080
- function isConfigObject4(value) {
1081
- return typeof value === "object" && value !== null && !Array.isArray(value);
1082
- }
1083
1080
  var init_types = __esm({
1084
1081
  "packages/config-mutations/src/types.ts"() {
1085
1082
  "use strict";
@@ -1432,38 +1429,38 @@ import { createTwoFilesPatch } from "diff";
1432
1429
  import chalk from "chalk";
1433
1430
  function createDryRunFileSystem(base, recorder) {
1434
1431
  const proxy = {
1435
- async readFile(path19, encoding) {
1432
+ async readFile(path20, encoding) {
1436
1433
  if (encoding) {
1437
- return base.readFile(path19, encoding);
1434
+ return base.readFile(path20, encoding);
1438
1435
  }
1439
- return base.readFile(path19);
1436
+ return base.readFile(path20);
1440
1437
  },
1441
- async writeFile(path19, data, options) {
1442
- const previousContent = await tryReadText(base, path19);
1438
+ async writeFile(path20, data, options) {
1439
+ const previousContent = await tryReadText(base, path20);
1443
1440
  const nextContent = formatData(data, options?.encoding);
1444
1441
  recorder.record({
1445
1442
  type: "writeFile",
1446
- path: path19,
1443
+ path: path20,
1447
1444
  nextContent,
1448
1445
  previousContent
1449
1446
  });
1450
1447
  },
1451
- async mkdir(path19, options) {
1452
- recorder.record({ type: "mkdir", path: path19, options });
1448
+ async mkdir(path20, options) {
1449
+ recorder.record({ type: "mkdir", path: path20, options });
1453
1450
  },
1454
- async stat(path19) {
1455
- return base.stat(path19);
1451
+ async stat(path20) {
1452
+ return base.stat(path20);
1456
1453
  },
1457
- async unlink(path19) {
1458
- recorder.record({ type: "unlink", path: path19 });
1454
+ async unlink(path20) {
1455
+ recorder.record({ type: "unlink", path: path20 });
1459
1456
  },
1460
- async readdir(path19) {
1461
- return base.readdir(path19);
1457
+ async readdir(path20) {
1458
+ return base.readdir(path20);
1462
1459
  }
1463
1460
  };
1464
1461
  if (typeof base.rm === "function") {
1465
- proxy.rm = async (path19, options) => {
1466
- recorder.record({ type: "rm", path: path19, options });
1462
+ proxy.rm = async (path20, options) => {
1463
+ recorder.record({ type: "rm", path: path20, options });
1467
1464
  };
1468
1465
  }
1469
1466
  if (typeof base.copyFile === "function") {
@@ -1553,8 +1550,8 @@ function describeWriteChange(previous, next) {
1553
1550
  }
1554
1551
  return "update";
1555
1552
  }
1556
- function renderWriteCommand(path19, change) {
1557
- const command = `cat > ${path19}`;
1553
+ function renderWriteCommand(path20, change) {
1554
+ const command = `cat > ${path20}`;
1558
1555
  if (change === "create") {
1559
1556
  return renderOperationCommand(command, chalk.green, "# create");
1560
1557
  }
@@ -1716,9 +1713,9 @@ function redactTomlLine(line) {
1716
1713
  }
1717
1714
  return line;
1718
1715
  }
1719
- async function tryReadText(base, path19) {
1716
+ async function tryReadText(base, path20) {
1720
1717
  try {
1721
- return await base.readFile(path19, "utf8");
1718
+ return await base.readFile(path20, "utf8");
1722
1719
  } catch (error2) {
1723
1720
  if (isNotFound(error2)) {
1724
1721
  return null;
@@ -1764,22 +1761,10 @@ var init_dry_run = __esm({
1764
1761
  });
1765
1762
 
1766
1763
  // src/cli/constants.ts
1767
- function stripModelNamespace(model) {
1768
- const slashIndex = model.indexOf("/");
1769
- const id = slashIndex === -1 ? model : model.slice(slashIndex + 1);
1770
- return id.toLowerCase();
1771
- }
1772
- var FRONTIER_MODELS, DEFAULT_FRONTIER_MODEL, DEFAULT_TEXT_MODEL, DEFAULT_IMAGE_BOT, DEFAULT_AUDIO_BOT, DEFAULT_VIDEO_BOT, CLAUDE_CODE_VARIANTS, DEFAULT_CLAUDE_CODE_MODEL, CODEX_MODELS, DEFAULT_CODEX_MODEL, KIMI_MODELS, DEFAULT_KIMI_MODEL, DEFAULT_REASONING, PROVIDER_NAME, FEEDBACK_URL;
1764
+ var DEFAULT_TEXT_MODEL, DEFAULT_IMAGE_BOT, DEFAULT_AUDIO_BOT, DEFAULT_VIDEO_BOT, CLAUDE_CODE_VARIANTS, DEFAULT_CLAUDE_CODE_MODEL, CODEX_MODELS, DEFAULT_CODEX_MODEL, KIMI_MODELS, DEFAULT_KIMI_MODEL, FEEDBACK_URL;
1773
1765
  var init_constants = __esm({
1774
1766
  "src/cli/constants.ts"() {
1775
1767
  "use strict";
1776
- FRONTIER_MODELS = [
1777
- "anthropic/claude-opus-4.6",
1778
- "anthropic/claude-sonnet-4.6",
1779
- "openai/gpt-5.2",
1780
- "google/gemini-3-pro"
1781
- ];
1782
- DEFAULT_FRONTIER_MODEL = "anthropic/claude-sonnet-4.6";
1783
1768
  DEFAULT_TEXT_MODEL = "anthropic/claude-sonnet-4.6";
1784
1769
  DEFAULT_IMAGE_BOT = "google/nano-banana-pro";
1785
1770
  DEFAULT_AUDIO_BOT = "elevenlabs/elevenlabs-v3";
@@ -1804,8 +1789,6 @@ var init_constants = __esm({
1804
1789
  "novitaai/kimi-k2-thinking"
1805
1790
  ];
1806
1791
  DEFAULT_KIMI_MODEL = KIMI_MODELS[0];
1807
- DEFAULT_REASONING = "medium";
1808
- PROVIDER_NAME = "poe";
1809
1792
  FEEDBACK_URL = "https://github.com/poe-platform/poe-code/issues";
1810
1793
  }
1811
1794
  });
@@ -2861,7 +2844,7 @@ var init_resolve_config = __esm({
2861
2844
  });
2862
2845
 
2863
2846
  // packages/agent-spawn/src/model-utils.ts
2864
- function stripModelNamespace2(model) {
2847
+ function stripModelNamespace(model) {
2865
2848
  const slashIndex = model.indexOf("/");
2866
2849
  return slashIndex === -1 ? model : model.slice(slashIndex + 1);
2867
2850
  }
@@ -2897,7 +2880,7 @@ function buildCliArgs(config2, options, stdinMode) {
2897
2880
  ...stdinMode.extraArgs
2898
2881
  ] : [config2.promptFlag, options.prompt];
2899
2882
  if (options.model && config2.modelFlag) {
2900
- let model = config2.modelStripProviderPrefix ? stripModelNamespace2(options.model) : options.model;
2883
+ let model = config2.modelStripProviderPrefix ? stripModelNamespace(options.model) : options.model;
2901
2884
  if (config2.modelTransform) model = config2.modelTransform(model);
2902
2885
  args.push(config2.modelFlag, model);
2903
2886
  }
@@ -2908,11 +2891,6 @@ function buildCliArgs(config2, options, stdinMode) {
2908
2891
  }
2909
2892
  return args;
2910
2893
  }
2911
- function buildSpawnArgs(agentId, options) {
2912
- const { binaryName, spawnConfig } = resolveCliConfig(agentId);
2913
- const stdinMode = options.useStdin && spawnConfig.stdinMode ? spawnConfig.stdinMode : void 0;
2914
- return { binaryName, args: buildCliArgs(spawnConfig, options, stdinMode) };
2915
- }
2916
2894
  async function spawn2(agentId, options, context) {
2917
2895
  const { agentId: resolvedId, binaryName, spawnConfig } = resolveCliConfig(agentId);
2918
2896
  const stdinMode = options.useStdin && spawnConfig.stdinMode ? spawnConfig.stdinMode : void 0;
@@ -2999,7 +2977,7 @@ async function spawnInteractive(agentId, options) {
2999
2977
  }
3000
2978
  }
3001
2979
  if (options.model && spawnConfig.modelFlag) {
3002
- let model = spawnConfig.modelStripProviderPrefix ? stripModelNamespace2(options.model) : options.model;
2980
+ let model = spawnConfig.modelStripProviderPrefix ? stripModelNamespace(options.model) : options.model;
3003
2981
  if (spawnConfig.modelTransform) model = spawnConfig.modelTransform(model);
3004
2982
  args.push(spawnConfig.modelFlag, model);
3005
2983
  }
@@ -3213,21 +3191,21 @@ async function* adaptClaude(lines) {
3213
3191
  if (blockType !== "tool_result") continue;
3214
3192
  const kind = toolKindsById.get(item.tool_use_id);
3215
3193
  toolKindsById.delete(item.tool_use_id);
3216
- let path19;
3194
+ let path20;
3217
3195
  if (typeof item.content === "string") {
3218
- path19 = item.content;
3196
+ path20 = item.content;
3219
3197
  } else {
3220
3198
  try {
3221
- path19 = JSON.stringify(item.content);
3199
+ path20 = JSON.stringify(item.content);
3222
3200
  } catch {
3223
- path19 = String(item.content);
3201
+ path20 = String(item.content);
3224
3202
  }
3225
3203
  }
3226
3204
  yield {
3227
3205
  event: "tool_complete",
3228
3206
  id: item.tool_use_id,
3229
3207
  kind,
3230
- path: path19
3208
+ path: path20
3231
3209
  };
3232
3210
  }
3233
3211
  }
@@ -3349,10 +3327,10 @@ async function* adaptCodex(lines) {
3349
3327
  const kindFromStart = toolKindById.get(item.id);
3350
3328
  const kind = kindFromStart ?? (itemType === "command_execution" ? "exec" : itemType === "file_edit" ? "edit" : "other");
3351
3329
  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;
3352
- const path19 = titleFromEvent ?? toolTitleById.get(item.id) ?? "";
3330
+ const path20 = titleFromEvent ?? toolTitleById.get(item.id) ?? "";
3353
3331
  toolTitleById.delete(item.id);
3354
3332
  toolKindById.delete(item.id);
3355
- yield { event: "tool_complete", id: item.id, kind, path: path19 };
3333
+ yield { event: "tool_complete", id: item.id, kind, path: path20 };
3356
3334
  }
3357
3335
  }
3358
3336
  }
@@ -3645,7 +3623,7 @@ function spawnStreaming(options) {
3645
3623
  args.push(options.prompt);
3646
3624
  }
3647
3625
  if (options.model && spawnConfig.modelFlag) {
3648
- let model = spawnConfig.modelStripProviderPrefix ? stripModelNamespace2(options.model) : options.model;
3626
+ let model = spawnConfig.modelStripProviderPrefix ? stripModelNamespace(options.model) : options.model;
3649
3627
  if (spawnConfig.modelTransform) model = spawnConfig.modelTransform(model);
3650
3628
  args.push(spawnConfig.modelFlag, model);
3651
3629
  }
@@ -3726,36 +3704,8 @@ var init_src4 = __esm({
3726
3704
  }
3727
3705
  });
3728
3706
 
3729
- // src/templates/python/env.hbs
3730
- var require_env = __commonJS({
3731
- "src/templates/python/env.hbs"(exports, module) {
3732
- module.exports = "POE_API_KEY={{apiKey}}\nPOE_BASE_URL=https://api.poe.com/v1\nMODEL={{model}}\n";
3733
- }
3734
- });
3735
-
3736
- // src/templates/python/main.py.hbs
3737
- var require_main_py = __commonJS({
3738
- "src/templates/python/main.py.hbs"(exports, module) {
3739
- module.exports = 'import os\nfrom openai import OpenAI\nfrom dotenv import load_dotenv\n\nload_dotenv()\n\nclient = OpenAI(\n api_key=os.getenv("POE_API_KEY"),\n base_url=os.getenv("POE_BASE_URL")\n)\n\nresponse = client.chat.completions.create(\n model=os.getenv("MODEL", "{{model}}"),\n messages=[{"role": "user", "content": "Tell me a joke"}]\n)\n\nprint(response.choices[0].message.content)\n';
3740
- }
3741
- });
3742
-
3743
- // src/templates/python/requirements.txt.hbs
3744
- var require_requirements_txt = __commonJS({
3745
- "src/templates/python/requirements.txt.hbs"(exports, module) {
3746
- module.exports = "openai>=1.0.0\npython-dotenv>=1.0.0\n";
3747
- }
3748
- });
3749
-
3750
- // src/templates/codex/config.toml.hbs
3751
- var require_config_toml = __commonJS({
3752
- "src/templates/codex/config.toml.hbs"(exports, module) {
3753
- module.exports = 'model_provider = "poe"\nmodel = "{{{model}}}"\nmodel_reasoning_effort = "{{reasoningEffort}}"\n\n[model_providers.poe]\nname = "poe"\nbase_url = "{{{baseUrl}}}"\nwire_api = "responses"\nexperimental_bearer_token = "{{apiKey}}"\n';
3754
- }
3755
- });
3756
-
3757
3707
  // src/cli/isolated-env.ts
3758
- import path5 from "node:path";
3708
+ import path6 from "node:path";
3759
3709
  async function resolveIsolatedEnvDetails(env, isolated, providerName, fs3) {
3760
3710
  if (!providerName) {
3761
3711
  throw new Error("resolveIsolatedEnvDetails requires providerName.");
@@ -3777,7 +3727,7 @@ function resolveIsolatedTargetDirectory(input) {
3777
3727
  const expanded = expandHomeShortcut(input.env, input.targetDirectory);
3778
3728
  const baseDir = resolveIsolatedBaseDir(input.env, input.providerName);
3779
3729
  const homeDir = input.env.homeDir;
3780
- const homeDirWithSep = `${homeDir}${path5.sep}`;
3730
+ const homeDirWithSep = `${homeDir}${path6.sep}`;
3781
3731
  if (expanded !== homeDir && !expanded.startsWith(homeDirWithSep)) {
3782
3732
  throw new Error(
3783
3733
  `Isolated config targets must live under the user's home directory (received "${input.targetDirectory}").`
@@ -3792,7 +3742,7 @@ function resolveIsolatedTargetDirectory(input) {
3792
3742
  if (!expanded.startsWith(homeDirWithSep)) {
3793
3743
  return expanded;
3794
3744
  }
3795
- const mapped = path5.join(baseDir, expanded.slice(homeDirWithSep.length));
3745
+ const mapped = path6.join(baseDir, expanded.slice(homeDirWithSep.length));
3796
3746
  return stripAgentHome(mapped, baseDir, input.isolated.agentBinary);
3797
3747
  }
3798
3748
  function resolveIsolatedBaseDir(env, providerName) {
@@ -3841,9 +3791,9 @@ async function resolveIsolatedEnvValue(env, baseDir, value, fs3) {
3841
3791
  function resolveIsolatedEnvPath(env, baseDir, value) {
3842
3792
  switch (value.kind) {
3843
3793
  case "isolatedDir":
3844
- return value.relativePath ? path5.join(baseDir, value.relativePath) : baseDir;
3794
+ return value.relativePath ? path6.join(baseDir, value.relativePath) : baseDir;
3845
3795
  case "isolatedFile":
3846
- return path5.join(baseDir, value.relativePath);
3796
+ return path6.join(baseDir, value.relativePath);
3847
3797
  }
3848
3798
  }
3849
3799
  function isEnvVarReference(value) {
@@ -3885,10 +3835,10 @@ async function applyIsolatedEnvRepairs(input) {
3885
3835
  if (repair.kind !== "chmod") {
3886
3836
  continue;
3887
3837
  }
3888
- if (path5.isAbsolute(repair.relativePath)) {
3838
+ if (path6.isAbsolute(repair.relativePath)) {
3889
3839
  continue;
3890
3840
  }
3891
- const repairPath = path5.join(baseDir, repair.relativePath);
3841
+ const repairPath = path6.join(baseDir, repair.relativePath);
3892
3842
  try {
3893
3843
  await input.fs.chmod(repairPath, repair.mode);
3894
3844
  } catch (error2) {
@@ -3939,13 +3889,13 @@ async function resolveCliSettingValue(value, env, fs3) {
3939
3889
  }
3940
3890
  function stripAgentHome(mapped, baseDir, agentBinary) {
3941
3891
  const agentDir = `.${agentBinary}`;
3942
- const prefix = path5.join(baseDir, agentDir);
3892
+ const prefix = path6.join(baseDir, agentDir);
3943
3893
  if (mapped === prefix) {
3944
3894
  return baseDir;
3945
3895
  }
3946
- const withSep = `${prefix}${path5.sep}`;
3896
+ const withSep = `${prefix}${path6.sep}`;
3947
3897
  if (mapped.startsWith(withSep)) {
3948
- return path5.join(baseDir, mapped.slice(withSep.length));
3898
+ return path6.join(baseDir, mapped.slice(withSep.length));
3949
3899
  }
3950
3900
  return mapped;
3951
3901
  }
@@ -3956,11 +3906,11 @@ function expandHomeShortcut(env, input) {
3956
3906
  if (input === "~") {
3957
3907
  return env.homeDir;
3958
3908
  }
3959
- if (input.startsWith("~/") || input.startsWith(`~${path5.sep}`)) {
3960
- return path5.join(env.homeDir, input.slice(2));
3909
+ if (input.startsWith("~/") || input.startsWith(`~${path6.sep}`)) {
3910
+ return path6.join(env.homeDir, input.slice(2));
3961
3911
  }
3962
- if (input.startsWith("~./") || input.startsWith(`~.${path5.sep}`)) {
3963
- return path5.join(env.homeDir, `.${input.slice(3)}`);
3912
+ if (input.startsWith("~./") || input.startsWith(`~.${path6.sep}`)) {
3913
+ return path6.join(env.homeDir, `.${input.slice(3)}`);
3964
3914
  }
3965
3915
  return input;
3966
3916
  }
@@ -3973,7 +3923,7 @@ var init_isolated_env = __esm({
3973
3923
  });
3974
3924
 
3975
3925
  // src/cli/commands/shared.ts
3976
- import path6 from "node:path";
3926
+ import path7 from "node:path";
3977
3927
  function resolveCommandFlags(program) {
3978
3928
  const opts = program.optsWithGlobals();
3979
3929
  return {
@@ -4046,7 +3996,7 @@ function buildResumeCommand(canonicalService, threadId, cwd) {
4046
3996
  if (!binaryName) {
4047
3997
  return void 0;
4048
3998
  }
4049
- const resumeCwd = path6.resolve(cwd);
3999
+ const resumeCwd = path7.resolve(cwd);
4050
4000
  const args = spawnConfig.resumeCommand(threadId, resumeCwd);
4051
4001
  const agentCommand = [binaryName, ...args.map(shlexQuote)].join(" ");
4052
4002
  const needsCdPrefix = !args.includes(resumeCwd);
@@ -7515,8 +7465,8 @@ var require_utils = __commonJS({
7515
7465
  }
7516
7466
  return ind;
7517
7467
  }
7518
- function removeDotSegments(path19) {
7519
- let input = path19;
7468
+ function removeDotSegments(path20) {
7469
+ let input = path20;
7520
7470
  const output = [];
7521
7471
  let nextSlash = -1;
7522
7472
  let len = 0;
@@ -7715,8 +7665,8 @@ var require_schemes = __commonJS({
7715
7665
  wsComponent.secure = void 0;
7716
7666
  }
7717
7667
  if (wsComponent.resourceName) {
7718
- const [path19, query] = wsComponent.resourceName.split("?");
7719
- wsComponent.path = path19 && path19 !== "/" ? path19 : void 0;
7668
+ const [path20, query] = wsComponent.resourceName.split("?");
7669
+ wsComponent.path = path20 && path20 !== "/" ? path20 : void 0;
7720
7670
  wsComponent.query = query;
7721
7671
  wsComponent.resourceName = void 0;
7722
7672
  }
@@ -16785,7 +16735,7 @@ var require_PROMPT_PARTIAL_plan = __commonJS({
16785
16735
  // src/templates/ralph/SKILL_plan.md
16786
16736
  var require_SKILL_plan = __commonJS({
16787
16737
  "src/templates/ralph/SKILL_plan.md"(exports, module) {
16788
- module.exports = "---\nname: poe-code-ralph-plan\ndescription: 'Generate a Ralph plan (YAML) from a user request. Triggers on: create a plan, write plan for, plan this feature, ralph plan.'\n---\n\n## If The Request Is Empty\n\nAsk the user for a one-sentence description of what they want to build.\n\n{{{PROMPT_PARTIAL_PLAN}}}\n\n## Output Path\n\nWrite the YAML file to `.agents/tasks/plan-<name>.yaml` unless the user specifies a different path.\n";
16738
+ module.exports = "---\nname: poe-code-ralph-plan\ndescription: 'Generate a Ralph plan (YAML) from a user request. Triggers on: create a plan, write plan for, plan this feature, ralph plan.'\n---\n\n## If The Request Is Empty\n\nAsk the user for a one-sentence description of what they want to build.\n\n{{{PROMPT_PARTIAL_PLAN}}}\n\n## Output Path\n\nWrite the YAML file to `.agents/poe-code-ralph/plans/plan-<name>.yaml` unless the user specifies a different path.\n";
16789
16739
  }
16790
16740
  });
16791
16741
 
@@ -17544,716 +17494,48 @@ ${entry.stack}`);
17544
17494
  init_src4();
17545
17495
  init_src3();
17546
17496
 
17547
- // src/utils/command-checks.ts
17548
- init_src4();
17549
- function formatCommandRunnerResult(result) {
17550
- const stdout = result.stdout.length > 0 ? result.stdout : "<empty>";
17551
- const stderr = result.stderr.length > 0 ? result.stderr : "<empty>";
17552
- return `stdout:
17553
- ${stdout}
17554
- stderr:
17555
- ${stderr}`;
17556
- }
17557
- function createSpawnHealthCheck(agentId, options) {
17558
- const prompt = `Output exactly: ${options.expectedOutput}`;
17559
- const { binaryName, args } = buildSpawnArgs(agentId, {
17560
- prompt,
17561
- model: options.model,
17562
- mode: "yolo"
17563
- });
17564
- return {
17565
- id: `${agentId}-cli-health`,
17566
- description: `spawn ${agentId} (expecting "${options.expectedOutput}")`,
17567
- async run(context) {
17568
- if (context.isDryRun) {
17569
- context.logDryRun?.(
17570
- `Dry run: ${[binaryName, ...args].join(" ")} (expecting "${options.expectedOutput}")`
17571
- );
17572
- return;
17573
- }
17574
- const result = await context.runCommand(binaryName, args);
17575
- if (result.exitCode !== 0) {
17576
- throw new Error(
17577
- `spawn ${agentId} failed with exit code ${result.exitCode}.
17578
- ${formatCommandRunnerResult(result)}`
17579
- );
17580
- }
17581
- if (!result.stdout.includes(options.expectedOutput)) {
17582
- throw new Error(
17583
- `spawn ${agentId}: expected "${options.expectedOutput}" in stdout.
17584
- ${formatCommandRunnerResult(result)}`
17585
- );
17586
- }
17587
- }
17588
- };
17589
- }
17590
- function createBinaryExistsCheck(binaryName, id, description) {
17591
- return {
17592
- id,
17593
- description,
17594
- async run({ runCommand: runCommand2 }) {
17595
- const commonPaths = [
17596
- `/usr/local/bin/${binaryName}`,
17597
- `/usr/bin/${binaryName}`,
17598
- `$HOME/.local/bin/${binaryName}`,
17599
- `$HOME/.claude/local/bin/${binaryName}`
17600
- ];
17601
- const detectors = [
17602
- {
17603
- command: "which",
17604
- args: [binaryName],
17605
- validate: (result) => result.exitCode === 0
17606
- },
17607
- {
17608
- command: "where",
17609
- args: [binaryName],
17610
- validate: (result) => result.exitCode === 0 && result.stdout.trim().length > 0
17611
- },
17612
- // Check common installation paths using shell expansion for $HOME
17613
- {
17614
- command: "sh",
17615
- args: [
17616
- "-c",
17617
- commonPaths.map((p) => `test -f "${p}"`).join(" || ")
17618
- ],
17619
- validate: (result) => result.exitCode === 0
17620
- }
17621
- ];
17622
- for (const detector of detectors) {
17623
- const result = await runCommand2(detector.command, detector.args);
17624
- if (detector.validate(result)) {
17625
- return;
17626
- }
17627
- }
17628
- throw new Error(`${binaryName} CLI binary not found on PATH.`);
17629
- }
17630
- };
17631
- }
17632
-
17633
- // src/providers/claude-code.ts
17634
- init_src();
17635
- init_constants();
17636
-
17637
- // src/providers/create-provider.ts
17638
- init_src();
17639
-
17640
- // src/services/service-install.ts
17641
- async function runServiceInstall(definition, context) {
17642
- const checkContext = {
17643
- isDryRun: context.isDryRun,
17644
- runCommand: context.runCommand
17645
- };
17646
- let needsInstall = false;
17647
- try {
17648
- await definition.check.run(checkContext);
17649
- context.logger(`${definition.summary} already installed.`);
17650
- } catch (error2) {
17651
- const detail = error2 instanceof Error ? error2.message : String(error2);
17652
- context.logger(`${definition.summary} not detected: ${detail}`);
17653
- needsInstall = true;
17497
+ // src/providers/index.ts
17498
+ import path5 from "node:path";
17499
+ import { readdir } from "node:fs/promises";
17500
+ import { fileURLToPath, pathToFileURL } from "node:url";
17501
+ var moduleDir = path5.dirname(fileURLToPath(import.meta.url));
17502
+ var currentDir = path5.basename(moduleDir) === "providers" ? moduleDir : path5.join(moduleDir, "providers");
17503
+ function isProviderModule(filename) {
17504
+ if (filename.endsWith(".d.ts") || filename.endsWith(".d.ts.map")) {
17505
+ return false;
17654
17506
  }
17655
- if (!needsInstall) {
17507
+ if (filename.endsWith(".map")) {
17656
17508
  return false;
17657
17509
  }
17658
- if (context.isDryRun) {
17659
- logInstallDryRun(definition, context);
17660
- return true;
17510
+ if (!(filename.endsWith(".ts") || filename.endsWith(".js"))) {
17511
+ return false;
17661
17512
  }
17662
- const platformSteps = filterStepsByPlatform(definition.steps, context.platform);
17663
- for (const step of platformSteps) {
17664
- await runInstallStep(step, context);
17513
+ if (filename.endsWith(".test.ts") || filename.endsWith(".test.js")) {
17514
+ return false;
17665
17515
  }
17666
- await definition.check.run(checkContext);
17667
- if (definition.postChecks) {
17668
- for (const postCheck of definition.postChecks) {
17669
- await postCheck.run(checkContext);
17670
- }
17516
+ if (filename === "index.ts" || filename === "index.js" || filename === "create-provider.ts" || filename === "create-provider.js" || filename === "spawn-options.ts" || filename === "spawn-options.js" || filename === "mcp-config.ts" || filename === "mcp-config.js" || filename === "provider-helpers.ts" || filename === "provider-helpers.js") {
17517
+ return false;
17671
17518
  }
17672
- context.logger(
17673
- definition.successMessage ?? `${definition.summary} installed.`
17674
- );
17675
17519
  return true;
17676
17520
  }
17677
- function describeInstallCommand(step) {
17678
- return `[${step.id}] ${formatCommand2(step.command, step.args)}`;
17679
- }
17680
- function formatCommand2(command, args) {
17681
- return [command, ...args.map(quoteIfNeeded)].join(" ");
17682
- }
17683
- function quoteIfNeeded(value) {
17684
- if (value.length === 0) {
17685
- return '""';
17686
- }
17687
- if (value.includes(" ") || value.includes(" ") || value.includes("\n")) {
17688
- return `"${value.replaceAll('"', '\\"')}"`;
17689
- }
17690
- return value;
17691
- }
17692
- function filterStepsByPlatform(steps, platform) {
17693
- return steps.filter(
17694
- (step) => !step.platforms || step.platforms.includes(platform)
17695
- );
17696
- }
17697
- function logInstallDryRun(definition, context) {
17698
- context.logger(`Dry run: would install ${definition.summary}.`);
17699
- const platformSteps = filterStepsByPlatform(definition.steps, context.platform);
17700
- for (const step of platformSteps) {
17701
- context.logger(`Dry run: ${describeInstallCommand(step)}`);
17702
- }
17703
- }
17704
- async function runInstallStep(step, context) {
17705
- context.logger(`Running ${describeInstallCommand(step)}`);
17706
- const result = await context.runCommand(step.command, step.args);
17707
- if (result.exitCode !== 0) {
17708
- const stderr = result.stderr.trim();
17709
- const suffix = stderr.length > 0 ? `: ${stderr}` : "";
17710
- throw new Error(
17711
- `${describeInstallCommand(step)} failed with exit code ${result.exitCode}${suffix}`
17712
- );
17713
- }
17714
- }
17715
-
17716
- // src/providers/create-provider.ts
17717
- var templateImports = {
17718
- "python/env.hbs": () => Promise.resolve().then(() => __toESM(require_env(), 1)),
17719
- "python/main.py.hbs": () => Promise.resolve().then(() => __toESM(require_main_py(), 1)),
17720
- "python/requirements.txt.hbs": () => Promise.resolve().then(() => __toESM(require_requirements_txt(), 1)),
17721
- "codex/config.toml.hbs": () => Promise.resolve().then(() => __toESM(require_config_toml(), 1))
17722
- };
17723
- async function loadTemplate(templateId) {
17724
- const loader = templateImports[templateId];
17725
- if (!loader) {
17726
- throw new Error(`Template not found: ${templateId}`);
17727
- }
17728
- const module = await loader();
17729
- return module.default;
17730
- }
17731
- function createProvider(opts) {
17732
- const provider = {
17733
- id: opts.id,
17734
- summary: opts.summary,
17735
- name: opts.name,
17736
- aliases: opts.aliases,
17737
- label: opts.label,
17738
- branding: opts.branding,
17739
- disabled: opts.disabled,
17740
- supportsStdinPrompt: opts.supportsStdinPrompt,
17741
- configurePrompts: opts.configurePrompts,
17742
- postConfigureMessages: opts.postConfigureMessages,
17743
- isolatedEnv: opts.isolatedEnv,
17744
- async configure(context, runOptions) {
17745
- await runMutations(opts.manifest.configure, {
17746
- fs: context.fs,
17747
- homeDir: context.env.homeDir,
17748
- observers: runOptions?.observers,
17749
- templates: loadTemplate,
17750
- pathMapper: context.pathMapper
17751
- }, context.options);
17752
- context.command.flushDryRun({ emitIfEmpty: false });
17753
- },
17754
- async unconfigure(context, runOptions) {
17755
- if (!opts.manifest.unconfigure) {
17756
- return false;
17757
- }
17758
- const result = await runMutations(opts.manifest.unconfigure, {
17759
- fs: context.fs,
17760
- homeDir: context.env.homeDir,
17761
- observers: runOptions?.observers,
17762
- templates: loadTemplate,
17763
- pathMapper: context.pathMapper
17764
- }, context.options);
17765
- context.command.flushDryRun({ emitIfEmpty: false });
17766
- return result.changed;
17767
- }
17768
- };
17769
- if (opts.install) {
17770
- provider.install = createInstallRunner(opts.install);
17771
- }
17772
- if (opts.test) {
17773
- provider.test = opts.test;
17774
- }
17775
- if (opts.spawn) {
17776
- provider.spawn = opts.spawn;
17777
- }
17778
- return provider;
17779
- }
17780
- function createInstallRunner(definition) {
17781
- return async (context) => {
17782
- await runServiceInstall(definition, {
17783
- isDryRun: context.logger.context.dryRun,
17784
- runCommand: context.command.runCommand,
17785
- logger: (message) => context.logger.verbose(message),
17786
- platform: context.env.platform
17787
- });
17788
- };
17789
- }
17790
-
17791
- // src/providers/claude-code.ts
17792
- init_src2();
17793
- var CLAUDE_CODE_INSTALL_DEFINITION = {
17794
- id: "claude-code",
17795
- summary: "Claude CLI",
17796
- check: createBinaryExistsCheck(
17797
- "claude",
17798
- "claude-cli-binary",
17799
- "Claude CLI binary must exist"
17800
- ),
17801
- steps: [
17802
- {
17803
- id: "install-claude-cli-unix",
17804
- command: "bash",
17805
- args: ["-c", "curl -fsSL https://claude.ai/install.sh | bash"],
17806
- platforms: ["darwin", "linux"]
17807
- },
17808
- {
17809
- id: "install-claude-cli-windows",
17810
- command: "powershell",
17811
- args: ["-Command", "irm https://claude.ai/install.ps1 | iex"],
17812
- platforms: ["win32"]
17813
- }
17814
- ],
17815
- successMessage: "Installed Claude CLI."
17816
- };
17817
- var claudeCodeService = createProvider({
17818
- ...claudeCodeAgent,
17819
- supportsStdinPrompt: true,
17820
- configurePrompts: {
17821
- model: {
17822
- label: "Claude Code default model",
17823
- defaultValue: DEFAULT_CLAUDE_CODE_MODEL,
17824
- choices: Object.values(CLAUDE_CODE_VARIANTS).map((id) => ({
17825
- title: id,
17826
- value: id
17827
- }))
17828
- }
17829
- },
17830
- postConfigureMessages: [
17831
- "If using VSCode - Open the Disable Login Prompt setting and check the box. vscode://settings/claudeCode.disableLoginPrompt"
17832
- ],
17833
- isolatedEnv: {
17834
- agentBinary: claudeCodeAgent.binaryName,
17835
- env: {
17836
- POE_API_KEY: { kind: "poeApiKey" }
17837
- },
17838
- requiresConfig: false,
17839
- cliSettings: {
17840
- values: {
17841
- apiKeyHelper: "echo $POE_API_KEY"
17842
- },
17843
- env: {
17844
- ANTHROPIC_BASE_URL: { kind: "poeBaseUrl" }
17845
- }
17846
- }
17847
- },
17848
- test(context) {
17849
- return context.runCheck(
17850
- createSpawnHealthCheck("claude-code", {
17851
- model: context.model ?? DEFAULT_CLAUDE_CODE_MODEL,
17852
- expectedOutput: "CLAUDE_CODE_OK"
17853
- })
17854
- );
17855
- },
17856
- manifest: {
17857
- configure: [
17858
- fileMutation.ensureDirectory({ path: "~/.claude" }),
17859
- configMutation.merge({
17860
- target: "~/.claude/settings.json",
17861
- value: (ctx) => {
17862
- const options = ctx;
17863
- return {
17864
- apiKeyHelper: `echo ${options.apiKey}`,
17865
- env: {
17866
- ANTHROPIC_BASE_URL: options.env.poeBaseUrl
17867
- },
17868
- model: stripModelNamespace(options.model ?? DEFAULT_CLAUDE_CODE_MODEL)
17869
- };
17870
- }
17871
- })
17872
- ],
17873
- unconfigure: [
17874
- configMutation.prune({
17875
- target: "~/.claude/settings.json",
17876
- shape: {
17877
- apiKeyHelper: true,
17878
- env: {
17879
- ANTHROPIC_BASE_URL: true,
17880
- ANTHROPIC_DEFAULT_HAIKU_MODEL: true,
17881
- ANTHROPIC_DEFAULT_SONNET_MODEL: true,
17882
- ANTHROPIC_DEFAULT_OPUS_MODEL: true
17883
- },
17884
- model: true
17885
- }
17886
- })
17887
- ]
17888
- },
17889
- install: CLAUDE_CODE_INSTALL_DEFINITION
17890
- });
17891
-
17892
- // src/providers/codex.ts
17893
- init_src();
17894
- init_constants();
17895
- init_src2();
17896
- var CODEX_PROVIDER_ID = "poe";
17897
- var CODEX_INSTALL_DEFINITION = {
17898
- id: "codex",
17899
- summary: "Codex CLI",
17900
- check: createBinaryExistsCheck(
17901
- "codex",
17902
- "codex-cli-binary",
17903
- "Codex CLI binary must exist"
17904
- ),
17905
- steps: [
17906
- {
17907
- id: "install-codex-cli-npm",
17908
- command: "npm",
17909
- args: ["install", "-g", "@openai/codex"]
17521
+ async function loadProviders() {
17522
+ const entries = await readdir(currentDir, { withFileTypes: true });
17523
+ const providers = [];
17524
+ for (const entry of entries) {
17525
+ if (!entry.isFile()) continue;
17526
+ if (!isProviderModule(entry.name)) continue;
17527
+ const moduleUrl = pathToFileURL(path5.join(currentDir, entry.name)).href;
17528
+ const moduleExports = await import(moduleUrl);
17529
+ if (!moduleExports.provider) {
17530
+ throw new Error(`Provider module "${entry.name}" must export "provider".`);
17910
17531
  }
17911
- ],
17912
- successMessage: "Installed Codex CLI via npm."
17913
- };
17914
- function stripCodexConfiguration(document) {
17915
- if (!isConfigObject4(document)) {
17916
- return { changed: false, empty: false };
17917
- }
17918
- if (document["model_provider"] !== CODEX_PROVIDER_ID) {
17919
- return { changed: false, empty: false };
17920
- }
17921
- const providers = document["model_providers"];
17922
- if (!isConfigObject4(providers) || !(CODEX_PROVIDER_ID in providers)) {
17923
- return { changed: false, empty: false };
17924
- }
17925
- delete document["model_provider"];
17926
- delete document["model"];
17927
- delete document["model_reasoning_effort"];
17928
- delete providers[CODEX_PROVIDER_ID];
17929
- if (isTableEmpty(providers)) {
17930
- delete document["model_providers"];
17532
+ providers.push(moduleExports.provider);
17931
17533
  }
17932
- return {
17933
- changed: true,
17934
- empty: isTableEmpty(document)
17935
- };
17534
+ return providers.sort((a, b) => a.name.localeCompare(b.name));
17936
17535
  }
17937
- function isTableEmpty(value) {
17938
- return isConfigObject4(value) && Object.keys(value).length === 0;
17939
- }
17940
- var codexService = createProvider({
17941
- ...codexAgent,
17942
- supportsStdinPrompt: true,
17943
- configurePrompts: {
17944
- model: {
17945
- label: "Codex model",
17946
- defaultValue: DEFAULT_CODEX_MODEL,
17947
- choices: CODEX_MODELS.map((id) => ({
17948
- title: id,
17949
- value: id
17950
- }))
17951
- },
17952
- reasoningEffort: {
17953
- label: "Codex reasoning effort",
17954
- defaultValue: DEFAULT_REASONING
17955
- }
17956
- },
17957
- isolatedEnv: {
17958
- agentBinary: codexAgent.binaryName,
17959
- configProbe: { kind: "isolatedFile", relativePath: "config.toml" },
17960
- env: {
17961
- CODEX_HOME: { kind: "isolatedDir" },
17962
- XDG_CONFIG_HOME: { kind: "isolatedDir" }
17963
- }
17964
- },
17965
- test(context) {
17966
- return context.runCheck(
17967
- createSpawnHealthCheck("codex", {
17968
- model: context.model ?? DEFAULT_CODEX_MODEL,
17969
- expectedOutput: "CODEX_OK"
17970
- })
17971
- );
17972
- },
17973
- manifest: {
17974
- configure: [
17975
- fileMutation.ensureDirectory({ path: "~/.codex" }),
17976
- fileMutation.backup({ target: "~/.codex/config.toml" }),
17977
- templateMutation.mergeToml({
17978
- target: "~/.codex/config.toml",
17979
- templateId: "codex/config.toml.hbs",
17980
- context: (ctx) => {
17981
- const options = ctx;
17982
- return {
17983
- apiKey: options.apiKey,
17984
- baseUrl: options.env.poeApiBaseUrl,
17985
- model: stripModelNamespace(options.model ?? DEFAULT_CODEX_MODEL),
17986
- reasoningEffort: options.reasoningEffort
17987
- };
17988
- }
17989
- })
17990
- ],
17991
- unconfigure: [
17992
- configMutation.transform({
17993
- target: "~/.codex/config.toml",
17994
- transform: (document) => {
17995
- const result = stripCodexConfiguration(document);
17996
- if (!result.changed) {
17997
- return { changed: false, content: document };
17998
- }
17999
- return {
18000
- changed: true,
18001
- content: result.empty ? null : document
18002
- };
18003
- }
18004
- })
18005
- ]
18006
- },
18007
- install: CODEX_INSTALL_DEFINITION
18008
- });
18009
-
18010
- // src/providers/opencode.ts
18011
- init_constants();
18012
- init_src();
18013
- init_src2();
18014
- function providerModel(model) {
18015
- const value = model ?? DEFAULT_FRONTIER_MODEL;
18016
- const prefix = `${PROVIDER_NAME}/`;
18017
- return value.startsWith(prefix) ? value : `${prefix}${value}`;
18018
- }
18019
- var OPEN_CODE_INSTALL_DEFINITION = {
18020
- id: "opencode",
18021
- summary: "OpenCode CLI",
18022
- check: createBinaryExistsCheck(
18023
- "opencode",
18024
- "opencode-cli-binary",
18025
- "OpenCode CLI binary must exist"
18026
- ),
18027
- steps: [
18028
- {
18029
- id: "install-opencode-cli-npm",
18030
- command: "npm",
18031
- args: ["install", "-g", "opencode-ai"]
18032
- }
18033
- ],
18034
- successMessage: "Installed OpenCode CLI via npm."
18035
- };
18036
- function getModelArgs(model) {
18037
- return ["--model", providerModel(model)];
18038
- }
18039
- var openCodeService = createProvider({
18040
- ...openCodeAgent,
18041
- supportsStdinPrompt: false,
18042
- configurePrompts: {
18043
- model: {
18044
- label: "OpenCode model",
18045
- defaultValue: DEFAULT_FRONTIER_MODEL,
18046
- choices: FRONTIER_MODELS.map((id) => ({
18047
- title: id,
18048
- value: id
18049
- }))
18050
- }
18051
- },
18052
- isolatedEnv: {
18053
- agentBinary: openCodeAgent.binaryName,
18054
- configProbe: {
18055
- kind: "isolatedFile",
18056
- relativePath: ".config/opencode/config.json"
18057
- },
18058
- env: {
18059
- XDG_CONFIG_HOME: { kind: "isolatedDir", relativePath: ".config" },
18060
- XDG_DATA_HOME: { kind: "isolatedDir", relativePath: ".local/share" }
18061
- }
18062
- },
18063
- manifest: {
18064
- configure: [
18065
- fileMutation.ensureDirectory({ path: "~/.config/opencode" }),
18066
- configMutation.merge({
18067
- target: "~/.config/opencode/config.json",
18068
- value: (ctx) => {
18069
- const { model } = ctx ?? {};
18070
- return {
18071
- $schema: "https://opencode.ai/config.json",
18072
- model: providerModel(model),
18073
- enabled_providers: [PROVIDER_NAME]
18074
- };
18075
- }
18076
- }),
18077
- fileMutation.ensureDirectory({ path: "~/.local/share/opencode" }),
18078
- configMutation.merge({
18079
- target: "~/.local/share/opencode/auth.json",
18080
- value: (ctx) => {
18081
- const { apiKey } = ctx ?? {};
18082
- return {
18083
- [PROVIDER_NAME]: {
18084
- type: "api",
18085
- key: apiKey ?? ""
18086
- }
18087
- };
18088
- }
18089
- })
18090
- ],
18091
- unconfigure: [
18092
- configMutation.prune({
18093
- target: "~/.config/opencode/config.json",
18094
- shape: { enabled_providers: true }
18095
- }),
18096
- configMutation.prune({
18097
- target: "~/.local/share/opencode/auth.json",
18098
- shape: { [PROVIDER_NAME]: true }
18099
- })
18100
- ]
18101
- },
18102
- install: OPEN_CODE_INSTALL_DEFINITION,
18103
- test(context) {
18104
- return context.runCheck(
18105
- createSpawnHealthCheck("opencode", {
18106
- model: context.model,
18107
- expectedOutput: "OPEN_CODE_OK"
18108
- })
18109
- );
18110
- },
18111
- spawn(context, options) {
18112
- const opts = options ?? {};
18113
- const args = [
18114
- ...getModelArgs(opts.model),
18115
- "run",
18116
- opts.prompt,
18117
- ...opts.args ?? []
18118
- ];
18119
- if (opts.cwd) {
18120
- return context.command.runCommand("poe-code", ["wrap", "opencode", ...args], {
18121
- cwd: opts.cwd
18122
- });
18123
- }
18124
- return context.command.runCommand("poe-code", ["wrap", "opencode", ...args]);
18125
- }
18126
- });
18127
-
18128
- // src/providers/kimi.ts
18129
- init_src();
18130
- init_constants();
18131
- init_src2();
18132
- var KIMI_INSTALL_DEFINITION = {
18133
- id: "kimi",
18134
- summary: "Kimi CLI",
18135
- check: createBinaryExistsCheck(
18136
- "kimi",
18137
- "kimi-cli-binary",
18138
- "Kimi CLI binary must exist"
18139
- ),
18140
- steps: [
18141
- {
18142
- id: "install-kimi-cli-uv",
18143
- command: "uv",
18144
- args: ["tool", "install", "--python", "3.13", "kimi-cli"]
18145
- }
18146
- ],
18147
- successMessage: "Installed Kimi CLI via uv."
18148
- };
18149
- function providerModel2(model) {
18150
- const stripped = stripModelNamespace(model);
18151
- return `${PROVIDER_NAME}/${stripped}`;
18152
- }
18153
- function buildKimiArgs(prompt, extraArgs) {
18154
- return ["--quiet", "-p", prompt, ...extraArgs ?? []];
18155
- }
18156
- var kimiService = createProvider({
18157
- ...kimiAgent,
18158
- disabled: false,
18159
- supportsStdinPrompt: false,
18160
- configurePrompts: {
18161
- model: {
18162
- label: "Kimi default model",
18163
- defaultValue: DEFAULT_KIMI_MODEL,
18164
- choices: KIMI_MODELS.map((id) => ({
18165
- title: id,
18166
- value: id
18167
- }))
18168
- }
18169
- },
18170
- isolatedEnv: {
18171
- // Use "kimi-cli" to avoid stripAgentHome stripping ".kimi" from paths
18172
- agentBinary: "kimi-cli",
18173
- configProbe: { kind: "isolatedFile", relativePath: ".kimi/config.toml" },
18174
- env: {
18175
- HOME: { kind: "isolatedDir" }
18176
- }
18177
- },
18178
- test(context) {
18179
- return context.runCheck(
18180
- createSpawnHealthCheck("kimi", {
18181
- model: context.model,
18182
- expectedOutput: "KIMI_OK"
18183
- })
18184
- );
18185
- },
18186
- manifest: {
18187
- configure: [
18188
- fileMutation.ensureDirectory({ path: "~/.kimi" }),
18189
- configMutation.merge({
18190
- target: "~/.kimi/config.toml",
18191
- pruneByPrefix: { models: `${PROVIDER_NAME}/` },
18192
- value: (ctx) => {
18193
- const { model, apiKey, env } = ctx ?? {};
18194
- const selectedModel = model ?? DEFAULT_KIMI_MODEL;
18195
- const models = {};
18196
- for (const m of KIMI_MODELS) {
18197
- models[providerModel2(m)] = {
18198
- provider: PROVIDER_NAME,
18199
- model: stripModelNamespace(m),
18200
- max_context_size: 256e3
18201
- };
18202
- }
18203
- return {
18204
- default_model: providerModel2(selectedModel),
18205
- default_thinking: true,
18206
- models,
18207
- providers: {
18208
- [PROVIDER_NAME]: {
18209
- type: "openai_legacy",
18210
- base_url: env.poeApiBaseUrl,
18211
- api_key: apiKey ?? ""
18212
- }
18213
- }
18214
- };
18215
- }
18216
- })
18217
- ],
18218
- unconfigure: [
18219
- configMutation.transform({
18220
- target: "~/.kimi/config.toml",
18221
- transform: (document) => {
18222
- const providers = document.providers;
18223
- if (!providers || typeof providers !== "object") {
18224
- return { changed: false, content: document };
18225
- }
18226
- if (!(PROVIDER_NAME in providers)) {
18227
- return { changed: false, content: document };
18228
- }
18229
- const { [PROVIDER_NAME]: ignoredProvider, ...rest } = providers;
18230
- void ignoredProvider;
18231
- const updatedProviders = rest;
18232
- if (Object.keys(updatedProviders).length === 0) {
18233
- const { providers: ignoredProviders, ...docWithoutProviders } = document;
18234
- void ignoredProviders;
18235
- return { changed: true, content: docWithoutProviders };
18236
- }
18237
- return { changed: true, content: { ...document, providers: updatedProviders } };
18238
- }
18239
- })
18240
- ]
18241
- },
18242
- install: KIMI_INSTALL_DEFINITION,
18243
- spawn(context, options) {
18244
- const args = buildKimiArgs(options.prompt, options.args);
18245
- if (options.cwd) {
18246
- return context.command.runCommand("kimi", args, {
18247
- cwd: options.cwd
18248
- });
18249
- }
18250
- return context.command.runCommand("kimi", args);
18251
- }
18252
- });
18253
-
18254
- // src/providers/index.ts
17536
+ var defaultProviders = await loadProviders();
18255
17537
  function getDefaultProviders() {
18256
- return [claudeCodeService, codexService, openCodeService, kimiService];
17538
+ return [...defaultProviders];
18257
17539
  }
18258
17540
 
18259
17541
  // src/cli/poe-code-command-runner.ts
@@ -18678,11 +17960,11 @@ init_src4();
18678
17960
  init_src3();
18679
17961
  init_credentials();
18680
17962
  init_shared();
18681
- import path9 from "node:path";
17963
+ import path10 from "node:path";
18682
17964
 
18683
17965
  // src/sdk/spawn-core.ts
18684
17966
  init_shared();
18685
- import path7 from "node:path";
17967
+ import path8 from "node:path";
18686
17968
  import chalk11 from "chalk";
18687
17969
  async function spawnCore(container, service, options, flags = { dryRun: false, verbose: false }) {
18688
17970
  const cwdOverride = resolveSpawnWorkingDirectory(
@@ -18780,16 +18062,16 @@ function resolveSpawnWorkingDirectory(baseDir, candidate) {
18780
18062
  if (!candidate || candidate.trim().length === 0) {
18781
18063
  return void 0;
18782
18064
  }
18783
- if (path7.isAbsolute(candidate)) {
18065
+ if (path8.isAbsolute(candidate)) {
18784
18066
  return candidate;
18785
18067
  }
18786
- return path7.resolve(baseDir, candidate);
18068
+ return path8.resolve(baseDir, candidate);
18787
18069
  }
18788
18070
 
18789
18071
  // src/sdk/credentials.ts
18790
18072
  import * as fs from "node:fs/promises";
18791
18073
  import * as os from "node:os";
18792
- import * as path8 from "node:path";
18074
+ import * as path9 from "node:path";
18793
18075
  var CREDENTIALS_RELATIVE_PATH = ".poe-code/credentials.json";
18794
18076
  async function getPoeApiKey() {
18795
18077
  const envKey = process.env.POE_API_KEY;
@@ -18797,7 +18079,7 @@ async function getPoeApiKey() {
18797
18079
  return envKey.trim();
18798
18080
  }
18799
18081
  const homeDir = os.homedir();
18800
- const credentialsPath = path8.join(homeDir, CREDENTIALS_RELATIVE_PATH);
18082
+ const credentialsPath = path9.join(homeDir, CREDENTIALS_RELATIVE_PATH);
18801
18083
  try {
18802
18084
  const content = await fs.readFile(credentialsPath, "utf8");
18803
18085
  const parsed = JSON.parse(content);
@@ -18839,21 +18121,21 @@ function createSdkContainer(options) {
18839
18121
  });
18840
18122
  loggerFactory.setErrorLogger(errorLogger);
18841
18123
  const asyncFs = {
18842
- readFile: ((path19, encoding) => {
18124
+ readFile: ((path20, encoding) => {
18843
18125
  if (encoding) {
18844
- return fs2.readFile(path19, encoding);
18126
+ return fs2.readFile(path20, encoding);
18845
18127
  }
18846
- return fs2.readFile(path19);
18128
+ return fs2.readFile(path20);
18847
18129
  }),
18848
- writeFile: (path19, data, opts) => fs2.writeFile(path19, data, opts),
18849
- mkdir: (path19, opts) => fs2.mkdir(path19, opts).then(() => {
18130
+ writeFile: (path20, data, opts) => fs2.writeFile(path20, data, opts),
18131
+ mkdir: (path20, opts) => fs2.mkdir(path20, opts).then(() => {
18850
18132
  }),
18851
- stat: (path19) => fs2.stat(path19),
18852
- rm: (path19, opts) => fs2.rm(path19, opts),
18853
- unlink: (path19) => fs2.unlink(path19),
18854
- readdir: (path19) => fs2.readdir(path19),
18133
+ stat: (path20) => fs2.stat(path20),
18134
+ rm: (path20, opts) => fs2.rm(path20, opts),
18135
+ unlink: (path20) => fs2.unlink(path20),
18136
+ readdir: (path20) => fs2.readdir(path20),
18855
18137
  copyFile: (src, dest) => fs2.copyFile(src, dest),
18856
- chmod: (path19, mode) => fs2.chmod(path19, mode)
18138
+ chmod: (path20, mode) => fs2.chmod(path20, mode)
18857
18139
  };
18858
18140
  const contextFactory = createCommandContextFactory({ fs: asyncFs });
18859
18141
  const noopPrompts = async () => {
@@ -19201,10 +18483,10 @@ function resolveSpawnWorkingDirectory2(baseDir, candidate) {
19201
18483
  if (!candidate || candidate.trim().length === 0) {
19202
18484
  return void 0;
19203
18485
  }
19204
- if (path9.isAbsolute(candidate)) {
18486
+ if (path10.isAbsolute(candidate)) {
19205
18487
  return candidate;
19206
18488
  }
19207
- return path9.resolve(baseDir, candidate);
18489
+ return path10.resolve(baseDir, candidate);
19208
18490
  }
19209
18491
 
19210
18492
  // src/cli/commands/research.ts
@@ -19212,7 +18494,7 @@ init_src4();
19212
18494
  init_credentials();
19213
18495
 
19214
18496
  // src/sdk/research.ts
19215
- import path10 from "node:path";
18497
+ import path11 from "node:path";
19216
18498
  var RESEARCH_SYSTEM_PROMPT = [
19217
18499
  "You are a codebase research assistant.",
19218
18500
  "Read files and answer the user's question about the codebase.",
@@ -19253,7 +18535,7 @@ async function research(container, options) {
19253
18535
  markdown: markdownOutput
19254
18536
  });
19255
18537
  outputPath = buildOutputPath(container.env.homeDir, options.prompt);
19256
- await ensureDirectory2(container.fs, path10.dirname(outputPath));
18538
+ await ensureDirectory2(container.fs, path11.dirname(outputPath));
19257
18539
  await container.fs.writeFile(outputPath, document, {
19258
18540
  encoding: "utf8"
19259
18541
  });
@@ -19328,7 +18610,7 @@ function buildResearchDocument(input) {
19328
18610
  }
19329
18611
  function buildClonePath(homeDir, github) {
19330
18612
  const slug = extractRepoSlug(github);
19331
- return path10.join(homeDir, ".poe-code", "repos", slug);
18613
+ return path11.join(homeDir, ".poe-code", "repos", slug);
19332
18614
  }
19333
18615
  function extractRepoSlug(value) {
19334
18616
  const trimmed = value.trim();
@@ -19366,7 +18648,7 @@ function extractRepoSlug(value) {
19366
18648
  function buildOutputPath(homeDir, prompt, now = /* @__PURE__ */ new Date()) {
19367
18649
  const timestamp = formatTimestamp(now);
19368
18650
  const slug = buildSlug(prompt);
19369
- return path10.join(
18651
+ return path11.join(
19370
18652
  homeDir,
19371
18653
  ".poe-code",
19372
18654
  "research",
@@ -19387,7 +18669,7 @@ async function resolveSource(input) {
19387
18669
  if (options.github) {
19388
18670
  const cloneUrl = resolveGithubCloneUrl(options.github);
19389
18671
  const clonePath = buildClonePath(container.env.homeDir, options.github);
19390
- await ensureDirectory2(container.fs, path10.dirname(clonePath));
18672
+ await ensureDirectory2(container.fs, path11.dirname(clonePath));
19391
18673
  const exists = await pathExists2(container.fs, clonePath);
19392
18674
  if (!exists) {
19393
18675
  const cloneResult = await container.commandRunner(
@@ -19485,10 +18767,10 @@ function formatYamlString(value) {
19485
18767
  return JSON.stringify(value);
19486
18768
  }
19487
18769
  function resolvePath2(baseDir, candidate) {
19488
- if (path10.isAbsolute(candidate)) {
18770
+ if (path11.isAbsolute(candidate)) {
19489
18771
  return candidate;
19490
18772
  }
19491
- return path10.resolve(baseDir, candidate);
18773
+ return path11.resolve(baseDir, candidate);
19492
18774
  }
19493
18775
  function teeAcpStream(events) {
19494
18776
  const chunks = [];
@@ -19548,7 +18830,7 @@ async function removePathFallback(fs3, target) {
19548
18830
  if (stats && typeof stats.isDirectory === "function" && stats.isDirectory()) {
19549
18831
  const entries = await fs3.readdir(target);
19550
18832
  for (const entry of entries) {
19551
- await removePathFallback(fs3, path10.join(target, entry));
18833
+ await removePathFallback(fs3, path11.join(target, entry));
19552
18834
  }
19553
18835
  }
19554
18836
  try {
@@ -20027,17 +19309,8 @@ async function executeUnconfigure(program, container, service, options) {
20027
19309
  resources.context.finalize();
20028
19310
  }
20029
19311
  async function createUnconfigurePayload(init) {
20030
- const { service, context } = init;
20031
- switch (service) {
20032
- case "claude-code":
20033
- return { env: context.env };
20034
- case "codex":
20035
- return { env: context.env };
20036
- case "opencode":
20037
- return { env: context.env };
20038
- default:
20039
- return {};
20040
- }
19312
+ const { context } = init;
19313
+ return { env: context.env };
20041
19314
  }
20042
19315
  function formatUnconfigureMessages(service, label, unconfigured, _payload) {
20043
19316
  const didUnconfigure = typeof unconfigured === "boolean" ? unconfigured : Boolean(unconfigured);
@@ -20245,7 +19518,7 @@ async function executeTest(program, container, service, options = {}) {
20245
19518
  init_src3();
20246
19519
  init_constants();
20247
19520
  init_shared();
20248
- import path11 from "node:path";
19521
+ import path12 from "node:path";
20249
19522
 
20250
19523
  // src/services/client-instance.ts
20251
19524
  init_credentials();
@@ -20722,11 +19995,11 @@ function getDefaultMimeType(type) {
20722
19995
  return defaults[type];
20723
19996
  }
20724
19997
  function resolveOutputPath(filename, cwd) {
20725
- if (path11.isAbsolute(filename)) {
19998
+ if (path12.isAbsolute(filename)) {
20726
19999
  return { path: filename, label: filename };
20727
20000
  }
20728
20001
  return {
20729
- path: path11.join(cwd, filename),
20002
+ path: path12.join(cwd, filename),
20730
20003
  label: `./${filename}`
20731
20004
  };
20732
20005
  }
@@ -21698,8 +20971,8 @@ function getErrorMap() {
21698
20971
 
21699
20972
  // node_modules/zod/v3/helpers/parseUtil.js
21700
20973
  var makeIssue = (params) => {
21701
- const { data, path: path19, errorMaps, issueData } = params;
21702
- const fullPath = [...path19, ...issueData.path || []];
20974
+ const { data, path: path20, errorMaps, issueData } = params;
20975
+ const fullPath = [...path20, ...issueData.path || []];
21703
20976
  const fullIssue = {
21704
20977
  ...issueData,
21705
20978
  path: fullPath
@@ -21814,11 +21087,11 @@ var errorUtil;
21814
21087
 
21815
21088
  // node_modules/zod/v3/types.js
21816
21089
  var ParseInputLazyPath = class {
21817
- constructor(parent, value, path19, key) {
21090
+ constructor(parent, value, path20, key) {
21818
21091
  this._cachedPath = [];
21819
21092
  this.parent = parent;
21820
21093
  this.data = value;
21821
- this._path = path19;
21094
+ this._path = path20;
21822
21095
  this._key = key;
21823
21096
  }
21824
21097
  get path() {
@@ -25462,10 +24735,10 @@ function mergeDefs(...defs) {
25462
24735
  function cloneDef(schema) {
25463
24736
  return mergeDefs(schema._zod.def);
25464
24737
  }
25465
- function getElementAtPath(obj, path19) {
25466
- if (!path19)
24738
+ function getElementAtPath(obj, path20) {
24739
+ if (!path20)
25467
24740
  return obj;
25468
- return path19.reduce((acc, key) => acc?.[key], obj);
24741
+ return path20.reduce((acc, key) => acc?.[key], obj);
25469
24742
  }
25470
24743
  function promiseAllObject(promisesObj) {
25471
24744
  const keys = Object.keys(promisesObj);
@@ -25848,11 +25121,11 @@ function aborted(x, startIndex = 0) {
25848
25121
  }
25849
25122
  return false;
25850
25123
  }
25851
- function prefixIssues(path19, issues) {
25124
+ function prefixIssues(path20, issues) {
25852
25125
  return issues.map((iss) => {
25853
25126
  var _a2;
25854
25127
  (_a2 = iss).path ?? (_a2.path = []);
25855
- iss.path.unshift(path19);
25128
+ iss.path.unshift(path20);
25856
25129
  return iss;
25857
25130
  });
25858
25131
  }
@@ -33879,7 +33152,7 @@ init_src3();
33879
33152
 
33880
33153
  // src/utils/execution-context.ts
33881
33154
  import { dirname } from "node:path";
33882
- import { fileURLToPath } from "node:url";
33155
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
33883
33156
  function detectExecutionContext(input) {
33884
33157
  const { argv, env, moduleUrl } = input;
33885
33158
  if (isDevelopmentMode(argv, env)) {
@@ -33936,7 +33209,7 @@ function detectNpxVersion(env) {
33936
33209
  return "default";
33937
33210
  }
33938
33211
  function createDevelopmentContext(moduleUrl) {
33939
- const modulePath = fileURLToPath(moduleUrl);
33212
+ const modulePath = fileURLToPath2(moduleUrl);
33940
33213
  const srcIndex = modulePath.lastIndexOf("/src/");
33941
33214
  const projectRoot = srcIndex !== -1 ? modulePath.substring(0, srcIndex) : dirname(dirname(modulePath));
33942
33215
  return {
@@ -34098,7 +33371,7 @@ function resolveConfigPath(config2, platform) {
34098
33371
 
34099
33372
  // packages/agent-mcp-config/src/apply.ts
34100
33373
  init_src();
34101
- import path12 from "node:path";
33374
+ import path13 from "node:path";
34102
33375
 
34103
33376
  // packages/agent-mcp-config/src/shapes.ts
34104
33377
  function transformStdioServer(config2, enabled) {
@@ -34161,7 +33434,7 @@ function getShapeTransformer(shape) {
34161
33434
 
34162
33435
  // packages/agent-mcp-config/src/apply.ts
34163
33436
  function getConfigDirectory(configPath) {
34164
- return path12.dirname(configPath);
33437
+ return path13.dirname(configPath);
34165
33438
  }
34166
33439
  var UnsupportedAgentError = class extends Error {
34167
33440
  constructor(agentId) {
@@ -34169,6 +33442,16 @@ var UnsupportedAgentError = class extends Error {
34169
33442
  this.name = "UnsupportedAgentError";
34170
33443
  }
34171
33444
  };
33445
+ function isConfigObject5(value) {
33446
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
33447
+ }
33448
+ function resolveServerMap(document, configKey) {
33449
+ const value = document[configKey];
33450
+ return isConfigObject5(value) ? value : {};
33451
+ }
33452
+ function mergeServerMap(document, configKey, servers) {
33453
+ return { ...document, [configKey]: servers };
33454
+ }
34172
33455
  async function configure(agentId, server, options) {
34173
33456
  if (!isSupported(agentId)) {
34174
33457
  throw new UnsupportedAgentError(agentId);
@@ -34194,15 +33477,14 @@ async function configure(agentId, server, options) {
34194
33477
  target: configPath,
34195
33478
  format: config2.format,
34196
33479
  transform: (document) => {
34197
- const serversKey = config2.configKey;
34198
- const servers = document[serversKey] ?? {};
33480
+ const servers = resolveServerMap(document, config2.configKey);
34199
33481
  const newServers = {
34200
33482
  ...servers,
34201
33483
  [server.name]: shaped
34202
33484
  };
34203
33485
  return {
34204
33486
  changed: true,
34205
- content: { ...document, [serversKey]: newServers }
33487
+ content: mergeServerMap(document, config2.configKey, newServers)
34206
33488
  };
34207
33489
  },
34208
33490
  label: `Add ${server.name} to ${configPath}`
@@ -34421,7 +33703,7 @@ init_src3();
34421
33703
  // packages/agent-skill-config/src/configs.ts
34422
33704
  init_src2();
34423
33705
  import os3 from "node:os";
34424
- import path13 from "node:path";
33706
+ import path14 from "node:path";
34425
33707
  var agentSkillConfigs = {
34426
33708
  "claude-code": {
34427
33709
  globalSkillDir: "~/.claude/skills",
@@ -34469,7 +33751,7 @@ async function getTemplates() {
34469
33751
  };
34470
33752
  return templatesCache;
34471
33753
  }
34472
- async function loadTemplate2(templateId) {
33754
+ async function loadTemplate(templateId) {
34473
33755
  const templates = await getTemplates();
34474
33756
  const template = templates[templateId];
34475
33757
  if (!template) {
@@ -34478,7 +33760,7 @@ async function loadTemplate2(templateId) {
34478
33760
  return template;
34479
33761
  }
34480
33762
  function createTemplateLoader() {
34481
- return loadTemplate2;
33763
+ return loadTemplate;
34482
33764
  }
34483
33765
 
34484
33766
  // packages/agent-skill-config/src/apply.ts
@@ -34882,7 +34164,7 @@ async function displayVersion(container, currentVersion) {
34882
34164
 
34883
34165
  // src/cli/commands/ralph.ts
34884
34166
  init_src3();
34885
- import path18 from "node:path";
34167
+ import path19 from "node:path";
34886
34168
 
34887
34169
  // packages/ralph/src/build/loop.ts
34888
34170
  import { basename as basename2, dirname as dirname6, resolve as resolvePath3 } from "node:path";
@@ -35135,13 +34417,13 @@ function getDirtyFiles(cwd) {
35135
34417
  for (const line of lines) {
35136
34418
  if (!line) continue;
35137
34419
  if (line.length < 4) continue;
35138
- let path19 = line.slice(3).trim();
34420
+ let path20 = line.slice(3).trim();
35139
34421
  const renameArrow = " -> ";
35140
- const arrowIndex = path19.lastIndexOf(renameArrow);
34422
+ const arrowIndex = path20.lastIndexOf(renameArrow);
35141
34423
  if (arrowIndex >= 0) {
35142
- path19 = path19.slice(arrowIndex + renameArrow.length).trim();
34424
+ path20 = path20.slice(arrowIndex + renameArrow.length).trim();
35143
34425
  }
35144
- if (path19) files.push(path19);
34426
+ if (path20) files.push(path20);
35145
34427
  }
35146
34428
  return files;
35147
34429
  }
@@ -35284,17 +34566,17 @@ function serializePlan(prd) {
35284
34566
  return yaml.endsWith("\n") ? yaml : `${yaml}
35285
34567
  `;
35286
34568
  }
35287
- function lockPlanFile(path19) {
35288
- return lockFile(path19, { retries: 20, minTimeout: 25, maxTimeout: 250 });
34569
+ function lockPlanFile(path20) {
34570
+ return lockFile(path20, { retries: 20, minTimeout: 25, maxTimeout: 250 });
35289
34571
  }
35290
- async function writePlan(path19, prd, options = {}) {
34572
+ async function writePlan(path20, prd, options = {}) {
35291
34573
  const fs3 = options.fs ?? fsPromises2;
35292
34574
  const lock = options.lock ?? lockPlanFile;
35293
- await fs3.mkdir(dirname3(path19), { recursive: true });
35294
- const release = await lock(path19);
34575
+ await fs3.mkdir(dirname3(path20), { recursive: true });
34576
+ const release = await lock(path20);
35295
34577
  try {
35296
34578
  const yaml = serializePlan(prd);
35297
- await fs3.writeFile(path19, yaml, { encoding: "utf8" });
34579
+ await fs3.writeFile(path20, yaml, { encoding: "utf8" });
35298
34580
  } finally {
35299
34581
  await release();
35300
34582
  }
@@ -35366,8 +34648,8 @@ function selectStory(prd, options = {}) {
35366
34648
  // packages/ralph/src/story/updater.ts
35367
34649
  import { dirname as dirname4 } from "node:path";
35368
34650
  import * as fsPromises3 from "node:fs/promises";
35369
- function lockPlanFile2(path19) {
35370
- return lockFile(path19, { retries: 20, minTimeout: 25, maxTimeout: 250 });
34651
+ function lockPlanFile2(path20) {
34652
+ return lockFile(path20, { retries: 20, minTimeout: 25, maxTimeout: 250 });
35371
34653
  }
35372
34654
  function assertStoryStatus(value) {
35373
34655
  if (value === "open") return;
@@ -35440,9 +34722,9 @@ function appendSection(lines, title, items, options) {
35440
34722
  }
35441
34723
  lines.push("");
35442
34724
  }
35443
- async function writeRunMeta(path19, metadata, options = {}) {
34725
+ async function writeRunMeta(path20, metadata, options = {}) {
35444
34726
  const fs3 = options.fs ?? fsPromises4;
35445
- await fs3.mkdir(dirname5(path19), { recursive: true });
34727
+ await fs3.mkdir(dirname5(path20), { recursive: true });
35446
34728
  const lines = [];
35447
34729
  lines.push("# Ralph Run Summary", "");
35448
34730
  lines.push(`- Run ID: ${metadata.runId}`);
@@ -35471,7 +34753,7 @@ async function writeRunMeta(path19, metadata, options = {}) {
35471
34753
  const git = metadata.git ?? null;
35472
34754
  if (!git) {
35473
34755
  lines.push("");
35474
- await fs3.writeFile(path19, lines.join("\n"), { encoding: "utf8" });
34756
+ await fs3.writeFile(path20, lines.join("\n"), { encoding: "utf8" });
35475
34757
  return;
35476
34758
  }
35477
34759
  lines.push("", "## Git");
@@ -35486,7 +34768,7 @@ async function writeRunMeta(path19, metadata, options = {}) {
35486
34768
  lines.push("");
35487
34769
  } else {
35488
34770
  lines.push("");
35489
- await fs3.writeFile(path19, lines.join("\n"), { encoding: "utf8" });
34771
+ await fs3.writeFile(path20, lines.join("\n"), { encoding: "utf8" });
35490
34772
  return;
35491
34773
  }
35492
34774
  if (git.commits !== void 0 && git.commits !== null) {
@@ -35506,7 +34788,7 @@ async function writeRunMeta(path19, metadata, options = {}) {
35506
34788
  appendSection(lines, "### Uncommitted Changes", git.dirtyFiles, {
35507
34789
  emptyLabel: "(none)"
35508
34790
  });
35509
- await fs3.writeFile(path19, lines.join("\n"), { encoding: "utf8" });
34791
+ await fs3.writeFile(path20, lines.join("\n"), { encoding: "utf8" });
35510
34792
  }
35511
34793
 
35512
34794
  // packages/ralph/src/build/overbaking.ts
@@ -35580,9 +34862,9 @@ async function defaultStreamingSpawn(agentId, options) {
35580
34862
  exitCode: result.exitCode
35581
34863
  };
35582
34864
  }
35583
- function absPath(cwd, path19) {
35584
- if (!path19) return resolvePath3(cwd);
35585
- return path19.startsWith("/") ? path19 : resolvePath3(cwd, path19);
34865
+ function absPath(cwd, path20) {
34866
+ if (!path20) return resolvePath3(cwd);
34867
+ return path20.startsWith("/") ? path20 : resolvePath3(cwd, path20);
35586
34868
  }
35587
34869
  function pad2(value) {
35588
34870
  return value < 10 ? `0${value}` : String(value);
@@ -35632,8 +34914,8 @@ async function appendToErrorsLog(fs3, errorsLogPath, message) {
35632
34914
  await fs3.mkdir(dirname6(errorsLogPath), { recursive: true });
35633
34915
  await fs3.writeFile(errorsLogPath, `${previous}${next}`, { encoding: "utf8" });
35634
34916
  }
35635
- function lockPlanFile3(path19) {
35636
- return lockFile(path19, { retries: 20, minTimeout: 25, maxTimeout: 250 });
34917
+ function lockPlanFile3(path20) {
34918
+ return lockFile(path20, { retries: 20, minTimeout: 25, maxTimeout: 250 });
35637
34919
  }
35638
34920
  function getCurrentBranch(cwd) {
35639
34921
  try {
@@ -35789,7 +35071,7 @@ async function buildLoop(options) {
35789
35071
  });
35790
35072
  worktreeBranch = entry.branch;
35791
35073
  const worktreePath = entry.path;
35792
- const symlinkFn = fs3.symlink ?? ((target, path19) => fsPromises5.symlink(target, path19));
35074
+ const symlinkFn = fs3.symlink ?? ((target, path20) => fsPromises5.symlink(target, path20));
35793
35075
  const exec = worktreeDeps.exec;
35794
35076
  const dirsToLink = [".poe-code-ralph", ".agents/poe-code-ralph"];
35795
35077
  for (const dir of dirsToLink) {
@@ -36077,21 +35359,21 @@ ${agentStderr}` : ""
36077
35359
  // packages/ralph/src/plan/resolver.ts
36078
35360
  init_src3();
36079
35361
  init_src();
36080
- import path14 from "node:path";
35362
+ import path15 from "node:path";
36081
35363
  import * as fsPromises6 from "node:fs/promises";
36082
35364
  function isPlanCandidateFile(fileName) {
36083
35365
  const lower = fileName.toLowerCase();
36084
35366
  if (!lower.startsWith("plan")) {
36085
35367
  return false;
36086
35368
  }
36087
- const ext = path14.extname(lower);
35369
+ const ext = path15.extname(lower);
36088
35370
  return ext === ".yml" || ext === ".yaml";
36089
35371
  }
36090
35372
  async function listPlanCandidates(fs3, cwd) {
36091
- const tasksDir = path14.join(cwd, ".agents", "tasks");
35373
+ const plansDir = path15.join(cwd, ".agents", "poe-code-ralph", "plans");
36092
35374
  let entries;
36093
35375
  try {
36094
- entries = await fs3.readdir(tasksDir);
35376
+ entries = await fs3.readdir(plansDir);
36095
35377
  } catch (error2) {
36096
35378
  if (isNotFound(error2)) {
36097
35379
  return [];
@@ -36103,12 +35385,12 @@ async function listPlanCandidates(fs3, cwd) {
36103
35385
  if (!isPlanCandidateFile(entry)) {
36104
35386
  continue;
36105
35387
  }
36106
- const absPath2 = path14.join(tasksDir, entry);
35388
+ const absPath2 = path15.join(plansDir, entry);
36107
35389
  const stats = await fs3.stat(absPath2);
36108
35390
  if (!stats.isFile()) {
36109
35391
  continue;
36110
35392
  }
36111
- const relativePath = path14.relative(cwd, absPath2);
35393
+ const relativePath = path15.relative(cwd, absPath2);
36112
35394
  const content = await fs3.readFile(absPath2, "utf8");
36113
35395
  const plan = parsePlan(content);
36114
35396
  const done = plan.stories.filter((s) => s.status === "done").length;
@@ -36127,7 +35409,7 @@ async function resolvePlanPath(options) {
36127
35409
  const cwd = options.cwd;
36128
35410
  const provided = options.plan?.trim();
36129
35411
  if (provided) {
36130
- const absPath2 = path14.isAbsolute(provided) ? provided : path14.resolve(cwd, provided);
35412
+ const absPath2 = path15.isAbsolute(provided) ? provided : path15.resolve(cwd, provided);
36131
35413
  try {
36132
35414
  const stats = await fs3.stat(absPath2);
36133
35415
  if (!stats.isFile()) {
@@ -36150,7 +35432,7 @@ async function resolvePlanPath(options) {
36150
35432
  if (candidates.length === 0) {
36151
35433
  if (options.assumeYes) {
36152
35434
  throw new Error(
36153
- "No plan found under .agents/tasks/. Provide --plan <path> to an existing plan file."
35435
+ "No plan found under .agents/poe-code-ralph/plans/. Provide --plan <path> to an existing plan file."
36154
35436
  );
36155
35437
  }
36156
35438
  return null;
@@ -36177,7 +35459,7 @@ async function resolvePlanPath(options) {
36177
35459
  // packages/ralph/src/plan/generator.ts
36178
35460
  init_src4();
36179
35461
  init_src();
36180
- import path15 from "node:path";
35462
+ import path16 from "node:path";
36181
35463
  import * as fsPromises7 from "node:fs/promises";
36182
35464
  var PLAN_PROMPT_TEMPLATE = [
36183
35465
  "# Plan",
@@ -36237,27 +35519,27 @@ function formatTimestamp3(date4) {
36237
35519
  const seconds = pad22(date4.getSeconds());
36238
35520
  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
36239
35521
  }
36240
- function validateLogPath(path19) {
36241
- if (typeof path19 !== "string" || path19.trim().length === 0) {
35522
+ function validateLogPath(path20) {
35523
+ if (typeof path20 !== "string" || path20.trim().length === 0) {
36242
35524
  throw new Error(
36243
- `Invalid activity log path: expected a non-empty string, got ${String(path19)}`
35525
+ `Invalid activity log path: expected a non-empty string, got ${String(path20)}`
36244
35526
  );
36245
35527
  }
36246
- if (path19.includes("\0")) {
35528
+ if (path20.includes("\0")) {
36247
35529
  throw new Error("Invalid activity log path: contains null byte");
36248
35530
  }
36249
35531
  }
36250
- async function logActivity(path19, message, options = {}) {
36251
- validateLogPath(path19);
35532
+ async function logActivity(path20, message, options = {}) {
35533
+ validateLogPath(path20);
36252
35534
  const fs3 = options.fs ?? fsPromises8;
36253
- const parent = dirname7(path19);
35535
+ const parent = dirname7(path20);
36254
35536
  if (parent && parent !== ".") {
36255
35537
  await fs3.mkdir(parent, { recursive: true });
36256
35538
  }
36257
35539
  const entry = `[${formatTimestamp3(/* @__PURE__ */ new Date())}] ${message}
36258
35540
  `;
36259
35541
  try {
36260
- await fs3.appendFile(path19, entry, { encoding: "utf8" });
35542
+ await fs3.appendFile(path20, entry, { encoding: "utf8" });
36261
35543
  } catch (error2) {
36262
35544
  const detail = error2 instanceof Error ? error2.message : `Unknown error: ${String(error2)}`;
36263
35545
  throw new Error(`Failed to append activity log entry: ${detail}`, { cause: error2 });
@@ -36266,7 +35548,7 @@ async function logActivity(path19, message, options = {}) {
36266
35548
 
36267
35549
  // packages/ralph/src/config/loader.ts
36268
35550
  init_src();
36269
- import path16 from "node:path";
35551
+ import path17 from "node:path";
36270
35552
  import * as fsPromises9 from "node:fs/promises";
36271
35553
  import YAML from "yaml";
36272
35554
  function isPlainObject2(value) {
@@ -36301,8 +35583,8 @@ function pickOptionalPositiveInt(config2, key, options) {
36301
35583
  return value;
36302
35584
  }
36303
35585
  async function loadSingleConfig(configDir, fs3) {
36304
- const yamlPath = path16.join(configDir, "config.yaml");
36305
- const jsonPath = path16.join(configDir, "config.json");
35586
+ const yamlPath = path17.join(configDir, "config.yaml");
35587
+ const jsonPath = path17.join(configDir, "config.json");
36306
35588
  let raw = null;
36307
35589
  let format = null;
36308
35590
  let sourcePath = null;
@@ -36375,14 +35657,14 @@ async function loadConfig(cwd, deps) {
36375
35657
  const sources = [];
36376
35658
  let merged = {};
36377
35659
  if (deps?.homeDir) {
36378
- const globalDir = path16.join(deps.homeDir, ".poe-code", "ralph");
35660
+ const globalDir = path17.join(deps.homeDir, ".poe-code", "ralph");
36379
35661
  const globalResult = await loadSingleConfig(globalDir, fs3);
36380
35662
  if (globalResult) {
36381
35663
  merged = globalResult.config;
36382
35664
  sources.push({ path: globalResult.sourcePath, scope: "global" });
36383
35665
  }
36384
35666
  }
36385
- const localDir = path16.join(cwd, ".agents", "poe-code-ralph");
35667
+ const localDir = path17.join(cwd, ".agents", "poe-code-ralph");
36386
35668
  const localResult = await loadSingleConfig(localDir, fs3);
36387
35669
  if (localResult) {
36388
35670
  merged = mergeConfigs(merged, localResult.config);
@@ -36405,14 +35687,14 @@ init_shared();
36405
35687
 
36406
35688
  // src/cli/commands/ralph-worktree.ts
36407
35689
  init_src3();
36408
- import path17 from "node:path";
35690
+ import path18 from "node:path";
36409
35691
  import { execSync as execSync3 } from "node:child_process";
36410
35692
  init_src4();
36411
35693
  init_src();
36412
35694
  function registerRalphWorktreeCommand(ralph, container) {
36413
35695
  ralph.command("worktree").description("Merge a completed worktree back into the main branch.").argument("<name>", "Name of the worktree to merge").option("--agent <name>", "Agent to use for the merge").action(async function(name) {
36414
35696
  const cwd = container.env.cwd;
36415
- const registryFile = path17.join(cwd, ".poe-code-ralph", "worktrees.yaml");
35697
+ const registryFile = path18.join(cwd, ".poe-code-ralph", "worktrees.yaml");
36416
35698
  const worktrees = await listWorktrees(cwd, registryFile, {
36417
35699
  fs: {
36418
35700
  readFile: (p, enc) => container.fs.readFile(p, enc),
@@ -36474,7 +35756,7 @@ function registerRalphWorktreeCommand(ralph, container) {
36474
35756
  }
36475
35757
 
36476
35758
  // src/cli/commands/ralph.ts
36477
- var templateImports2 = {
35759
+ var templateImports = {
36478
35760
  promptPartialPlan: () => Promise.resolve().then(() => __toESM(require_PROMPT_PARTIAL_plan(), 1)),
36479
35761
  skillPlan: () => Promise.resolve().then(() => __toESM(require_SKILL_plan(), 1)),
36480
35762
  promptPlan: () => Promise.resolve().then(() => __toESM(require_PROMPT_plan(), 1)),
@@ -36499,16 +35781,16 @@ async function loadRalphTemplates() {
36499
35781
  stateErrors,
36500
35782
  stateActivity
36501
35783
  ] = await Promise.all([
36502
- templateImports2.promptPartialPlan(),
36503
- templateImports2.skillPlan(),
36504
- templateImports2.promptPlan(),
36505
- templateImports2.promptBuild(),
36506
- templateImports2.refGuardrails(),
36507
- templateImports2.refContextEngineering(),
36508
- templateImports2.stateProgress(),
36509
- templateImports2.stateGuardrails(),
36510
- templateImports2.stateErrors(),
36511
- templateImports2.stateActivity()
35784
+ templateImports.promptPartialPlan(),
35785
+ templateImports.skillPlan(),
35786
+ templateImports.promptPlan(),
35787
+ templateImports.promptBuild(),
35788
+ templateImports.refGuardrails(),
35789
+ templateImports.refContextEngineering(),
35790
+ templateImports.stateProgress(),
35791
+ templateImports.stateGuardrails(),
35792
+ templateImports.stateErrors(),
35793
+ templateImports.stateActivity()
36512
35794
  ]);
36513
35795
  return {
36514
35796
  promptPartialPlan: promptPartialPlan.default,
@@ -36571,7 +35853,7 @@ async function writeFileOrSkip(args) {
36571
35853
  args.logger.info(`Skip: ${args.displayPath} (already exists)`);
36572
35854
  return "skipped";
36573
35855
  }
36574
- await args.fs.mkdir(path18.dirname(args.filePath), { recursive: true });
35856
+ await args.fs.mkdir(path19.dirname(args.filePath), { recursive: true });
36575
35857
  await args.fs.writeFile(args.filePath, args.contents, { encoding: "utf8" });
36576
35858
  args.logger.info(`${exists ? "Overwrite" : "Create"}: ${args.displayPath}`);
36577
35859
  return "written";
@@ -36607,22 +35889,22 @@ async function installRalphTemplates(args) {
36607
35889
  const promptPlanContents = templates.promptPlan.replace("{{{PROMPT_PARTIAL_PLAN}}}", templates.promptPartialPlan);
36608
35890
  const templateWrites = [
36609
35891
  {
36610
- targetPath: path18.join(cwd, ".agents", "poe-code-ralph", "PROMPT_plan.md"),
35892
+ targetPath: path19.join(cwd, ".agents", "poe-code-ralph", "PROMPT_plan.md"),
36611
35893
  displayPath: ".agents/poe-code-ralph/PROMPT_plan.md",
36612
35894
  contents: promptPlanContents
36613
35895
  },
36614
35896
  {
36615
- targetPath: path18.join(cwd, ".agents", "poe-code-ralph", "PROMPT_build.md"),
35897
+ targetPath: path19.join(cwd, ".agents", "poe-code-ralph", "PROMPT_build.md"),
36616
35898
  displayPath: ".agents/poe-code-ralph/PROMPT_build.md",
36617
35899
  contents: templates.promptBuild
36618
35900
  },
36619
35901
  {
36620
- targetPath: path18.join(cwd, ".agents", "poe-code-ralph", "references", "GUARDRAILS.md"),
35902
+ targetPath: path19.join(cwd, ".agents", "poe-code-ralph", "references", "GUARDRAILS.md"),
36621
35903
  displayPath: ".agents/poe-code-ralph/references/GUARDRAILS.md",
36622
35904
  contents: templates.refGuardrails
36623
35905
  },
36624
35906
  {
36625
- targetPath: path18.join(cwd, ".agents", "poe-code-ralph", "references", "CONTEXT_ENGINEERING.md"),
35907
+ targetPath: path19.join(cwd, ".agents", "poe-code-ralph", "references", "CONTEXT_ENGINEERING.md"),
36626
35908
  displayPath: ".agents/poe-code-ralph/references/CONTEXT_ENGINEERING.md",
36627
35909
  contents: templates.refContextEngineering
36628
35910
  }
@@ -36640,22 +35922,22 @@ async function installRalphTemplates(args) {
36640
35922
  const stateFiles = [
36641
35923
  {
36642
35924
  contents: templates.stateProgress,
36643
- targetPath: path18.join(cwd, ".poe-code-ralph", "progress.md"),
35925
+ targetPath: path19.join(cwd, ".poe-code-ralph", "progress.md"),
36644
35926
  displayPath: ".poe-code-ralph/progress.md"
36645
35927
  },
36646
35928
  {
36647
35929
  contents: templates.stateGuardrails,
36648
- targetPath: path18.join(cwd, ".poe-code-ralph", "guardrails.md"),
35930
+ targetPath: path19.join(cwd, ".poe-code-ralph", "guardrails.md"),
36649
35931
  displayPath: ".poe-code-ralph/guardrails.md"
36650
35932
  },
36651
35933
  {
36652
35934
  contents: templates.stateErrors,
36653
- targetPath: path18.join(cwd, ".poe-code-ralph", "errors.log"),
35935
+ targetPath: path19.join(cwd, ".poe-code-ralph", "errors.log"),
36654
35936
  displayPath: ".poe-code-ralph/errors.log"
36655
35937
  },
36656
35938
  {
36657
35939
  contents: templates.stateActivity,
36658
- targetPath: path18.join(cwd, ".poe-code-ralph", "activity.log"),
35940
+ targetPath: path19.join(cwd, ".poe-code-ralph", "activity.log"),
36659
35941
  displayPath: ".poe-code-ralph/activity.log"
36660
35942
  }
36661
35943
  ];
@@ -36702,7 +35984,7 @@ function registerRalphCommand(program, container) {
36702
35984
  throw new ValidationError(message2);
36703
35985
  }
36704
35986
  const rawPath = options.activityLog?.trim() || configActivityLogPath || ".poe-code-ralph/activity.log";
36705
- const resolvedPath = path18.isAbsolute(rawPath) ? rawPath : path18.resolve(container.env.cwd, rawPath);
35987
+ const resolvedPath = path19.isAbsolute(rawPath) ? rawPath : path19.resolve(container.env.cwd, rawPath);
36706
35988
  await logActivity(resolvedPath, trimmedMessage, {
36707
35989
  fs: container.fs
36708
35990
  });
@@ -36714,7 +35996,7 @@ function registerRalphCommand(program, container) {
36714
35996
  if (!planPath) {
36715
35997
  throw new ValidationError("--plan <path> is required.");
36716
35998
  }
36717
- const resolvedPath = path18.isAbsolute(planPath) ? planPath : path18.resolve(cwd, planPath);
35999
+ const resolvedPath = path19.isAbsolute(planPath) ? planPath : path19.resolve(cwd, planPath);
36718
36000
  let content;
36719
36001
  try {
36720
36002
  content = await container.fs.readFile(resolvedPath, "utf8");
@@ -36865,7 +36147,7 @@ function registerRalphCommand(program, container) {
36865
36147
  } else {
36866
36148
  const entered = await text3({
36867
36149
  message: "Enter path to plan file:",
36868
- placeholder: ".agents/tasks/plan.yaml"
36150
+ placeholder: ".agents/poe-code-ralph/plans/plan.yaml"
36869
36151
  });
36870
36152
  if (isCancel(entered)) {
36871
36153
  cancel("Operation cancelled");
@@ -36889,7 +36171,7 @@ function registerRalphCommand(program, container) {
36889
36171
  } else {
36890
36172
  try {
36891
36173
  const planContent = await container.fs.readFile(
36892
- path18.resolve(cwd, planPath),
36174
+ path19.resolve(cwd, planPath),
36893
36175
  "utf8"
36894
36176
  );
36895
36177
  const plan = parsePlan(planContent);
@@ -36923,7 +36205,7 @@ function registerRalphCommand(program, container) {
36923
36205
  } else {
36924
36206
  try {
36925
36207
  const planContent = await container.fs.readFile(
36926
- path18.resolve(cwd, planPath),
36208
+ path19.resolve(cwd, planPath),
36927
36209
  "utf8"
36928
36210
  );
36929
36211
  const plan = parsePlan(planContent);
@@ -37456,7 +36738,7 @@ function registerModelsCommand(program, container) {
37456
36738
  // package.json
37457
36739
  var package_default = {
37458
36740
  name: "poe-code",
37459
- version: "3.0.60",
36741
+ version: "3.0.61",
37460
36742
  description: "CLI tool to configure Poe API for developer workflows.",
37461
36743
  type: "module",
37462
36744
  workspaces: [
@@ -37584,7 +36866,7 @@ function formatHelpText(input) {
37584
36866
  {
37585
36867
  name: "configure",
37586
36868
  args: "[agent]",
37587
- description: "Configure a coding agent (claude-code, codex, opencode)"
36869
+ description: "Configure a coding agent"
37588
36870
  },
37589
36871
  {
37590
36872
  name: "unconfigure",
@@ -37833,7 +37115,7 @@ import * as nodeFs from "node:fs/promises";
37833
37115
  import * as nodeFsSync3 from "node:fs";
37834
37116
  import { realpathSync } from "node:fs";
37835
37117
  import { homedir as homedir3 } from "node:os";
37836
- import { pathToFileURL } from "node:url";
37118
+ import { pathToFileURL as pathToFileURL2 } from "node:url";
37837
37119
  import { join as join3 } from "node:path";
37838
37120
  import chalk13 from "chalk";
37839
37121
 
@@ -37965,9 +37247,9 @@ function isCliInvocation(argv, moduleUrl, realpath = realpathSync) {
37965
37247
  if (typeof entry !== "string") {
37966
37248
  return false;
37967
37249
  }
37968
- const candidates = [pathToFileURL(entry).href];
37250
+ const candidates = [pathToFileURL2(entry).href];
37969
37251
  try {
37970
- candidates.push(pathToFileURL(realpath(entry)).href);
37252
+ candidates.push(pathToFileURL2(realpath(entry)).href);
37971
37253
  } catch {
37972
37254
  }
37973
37255
  return candidates.includes(moduleUrl);