poe-code 3.0.222 → 3.0.224

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.
Files changed (98) hide show
  1. package/dist/cli/commands/configure-payload.js +72 -15
  2. package/dist/cli/commands/configure-payload.js.map +1 -1
  3. package/dist/cli/commands/configure.d.ts +2 -0
  4. package/dist/cli/commands/configure.js +55 -15
  5. package/dist/cli/commands/configure.js.map +1 -1
  6. package/dist/cli/commands/ensure-isolated-config.js +24 -3
  7. package/dist/cli/commands/ensure-isolated-config.js.map +1 -1
  8. package/dist/cli/commands/harness.js +45 -2
  9. package/dist/cli/commands/harness.js.map +1 -1
  10. package/dist/cli/commands/login.js +11 -2
  11. package/dist/cli/commands/login.js.map +1 -1
  12. package/dist/cli/commands/plan.js +52 -20
  13. package/dist/cli/commands/plan.js.map +1 -1
  14. package/dist/cli/commands/provider.d.ts +2 -0
  15. package/dist/cli/commands/provider.js +126 -3
  16. package/dist/cli/commands/provider.js.map +1 -1
  17. package/dist/cli/commands/shared.d.ts +16 -1
  18. package/dist/cli/commands/shared.js +141 -18
  19. package/dist/cli/commands/shared.js.map +1 -1
  20. package/dist/cli/commands/spawn.js +24 -3
  21. package/dist/cli/commands/spawn.js.map +1 -1
  22. package/dist/cli/commands/tasks-options.d.ts +9 -1
  23. package/dist/cli/commands/tasks-options.js +88 -5
  24. package/dist/cli/commands/tasks-options.js.map +1 -1
  25. package/dist/cli/commands/tasks.js +250 -7
  26. package/dist/cli/commands/tasks.js.map +1 -1
  27. package/dist/cli/constants.d.ts +1 -2
  28. package/dist/cli/constants.js +1 -13
  29. package/dist/cli/constants.js.map +1 -1
  30. package/dist/cli/container.js +22 -9
  31. package/dist/cli/container.js.map +1 -1
  32. package/dist/cli/environment.d.ts +1 -0
  33. package/dist/cli/environment.js +3 -1
  34. package/dist/cli/environment.js.map +1 -1
  35. package/dist/cli/options.d.ts +1 -1
  36. package/dist/cli/options.js +10 -1
  37. package/dist/cli/options.js.map +1 -1
  38. package/dist/cli/program.js +127 -13
  39. package/dist/cli/program.js.map +1 -1
  40. package/dist/cli/prompt-runner.js +4 -2
  41. package/dist/cli/prompt-runner.js.map +1 -1
  42. package/dist/cli/prompts.d.ts +3 -1
  43. package/dist/cli/prompts.js +13 -0
  44. package/dist/cli/prompts.js.map +1 -1
  45. package/dist/index.d.ts +5 -1
  46. package/dist/index.js +47146 -26676
  47. package/dist/index.js.map +4 -4
  48. package/dist/providers/claude-code.js +4547 -1202
  49. package/dist/providers/claude-code.js.map +4 -4
  50. package/dist/providers/codex.js +4558 -1210
  51. package/dist/providers/codex.js.map +4 -4
  52. package/dist/providers/goose.js +4652 -1137
  53. package/dist/providers/goose.js.map +4 -4
  54. package/dist/providers/kimi.js +4548 -1203
  55. package/dist/providers/kimi.js.map +4 -4
  56. package/dist/providers/opencode.js +4543 -1198
  57. package/dist/providers/opencode.js.map +4 -4
  58. package/dist/providers/poe-agent.js +12879 -11508
  59. package/dist/providers/poe-agent.js.map +4 -4
  60. package/dist/providers/spawn-options.d.ts +1 -0
  61. package/dist/sdk/container.js +22 -9
  62. package/dist/sdk/container.js.map +1 -1
  63. package/dist/sdk/pipeline.js +1 -0
  64. package/dist/sdk/pipeline.js.map +1 -1
  65. package/dist/sdk/spawn-core.d.ts +2 -0
  66. package/dist/sdk/spawn-core.js +2 -1
  67. package/dist/sdk/spawn-core.js.map +1 -1
  68. package/dist/sdk/spawn.d.ts +6 -1
  69. package/dist/sdk/spawn.js +192 -4
  70. package/dist/sdk/spawn.js.map +1 -1
  71. package/dist/sdk/types.d.ts +10 -1
  72. package/dist/services/config.d.ts +4 -14
  73. package/dist/services/config.js +12 -54
  74. package/dist/services/config.js.map +1 -1
  75. package/dist/workflow-templates/maestro-turn.yml +159 -0
  76. package/package.json +6 -2
  77. package/packages/agent-skill-config/dist/bridge-active-skills.d.ts +23 -0
  78. package/packages/agent-skill-config/dist/bridge-active-skills.js +194 -0
  79. package/packages/agent-skill-config/dist/configs.d.ts +1 -1
  80. package/packages/agent-skill-config/dist/configs.js +5 -5
  81. package/packages/agent-skill-config/dist/git-exclude.d.ts +4 -0
  82. package/packages/agent-skill-config/dist/git-exclude.js +93 -0
  83. package/packages/agent-skill-config/dist/index.d.ts +5 -0
  84. package/packages/agent-skill-config/dist/index.js +3 -0
  85. package/packages/agent-skill-config/dist/resolve-skill-reference.d.ts +22 -0
  86. package/packages/agent-skill-config/dist/resolve-skill-reference.js +82 -0
  87. package/packages/design-system/dist/components/browser.d.ts +15 -0
  88. package/packages/design-system/dist/components/browser.js +26 -0
  89. package/packages/design-system/dist/explorer/index.d.ts +1 -1
  90. package/packages/design-system/dist/explorer/keymap.js +6 -3
  91. package/packages/design-system/dist/explorer/render/footer.js +14 -0
  92. package/packages/design-system/dist/explorer/runtime.js +11 -4
  93. package/packages/design-system/dist/explorer/state.d.ts +6 -1
  94. package/packages/design-system/dist/index.d.ts +2 -1
  95. package/packages/design-system/dist/index.js +1 -0
  96. package/packages/memory/dist/index.js +2564 -568
  97. package/packages/memory/dist/index.js.map +4 -4
  98. package/scripts/postinstall-sync-skills.mjs +15 -2
@@ -35,7 +35,7 @@ function assertSafeRelPath(input) {
35
35
  }
36
36
 
37
37
  // packages/memory/src/resolve-root.ts
38
- import path11 from "node:path";
38
+ import path12 from "node:path";
39
39
 
40
40
  // packages/poe-code-config/src/runtime.ts
41
41
  import { existsSync } from "node:fs";
@@ -523,7 +523,7 @@ import path7 from "node:path";
523
523
 
524
524
  // packages/config-extends/src/discover.ts
525
525
  import path3 from "node:path";
526
- async function findBase(name, bases, fs14) {
526
+ async function findBase(name, bases, fs16) {
527
527
  const checkedPaths = [];
528
528
  for (const basePath of bases) {
529
529
  for (const extension of [".md", ".yaml", ".yml", ".json"]) {
@@ -531,7 +531,7 @@ async function findBase(name, bases, fs14) {
531
531
  checkedPaths.push(filePath);
532
532
  try {
533
533
  return {
534
- content: await fs14.readFile(filePath, "utf8"),
534
+ content: await fs16.readFile(filePath, "utf8"),
535
535
  filePath
536
536
  };
537
537
  } catch (error2) {
@@ -611,11 +611,11 @@ function stripBom(content) {
611
611
  function mergeLayers(layers) {
612
612
  return mergeObjectLayers(layers, []);
613
613
  }
614
- function mergeObjectLayers(layers, path45) {
614
+ function mergeObjectLayers(layers, path50) {
615
615
  const data = {};
616
616
  const sources = {};
617
617
  for (const key of collectKeys(layers)) {
618
- const resolved = resolveKey(layers, key, path45);
618
+ const resolved = resolveKey(layers, key, path50);
619
619
  if (resolved === void 0) {
620
620
  continue;
621
621
  }
@@ -633,7 +633,7 @@ function collectKeys(layers) {
633
633
  }
634
634
  return [...keys];
635
635
  }
636
- function resolveKey(layers, key, path45) {
636
+ function resolveKey(layers, key, path50) {
637
637
  let winningSource;
638
638
  let winningValue;
639
639
  const objectLayers = [];
@@ -663,9 +663,9 @@ function resolveKey(layers, key, path45) {
663
663
  if (winningSource === void 0) {
664
664
  return void 0;
665
665
  }
666
- const fullPath = buildPath(path45, key);
666
+ const fullPath = buildPath(path50, key);
667
667
  if (isPlainObject(winningValue)) {
668
- const merged = mergeObjectLayers(objectLayers, [...path45, key]);
668
+ const merged = mergeObjectLayers(objectLayers, [...path50, key]);
669
669
  return {
670
670
  value: merged.data,
671
671
  sources: {
@@ -690,8 +690,8 @@ function isWinningCandidate(key, value) {
690
690
  }
691
691
  return true;
692
692
  }
693
- function buildPath(path45, key) {
694
- return [...path45, key].join(".");
693
+ function buildPath(path50, key) {
694
+ return [...path50, key].join(".");
695
695
  }
696
696
  function isPlainObject(value) {
697
697
  if (value === null || Array.isArray(value) || typeof value !== "object") {
@@ -1445,6 +1445,10 @@ function hasProperty(value, key) {
1445
1445
  return key in value;
1446
1446
  }
1447
1447
 
1448
+ // packages/design-system/src/components/browser.ts
1449
+ import { spawn } from "node:child_process";
1450
+ import process2 from "node:process";
1451
+
1448
1452
  // packages/design-system/src/acp/writer.ts
1449
1453
  import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
1450
1454
  var storage = new AsyncLocalStorage2();
@@ -2075,16 +2079,16 @@ function getConfigFormat(pathOrFormat) {
2075
2079
  }
2076
2080
  return formatRegistry[formatName];
2077
2081
  }
2078
- function detectFormat2(path45) {
2079
- const ext = getExtension(path45);
2082
+ function detectFormat2(path50) {
2083
+ const ext = getExtension(path50);
2080
2084
  return extensionMap[ext];
2081
2085
  }
2082
- function getExtension(path45) {
2083
- const lastDot = path45.lastIndexOf(".");
2086
+ function getExtension(path50) {
2087
+ const lastDot = path50.lastIndexOf(".");
2084
2088
  if (lastDot === -1) {
2085
2089
  return "";
2086
2090
  }
2087
- return path45.slice(lastDot).toLowerCase();
2091
+ return path50.slice(lastDot).toLowerCase();
2088
2092
  }
2089
2093
 
2090
2094
  // packages/config-mutations/src/execution/path-utils.ts
@@ -2135,9 +2139,9 @@ function resolvePath(rawPath, homeDir, pathMapper) {
2135
2139
  function isNotFound(error2) {
2136
2140
  return typeof error2 === "object" && error2 !== null && "code" in error2 && error2.code === "ENOENT";
2137
2141
  }
2138
- async function readFileIfExists(fs14, target) {
2142
+ async function readFileIfExists(fs16, target) {
2139
2143
  try {
2140
- return await fs14.readFile(target, "utf8");
2144
+ return await fs16.readFile(target, "utf8");
2141
2145
  } catch (error2) {
2142
2146
  if (isNotFound(error2)) {
2143
2147
  return null;
@@ -2145,9 +2149,9 @@ async function readFileIfExists(fs14, target) {
2145
2149
  throw error2;
2146
2150
  }
2147
2151
  }
2148
- async function pathExists(fs14, target) {
2152
+ async function pathExists(fs16, target) {
2149
2153
  try {
2150
- await fs14.stat(target);
2154
+ await fs16.stat(target);
2151
2155
  return true;
2152
2156
  } catch (error2) {
2153
2157
  if (isNotFound(error2)) {
@@ -2171,9 +2175,9 @@ function createInvalidDocumentBackupPath(targetPath) {
2171
2175
  const ext = targetPath.includes(".") ? targetPath.split(".").pop() : "bak";
2172
2176
  return `${targetPath}.invalid-${createTimestamp()}.${ext}`;
2173
2177
  }
2174
- async function backupInvalidDocument(fs14, targetPath, content) {
2178
+ async function backupInvalidDocument(fs16, targetPath, content) {
2175
2179
  const backupPath = createInvalidDocumentBackupPath(targetPath);
2176
- await fs14.writeFile(backupPath, content, { encoding: "utf8" });
2180
+ await fs16.writeFile(backupPath, content, { encoding: "utf8" });
2177
2181
  }
2178
2182
  function describeMutation(kind, targetPath) {
2179
2183
  const displayPath = targetPath ?? "target";
@@ -2731,12 +2735,12 @@ async function executeMutation(mutation, context, options) {
2731
2735
  }
2732
2736
 
2733
2737
  // packages/poe-code-config/src/store.ts
2734
- async function readMergedDocument(fs14, globalPath, projectPath) {
2735
- const globalDocument = await readStoredDocument(fs14, globalPath);
2738
+ async function readMergedDocument(fs16, globalPath, projectPath) {
2739
+ const globalDocument = await readStoredDocument(fs16, globalPath);
2736
2740
  if (!projectPath || projectPath === globalPath) {
2737
2741
  return globalDocument.data;
2738
2742
  }
2739
- const projectDocument = await readStoredDocument(fs14, projectPath);
2743
+ const projectDocument = await readStoredDocument(fs16, projectPath);
2740
2744
  const resolved = await resolve(
2741
2745
  [
2742
2746
  {
@@ -2750,16 +2754,16 @@ async function readMergedDocument(fs14, globalPath, projectPath) {
2750
2754
  }
2751
2755
  ],
2752
2756
  {
2753
- fs: createResolvedConfigFs(fs14, globalPath, globalDocument.content),
2757
+ fs: createResolvedConfigFs(fs16, globalPath, globalDocument.content),
2754
2758
  autoExtend: true
2755
2759
  }
2756
2760
  );
2757
2761
  return normalizeDocument(resolved.data);
2758
2762
  }
2759
- async function readStoredDocument(fs14, filePath) {
2763
+ async function readStoredDocument(fs16, filePath) {
2760
2764
  try {
2761
- const raw = await fs14.readFile(filePath, "utf8");
2762
- return await parseStoredDocument(fs14, filePath, raw);
2765
+ const raw = await fs16.readFile(filePath, "utf8");
2766
+ return await parseStoredDocument(fs16, filePath, raw);
2763
2767
  } catch (error2) {
2764
2768
  if (isNotFound(error2)) {
2765
2769
  return {
@@ -2770,7 +2774,7 @@ async function readStoredDocument(fs14, filePath) {
2770
2774
  throw error2;
2771
2775
  }
2772
2776
  }
2773
- async function parseStoredDocument(fs14, filePath, raw) {
2777
+ async function parseStoredDocument(fs16, filePath, raw) {
2774
2778
  try {
2775
2779
  return {
2776
2780
  content: raw,
@@ -2778,7 +2782,7 @@ async function parseStoredDocument(fs14, filePath, raw) {
2778
2782
  };
2779
2783
  } catch (error2) {
2780
2784
  if (error2 instanceof SyntaxError) {
2781
- await recoverInvalidDocument(fs14, filePath, raw);
2785
+ await recoverInvalidDocument(fs16, filePath, raw);
2782
2786
  return {
2783
2787
  content: EMPTY_DOCUMENT,
2784
2788
  data: {}
@@ -2812,21 +2816,21 @@ function normalizeScopeValues(value) {
2812
2816
  }
2813
2817
  return normalized;
2814
2818
  }
2815
- function createResolvedConfigFs(fs14, globalPath, globalContent) {
2819
+ function createResolvedConfigFs(fs16, globalPath, globalContent) {
2816
2820
  return {
2817
2821
  readFile(filePath, _encoding) {
2818
2822
  if (filePath === globalPath) {
2819
2823
  return Promise.resolve(globalContent);
2820
2824
  }
2821
- return fs14.readFile(filePath, "utf8");
2825
+ return fs16.readFile(filePath, "utf8");
2822
2826
  }
2823
2827
  };
2824
2828
  }
2825
- async function recoverInvalidDocument(fs14, filePath, content) {
2826
- await fs14.mkdir(path7.dirname(filePath), { recursive: true });
2829
+ async function recoverInvalidDocument(fs16, filePath, content) {
2830
+ await fs16.mkdir(path7.dirname(filePath), { recursive: true });
2827
2831
  const backupPath = createInvalidBackupPath(filePath);
2828
- await fs14.writeFile(backupPath, content, { encoding: "utf8" });
2829
- await fs14.writeFile(filePath, EMPTY_DOCUMENT, { encoding: "utf8" });
2832
+ await fs16.writeFile(backupPath, content, { encoding: "utf8" });
2833
+ await fs16.writeFile(filePath, EMPTY_DOCUMENT, { encoding: "utf8" });
2830
2834
  }
2831
2835
  function createInvalidBackupPath(filePath) {
2832
2836
  const directory = path7.dirname(filePath);
@@ -2950,7 +2954,7 @@ function mergeScope(scope, baseScope, overrideScope) {
2950
2954
  ...Object.fromEntries(scopeEntries)
2951
2955
  };
2952
2956
  }
2953
- function mergeRuntimeScope(baseScope, overrideScope, path45 = []) {
2957
+ function mergeRuntimeScope(baseScope, overrideScope, path50 = []) {
2954
2958
  const merged = {};
2955
2959
  const keys = /* @__PURE__ */ new Set([...Object.keys(baseScope), ...Object.keys(overrideScope)]);
2956
2960
  for (const key of keys) {
@@ -2962,20 +2966,20 @@ function mergeRuntimeScope(baseScope, overrideScope, path45 = []) {
2962
2966
  }
2963
2967
  continue;
2964
2968
  }
2965
- if (isRuntimeConcatenativeArray([...path45, key]) && Array.isArray(baseValue) && Array.isArray(overrideValue)) {
2969
+ if (isRuntimeConcatenativeArray([...path50, key]) && Array.isArray(baseValue) && Array.isArray(overrideValue)) {
2966
2970
  merged[key] = [...baseValue, ...overrideValue];
2967
2971
  continue;
2968
2972
  }
2969
2973
  if (isRecord3(baseValue) && isRecord3(overrideValue)) {
2970
- merged[key] = mergeRuntimeScope(baseValue, overrideValue, [...path45, key]);
2974
+ merged[key] = mergeRuntimeScope(baseValue, overrideValue, [...path50, key]);
2971
2975
  continue;
2972
2976
  }
2973
2977
  merged[key] = overrideValue;
2974
2978
  }
2975
2979
  return merged;
2976
2980
  }
2977
- function isRuntimeConcatenativeArray(path45) {
2978
- return path45.join(".") === "mounts" || path45.join(".") === "runner.workspace.exclude";
2981
+ function isRuntimeConcatenativeArray(path50) {
2982
+ return path50.join(".") === "mounts" || path50.join(".") === "runner.workspace.exclude";
2979
2983
  }
2980
2984
  function isRecord3(value) {
2981
2985
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
@@ -3031,11 +3035,420 @@ import path8 from "node:path";
3031
3035
  var EMPTY_DOCUMENT2 = `${JSON.stringify({}, null, 2)}
3032
3036
  `;
3033
3037
 
3038
+ // packages/poe-code-config/src/configured-services.ts
3039
+ import path9 from "node:path";
3040
+
3041
+ // packages/agent-defs/src/agents/claude-code.ts
3042
+ var claudeCodeAgent = {
3043
+ id: "claude-code",
3044
+ name: "claude-code",
3045
+ label: "Claude Code",
3046
+ summary: "Configure Claude Code to route through Poe.",
3047
+ aliases: ["claude"],
3048
+ binaryName: "claude",
3049
+ apiShapes: ["anthropic-messages"],
3050
+ configPath: "~/.claude/settings.json",
3051
+ branding: {
3052
+ colors: {
3053
+ dark: "#C15F3C",
3054
+ light: "#C15F3C"
3055
+ }
3056
+ }
3057
+ };
3058
+
3059
+ // packages/agent-defs/src/agents/claude-desktop.ts
3060
+ var claudeDesktopAgent = {
3061
+ id: "claude-desktop",
3062
+ name: "claude-desktop",
3063
+ label: "Claude Desktop",
3064
+ summary: "Anthropic's official desktop application for Claude",
3065
+ configPath: "~/.claude/settings.json",
3066
+ branding: {
3067
+ colors: {
3068
+ dark: "#D97757",
3069
+ light: "#D97757"
3070
+ }
3071
+ }
3072
+ };
3073
+
3074
+ // packages/agent-defs/src/agents/codex.ts
3075
+ var codexAgent = {
3076
+ id: "codex",
3077
+ name: "codex",
3078
+ label: "Codex",
3079
+ summary: "Configure Codex to use Poe as the model provider.",
3080
+ binaryName: "codex",
3081
+ apiShapes: ["openai-responses"],
3082
+ configPath: "~/.codex/config.toml",
3083
+ branding: {
3084
+ colors: {
3085
+ dark: "#D5D9DF",
3086
+ light: "#7A7F86"
3087
+ }
3088
+ }
3089
+ };
3090
+
3091
+ // packages/agent-defs/src/agents/opencode.ts
3092
+ var openCodeAgent = {
3093
+ id: "opencode",
3094
+ name: "opencode",
3095
+ label: "OpenCode CLI",
3096
+ summary: "Configure OpenCode CLI to use the Poe API.",
3097
+ binaryName: "opencode",
3098
+ apiShapes: ["openai-chat-completions"],
3099
+ configPath: "~/.config/opencode/config.json",
3100
+ branding: {
3101
+ colors: {
3102
+ dark: "#4A4F55",
3103
+ light: "#2F3338"
3104
+ }
3105
+ }
3106
+ };
3107
+
3108
+ // packages/agent-defs/src/agents/kimi.ts
3109
+ var kimiAgent = {
3110
+ id: "kimi",
3111
+ name: "kimi",
3112
+ label: "Kimi",
3113
+ summary: "Configure Kimi CLI to use Poe API",
3114
+ aliases: ["kimi-cli"],
3115
+ binaryName: "kimi",
3116
+ apiShapes: ["openai-chat-completions"],
3117
+ configPath: "~/.kimi/config.toml",
3118
+ branding: {
3119
+ colors: {
3120
+ dark: "#7B68EE",
3121
+ light: "#6A5ACD"
3122
+ }
3123
+ }
3124
+ };
3125
+
3126
+ // packages/agent-defs/src/agents/goose.ts
3127
+ var gooseAgent = {
3128
+ id: "goose",
3129
+ name: "goose",
3130
+ label: "Goose",
3131
+ summary: "Block's open-source AI agent with ACP support.",
3132
+ binaryName: "goose",
3133
+ apiShapes: ["openai-chat-completions"],
3134
+ configPath: "~/.config/goose/config.yaml",
3135
+ branding: {
3136
+ colors: {
3137
+ dark: "#FF6B35",
3138
+ light: "#E85D26"
3139
+ }
3140
+ }
3141
+ };
3142
+
3143
+ // packages/agent-defs/src/agents/poe-agent.ts
3144
+ var poeAgentAgent = {
3145
+ id: "poe-agent",
3146
+ name: "poe-agent",
3147
+ label: "Poe Agent",
3148
+ summary: "Run one-shot prompts with the built-in Poe agent runtime.",
3149
+ apiShapes: ["openai-responses", "openai-chat-completions"],
3150
+ configPath: "~/.poe-code/config.json",
3151
+ branding: {
3152
+ colors: {
3153
+ dark: "#A465F7",
3154
+ light: "#7A3FD3"
3155
+ }
3156
+ }
3157
+ };
3158
+
3159
+ // packages/agent-defs/src/registry.ts
3160
+ var allAgents = [
3161
+ claudeCodeAgent,
3162
+ claudeDesktopAgent,
3163
+ codexAgent,
3164
+ openCodeAgent,
3165
+ kimiAgent,
3166
+ gooseAgent,
3167
+ poeAgentAgent
3168
+ ];
3169
+ var lookup2 = /* @__PURE__ */ new Map();
3170
+ for (const agent of allAgents) {
3171
+ const values = [agent.id, agent.name, ...agent.aliases ?? []];
3172
+ for (const value of values) {
3173
+ const normalized = value.toLowerCase();
3174
+ if (!lookup2.has(normalized)) {
3175
+ lookup2.set(normalized, agent.id);
3176
+ }
3177
+ }
3178
+ }
3179
+ function resolveAgentId(input) {
3180
+ if (!input) {
3181
+ return void 0;
3182
+ }
3183
+ return lookup2.get(input.toLowerCase());
3184
+ }
3185
+
3186
+ // packages/providers/src/auth/api-key.ts
3187
+ function requireApiKeyAuth(provider) {
3188
+ if (provider.auth.kind !== "api-key") {
3189
+ throw new Error(
3190
+ `Provider ${provider.id} does not use api-key auth (got ${provider.auth.kind}).`
3191
+ );
3192
+ }
3193
+ return provider.auth;
3194
+ }
3195
+ async function acquireApiKey(provider, options, context) {
3196
+ const auth = requireApiKeyAuth(provider);
3197
+ const candidate = options.apiKey ?? await context.promptForSecret?.(auth.prompt);
3198
+ const trimmed = candidate?.trim();
3199
+ if (!trimmed) {
3200
+ throw new Error(
3201
+ `No API key available for provider "${provider.id}". Pass --api-key or run interactively.`
3202
+ );
3203
+ }
3204
+ return trimmed;
3205
+ }
3206
+ var apiKeyAuthStrategy = {
3207
+ async login(provider, options, context) {
3208
+ const apiKey = await acquireApiKey(provider, options, context);
3209
+ await context.secretStore.set(apiKey);
3210
+ return apiKey;
3211
+ },
3212
+ async logout(_provider, context) {
3213
+ await context.secretStore.delete();
3214
+ },
3215
+ async isLoggedIn(_provider, context) {
3216
+ const value = await context.secretStore.get();
3217
+ return typeof value === "string" && value.trim().length > 0;
3218
+ },
3219
+ async resolveCredential(provider, context) {
3220
+ requireApiKeyAuth(provider);
3221
+ const value = await context.secretStore.get();
3222
+ if (!value || value.trim().length === 0) {
3223
+ throw new Error(
3224
+ `No stored credential for provider "${provider.id}". Run \`poe-code provider login ${provider.id}\`.`
3225
+ );
3226
+ }
3227
+ return value;
3228
+ }
3229
+ };
3230
+
3231
+ // packages/providers/src/compatibility.ts
3232
+ function resolveApiShape(provider, agent) {
3233
+ if (!provider.apiShapes || !agent.apiShapes) {
3234
+ return void 0;
3235
+ }
3236
+ for (const shapeId of agent.apiShapes) {
3237
+ if (provider.apiShapes.some((shape) => shape.id === shapeId)) {
3238
+ return shapeId;
3239
+ }
3240
+ }
3241
+ return void 0;
3242
+ }
3243
+
3244
+ // packages/providers/src/registry.ts
3245
+ var ProviderRegistry = class {
3246
+ providers;
3247
+ byId;
3248
+ storeFactory;
3249
+ envVars;
3250
+ constructor(providers, storeFactory, options) {
3251
+ const byId = /* @__PURE__ */ new Map();
3252
+ for (const provider of providers) {
3253
+ if (byId.has(provider.id)) {
3254
+ throw new Error(`Duplicate provider id: ${provider.id}`);
3255
+ }
3256
+ byId.set(provider.id, provider);
3257
+ }
3258
+ this.providers = providers;
3259
+ this.byId = byId;
3260
+ this.storeFactory = storeFactory;
3261
+ this.envVars = options?.envVars ?? {};
3262
+ }
3263
+ list() {
3264
+ return this.providers;
3265
+ }
3266
+ get(id) {
3267
+ return this.byId.get(id);
3268
+ }
3269
+ forAgent(agent) {
3270
+ return this.providers.filter((provider) => {
3271
+ return resolveApiShape(provider, agent) !== void 0;
3272
+ });
3273
+ }
3274
+ async isLoggedIn(id) {
3275
+ const provider = this.requireProvider(id);
3276
+ if (provider.auth.kind === "api-key") {
3277
+ const envValue = this.envVars[provider.auth.envVar];
3278
+ if (typeof envValue === "string" && envValue.trim().length > 0) {
3279
+ return true;
3280
+ }
3281
+ }
3282
+ const store = this.requireStore(id);
3283
+ const credential = await store.get();
3284
+ return credential !== null;
3285
+ }
3286
+ async login(id, options, context) {
3287
+ const provider = this.requireProvider(id);
3288
+ const store = this.requireStore(id);
3289
+ if (provider.auth.kind !== "api-key") {
3290
+ throw new Error(`Provider "${id}" does not use api-key auth.`);
3291
+ }
3292
+ const auth = provider.auth;
3293
+ const envApiKey = context?.envVars?.[auth.envVar];
3294
+ const resolvedApiKey = options.apiKey ?? (typeof envApiKey === "string" && envApiKey.trim() ? envApiKey : void 0);
3295
+ if (auth.preferredLogin && context?.resolvePreferredLogin) {
3296
+ const apiKey = await context.resolvePreferredLogin({
3297
+ provider,
3298
+ apiKey: options.apiKey,
3299
+ envValue: typeof envApiKey === "string" ? envApiKey : void 0
3300
+ });
3301
+ await store.set(apiKey);
3302
+ return;
3303
+ }
3304
+ await apiKeyAuthStrategy.login(
3305
+ provider,
3306
+ { apiKey: resolvedApiKey },
3307
+ { secretStore: store, promptForSecret: context?.promptForSecret }
3308
+ );
3309
+ }
3310
+ async resolveCredential(id, options = {}, context) {
3311
+ const provider = this.requireProvider(id);
3312
+ if (provider.auth.kind !== "api-key") {
3313
+ throw new Error(`Provider "${id}" does not use api-key auth.`);
3314
+ }
3315
+ if (options.apiKey !== void 0) {
3316
+ return normalizeRequiredCredential(provider.id, options.apiKey);
3317
+ }
3318
+ const envVars = context?.envVars ?? this.envVars;
3319
+ const envApiKey = envVars[provider.auth.envVar];
3320
+ if (typeof envApiKey === "string" && envApiKey.trim().length > 0) {
3321
+ return envApiKey.trim();
3322
+ }
3323
+ const store = this.requireStore(id);
3324
+ return apiKeyAuthStrategy.resolveCredential(provider, { secretStore: store });
3325
+ }
3326
+ async logout(id) {
3327
+ this.requireProvider(id);
3328
+ const store = this.requireStore(id);
3329
+ await store.delete();
3330
+ }
3331
+ requireProvider(id) {
3332
+ const provider = this.byId.get(id);
3333
+ if (!provider) {
3334
+ throw new Error(`Unknown provider: "${id}".`);
3335
+ }
3336
+ return provider;
3337
+ }
3338
+ requireStore(id) {
3339
+ if (!this.storeFactory) {
3340
+ throw new Error(`No store factory configured for ProviderRegistry.`);
3341
+ }
3342
+ return this.storeFactory(id);
3343
+ }
3344
+ };
3345
+ function normalizeRequiredCredential(providerId, value) {
3346
+ const trimmed = value.trim();
3347
+ if (trimmed.length === 0) {
3348
+ throw new Error(`No API key available for provider "${providerId}".`);
3349
+ }
3350
+ return trimmed;
3351
+ }
3352
+
3353
+ // packages/providers/src/providers/poe.ts
3354
+ var POE_PROVIDER_ID = "poe";
3355
+ var poeProvider = {
3356
+ id: POE_PROVIDER_ID,
3357
+ label: "Poe",
3358
+ summary: "Route AI coding agents through Poe's API.",
3359
+ baseUrl: "https://api.poe.com",
3360
+ auth: {
3361
+ kind: "api-key",
3362
+ envVar: "POE_API_KEY",
3363
+ storageKey: "provider:poe",
3364
+ prompt: { title: "Poe API key" },
3365
+ preferredLogin: "oauth"
3366
+ },
3367
+ apiShapes: [
3368
+ {
3369
+ id: "openai-chat-completions",
3370
+ defaultBaseUrl: "https://api.poe.com/v1"
3371
+ },
3372
+ {
3373
+ id: "openai-responses",
3374
+ defaultBaseUrl: "https://api.poe.com/v1"
3375
+ },
3376
+ {
3377
+ id: "anthropic-messages",
3378
+ defaultBaseUrl: "https://api.poe.com/anthropic"
3379
+ }
3380
+ ]
3381
+ };
3382
+
3383
+ // packages/providers/src/providers/anthropic.ts
3384
+ var anthropicProvider = {
3385
+ id: "anthropic",
3386
+ label: "Anthropic",
3387
+ summary: "Route AI coding agents through Anthropic's API.",
3388
+ baseUrl: "https://api.anthropic.com",
3389
+ auth: {
3390
+ kind: "api-key",
3391
+ envVar: "ANTHROPIC_API_KEY",
3392
+ storageKey: "provider:anthropic",
3393
+ prompt: { title: "Anthropic API key" }
3394
+ },
3395
+ apiShapes: [
3396
+ {
3397
+ id: "anthropic-messages",
3398
+ defaultBaseUrl: "https://api.anthropic.com"
3399
+ }
3400
+ ]
3401
+ };
3402
+
3403
+ // packages/providers/src/providers/cloudflare.ts
3404
+ var cloudflareProvider = {
3405
+ id: "cloudflare",
3406
+ label: "Cloudflare AI Gateway",
3407
+ summary: "Route coding agents through Cloudflare AI Gateway.",
3408
+ baseUrlEnvVar: "CF_AIG_BASE_URL",
3409
+ requiresBaseUrl: true,
3410
+ modelInput: { kind: "freeform" },
3411
+ auth: {
3412
+ kind: "api-key",
3413
+ envVar: "CF_AIG_TOKEN",
3414
+ storageKey: "provider:cloudflare",
3415
+ prompt: { title: "Cloudflare AI Gateway token" }
3416
+ },
3417
+ apiShapes: [
3418
+ {
3419
+ id: "openai-chat-completions",
3420
+ baseUrlPath: "compat"
3421
+ },
3422
+ {
3423
+ id: "openai-responses",
3424
+ baseUrlPath: "openai"
3425
+ },
3426
+ {
3427
+ id: "anthropic-messages",
3428
+ baseUrlPath: "anthropic"
3429
+ },
3430
+ {
3431
+ id: "google-generations",
3432
+ baseUrlPath: "google-ai-studio"
3433
+ }
3434
+ ]
3435
+ };
3436
+
3437
+ // packages/poe-code-config/src/configured-services.ts
3438
+ var agentsById = new Map(allAgents.map((agent) => [agent.id, agent]));
3439
+ var defaultProviderRegistry = new ProviderRegistry([
3440
+ poeProvider,
3441
+ anthropicProvider,
3442
+ cloudflareProvider
3443
+ ]);
3444
+ var EMPTY_DOCUMENT3 = `${JSON.stringify({}, null, 2)}
3445
+ `;
3446
+
3034
3447
  // packages/poe-code-config/src/state/index.ts
3035
3448
  import os2 from "node:os";
3036
3449
 
3037
3450
  // packages/poe-code-config/src/state/jobs.ts
3038
- import path9 from "node:path";
3451
+ import path10 from "node:path";
3039
3452
 
3040
3453
  // packages/file-lock/src/lock.ts
3041
3454
  import * as fsPromises from "node:fs/promises";
@@ -3096,17 +3509,17 @@ function isPidRunning(pid) {
3096
3509
  }
3097
3510
  function createDefaultFs() {
3098
3511
  return {
3099
- open: (path45, flags) => fsPromises.open(path45, flags),
3100
- readFile: (path45, encoding) => fsPromises.readFile(path45, encoding),
3512
+ open: (path50, flags) => fsPromises.open(path50, flags),
3513
+ readFile: (path50, encoding) => fsPromises.readFile(path50, encoding),
3101
3514
  stat: fsPromises.stat,
3102
3515
  unlink: fsPromises.unlink
3103
3516
  };
3104
3517
  }
3105
- async function removeLockFile(fs14, lockPath, signal) {
3518
+ async function removeLockFile(fs16, lockPath, signal) {
3106
3519
  for (let attempt = 0; attempt <= 4; attempt += 1) {
3107
3520
  throwIfAborted(signal);
3108
3521
  try {
3109
- await fs14.unlink(lockPath);
3522
+ await fs16.unlink(lockPath);
3110
3523
  return;
3111
3524
  } catch (error2) {
3112
3525
  if (hasErrorCode(error2, "ENOENT")) {
@@ -3137,12 +3550,12 @@ function parseLockMetadata(content) {
3137
3550
  }
3138
3551
  return void 0;
3139
3552
  }
3140
- async function readLockMetadata(fs14, lockPath) {
3141
- if (!fs14.readFile) {
3553
+ async function readLockMetadata(fs16, lockPath) {
3554
+ if (!fs16.readFile) {
3142
3555
  return void 0;
3143
3556
  }
3144
3557
  try {
3145
- return parseLockMetadata(await fs14.readFile(lockPath, "utf8"));
3558
+ return parseLockMetadata(await fs16.readFile(lockPath, "utf8"));
3146
3559
  } catch (error2) {
3147
3560
  if (hasErrorCode(error2, "ENOENT")) {
3148
3561
  return null;
@@ -3176,7 +3589,7 @@ async function writeLockMetadata(handle) {
3176
3589
  }
3177
3590
  }
3178
3591
  async function acquireFileLock(filePath, options = {}) {
3179
- const fs14 = options.fs ?? createDefaultFs();
3592
+ const fs16 = options.fs ?? createDefaultFs();
3180
3593
  const retries = options.retries ?? 20;
3181
3594
  const minTimeout = options.minTimeout ?? 25;
3182
3595
  const maxTimeout = options.maxTimeout ?? 250;
@@ -3187,7 +3600,7 @@ async function acquireFileLock(filePath, options = {}) {
3187
3600
  while (attempt <= retries) {
3188
3601
  throwIfAborted(options.signal);
3189
3602
  try {
3190
- const handle = await fs14.open(lockPath, "wx");
3603
+ const handle = await fs16.open(lockPath, "wx");
3191
3604
  await writeLockMetadata(handle);
3192
3605
  let released = false;
3193
3606
  return async () => {
@@ -3195,7 +3608,7 @@ async function acquireFileLock(filePath, options = {}) {
3195
3608
  return;
3196
3609
  }
3197
3610
  released = true;
3198
- await removeLockFile(fs14, lockPath, options.signal);
3611
+ await removeLockFile(fs16, lockPath, options.signal);
3199
3612
  };
3200
3613
  } catch (error2) {
3201
3614
  if (!hasErrorCode(error2, "EEXIST")) {
@@ -3204,7 +3617,7 @@ async function acquireFileLock(filePath, options = {}) {
3204
3617
  }
3205
3618
  let stat7;
3206
3619
  try {
3207
- stat7 = await fs14.stat(lockPath);
3620
+ stat7 = await fs16.stat(lockPath);
3208
3621
  } catch (statError) {
3209
3622
  if (hasErrorCode(statError, "ENOENT")) {
3210
3623
  continue;
@@ -3212,7 +3625,7 @@ async function acquireFileLock(filePath, options = {}) {
3212
3625
  throw statError;
3213
3626
  }
3214
3627
  const reclaimLock = await shouldReclaimLock({
3215
- fs: fs14,
3628
+ fs: fs16,
3216
3629
  isPidRunning: pidIsRunning,
3217
3630
  lockPath,
3218
3631
  staleMs,
@@ -3222,7 +3635,7 @@ async function acquireFileLock(filePath, options = {}) {
3222
3635
  continue;
3223
3636
  }
3224
3637
  if (reclaimLock) {
3225
- await removeLockFile(fs14, lockPath, options.signal);
3638
+ await removeLockFile(fs16, lockPath, options.signal);
3226
3639
  continue;
3227
3640
  }
3228
3641
  if (attempt >= retries) {
@@ -3242,15 +3655,15 @@ function isNotFoundError(error2) {
3242
3655
  }
3243
3656
 
3244
3657
  // packages/poe-code-config/src/state/jobs.ts
3245
- function createJobRegistry(homeDir, fs14 = defaultStateFs) {
3246
- const jobsDir = path9.join(homeDir, ".poe-code", "state", "jobs");
3658
+ function createJobRegistry(homeDir, fs16 = defaultStateFs) {
3659
+ const jobsDir = path10.join(homeDir, ".poe-code", "state", "jobs");
3247
3660
  function jobPath(id) {
3248
3661
  assertSafeJobId(id);
3249
- return path9.join(jobsDir, `${id}.json`);
3662
+ return path10.join(jobsDir, `${id}.json`);
3250
3663
  }
3251
3664
  async function get(id) {
3252
3665
  try {
3253
- return parseJobEntry(await fs14.readFile(jobPath(id), "utf8"));
3666
+ return parseJobEntry(await fs16.readFile(jobPath(id), "utf8"));
3254
3667
  } catch (error2) {
3255
3668
  if (isNotFoundError(error2)) {
3256
3669
  return null;
@@ -3261,8 +3674,8 @@ function createJobRegistry(homeDir, fs14 = defaultStateFs) {
3261
3674
  async function put(entry) {
3262
3675
  assertJobEntry(entry);
3263
3676
  const filePath = jobPath(entry.id);
3264
- await fs14.mkdir(jobsDir, { recursive: true });
3265
- const release = await acquireFileLock(filePath, { fs: fs14 });
3677
+ await fs16.mkdir(jobsDir, { recursive: true });
3678
+ const release = await acquireFileLock(filePath, { fs: fs16 });
3266
3679
  try {
3267
3680
  await writeJobAtomically(filePath, entry);
3268
3681
  } finally {
@@ -3271,8 +3684,8 @@ function createJobRegistry(homeDir, fs14 = defaultStateFs) {
3271
3684
  }
3272
3685
  async function update(id, patch) {
3273
3686
  const filePath = jobPath(id);
3274
- await fs14.mkdir(jobsDir, { recursive: true });
3275
- const release = await acquireFileLock(filePath, { fs: fs14 });
3687
+ await fs16.mkdir(jobsDir, { recursive: true });
3688
+ const release = await acquireFileLock(filePath, { fs: fs16 });
3276
3689
  try {
3277
3690
  const current = await get(id);
3278
3691
  if (current === null) {
@@ -3293,7 +3706,7 @@ function createJobRegistry(homeDir, fs14 = defaultStateFs) {
3293
3706
  async function list(filter = {}) {
3294
3707
  let entries;
3295
3708
  try {
3296
- entries = await fs14.readdir(jobsDir);
3709
+ entries = await fs16.readdir(jobsDir);
3297
3710
  } catch (error2) {
3298
3711
  if (isNotFoundError(error2)) {
3299
3712
  return [];
@@ -3305,12 +3718,12 @@ function createJobRegistry(homeDir, fs14 = defaultStateFs) {
3305
3718
  if (!entry.endsWith(".json")) {
3306
3719
  continue;
3307
3720
  }
3308
- const filePath = path9.join(jobsDir, entry);
3309
- const stat7 = await fs14.stat(filePath);
3721
+ const filePath = path10.join(jobsDir, entry);
3722
+ const stat7 = await fs16.stat(filePath);
3310
3723
  if (!stat7.isFile()) {
3311
3724
  continue;
3312
3725
  }
3313
- const job = parseJobEntry(await fs14.readFile(filePath, "utf8"));
3726
+ const job = parseJobEntry(await fs16.readFile(filePath, "utf8"));
3314
3727
  if (matchesFilter(job, filter)) {
3315
3728
  jobs.push(job);
3316
3729
  }
@@ -3320,16 +3733,16 @@ function createJobRegistry(homeDir, fs14 = defaultStateFs) {
3320
3733
  async function remove2(id) {
3321
3734
  const filePath = jobPath(id);
3322
3735
  try {
3323
- await fs14.stat(jobsDir);
3736
+ await fs16.stat(jobsDir);
3324
3737
  } catch (error2) {
3325
3738
  if (isNotFoundError(error2)) {
3326
3739
  return;
3327
3740
  }
3328
3741
  throw error2;
3329
3742
  }
3330
- const release = await acquireFileLock(filePath, { fs: fs14 });
3743
+ const release = await acquireFileLock(filePath, { fs: fs16 });
3331
3744
  try {
3332
- await fs14.unlink(filePath);
3745
+ await fs16.unlink(filePath);
3333
3746
  } catch (error2) {
3334
3747
  if (!isNotFoundError(error2)) {
3335
3748
  throw error2;
@@ -3339,14 +3752,14 @@ function createJobRegistry(homeDir, fs14 = defaultStateFs) {
3339
3752
  }
3340
3753
  }
3341
3754
  async function writeJobAtomically(filePath, entry) {
3342
- await fs14.mkdir(path9.dirname(filePath), { recursive: true });
3755
+ await fs16.mkdir(path10.dirname(filePath), { recursive: true });
3343
3756
  const tempPath = `${filePath}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`;
3344
3757
  try {
3345
- await fs14.writeFile(tempPath, `${JSON.stringify(entry, null, 2)}
3758
+ await fs16.writeFile(tempPath, `${JSON.stringify(entry, null, 2)}
3346
3759
  `, {
3347
3760
  encoding: "utf8"
3348
3761
  });
3349
- await fs14.rename(tempPath, filePath);
3762
+ await fs16.rename(tempPath, filePath);
3350
3763
  } catch (error2) {
3351
3764
  await removeTempFile(tempPath);
3352
3765
  throw error2;
@@ -3354,7 +3767,7 @@ function createJobRegistry(homeDir, fs14 = defaultStateFs) {
3354
3767
  }
3355
3768
  async function removeTempFile(tempPath) {
3356
3769
  try {
3357
- await fs14.unlink(tempPath);
3770
+ await fs16.unlink(tempPath);
3358
3771
  } catch (error2) {
3359
3772
  if (!isNotFoundError(error2)) {
3360
3773
  throw error2;
@@ -3370,7 +3783,7 @@ function createJobRegistry(homeDir, fs14 = defaultStateFs) {
3370
3783
  };
3371
3784
  }
3372
3785
  function assertSafeJobId(id) {
3373
- if (id.length === 0 || id === "." || id === ".." || path9.isAbsolute(id) || id.includes("/") || id.includes("\\") || id.includes("\0")) {
3786
+ if (id.length === 0 || id === "." || id === ".." || path10.isAbsolute(id) || id.includes("/") || id.includes("\\") || id.includes("\0")) {
3374
3787
  throw new Error("Invalid job id.");
3375
3788
  }
3376
3789
  }
@@ -3400,12 +3813,12 @@ function isRecord4(value) {
3400
3813
  }
3401
3814
 
3402
3815
  // packages/poe-code-config/src/state/templates.ts
3403
- import path10 from "node:path";
3404
- function createTemplateRegistry(homeDir, fs14 = defaultStateFs) {
3405
- const filePath = path10.join(homeDir, ".poe-code", "state", "templates.json");
3816
+ import path11 from "node:path";
3817
+ function createTemplateRegistry(homeDir, fs16 = defaultStateFs) {
3818
+ const filePath = path11.join(homeDir, ".poe-code", "state", "templates.json");
3406
3819
  async function readState() {
3407
3820
  try {
3408
- const raw = await fs14.readFile(filePath, "utf8");
3821
+ const raw = await fs16.readFile(filePath, "utf8");
3409
3822
  return normalizeTemplateState(JSON.parse(raw));
3410
3823
  } catch (error2) {
3411
3824
  if (isNotFoundError(error2)) {
@@ -3415,14 +3828,14 @@ function createTemplateRegistry(homeDir, fs14 = defaultStateFs) {
3415
3828
  }
3416
3829
  }
3417
3830
  async function writeState(state) {
3418
- await fs14.writeFile(filePath, `${JSON.stringify(state, null, 2)}
3831
+ await fs16.writeFile(filePath, `${JSON.stringify(state, null, 2)}
3419
3832
  `, {
3420
3833
  encoding: "utf8"
3421
3834
  });
3422
3835
  }
3423
3836
  async function updateState(mutator) {
3424
- await fs14.mkdir(path10.dirname(filePath), { recursive: true });
3425
- const release = await acquireFileLock(filePath, { fs: fs14 });
3837
+ await fs16.mkdir(path11.dirname(filePath), { recursive: true });
3838
+ const release = await acquireFileLock(filePath, { fs: fs16 });
3426
3839
  try {
3427
3840
  const state = await readState();
3428
3841
  mutator(state);
@@ -3492,10 +3905,10 @@ function isRecord5(value) {
3492
3905
  }
3493
3906
 
3494
3907
  // packages/poe-code-config/src/state/index.ts
3495
- function createStateManager(homeDir, fs14) {
3908
+ function createStateManager(homeDir, fs16) {
3496
3909
  return {
3497
- templates: createTemplateRegistry(homeDir, fs14),
3498
- jobs: createJobRegistry(homeDir, fs14)
3910
+ templates: createTemplateRegistry(homeDir, fs16),
3911
+ jobs: createJobRegistry(homeDir, fs16)
3499
3912
  };
3500
3913
  }
3501
3914
 
@@ -3517,16 +3930,16 @@ async function resolveConfiguredMemoryRoot(options) {
3517
3930
  return resolveMemoryRoot(options.cwd);
3518
3931
  }
3519
3932
  function resolveAgainstCwd(cwd, value) {
3520
- return path11.isAbsolute(value) ? value : path11.resolve(cwd, value);
3933
+ return path12.isAbsolute(value) ? value : path12.resolve(cwd, value);
3521
3934
  }
3522
3935
 
3523
3936
  // packages/memory/src/init.ts
3524
3937
  import * as fs from "node:fs/promises";
3525
- import path12 from "node:path";
3938
+ import path13 from "node:path";
3526
3939
  async function initMemory(root) {
3527
- await fs.mkdir(path12.join(root, MEMORY_PAGES_DIR_RELPATH), { recursive: true });
3528
- await writeFileIfMissing(path12.join(root, MEMORY_INDEX_RELPATH), "# Memory index\n");
3529
- await writeFileIfMissing(path12.join(root, MEMORY_LOG_RELPATH), "");
3940
+ await fs.mkdir(path13.join(root, MEMORY_PAGES_DIR_RELPATH), { recursive: true });
3941
+ await writeFileIfMissing(path13.join(root, MEMORY_INDEX_RELPATH), "# Memory index\n");
3942
+ await writeFileIfMissing(path13.join(root, MEMORY_LOG_RELPATH), "");
3530
3943
  }
3531
3944
  async function writeFileIfMissing(filePath, content) {
3532
3945
  try {
@@ -3543,7 +3956,7 @@ function hasErrorCode2(error2, code) {
3543
3956
 
3544
3957
  // packages/memory/src/pages.ts
3545
3958
  import * as fs2 from "node:fs/promises";
3546
- import path13 from "node:path";
3959
+ import path14 from "node:path";
3547
3960
 
3548
3961
  // packages/memory/src/frontmatter.ts
3549
3962
  import { parse as parse6, stringify } from "yaml";
@@ -3723,10 +4136,10 @@ function parseSources(value) {
3723
4136
  if (!isRecord6(item)) {
3724
4137
  throw new Error('Invalid "sources" frontmatter. Expected each source to be a string or object.');
3725
4138
  }
3726
- const path45 = readRequiredString(item.path, "sources[].path");
4139
+ const path50 = readRequiredString(item.path, "sources[].path");
3727
4140
  const startLine = readOptionalPositiveInteger(item.startLine, "sources[].startLine");
3728
4141
  const endLine = readOptionalPositiveInteger(item.endLine, "sources[].endLine");
3729
- return parseSourceRef(serializeSourceRef({ path: path45, ...startLine === void 0 ? {} : { startLine }, ...endLine === void 0 ? {} : { endLine } }));
4142
+ return parseSourceRef(serializeSourceRef({ path: path50, ...startLine === void 0 ? {} : { startLine }, ...endLine === void 0 ? {} : { endLine } }));
3730
4143
  });
3731
4144
  }
3732
4145
  function readOptionalString(value, field) {
@@ -3771,7 +4184,7 @@ async function listPages(root) {
3771
4184
  }
3772
4185
  async function readPage(root, relPath) {
3773
4186
  const normalizedRelPath = assertMarkdownRelPath(relPath);
3774
- const absPath = path13.join(root, normalizedRelPath);
4187
+ const absPath = path14.join(root, normalizedRelPath);
3775
4188
  const [content, stat7] = await Promise.all([fs2.readFile(absPath, "utf8"), fs2.stat(absPath)]);
3776
4189
  try {
3777
4190
  const parsed = parseFrontmatter(content);
@@ -3800,7 +4213,7 @@ async function collectMarkdownRelPaths(root, startRelPath = "") {
3800
4213
  return relPaths.sort((left, right) => left.localeCompare(right));
3801
4214
  }
3802
4215
  async function collectMarkdownRelPathsInto(root, currentRelPath, relPaths) {
3803
- const absPath = path13.join(root, currentRelPath);
4216
+ const absPath = path14.join(root, currentRelPath);
3804
4217
  let entryNames;
3805
4218
  try {
3806
4219
  entryNames = await fs2.readdir(absPath);
@@ -3811,8 +4224,8 @@ async function collectMarkdownRelPathsInto(root, currentRelPath, relPaths) {
3811
4224
  throw error2;
3812
4225
  }
3813
4226
  for (const entryName of entryNames.sort((left, right) => left.localeCompare(right))) {
3814
- const entryRelPath = currentRelPath.length === 0 ? entryName : path13.posix.join(currentRelPath, entryName);
3815
- const entryAbsPath = path13.join(root, entryRelPath);
4227
+ const entryRelPath = currentRelPath.length === 0 ? entryName : path14.posix.join(currentRelPath, entryName);
4228
+ const entryAbsPath = path14.join(root, entryRelPath);
3816
4229
  const entryStat = await fs2.stat(entryAbsPath);
3817
4230
  if (entryStat.isDirectory()) {
3818
4231
  if (entryName === MEMORY_CACHE_DIR_RELPATH) {
@@ -3842,7 +4255,7 @@ function assertMarkdownRelPath(relPath) {
3842
4255
  return normalizedRelPath;
3843
4256
  }
3844
4257
  function isMarkdownPath(relPath) {
3845
- return path13.posix.extname(relPath).toLowerCase() === ".md";
4258
+ return path14.posix.extname(relPath).toLowerCase() === ".md";
3846
4259
  }
3847
4260
  function isMissing(error2) {
3848
4261
  return typeof error2 === "object" && error2 !== null && "code" in error2 && error2.code === "ENOENT";
@@ -3850,7 +4263,7 @@ function isMissing(error2) {
3850
4263
 
3851
4264
  // packages/memory/src/search.ts
3852
4265
  import * as fs3 from "node:fs/promises";
3853
- import path14 from "node:path";
4266
+ import path15 from "node:path";
3854
4267
  async function searchMemory(root, query) {
3855
4268
  const normalizedQuery = query.trim();
3856
4269
  if (normalizedQuery.length === 0) {
@@ -3859,7 +4272,7 @@ async function searchMemory(root, query) {
3859
4272
  const relPaths = await collectMarkdownRelPaths(root);
3860
4273
  const hits = [];
3861
4274
  for (const relPath of relPaths) {
3862
- const content = await fs3.readFile(path14.join(root, relPath), "utf8");
4275
+ const content = await fs3.readFile(path15.join(root, relPath), "utf8");
3863
4276
  if (content.length === 0) {
3864
4277
  continue;
3865
4278
  }
@@ -3880,7 +4293,7 @@ async function searchMemory(root, query) {
3880
4293
 
3881
4294
  // packages/memory/src/status.ts
3882
4295
  import * as fs4 from "node:fs/promises";
3883
- import path15 from "node:path";
4296
+ import path16 from "node:path";
3884
4297
  async function statusOf(root) {
3885
4298
  if (!await pathExists2(root)) {
3886
4299
  return {
@@ -3897,7 +4310,7 @@ async function statusOf(root) {
3897
4310
  let totalBytes = 0;
3898
4311
  let lastWriteAtMs = Number.NEGATIVE_INFINITY;
3899
4312
  for (const relPath of markdownRelPaths) {
3900
- const stat7 = await fs4.stat(path15.join(root, relPath));
4313
+ const stat7 = await fs4.stat(path16.join(root, relPath));
3901
4314
  totalBytes += stat7.size;
3902
4315
  lastWriteAtMs = Math.max(lastWriteAtMs, stat7.mtimeMs);
3903
4316
  }
@@ -3922,15 +4335,15 @@ async function pathExists2(targetPath) {
3922
4335
 
3923
4336
  // packages/memory/src/edit.ts
3924
4337
  import * as fs7 from "node:fs/promises";
3925
- import path19 from "node:path";
4338
+ import path20 from "node:path";
3926
4339
 
3927
4340
  // packages/memory/src/write.ts
3928
4341
  import * as fs6 from "node:fs/promises";
3929
- import path18 from "node:path";
4342
+ import path19 from "node:path";
3930
4343
 
3931
4344
  // packages/memory/src/lock.ts
3932
4345
  import * as fsPromises2 from "node:fs/promises";
3933
- import path16 from "node:path";
4346
+ import path17 from "node:path";
3934
4347
  function createDefaultFs2() {
3935
4348
  return {
3936
4349
  readFile: (filePath, encoding) => fsPromises2.readFile(filePath, encoding),
@@ -3968,18 +4381,18 @@ function isPidRunning2(pid) {
3968
4381
  return !hasErrorCode3(error2, "ESRCH");
3969
4382
  }
3970
4383
  }
3971
- async function removeLockFile2(fs14, lockPath) {
4384
+ async function removeLockFile2(fs16, lockPath) {
3972
4385
  try {
3973
- await fs14.unlink(lockPath);
4386
+ await fs16.unlink(lockPath);
3974
4387
  } catch (error2) {
3975
4388
  if (!hasErrorCode3(error2, "ENOENT")) {
3976
4389
  throw error2;
3977
4390
  }
3978
4391
  }
3979
4392
  }
3980
- async function readLockPid(fs14, lockPath) {
4393
+ async function readLockPid(fs16, lockPath) {
3981
4394
  try {
3982
- return parsePid(await fs14.readFile(lockPath, "utf8"));
4395
+ return parsePid(await fs16.readFile(lockPath, "utf8"));
3983
4396
  } catch (error2) {
3984
4397
  if (hasErrorCode3(error2, "ENOENT")) {
3985
4398
  return null;
@@ -3988,8 +4401,8 @@ async function readLockPid(fs14, lockPath) {
3988
4401
  }
3989
4402
  }
3990
4403
  async function withLock(root, run, options = {}) {
3991
- const fs14 = options.fs ?? createDefaultFs2();
3992
- const lockPath = path16.join(root, MEMORY_LOCK_RELPATH);
4404
+ const fs16 = options.fs ?? createDefaultFs2();
4405
+ const lockPath = path17.join(root, MEMORY_LOCK_RELPATH);
3993
4406
  const pid = options.pid ?? process.pid;
3994
4407
  const retries = options.retries ?? 20;
3995
4408
  const minTimeoutMs = options.minTimeoutMs ?? 25;
@@ -3997,24 +4410,24 @@ async function withLock(root, run, options = {}) {
3997
4410
  const pidIsRunning = options.isPidRunning ?? isPidRunning2;
3998
4411
  for (let attempt = 0; attempt <= retries; attempt += 1) {
3999
4412
  try {
4000
- await fs14.writeFile(lockPath, `${pid}
4413
+ await fs16.writeFile(lockPath, `${pid}
4001
4414
  `, { encoding: "utf8", flag: "wx" });
4002
4415
  try {
4003
4416
  return await run();
4004
4417
  } finally {
4005
- await removeLockFile2(fs14, lockPath);
4418
+ await removeLockFile2(fs16, lockPath);
4006
4419
  }
4007
4420
  } catch (error2) {
4008
4421
  if (!hasErrorCode3(error2, "EEXIST")) {
4009
4422
  throw error2;
4010
4423
  }
4011
4424
  }
4012
- const existingPid = await readLockPid(fs14, lockPath);
4425
+ const existingPid = await readLockPid(fs16, lockPath);
4013
4426
  if (existingPid === null) {
4014
4427
  continue;
4015
4428
  }
4016
4429
  if (existingPid === void 0 || !pidIsRunning(existingPid)) {
4017
- await removeLockFile2(fs14, lockPath);
4430
+ await removeLockFile2(fs16, lockPath);
4018
4431
  continue;
4019
4432
  }
4020
4433
  if (attempt < retries) {
@@ -4027,7 +4440,7 @@ async function withLock(root, run, options = {}) {
4027
4440
  // packages/memory/src/reconcile.ts
4028
4441
  import { createHash } from "node:crypto";
4029
4442
  import * as fs5 from "node:fs/promises";
4030
- import path17 from "node:path";
4443
+ import path18 from "node:path";
4031
4444
 
4032
4445
  // packages/memory/src/confidence.ts
4033
4446
  var TAG_RE = /^<!--\s*memory:(?<verb>extracted|inferred|ambiguous)(?<rest>[^>]*?)-->\s*$/;
@@ -4239,7 +4652,7 @@ async function snapshot(root) {
4239
4652
  await Promise.all(
4240
4653
  (await collectMarkdownRelPaths(root, MEMORY_PAGES_DIR_RELPATH)).map(async (relPath) => [
4241
4654
  relPath,
4242
- hashContent(await fs5.readFile(path17.join(root, relPath), "utf8"))
4655
+ hashContent(await fs5.readFile(path18.join(root, relPath), "utf8"))
4243
4656
  ])
4244
4657
  )
4245
4658
  );
@@ -4250,7 +4663,7 @@ async function reconcile(root, before, _verb, detail) {
4250
4663
  const timestamp = (/* @__PURE__ */ new Date()).toISOString();
4251
4664
  const currentPages = await Promise.all(
4252
4665
  (await collectMarkdownRelPaths(root, MEMORY_PAGES_DIR_RELPATH)).map(async (relPath) => {
4253
- const absPath = path17.join(root, relPath);
4666
+ const absPath = path18.join(root, relPath);
4254
4667
  const markdown = await fs5.readFile(absPath, "utf8");
4255
4668
  const parsed = parsePageMarkdown(relPath, markdown);
4256
4669
  const normalizedFrontmatter = withDenormalizedSources(parsed.frontmatter, parsed.body);
@@ -4272,7 +4685,7 @@ async function reconcile(root, before, _verb, detail) {
4272
4685
  })
4273
4686
  );
4274
4687
  await Promise.all(
4275
- currentPages.filter((page) => page.currentMarkdown !== page.nextMarkdown).map((page) => fs5.writeFile(path17.join(root, page.relPath), page.nextMarkdown, "utf8"))
4688
+ currentPages.filter((page) => page.currentMarkdown !== page.nextMarkdown).map((page) => fs5.writeFile(path18.join(root, page.relPath), page.nextMarkdown, "utf8"))
4276
4689
  );
4277
4690
  const diff2 = diffSnapshots(before, await snapshot(root));
4278
4691
  await writeIndex(root);
@@ -4302,7 +4715,7 @@ async function appendLogEntries(root, diff2, detail, timestamp = (/* @__PURE__ *
4302
4715
  if (entries.length === 0) {
4303
4716
  return;
4304
4717
  }
4305
- const logPath = path17.join(root, MEMORY_LOG_RELPATH);
4718
+ const logPath = path18.join(root, MEMORY_LOG_RELPATH);
4306
4719
  const existing = await fs5.readFile(logPath, "utf8");
4307
4720
  const separator = existing.length === 0 || existing.endsWith("\n") ? "" : "\n";
4308
4721
  await fs5.writeFile(logPath, `${existing}${separator}${entries.join("\n")}
@@ -4326,7 +4739,7 @@ async function writeIndex(root) {
4326
4739
  description: page.frontmatter.description ?? ""
4327
4740
  }))
4328
4741
  );
4329
- await fs5.writeFile(path17.join(root, MEMORY_INDEX_RELPATH), index, "utf8");
4742
+ await fs5.writeFile(path18.join(root, MEMORY_INDEX_RELPATH), index, "utf8");
4330
4743
  }
4331
4744
  function parsePageMarkdown(relPath, markdown) {
4332
4745
  try {
@@ -4371,9 +4784,9 @@ async function writePage(root, relPath, body, opts) {
4371
4784
  const pageRelPath = assertPageRelPath(relPath);
4372
4785
  return withLock(root, async () => {
4373
4786
  const before = await snapshot(root);
4374
- await fs6.mkdir(path18.dirname(path18.join(root, pageRelPath)), { recursive: true });
4787
+ await fs6.mkdir(path19.dirname(path19.join(root, pageRelPath)), { recursive: true });
4375
4788
  await fs6.writeFile(
4376
- path18.join(root, pageRelPath),
4789
+ path19.join(root, pageRelPath),
4377
4790
  serializeFrontmatter(opts.frontmatter ?? {}, body),
4378
4791
  "utf8"
4379
4792
  );
@@ -4384,8 +4797,8 @@ async function appendToPage(root, relPath, content, opts) {
4384
4797
  const pageRelPath = assertPageRelPath(relPath);
4385
4798
  return withLock(root, async () => {
4386
4799
  const before = await snapshot(root);
4387
- const pagePath = path18.join(root, pageRelPath);
4388
- await fs6.mkdir(path18.dirname(pagePath), { recursive: true });
4800
+ const pagePath = path19.join(root, pageRelPath);
4801
+ await fs6.mkdir(path19.dirname(pagePath), { recursive: true });
4389
4802
  const existing = await readMarkdownIfPresent(pagePath);
4390
4803
  const parsed = existing === void 0 ? { frontmatter: {}, body: "" } : parseFrontmatter(existing);
4391
4804
  await fs6.writeFile(
@@ -4407,7 +4820,7 @@ async function removeChildren(directoryPath) {
4407
4820
  if (entryName === MEMORY_LOCK_RELPATH) {
4408
4821
  continue;
4409
4822
  }
4410
- const entryPath = path18.join(directoryPath, entryName);
4823
+ const entryPath = path19.join(directoryPath, entryName);
4411
4824
  const stat7 = await fs6.stat(entryPath);
4412
4825
  if (stat7.isDirectory()) {
4413
4826
  await removeDirectory2(entryPath);
@@ -4424,7 +4837,7 @@ async function removeDirectory2(directoryPath) {
4424
4837
  }
4425
4838
  function assertPageRelPath(relPath) {
4426
4839
  const normalizedRelPath = assertSafeRelPath(relPath);
4427
- if (!normalizedRelPath.startsWith(`${MEMORY_PAGES_DIR_RELPATH}/`) || path18.posix.extname(normalizedRelPath).toLowerCase() !== ".md") {
4840
+ if (!normalizedRelPath.startsWith(`${MEMORY_PAGES_DIR_RELPATH}/`) || path19.posix.extname(normalizedRelPath).toLowerCase() !== ".md") {
4428
4841
  throw new Error(`Expected a markdown page path under "${MEMORY_PAGES_DIR_RELPATH}/".`);
4429
4842
  }
4430
4843
  return normalizedRelPath;
@@ -4442,12 +4855,12 @@ async function readMarkdownIfPresent(filePath) {
4442
4855
 
4443
4856
  // packages/memory/src/edit.ts
4444
4857
  async function editPage(root, relPath, opts) {
4445
- const pagePath = path19.join(root, relPath);
4858
+ const pagePath = path20.join(root, relPath);
4446
4859
  const original = await readIfPresent(pagePath);
4447
- const tempRoot = path19.join(root, ".tmp");
4860
+ const tempRoot = path20.join(root, ".tmp");
4448
4861
  await fs7.mkdir(tempRoot, { recursive: true });
4449
- const tempDir = await fs7.mkdtemp(path19.join(tempRoot, "poe-code-memory-edit-"));
4450
- const tempPath = path19.join(tempDir, path19.basename(relPath));
4862
+ const tempDir = await fs7.mkdtemp(path20.join(tempRoot, "poe-code-memory-edit-"));
4863
+ const tempPath = path20.join(tempDir, path20.basename(relPath));
4451
4864
  try {
4452
4865
  await fs7.writeFile(tempPath, original ?? "", "utf8");
4453
4866
  await opts.launchEditor(tempPath);
@@ -4481,7 +4894,7 @@ async function readIfPresent(filePath) {
4481
4894
 
4482
4895
  // packages/memory/src/audit.ts
4483
4896
  import * as fs8 from "node:fs/promises";
4484
- import path20 from "node:path";
4897
+ import path21 from "node:path";
4485
4898
  var DEFAULT_MIN_INFERRED_CONFIDENCE = 0.3;
4486
4899
  var DEFAULT_REJECT_UNTAGGED = false;
4487
4900
  var DEFAULT_UNTAGGED_BODY_THRESHOLD_CHARS = 200;
@@ -4536,10 +4949,10 @@ async function auditSourceRef(source, claimLineNumber, repoRoot, sourceCache) {
4536
4949
  if (isUrlLike(source.path)) {
4537
4950
  return void 0;
4538
4951
  }
4539
- if (path20.isAbsolute(source.path)) {
4952
+ if (path21.isAbsolute(source.path)) {
4540
4953
  return `Claim on line ${claimLineNumber} cites "${serializeSourceRef(source)}", but source paths must be repo-relative or URLs.`;
4541
4954
  }
4542
- const absPath = path20.resolve(repoRoot, source.path);
4955
+ const absPath = path21.resolve(repoRoot, source.path);
4543
4956
  if (!isWithinRoot(repoRoot, absPath)) {
4544
4957
  return `Claim on line ${claimLineNumber} cites "${serializeSourceRef(source)}", which resolves outside the repo root.`;
4545
4958
  }
@@ -4605,14 +5018,14 @@ function isUrlLike(value) {
4605
5018
  return /^[a-z][a-z\d+.-]*:\/\//i.test(value);
4606
5019
  }
4607
5020
  function isWithinRoot(root, absPath) {
4608
- const relative = path20.relative(root, absPath);
4609
- return relative === "" || !relative.startsWith("..") && !path20.isAbsolute(relative);
5021
+ const relative = path21.relative(root, absPath);
5022
+ return relative === "" || !relative.startsWith("..") && !path21.isAbsolute(relative);
4610
5023
  }
4611
5024
 
4612
5025
  // packages/memory/src/cache.ts
4613
5026
  import { createHash as createHash2 } from "node:crypto";
4614
5027
  import * as fs9 from "node:fs/promises";
4615
- import path21 from "node:path";
5028
+ import path22 from "node:path";
4616
5029
  function computeIngestKey(input) {
4617
5030
  const hash = createHash2("sha256");
4618
5031
  hash.update(input.sourceBytes);
@@ -4625,7 +5038,7 @@ function computeIngestKey(input) {
4625
5038
  return hash.digest("hex");
4626
5039
  }
4627
5040
  async function readCacheEntry(root, key) {
4628
- const cachePath = path21.join(root, MEMORY_INGEST_CACHE_DIR_RELPATH, `${key}.json`);
5041
+ const cachePath = path22.join(root, MEMORY_INGEST_CACHE_DIR_RELPATH, `${key}.json`);
4629
5042
  let raw;
4630
5043
  try {
4631
5044
  raw = await fs9.readFile(cachePath, "utf8");
@@ -4644,17 +5057,17 @@ async function readCacheEntry(root, key) {
4644
5057
  }
4645
5058
  }
4646
5059
  async function writeCacheEntry(root, entry) {
4647
- await fs9.mkdir(path21.join(root, MEMORY_INGEST_CACHE_DIR_RELPATH), { recursive: true });
5060
+ await fs9.mkdir(path22.join(root, MEMORY_INGEST_CACHE_DIR_RELPATH), { recursive: true });
4648
5061
  await fs9.writeFile(
4649
- path21.join(root, MEMORY_INGEST_CACHE_DIR_RELPATH, `${entry.key}.json`),
5062
+ path22.join(root, MEMORY_INGEST_CACHE_DIR_RELPATH, `${entry.key}.json`),
4650
5063
  `${JSON.stringify(entry)}
4651
5064
  `,
4652
5065
  "utf8"
4653
5066
  );
4654
5067
  }
4655
5068
  async function clearCache(root, opts = {}) {
4656
- const ingestDir = path21.join(root, MEMORY_INGEST_CACHE_DIR_RELPATH);
4657
- const cacheDir = path21.join(root, MEMORY_CACHE_DIR_RELPATH);
5069
+ const ingestDir = path22.join(root, MEMORY_INGEST_CACHE_DIR_RELPATH);
5070
+ const cacheDir = path22.join(root, MEMORY_CACHE_DIR_RELPATH);
4658
5071
  const fileNames = await readCacheFileNames(ingestDir);
4659
5072
  if (fileNames.length === 0) {
4660
5073
  if (opts.olderThanMs === void 0) {
@@ -4674,7 +5087,7 @@ async function clearCache(root, opts = {}) {
4674
5087
  if (entry === null || Date.parse(entry.ingestedAt) > cutoff) {
4675
5088
  continue;
4676
5089
  }
4677
- await fs9.rm(path21.join(ingestDir, fileName), { force: true });
5090
+ await fs9.rm(path22.join(ingestDir, fileName), { force: true });
4678
5091
  removed += 1;
4679
5092
  }
4680
5093
  await removeEmptyDirectory(ingestDir);
@@ -4730,7 +5143,7 @@ function expectStringArray(value, field) {
4730
5143
  }
4731
5144
  async function readCacheFileNames(ingestDir) {
4732
5145
  try {
4733
- return (await fs9.readdir(ingestDir)).filter((fileName) => path21.posix.extname(fileName).toLowerCase() === ".json").sort((left, right) => left.localeCompare(right));
5146
+ return (await fs9.readdir(ingestDir)).filter((fileName) => path22.posix.extname(fileName).toLowerCase() === ".json").sort((left, right) => left.localeCompare(right));
4734
5147
  } catch (error2) {
4735
5148
  if (isMissing3(error2)) {
4736
5149
  return [];
@@ -4781,18 +5194,18 @@ function parseOlderThan(value) {
4781
5194
  }
4782
5195
 
4783
5196
  // packages/memory/src/ingest.ts
4784
- import * as fs11 from "node:fs/promises";
4785
- import path38 from "node:path";
5197
+ import * as fs13 from "node:fs/promises";
5198
+ import path45 from "node:path";
4786
5199
 
4787
5200
  // packages/agent-spawn/src/register-factories.ts
4788
5201
  import { spawn as spawnChildProcess2 } from "node:child_process";
4789
5202
 
4790
5203
  // packages/agent-harness-tools/src/paths.ts
4791
- import path22 from "node:path";
5204
+ import path23 from "node:path";
4792
5205
 
4793
5206
  // packages/agent-harness-tools/src/plans.ts
4794
5207
  import * as fsPromises4 from "node:fs/promises";
4795
- import path27 from "node:path";
5208
+ import path29 from "node:path";
4796
5209
 
4797
5210
  // packages/task-list/src/open.ts
4798
5211
  import * as fsPromises3 from "node:fs/promises";
@@ -4875,7 +5288,7 @@ import * as childProcess from "node:child_process";
4875
5288
  import { randomBytes } from "node:crypto";
4876
5289
 
4877
5290
  // packages/process-runner/src/docker/args.ts
4878
- import path23 from "node:path";
5291
+ import path24 from "node:path";
4879
5292
  function buildDockerRunArgs(input) {
4880
5293
  const args = [input.engine];
4881
5294
  if (input.engine === "docker" && input.context) {
@@ -4902,7 +5315,7 @@ function buildDockerRunArgs(input) {
4902
5315
  args.push("-e", `${key}=${value}`);
4903
5316
  }
4904
5317
  for (const mount of input.mounts) {
4905
- const volume = `${path23.resolve(mount.source)}:${mount.target}${mount.readonly ? ":ro" : ""}`;
5318
+ const volume = `${path24.resolve(mount.source)}:${mount.target}${mount.readonly ? ":ro" : ""}`;
4906
5319
  args.push("-v", volume);
4907
5320
  }
4908
5321
  for (const port of input.ports) {
@@ -4921,7 +5334,7 @@ import { createHash as createHash3, randomBytes as randomBytes2 } from "node:cry
4921
5334
  import { mkdtempSync, rmSync } from "node:fs";
4922
5335
  import { readFile as readFile10 } from "node:fs/promises";
4923
5336
  import { tmpdir } from "node:os";
4924
- import path24 from "node:path";
5337
+ import path25 from "node:path";
4925
5338
 
4926
5339
  // packages/process-runner/src/host/host-runner.ts
4927
5340
  import { spawn as spawnChildProcess } from "node:child_process";
@@ -5061,8 +5474,8 @@ function createDockerEnv(input) {
5061
5474
  id: containerRef,
5062
5475
  job: input.attachedJobId === void 0 ? null : createContainerJob(containerRef, input.runner, input.engine, input.context, input.attachedJobId),
5063
5476
  async uploadWorkspace() {
5064
- const tempDir = mkdtempSync(path24.join(tmpdir(), "poe-docker-upload-"));
5065
- const archivePath = path24.join(tempDir, "workspace.tar");
5477
+ const tempDir = mkdtempSync(path25.join(tmpdir(), "poe-docker-upload-"));
5478
+ const archivePath = path25.join(tempDir, "workspace.tar");
5066
5479
  try {
5067
5480
  const excludeArgs = input.spec.uploadIgnoreFiles.flatMap((ignored) => [
5068
5481
  "--exclude",
@@ -5105,8 +5518,8 @@ function createDockerEnv(input) {
5105
5518
  }
5106
5519
  },
5107
5520
  async downloadWorkspace(opts) {
5108
- const tempDir = mkdtempSync(path24.join(tmpdir(), "poe-docker-download-"));
5109
- const archivePath = path24.join(tempDir, "workspace.tar");
5521
+ const tempDir = mkdtempSync(path25.join(tmpdir(), "poe-docker-download-"));
5522
+ const archivePath = path25.join(tempDir, "workspace.tar");
5110
5523
  try {
5111
5524
  await runOrThrow(input.runner, {
5112
5525
  command: input.engine,
@@ -5206,11 +5619,11 @@ async function buildDockerRuntimeTemplate(input) {
5206
5619
  const runner = input.runner ?? createHostRunner();
5207
5620
  const engine = input.runtime.engine ?? detectEngine();
5208
5621
  const context = detectContext();
5209
- const dockerfilePath = path24.resolve(
5622
+ const dockerfilePath = path25.resolve(
5210
5623
  input.cwd,
5211
- input.runtime.dockerfile ?? path24.join(".poe-code", "Dockerfile")
5624
+ input.runtime.dockerfile ?? path25.join(".poe-code", "Dockerfile")
5212
5625
  );
5213
- const buildContext = path24.resolve(input.cwd, input.runtime.build_context ?? ".");
5626
+ const buildContext = path25.resolve(input.cwd, input.runtime.build_context ?? ".");
5214
5627
  const dockerfileBytes = await readFile10(dockerfilePath);
5215
5628
  const hash = hashDockerTemplate(dockerfileBytes, input.runtime.build_args ?? {});
5216
5629
  const cached2 = input.force ? null : await input.state?.templates.get("docker", hash);
@@ -5472,10 +5885,10 @@ var hostExecutionEnvFactory = {
5472
5885
  import { Readable, Writable } from "node:stream";
5473
5886
 
5474
5887
  // packages/task-list/src/backends/utils.ts
5475
- import path25 from "node:path";
5888
+ import path26 from "node:path";
5476
5889
 
5477
5890
  // packages/task-list/src/backends/markdown-dir.ts
5478
- import path26 from "node:path";
5891
+ import path27 from "node:path";
5479
5892
  import { parseDocument as parseDocument2, stringify as stringify2 } from "yaml";
5480
5893
 
5481
5894
  // packages/task-list/src/schema/task.schema.json
@@ -5549,6 +5962,7 @@ var defaultTransitions = deriveLegacyTransitions(defaultStateMachine);
5549
5962
  var TASK_SCHEMA_ID = task_schema_default.$id;
5550
5963
 
5551
5964
  // packages/task-list/src/backends/yaml-file.ts
5965
+ import path28 from "node:path";
5552
5966
  import { isMap, parseDocument as parseDocument3 } from "yaml";
5553
5967
 
5554
5968
  // packages/task-list/src/schema/store.schema.json
@@ -5589,145 +6003,6 @@ var store_schema_default = {
5589
6003
  var STORE_SCHEMA_ID = store_schema_default.$id;
5590
6004
  var TASK_SCHEMA_ID2 = task_schema_default.$id;
5591
6005
 
5592
- // packages/agent-defs/src/agents/claude-code.ts
5593
- var claudeCodeAgent = {
5594
- id: "claude-code",
5595
- name: "claude-code",
5596
- label: "Claude Code",
5597
- summary: "Configure Claude Code to route through Poe.",
5598
- aliases: ["claude"],
5599
- binaryName: "claude",
5600
- configPath: "~/.claude/settings.json",
5601
- branding: {
5602
- colors: {
5603
- dark: "#C15F3C",
5604
- light: "#C15F3C"
5605
- }
5606
- }
5607
- };
5608
-
5609
- // packages/agent-defs/src/agents/claude-desktop.ts
5610
- var claudeDesktopAgent = {
5611
- id: "claude-desktop",
5612
- name: "claude-desktop",
5613
- label: "Claude Desktop",
5614
- summary: "Anthropic's official desktop application for Claude",
5615
- configPath: "~/.claude/settings.json",
5616
- branding: {
5617
- colors: {
5618
- dark: "#D97757",
5619
- light: "#D97757"
5620
- }
5621
- }
5622
- };
5623
-
5624
- // packages/agent-defs/src/agents/codex.ts
5625
- var codexAgent = {
5626
- id: "codex",
5627
- name: "codex",
5628
- label: "Codex",
5629
- summary: "Configure Codex to use Poe as the model provider.",
5630
- binaryName: "codex",
5631
- configPath: "~/.codex/config.toml",
5632
- branding: {
5633
- colors: {
5634
- dark: "#D5D9DF",
5635
- light: "#7A7F86"
5636
- }
5637
- }
5638
- };
5639
-
5640
- // packages/agent-defs/src/agents/opencode.ts
5641
- var openCodeAgent = {
5642
- id: "opencode",
5643
- name: "opencode",
5644
- label: "OpenCode CLI",
5645
- summary: "Configure OpenCode CLI to use the Poe API.",
5646
- binaryName: "opencode",
5647
- configPath: "~/.config/opencode/config.json",
5648
- branding: {
5649
- colors: {
5650
- dark: "#4A4F55",
5651
- light: "#2F3338"
5652
- }
5653
- }
5654
- };
5655
-
5656
- // packages/agent-defs/src/agents/kimi.ts
5657
- var kimiAgent = {
5658
- id: "kimi",
5659
- name: "kimi",
5660
- label: "Kimi",
5661
- summary: "Configure Kimi CLI to use Poe API",
5662
- aliases: ["kimi-cli"],
5663
- binaryName: "kimi",
5664
- configPath: "~/.kimi/config.toml",
5665
- branding: {
5666
- colors: {
5667
- dark: "#7B68EE",
5668
- light: "#6A5ACD"
5669
- }
5670
- }
5671
- };
5672
-
5673
- // packages/agent-defs/src/agents/goose.ts
5674
- var gooseAgent = {
5675
- id: "goose",
5676
- name: "goose",
5677
- label: "Goose",
5678
- summary: "Block's open-source AI agent with ACP support.",
5679
- binaryName: "goose",
5680
- configPath: "~/.config/goose/config.yaml",
5681
- branding: {
5682
- colors: {
5683
- dark: "#FF6B35",
5684
- light: "#E85D26"
5685
- }
5686
- }
5687
- };
5688
-
5689
- // packages/agent-defs/src/agents/poe-agent.ts
5690
- var poeAgentAgent = {
5691
- id: "poe-agent",
5692
- name: "poe-agent",
5693
- label: "Poe Agent",
5694
- summary: "Run one-shot prompts with the built-in Poe agent runtime.",
5695
- configPath: "~/.poe-code/config.json",
5696
- branding: {
5697
- colors: {
5698
- dark: "#A465F7",
5699
- light: "#7A3FD3"
5700
- }
5701
- }
5702
- };
5703
-
5704
- // packages/agent-defs/src/registry.ts
5705
- var allAgents = [
5706
- claudeCodeAgent,
5707
- claudeDesktopAgent,
5708
- codexAgent,
5709
- openCodeAgent,
5710
- kimiAgent,
5711
- gooseAgent,
5712
- poeAgentAgent
5713
- ];
5714
- var lookup2 = /* @__PURE__ */ new Map();
5715
- for (const agent of allAgents) {
5716
- const values = [agent.id, agent.name, ...agent.aliases ?? []];
5717
- for (const value of values) {
5718
- const normalized = value.toLowerCase();
5719
- if (!lookup2.has(normalized)) {
5720
- lookup2.set(normalized, agent.id);
5721
- }
5722
- }
5723
- }
5724
- function resolveAgentId(input) {
5725
- if (!input) {
5726
- return void 0;
5727
- }
5728
- return lookup2.get(input.toLowerCase());
5729
- }
5730
-
5731
6006
  // packages/agent-harness-tools/src/select-agent.ts
5732
6007
  var loopAgents = allAgents.filter(
5733
6008
  (agent) => agent.binaryName !== void 0 || agent.id === "poe-agent"
@@ -5735,7 +6010,7 @@ var loopAgents = allAgents.filter(
5735
6010
  var supportedAgents = loopAgents.map((agent) => agent.id).join(", ");
5736
6011
 
5737
6012
  // packages/agent-harness-tools/src/run-logs.ts
5738
- import path28 from "node:path";
6013
+ import path30 from "node:path";
5739
6014
 
5740
6015
  // packages/agent-harness-tools/src/log-stream.ts
5741
6016
  import nodeFs2 from "node:fs";
@@ -5756,29 +6031,29 @@ function wrapForLogTee(argv, jobId) {
5756
6031
  return ["sh", "-c", script];
5757
6032
  }
5758
6033
  async function* streamLogFile(env, jobId, opts) {
5759
- const fs14 = env.fs ?? nodeFs2;
6034
+ const fs16 = env.fs ?? nodeFs2;
5760
6035
  const file = jobLogPath(jobId);
5761
6036
  let byteOffset = opts.sinceByte ?? 0;
5762
6037
  while (true) {
5763
- if (opts.since !== void 0 && !await wasModifiedSince(fs14, file, opts.since)) {
5764
- await waitForLogChange(fs14, file);
6038
+ if (opts.since !== void 0 && !await wasModifiedSince(fs16, file, opts.since)) {
6039
+ await waitForLogChange(fs16, file);
5765
6040
  continue;
5766
6041
  }
5767
- const result = await readLogChunk(fs14, file, byteOffset);
6042
+ const result = await readLogChunk(fs16, file, byteOffset);
5768
6043
  if (result !== null) {
5769
6044
  byteOffset = result.nextByteOffset;
5770
6045
  yield result.chunk;
5771
6046
  continue;
5772
6047
  }
5773
- await waitForLogChange(fs14, file);
6048
+ await waitForLogChange(fs16, file);
5774
6049
  }
5775
6050
  }
5776
- async function wasModifiedSince(fs14, file, since) {
5777
- if (fs14.promises.stat === void 0) {
6051
+ async function wasModifiedSince(fs16, file, since) {
6052
+ if (fs16.promises.stat === void 0) {
5778
6053
  return true;
5779
6054
  }
5780
6055
  try {
5781
- const stat7 = await fs14.promises.stat(file);
6056
+ const stat7 = await fs16.promises.stat(file);
5782
6057
  return stat7.mtimeMs >= since.getTime();
5783
6058
  } catch (error2) {
5784
6059
  if (isNodeError(error2) && error2.code === "ENOENT") {
@@ -5788,11 +6063,11 @@ async function wasModifiedSince(fs14, file, since) {
5788
6063
  }
5789
6064
  }
5790
6065
  async function waitForExit(env, jobId, opts = {}) {
5791
- const fs14 = env.fs ?? nodeFs2;
6066
+ const fs16 = env.fs ?? nodeFs2;
5792
6067
  const file = jobExitPath(jobId);
5793
6068
  while (true) {
5794
6069
  throwIfAborted2(opts.signal);
5795
- const contents = await readTextFileIfExists(fs14, file);
6070
+ const contents = await readTextFileIfExists(fs16, file);
5796
6071
  if (contents !== null) {
5797
6072
  const text5 = contents.trim();
5798
6073
  const exitCode = Number(text5);
@@ -5810,8 +6085,8 @@ function jobLogPath(jobId) {
5810
6085
  function jobExitPath(jobId) {
5811
6086
  return `${JOB_DIR}/${jobId}.exit`;
5812
6087
  }
5813
- async function readLogChunk(fs14, file, byteOffset) {
5814
- const contents = await readFileIfExists2(fs14, file);
6088
+ async function readLogChunk(fs16, file, byteOffset) {
6089
+ const contents = await readFileIfExists2(fs16, file);
5815
6090
  if (contents === null || byteOffset >= contents.byteLength) {
5816
6091
  return null;
5817
6092
  }
@@ -5823,13 +6098,13 @@ async function readLogChunk(fs14, file, byteOffset) {
5823
6098
  nextByteOffset: contents.byteLength
5824
6099
  };
5825
6100
  }
5826
- async function readTextFileIfExists(fs14, file) {
5827
- const contents = await readFileIfExists2(fs14, file);
6101
+ async function readTextFileIfExists(fs16, file) {
6102
+ const contents = await readFileIfExists2(fs16, file);
5828
6103
  return contents?.toString("utf8") ?? null;
5829
6104
  }
5830
- async function readFileIfExists2(fs14, file) {
6105
+ async function readFileIfExists2(fs16, file) {
5831
6106
  try {
5832
- const contents = await fs14.promises.readFile(file);
6107
+ const contents = await fs16.promises.readFile(file);
5833
6108
  return Buffer.isBuffer(contents) ? contents : Buffer.from(contents);
5834
6109
  } catch (error2) {
5835
6110
  if (isNodeError(error2) && error2.code === "ENOENT") {
@@ -5838,8 +6113,8 @@ async function readFileIfExists2(fs14, file) {
5838
6113
  throw error2;
5839
6114
  }
5840
6115
  }
5841
- async function waitForLogChange(fs14, file) {
5842
- const watch = fs14.watch;
6116
+ async function waitForLogChange(fs16, file) {
6117
+ const watch = fs16.watch;
5843
6118
  if (typeof watch !== "function") {
5844
6119
  await sleep3(POLL_INTERVAL_MS);
5845
6120
  return;
@@ -5960,8 +6235,7 @@ async function runPoeCommand(opts) {
5960
6235
  signal: opts.signal
5961
6236
  });
5962
6237
  if (execution?.input !== void 0) {
5963
- handle.stdin?.setDefaultEncoding("utf8");
5964
- handle.stdin?.end(execution.input);
6238
+ writeExecutionInput(handle, execution.input);
5965
6239
  }
5966
6240
  const runningJob = opts.state.jobs.update(jobId, {
5967
6241
  status: "running",
@@ -6271,6 +6545,19 @@ function setDetachedJobContext(env, context) {
6271
6545
  const candidate = env;
6272
6546
  candidate.setDetachedJobContext?.(context);
6273
6547
  }
6548
+ function writeExecutionInput(handle, input) {
6549
+ const stdin = handle.stdin;
6550
+ if (stdin === null) {
6551
+ return;
6552
+ }
6553
+ stdin.on("error", (error2) => {
6554
+ if (error2.code !== "EPIPE") {
6555
+ throw error2;
6556
+ }
6557
+ });
6558
+ stdin.setDefaultEncoding("utf8");
6559
+ stdin.end(input);
6560
+ }
6274
6561
  function isPromiseLike(value) {
6275
6562
  return typeof value.then === "function";
6276
6563
  }
@@ -6456,10 +6743,10 @@ function createMemoryStateManager() {
6456
6743
  // packages/agent-harness-tools/src/workspace-transfer.ts
6457
6744
  import { createHash as createHash4 } from "node:crypto";
6458
6745
  import { promises as nodeFs3 } from "node:fs";
6459
- import path29 from "node:path";
6746
+ import path31 from "node:path";
6460
6747
 
6461
6748
  // packages/runner-e2b/src/factory.ts
6462
- import path33 from "node:path";
6749
+ import path35 from "node:path";
6463
6750
 
6464
6751
  // packages/runner-e2b/src/sdk.ts
6465
6752
  import { Template, Sandbox } from "e2b";
@@ -6508,7 +6795,7 @@ async function readableToString(stream) {
6508
6795
  // packages/runner-e2b/src/template-build.ts
6509
6796
  import { createHash as createHash5 } from "node:crypto";
6510
6797
  import { readdir as readdir4, readFile as readFile11 } from "node:fs/promises";
6511
- import path30 from "node:path";
6798
+ import path32 from "node:path";
6512
6799
  var BUILD_LOG_TAIL_SIZE = 30;
6513
6800
  async function buildE2bRuntimeTemplate(input) {
6514
6801
  const dockerfileBytes = await readFile11(input.dockerfilePath);
@@ -6589,10 +6876,10 @@ async function readBuildContextFiles(buildContext) {
6589
6876
  return files.sort((left, right) => left.relativePath.localeCompare(right.relativePath));
6590
6877
  }
6591
6878
  async function collectBuildContextFiles(buildContext, relativeDir, files) {
6592
- const absoluteDir = path30.join(buildContext, relativeDir);
6879
+ const absoluteDir = path32.join(buildContext, relativeDir);
6593
6880
  const entries = await readdir4(absoluteDir, { withFileTypes: true });
6594
6881
  for (const entry of entries) {
6595
- const relativePath = path30.join(relativeDir, entry.name);
6882
+ const relativePath = path32.join(relativeDir, entry.name);
6596
6883
  if (entry.isDirectory()) {
6597
6884
  await collectBuildContextFiles(buildContext, relativePath, files);
6598
6885
  continue;
@@ -6601,8 +6888,8 @@ async function collectBuildContextFiles(buildContext, relativeDir, files) {
6601
6888
  continue;
6602
6889
  }
6603
6890
  files.push({
6604
- relativePath: relativePath.split(path30.sep).join("/"),
6605
- bytes: await readFile11(path30.join(buildContext, relativePath))
6891
+ relativePath: relativePath.split(path32.sep).join("/"),
6892
+ bytes: await readFile11(path32.join(buildContext, relativePath))
6606
6893
  });
6607
6894
  }
6608
6895
  }
@@ -6611,14 +6898,14 @@ async function collectBuildContextFiles(buildContext, relativeDir, files) {
6611
6898
  import { mkdtempSync as mkdtempSync2, rmSync as rmSync2 } from "node:fs";
6612
6899
  import { readFile as readFile12, writeFile as writeFile7 } from "node:fs/promises";
6613
6900
  import { tmpdir as tmpdir2 } from "node:os";
6614
- import path32 from "node:path";
6901
+ import path34 from "node:path";
6615
6902
  import { PassThrough as PassThrough2, Writable as Writable2 } from "node:stream";
6616
6903
 
6617
6904
  // packages/runner-e2b/src/job-handle.ts
6618
- import path31 from "node:path";
6905
+ import path33 from "node:path";
6619
6906
  var JOB_DIR2 = "/tmp/poe-jobs";
6620
6907
  function createE2bJobHandle(input) {
6621
- const fs14 = createE2bLogStreamFs(input.sandbox);
6908
+ const fs16 = createE2bLogStreamFs(input.sandbox);
6622
6909
  return {
6623
6910
  id: input.jobId,
6624
6911
  envId: input.envId,
@@ -6630,14 +6917,14 @@ function createE2bJobHandle(input) {
6630
6917
  return "exited";
6631
6918
  }
6632
6919
  const processes = await input.sandbox.commands.list();
6633
- const isRunning = input.pid === void 0 ? processes.some((process2) => processMentionsJob(process2, input.jobId)) : processes.some((process2) => process2.pid === input.pid);
6920
+ const isRunning = input.pid === void 0 ? processes.some((process3) => processMentionsJob(process3, input.jobId)) : processes.some((process3) => process3.pid === input.pid);
6634
6921
  return isRunning ? "running" : "lost";
6635
6922
  },
6636
6923
  stream(opts = {}) {
6637
- return streamLogFile({ fs: fs14 }, input.jobId, opts);
6924
+ return streamLogFile({ fs: fs16 }, input.jobId, opts);
6638
6925
  },
6639
6926
  async wait() {
6640
- const result = await waitForExit({ fs: fs14 }, input.jobId);
6927
+ const result = await waitForExit({ fs: fs16 }, input.jobId);
6641
6928
  const preserveMs = input.preserveAfterExitHours * 60 * 60 * 1e3;
6642
6929
  if (preserveMs > 0) {
6643
6930
  await input.sandbox.setTimeout(preserveMs);
@@ -6645,7 +6932,7 @@ function createE2bJobHandle(input) {
6645
6932
  return result;
6646
6933
  },
6647
6934
  async kill() {
6648
- const pids = input.pid === void 0 ? (await input.sandbox.commands.list()).filter((process2) => processMentionsJob(process2, input.jobId)).map((process2) => process2.pid) : [input.pid];
6935
+ const pids = input.pid === void 0 ? (await input.sandbox.commands.list()).filter((process3) => processMentionsJob(process3, input.jobId)).map((process3) => process3.pid) : [input.pid];
6649
6936
  await Promise.all(pids.map((pid) => input.sandbox.commands.kill(pid)));
6650
6937
  }
6651
6938
  };
@@ -6673,7 +6960,7 @@ function createE2bLogStreamFs(sandbox) {
6673
6960
  watch(filePath, listener) {
6674
6961
  let closed = false;
6675
6962
  let stop = null;
6676
- void sandbox.files.watchDir(path31.dirname(filePath), listener, { recursive: false }).then((handle) => {
6963
+ void sandbox.files.watchDir(path33.dirname(filePath), listener, { recursive: false }).then((handle) => {
6677
6964
  if (closed) {
6678
6965
  void handle.stop();
6679
6966
  return;
@@ -6691,9 +6978,9 @@ function createE2bLogStreamFs(sandbox) {
6691
6978
  }
6692
6979
  };
6693
6980
  }
6694
- function processMentionsJob(process2, jobId) {
6981
+ function processMentionsJob(process3, jobId) {
6695
6982
  const needle = `/tmp/poe-jobs/${jobId}`;
6696
- return process2.cmd.includes(needle) || process2.args.some((arg) => arg.includes(needle));
6983
+ return process3.cmd.includes(needle) || process3.args.some((arg) => arg.includes(needle));
6697
6984
  }
6698
6985
  function shellQuote3(value) {
6699
6986
  return `'${value.replaceAll("'", "'\\''")}'`;
@@ -6712,7 +6999,7 @@ async function readExitCode(sandbox, jobId) {
6712
6999
  var REMOTE_COMMAND_STDERR_TAIL_SIZE = 30;
6713
7000
  function createOpenedE2bEnv(input) {
6714
7001
  const hostRunner = input.spec.hostRunner ?? createHostRunner();
6715
- const hostWorkspaceDir = path32.resolve(input.spec.cwd);
7002
+ const hostWorkspaceDir = path34.resolve(input.spec.cwd);
6716
7003
  const sandboxWorkspaceDir = normalizeSandboxWorkspaceDir(input.runtime.workspace_dir);
6717
7004
  let lastProcess = null;
6718
7005
  let detachedJobContext = null;
@@ -6720,7 +7007,7 @@ function createOpenedE2bEnv(input) {
6720
7007
  if (cwd === void 0) {
6721
7008
  return void 0;
6722
7009
  }
6723
- if (path32.isAbsolute(cwd) && path32.resolve(cwd) === hostWorkspaceDir) {
7010
+ if (path34.isAbsolute(cwd) && path34.resolve(cwd) === hostWorkspaceDir) {
6724
7011
  return sandboxWorkspaceDir;
6725
7012
  }
6726
7013
  return cwd;
@@ -6744,8 +7031,8 @@ function createOpenedE2bEnv(input) {
6744
7031
  if (input.spec.runner?.sync === "none") {
6745
7032
  return { files: 0, bytes: 0, skipped: [] };
6746
7033
  }
6747
- const tempDir = mkdtempSync2(path32.join(tmpdir2(), "poe-e2b-upload-"));
6748
- const archivePath = path32.join(tempDir, "workspace.tar");
7034
+ const tempDir = mkdtempSync2(path34.join(tmpdir2(), "poe-e2b-upload-"));
7035
+ const archivePath = path34.join(tempDir, "workspace.tar");
6749
7036
  try {
6750
7037
  await runOrThrow2(hostRunner, {
6751
7038
  command: "tar",
@@ -6777,8 +7064,8 @@ function createOpenedE2bEnv(input) {
6777
7064
  if (input.spec.runner?.sync === "upload" || input.spec.runner?.sync === "none") {
6778
7065
  return { files: 0, bytes: 0, conflicts: [] };
6779
7066
  }
6780
- const tempDir = mkdtempSync2(path32.join(tmpdir2(), "poe-e2b-download-"));
6781
- const archivePath = path32.join(tempDir, "workspace.tar");
7067
+ const tempDir = mkdtempSync2(path34.join(tmpdir2(), "poe-e2b-download-"));
7068
+ const archivePath = path34.join(tempDir, "workspace.tar");
6782
7069
  try {
6783
7070
  await runRemoteOrThrow(
6784
7071
  input.sandbox,
@@ -7101,10 +7388,10 @@ function resolveSandboxCommandEnv(env) {
7101
7388
  }
7102
7389
  function normalizeSandboxWorkspaceDir(workspaceDir) {
7103
7390
  const resolvedWorkspaceDir = workspaceDir ?? "/workspace";
7104
- if (!path32.posix.isAbsolute(resolvedWorkspaceDir)) {
7391
+ if (!path34.posix.isAbsolute(resolvedWorkspaceDir)) {
7105
7392
  throw new Error("E2B runtime workspace_dir must be an absolute sandbox path.");
7106
7393
  }
7107
- let normalized = path32.posix.normalize(resolvedWorkspaceDir);
7394
+ let normalized = path34.posix.normalize(resolvedWorkspaceDir);
7108
7395
  while (normalized.length > 1 && normalized.endsWith("/")) {
7109
7396
  normalized = normalized.slice(0, -1);
7110
7397
  }
@@ -7134,10 +7421,10 @@ var e2bAuthScope = defineScope("e2b", {
7134
7421
  });
7135
7422
  async function resolveE2bApiKey(input) {
7136
7423
  const homeDir = input.homeDir ?? os4.homedir();
7137
- const fs14 = input.fs ?? nodeFs4;
7424
+ const fs16 = input.fs ?? nodeFs4;
7138
7425
  const env = input.env ?? process.env;
7139
7426
  const document = await readMergedDocument(
7140
- fs14,
7427
+ fs16,
7141
7428
  resolveConfigPath(homeDir),
7142
7429
  resolveProjectConfigPath(input.cwd)
7143
7430
  );
@@ -7160,11 +7447,11 @@ var e2bExecutionEnvFactory = {
7160
7447
  const apiKey = await resolveE2bApiKey({ cwd: runtimeCwd });
7161
7448
  const templateId = runtime.template_id ?? (await buildE2bRuntimeTemplate({
7162
7449
  runtime,
7163
- dockerfilePath: path33.resolve(
7450
+ dockerfilePath: path35.resolve(
7164
7451
  runtimeCwd,
7165
- runtime.dockerfile ?? path33.join(".poe-code", "Dockerfile")
7452
+ runtime.dockerfile ?? path35.join(".poe-code", "Dockerfile")
7166
7453
  ),
7167
- buildContext: path33.resolve(runtimeCwd, runtime.build_context ?? "."),
7454
+ buildContext: path35.resolve(runtimeCwd, runtime.build_context ?? "."),
7168
7455
  state: spec.state,
7169
7456
  apiKey
7170
7457
  })).templateId;
@@ -7309,8 +7596,83 @@ function runHost(spawnProcess, spec) {
7309
7596
  };
7310
7597
  }
7311
7598
 
7599
+ // packages/agent-spawn/src/observability/otel.ts
7600
+ var noopOtelSpan = {
7601
+ setAttribute: () => void 0,
7602
+ addEvent: () => void 0,
7603
+ end: () => void 0
7604
+ };
7605
+ function observeAgentSpawn(input, operation) {
7606
+ const span = safeStartSpan(input.otelSink, "agent.spawn", {
7607
+ agent: input.agent,
7608
+ mode: input.mode ?? "yolo",
7609
+ cwd: input.cwd ?? process.cwd()
7610
+ });
7611
+ safeAddEvent(span, "prompt", { prompt: input.prompt });
7612
+ return (async () => {
7613
+ try {
7614
+ const result = await operation();
7615
+ safeAddEvent(span, "summary", { summary: readSummary(result) });
7616
+ safeAddEvent(span, "exit", { exitCode: result.exitCode });
7617
+ return result;
7618
+ } catch (error2) {
7619
+ safeRecordException(input.otelSink, span, error2);
7620
+ throw error2;
7621
+ } finally {
7622
+ safeEndSpan(span);
7623
+ }
7624
+ })();
7625
+ }
7626
+ function safeStartSpan(sink, name, attrs) {
7627
+ if (sink === void 0) {
7628
+ return noopOtelSpan;
7629
+ }
7630
+ try {
7631
+ return sink.startSpan(name, attrs);
7632
+ } catch (error2) {
7633
+ warnOtelSinkFailure("startSpan", error2);
7634
+ return noopOtelSpan;
7635
+ }
7636
+ }
7637
+ function safeAddEvent(span, name, attrs) {
7638
+ if (span === void 0) {
7639
+ return;
7640
+ }
7641
+ try {
7642
+ span.addEvent(name, attrs);
7643
+ } catch (error2) {
7644
+ warnOtelSinkFailure("addEvent", error2);
7645
+ }
7646
+ }
7647
+ function safeRecordException(sink, span, error2) {
7648
+ if (sink === void 0) {
7649
+ return;
7650
+ }
7651
+ try {
7652
+ sink.recordException(span, error2);
7653
+ } catch (recordError) {
7654
+ warnOtelSinkFailure("recordException", recordError);
7655
+ }
7656
+ }
7657
+ function safeEndSpan(span) {
7658
+ try {
7659
+ span.end();
7660
+ } catch (error2) {
7661
+ warnOtelSinkFailure("end", error2);
7662
+ }
7663
+ }
7664
+ function readSummary(result) {
7665
+ return result.stdout.trim() || result.stderr.trim();
7666
+ }
7667
+ function warnOtelSinkFailure(method, error2) {
7668
+ console.warn(`OpenTelemetry sink ${method} failed: ${readErrorMessage(error2)}`);
7669
+ }
7670
+ function readErrorMessage(error2) {
7671
+ return error2 instanceof Error ? error2.message : String(error2);
7672
+ }
7673
+
7312
7674
  // packages/agent-spawn/src/run-command.ts
7313
- import { spawn as spawn2 } from "node:child_process";
7675
+ import { spawn as spawn3 } from "node:child_process";
7314
7676
 
7315
7677
  // packages/agent-spawn/src/types.ts
7316
7678
  function resolveModeConfig(modeConfig) {
@@ -7604,8 +7966,8 @@ function listMcpSupportedAgents() {
7604
7966
  }
7605
7967
 
7606
7968
  // packages/agent-spawn/src/spawn.ts
7607
- import { mkdirSync, openSync, writeSync, closeSync } from "node:fs";
7608
- import path34 from "node:path";
7969
+ import { mkdirSync as mkdirSync3, openSync, writeSync, closeSync } from "node:fs";
7970
+ import path41 from "node:path";
7609
7971
 
7610
7972
  // packages/agent-spawn/src/configs/resolve-config.ts
7611
7973
  function resolveConfig(agentId) {
@@ -7641,6 +8003,12 @@ function getMcpArgs(config, servers) {
7641
8003
  }
7642
8004
  return config.mcpArgs(servers);
7643
8005
  }
8006
+ function getMcpEnv(config, servers) {
8007
+ if (!hasMcpServers(servers) || !config.mcpEnv) {
8008
+ return {};
8009
+ }
8010
+ return config.mcpEnv(servers);
8011
+ }
7644
8012
  function formatUnsupportedMcpSpawnMessage(agentId) {
7645
8013
  const supported = listMcpSupportedAgents();
7646
8014
  const supportedText = supported.length > 0 ? supported.join(", ") : "(none)";
@@ -7654,50 +8022,1743 @@ function stripModelNamespace(model) {
7654
8022
  return slashIndex === -1 ? model : model.slice(slashIndex + 1);
7655
8023
  }
7656
8024
 
7657
- // packages/agent-spawn/src/spawn.ts
7658
- function createAbortError3() {
7659
- const error2 = new Error("Agent spawn aborted");
7660
- error2.name = "AbortError";
7661
- return error2;
8025
+ // packages/agent-spawn/src/parallel.ts
8026
+ var SpawnParallelError = class extends Error {
8027
+ index;
8028
+ result;
8029
+ results;
8030
+ constructor(index, result, results) {
8031
+ super(`spawn.parallel call ${index} failed with exit code ${result.exitCode}.`);
8032
+ this.name = "SpawnParallelError";
8033
+ this.index = index;
8034
+ this.result = result;
8035
+ this.results = results;
8036
+ }
8037
+ };
8038
+ function createSpawnParallel(spawnOnce) {
8039
+ return async function parallel(calls, options = {}) {
8040
+ if (calls.length === 0) {
8041
+ return [];
8042
+ }
8043
+ const maxConcurrent = normalizeMaxConcurrent(options.maxConcurrent);
8044
+ const failFast = options.failFast ?? true;
8045
+ const group = new AbortController();
8046
+ const results = new Array(calls.length);
8047
+ const errors = [];
8048
+ let nextIndex = 0;
8049
+ let primaryFailure;
8050
+ const removeParentAbort = linkParentAbort(options.signal, group, (error2) => {
8051
+ primaryFailure ??= error2;
8052
+ });
8053
+ const worker = async () => {
8054
+ while (!primaryFailure) {
8055
+ const index = nextIndex;
8056
+ nextIndex += 1;
8057
+ if (index >= calls.length) {
8058
+ return;
8059
+ }
8060
+ try {
8061
+ const result = await runParallelCall(calls[index], spawnOnce, group.signal);
8062
+ results[index] = result;
8063
+ if (failFast && result.exitCode !== 0) {
8064
+ const error2 = new SpawnParallelError(index, result, results);
8065
+ primaryFailure ??= error2;
8066
+ group.abort(error2);
8067
+ return;
8068
+ }
8069
+ } catch (error2) {
8070
+ if (failFast || group.signal.aborted) {
8071
+ primaryFailure ??= error2;
8072
+ group.abort(error2);
8073
+ return;
8074
+ }
8075
+ errors.push(error2);
8076
+ }
8077
+ }
8078
+ };
8079
+ try {
8080
+ await Promise.allSettled(
8081
+ Array.from({ length: Math.min(maxConcurrent, calls.length) }, () => worker())
8082
+ );
8083
+ } finally {
8084
+ removeParentAbort();
8085
+ }
8086
+ if (primaryFailure) {
8087
+ throw primaryFailure;
8088
+ }
8089
+ if (errors.length > 0) {
8090
+ throw new AggregateError(errors, "spawn.parallel failed before every call returned a result.");
8091
+ }
8092
+ return results;
8093
+ };
7662
8094
  }
7663
- function resolveCliConfig(agentId) {
7664
- const resolved = resolveConfig(agentId);
7665
- if (!resolved.spawnConfig) {
7666
- throw new Error(`Agent "${resolved.agentId}" has no spawn config.`);
8095
+ async function runParallelCall(call, spawnOnce, signal) {
8096
+ throwIfAborted3(signal);
8097
+ if (typeof call === "function") {
8098
+ const handle = call(signal);
8099
+ const [result] = await Promise.all([handle.result, drainEvents(handle.events)]);
8100
+ return result;
7667
8101
  }
7668
- if (resolved.spawnConfig.kind !== "cli") {
7669
- throw new Error(`Agent "${resolved.agentId}" does not support CLI spawn.`);
8102
+ if (!isSpawnTuple(call)) {
8103
+ throw new Error("spawn.parallel calls must be [service, options] tuples or spawn thunks.");
7670
8104
  }
7671
- if (!resolved.binaryName) {
7672
- throw new Error(`Agent "${resolved.agentId}" has no binaryName.`);
8105
+ const { options, cleanup } = withAbortSignal(call[1], signal);
8106
+ try {
8107
+ const handle = spawnOnce(call[0], options);
8108
+ const [result] = await Promise.all([handle.result, drainEvents(handle.events)]);
8109
+ return result;
8110
+ } finally {
8111
+ cleanup();
7673
8112
  }
7674
- return {
7675
- agentId: resolved.agentId,
7676
- binaryName: resolved.binaryName,
7677
- spawnConfig: resolved.spawnConfig
7678
- };
7679
- }
7680
- function getDefaultArgsPosition(config) {
7681
- return config.defaultArgsPosition ?? "afterPrompt";
7682
8113
  }
7683
- function getMcpArgsPosition(config) {
7684
- if (config.mcpArgsPosition) {
7685
- return config.mcpArgsPosition;
8114
+ async function drainEvents(events) {
8115
+ for await (const ignoredEvent of events) {
8116
+ void ignoredEvent;
7686
8117
  }
7687
- return config.mcpArgsBeforeCommand ? "beforeCommand" : "afterCommand";
7688
8118
  }
7689
- function buildCliArgs(config, options, stdinMode) {
7690
- const mcpArgs = getMcpArgs(config, options.mcpServers);
7691
- const resumeArgs = getResumeArgs(config, options);
7692
- const defaultArgsPosition = getDefaultArgsPosition(config);
7693
- const mcpArgsPosition = getMcpArgsPosition(config);
7694
- const resumeArgsPosition = config.resume?.position ?? "afterPrompt";
7695
- const args = [];
7696
- if (mcpArgsPosition === "beforeCommand") {
7697
- args.push(...mcpArgs);
8119
+ function normalizeMaxConcurrent(maxConcurrent) {
8120
+ const value = maxConcurrent ?? 4;
8121
+ if (!Number.isInteger(value) || value < 1) {
8122
+ throw new Error("spawn.parallel maxConcurrent must be an integer greater than or equal to 1.");
7698
8123
  }
7699
- if (defaultArgsPosition === "beforePrompt") {
7700
- args.push(...config.defaultArgs);
8124
+ return value;
8125
+ }
8126
+ function isSpawnTuple(call) {
8127
+ return Array.isArray(call) && call.length === 2;
8128
+ }
8129
+ function withAbortSignal(options, signal) {
8130
+ if (!options.signal) {
8131
+ return {
8132
+ options: { ...options, signal },
8133
+ cleanup() {
8134
+ }
8135
+ };
8136
+ }
8137
+ const controller = new AbortController();
8138
+ const abort = () => {
8139
+ controller.abort();
8140
+ };
8141
+ if (signal.aborted || options.signal.aborted) {
8142
+ controller.abort();
8143
+ } else {
8144
+ signal.addEventListener("abort", abort, { once: true });
8145
+ options.signal.addEventListener("abort", abort, { once: true });
8146
+ }
8147
+ return {
8148
+ options: { ...options, signal: controller.signal },
8149
+ cleanup() {
8150
+ signal.removeEventListener("abort", abort);
8151
+ options.signal?.removeEventListener("abort", abort);
8152
+ }
8153
+ };
8154
+ }
8155
+ function linkParentAbort(parentSignal, group, setFailure) {
8156
+ if (!parentSignal) {
8157
+ return () => {
8158
+ };
8159
+ }
8160
+ const abort = () => {
8161
+ const error2 = createAbortError3();
8162
+ setFailure(error2);
8163
+ group.abort(error2);
8164
+ };
8165
+ if (parentSignal.aborted) {
8166
+ abort();
8167
+ return () => {
8168
+ };
8169
+ }
8170
+ parentSignal.addEventListener("abort", abort, { once: true });
8171
+ return () => parentSignal.removeEventListener("abort", abort);
8172
+ }
8173
+ function throwIfAborted3(signal) {
8174
+ if (signal.aborted) {
8175
+ throw createAbortError3();
8176
+ }
8177
+ }
8178
+ function createAbortError3() {
8179
+ const error2 = new Error("Agent spawn parallel aborted");
8180
+ error2.name = "AbortError";
8181
+ return error2;
8182
+ }
8183
+
8184
+ // packages/agent-spawn/src/prompt-transport.ts
8185
+ function shouldSendPromptViaStdin(config, options) {
8186
+ return !!config.stdinMode && (options.useStdin === true || options.prompt.includes("\0"));
8187
+ }
8188
+
8189
+ // packages/agent-spawn/src/retry.ts
8190
+ var retryableExitCodes = /* @__PURE__ */ new Set([1, 124, 125, 137]);
8191
+ var maxBackoffMs = 3e4;
8192
+ function createSpawnRetry(spawnOnce) {
8193
+ return (service, options, retryOptions) => {
8194
+ const normalizedRetryOptions = normalizeRetryOptions(retryOptions);
8195
+ const queue = createEventQueue();
8196
+ const result = runRetryingSpawn({
8197
+ service,
8198
+ options,
8199
+ retryOptions: normalizedRetryOptions,
8200
+ spawnOnce,
8201
+ emit: queue.push
8202
+ }).then((value) => {
8203
+ queue.close();
8204
+ return value;
8205
+ }).catch((error2) => {
8206
+ queue.fail(error2);
8207
+ throw error2;
8208
+ });
8209
+ return {
8210
+ events: queue,
8211
+ result
8212
+ };
8213
+ };
8214
+ }
8215
+ function defaultIsRetryable(result) {
8216
+ return retryableExitCodes.has(result.exitCode);
8217
+ }
8218
+ function calculateBackoffMs(baseBackoffMs, completedAttempt) {
8219
+ return Math.min(baseBackoffMs * 2 ** (completedAttempt - 1), maxBackoffMs);
8220
+ }
8221
+ function normalizeRetryOptions(retryOptions) {
8222
+ if (!Number.isInteger(retryOptions.maxAttempts) || retryOptions.maxAttempts < 1) {
8223
+ throw new Error("spawn.retry maxAttempts must be an integer greater than or equal to 1.");
8224
+ }
8225
+ if (!Number.isFinite(retryOptions.backoffMs) || retryOptions.backoffMs < 0) {
8226
+ throw new Error("spawn.retry backoffMs must be a non-negative finite number.");
8227
+ }
8228
+ return {
8229
+ maxAttempts: retryOptions.maxAttempts,
8230
+ backoffMs: retryOptions.backoffMs,
8231
+ isRetryable: retryOptions.isRetryable ?? defaultIsRetryable
8232
+ };
8233
+ }
8234
+ async function runRetryingSpawn(input) {
8235
+ for (let attempt = 1; attempt <= input.retryOptions.maxAttempts; attempt += 1) {
8236
+ throwIfAborted4(input.options.signal);
8237
+ const handle = input.spawnOnce(input.service, input.options);
8238
+ const events = forwardAttemptEvents(handle.events, attempt, input.emit);
8239
+ const result = await handle.result;
8240
+ await events;
8241
+ const isLastAttempt = attempt >= input.retryOptions.maxAttempts;
8242
+ if (result.exitCode === 0 || isLastAttempt || !input.retryOptions.isRetryable(result)) {
8243
+ return result;
8244
+ }
8245
+ const delayMs = calculateBackoffMs(input.retryOptions.backoffMs, attempt);
8246
+ input.emit(createWaitEvent(attempt, delayMs));
8247
+ await sleep4(delayMs, input.options.signal);
8248
+ }
8249
+ throw new Error("spawn.retry reached an unreachable retry state.");
8250
+ }
8251
+ async function forwardAttemptEvents(events, attempt, emit) {
8252
+ for await (const event of events) {
8253
+ emit(prefixEvent(event, attempt));
8254
+ }
8255
+ }
8256
+ function prefixEvent(event, attempt) {
8257
+ const prefix = `attempt: ${attempt}`;
8258
+ if (event.event === "agent_message" || event.event === "reasoning") {
8259
+ return { ...event, text: `${prefix} ${event.text}` };
8260
+ }
8261
+ if (event.event === "error") {
8262
+ return { ...event, message: `${prefix} ${event.message}` };
8263
+ }
8264
+ if (event.event === "tool_start") {
8265
+ return { ...event, title: `${prefix} ${event.title}` };
8266
+ }
8267
+ if (event.event === "tool_complete") {
8268
+ return { ...event, path: `${prefix} ${event.path}` };
8269
+ }
8270
+ return {
8271
+ ...event,
8272
+ _meta: {
8273
+ ...typeof event._meta === "object" && event._meta !== null ? event._meta : {},
8274
+ attempt
8275
+ }
8276
+ };
8277
+ }
8278
+ function createWaitEvent(attempt, delayMs) {
8279
+ return {
8280
+ event: "agent_message",
8281
+ text: `attempt: ${attempt} wait ${delayMs}ms before retry`
8282
+ };
8283
+ }
8284
+ function sleep4(delayMs, signal) {
8285
+ throwIfAborted4(signal);
8286
+ return new Promise((resolve2, reject) => {
8287
+ const timeout = setTimeout(() => {
8288
+ signal?.removeEventListener("abort", onAbort);
8289
+ resolve2();
8290
+ }, delayMs);
8291
+ const onAbort = () => {
8292
+ clearTimeout(timeout);
8293
+ reject(createAbortError4());
8294
+ };
8295
+ signal?.addEventListener("abort", onAbort, { once: true });
8296
+ });
8297
+ }
8298
+ function throwIfAborted4(signal) {
8299
+ if (signal?.aborted) {
8300
+ throw createAbortError4();
8301
+ }
8302
+ }
8303
+ function createAbortError4() {
8304
+ const error2 = new Error("Agent spawn retry aborted");
8305
+ error2.name = "AbortError";
8306
+ return error2;
8307
+ }
8308
+ function createEventQueue() {
8309
+ const values = [];
8310
+ const waiters = [];
8311
+ let closed = false;
8312
+ let failure;
8313
+ const next = () => {
8314
+ if (values.length > 0) {
8315
+ return Promise.resolve({ value: values.shift(), done: false });
8316
+ }
8317
+ if (failure !== void 0) {
8318
+ return Promise.reject(failure);
8319
+ }
8320
+ if (closed) {
8321
+ return Promise.resolve({ value: void 0, done: true });
8322
+ }
8323
+ return new Promise((resolve2, reject) => {
8324
+ waiters.push({ resolve: resolve2, reject });
8325
+ });
8326
+ };
8327
+ return {
8328
+ push(value) {
8329
+ if (closed || failure !== void 0) {
8330
+ return;
8331
+ }
8332
+ const waiter = waiters.shift();
8333
+ if (waiter) {
8334
+ waiter.resolve({ value, done: false });
8335
+ return;
8336
+ }
8337
+ values.push(value);
8338
+ },
8339
+ close() {
8340
+ if (closed || failure !== void 0) {
8341
+ return;
8342
+ }
8343
+ closed = true;
8344
+ for (const waiter of waiters.splice(0)) {
8345
+ waiter.resolve({ value: void 0, done: true });
8346
+ }
8347
+ },
8348
+ fail(error2) {
8349
+ if (closed || failure !== void 0) {
8350
+ return;
8351
+ }
8352
+ failure = error2;
8353
+ for (const waiter of waiters.splice(0)) {
8354
+ waiter.reject(error2);
8355
+ }
8356
+ },
8357
+ async *[Symbol.asyncIterator]() {
8358
+ while (true) {
8359
+ const item = await next();
8360
+ if (item.done) {
8361
+ return;
8362
+ }
8363
+ yield item.value;
8364
+ }
8365
+ }
8366
+ };
8367
+ }
8368
+
8369
+ // packages/agent-spawn/src/skill-bridge.ts
8370
+ import crypto from "node:crypto";
8371
+ import os6 from "node:os";
8372
+
8373
+ // packages/agent-skill-config/src/configs.ts
8374
+ import os5 from "node:os";
8375
+ import path36 from "node:path";
8376
+ var agentSkillConfigs = {
8377
+ "claude-code": {
8378
+ globalSkillDir: "~/.claude/skills",
8379
+ localSkillDir: ".claude/skills"
8380
+ },
8381
+ codex: {
8382
+ globalSkillDir: "~/.codex/skills",
8383
+ localSkillDir: ".codex/skills"
8384
+ },
8385
+ opencode: {
8386
+ globalSkillDir: "~/.config/opencode/skills",
8387
+ localSkillDir: ".opencode/skills"
8388
+ },
8389
+ goose: {
8390
+ globalSkillDir: "~/.agents/skills",
8391
+ localSkillDir: ".agents/skills"
8392
+ }
8393
+ };
8394
+ var supportedAgents2 = Object.keys(agentSkillConfigs);
8395
+ function resolveAgentSupport(input, registry = agentSkillConfigs) {
8396
+ const resolvedId = resolveAgentId(input);
8397
+ if (!resolvedId) {
8398
+ return { status: "unknown", input };
8399
+ }
8400
+ const config = registry[resolvedId];
8401
+ if (!config) {
8402
+ return { status: "unsupported", input, id: resolvedId };
8403
+ }
8404
+ return { status: "supported", input, id: resolvedId, config };
8405
+ }
8406
+ function getAgentConfig(agentId) {
8407
+ const support = resolveAgentSupport(agentId);
8408
+ return support.status === "supported" ? support.config : void 0;
8409
+ }
8410
+ function expandHome2(targetPath, homeDir = os5.homedir()) {
8411
+ if (!targetPath?.startsWith("~")) {
8412
+ return targetPath;
8413
+ }
8414
+ if (targetPath === "~") {
8415
+ return homeDir;
8416
+ }
8417
+ if (targetPath.startsWith("~./")) {
8418
+ targetPath = `~/.${targetPath.slice(3)}`;
8419
+ }
8420
+ let remainder = targetPath.slice(1);
8421
+ if (remainder.startsWith("/") || remainder.startsWith("\\")) {
8422
+ remainder = remainder.slice(1);
8423
+ } else if (remainder.startsWith(".")) {
8424
+ remainder = remainder.slice(1);
8425
+ if (remainder.startsWith("/") || remainder.startsWith("\\")) {
8426
+ remainder = remainder.slice(1);
8427
+ }
8428
+ }
8429
+ return remainder.length === 0 ? homeDir : path36.join(homeDir, remainder);
8430
+ }
8431
+ function resolveSkillDir(config, scope, cwd, homeDir) {
8432
+ if (scope === "global") {
8433
+ return path36.resolve(expandHome2(config.globalSkillDir, homeDir));
8434
+ }
8435
+ return path36.resolve(cwd, config.localSkillDir);
8436
+ }
8437
+
8438
+ // packages/agent-skill-config/src/templates.ts
8439
+ import { readFile as readFile13, stat as stat5 } from "node:fs/promises";
8440
+ import path37 from "node:path";
8441
+ import { fileURLToPath } from "node:url";
8442
+
8443
+ // packages/agent-skill-config/src/apply.ts
8444
+ var UnsupportedAgentError = class extends Error {
8445
+ constructor(agentId) {
8446
+ super(`Unsupported agent: ${agentId}`);
8447
+ this.name = "UnsupportedAgentError";
8448
+ }
8449
+ };
8450
+ function toHomeRelative(localSkillDir) {
8451
+ if (localSkillDir.startsWith("~/") || localSkillDir === "~") {
8452
+ return localSkillDir;
8453
+ }
8454
+ const normalized = localSkillDir.startsWith("./") ? localSkillDir.slice(2) : localSkillDir;
8455
+ return `~/${normalized}`;
8456
+ }
8457
+ var SKILL_TEMPLATE_ID = "__skill_content__";
8458
+ async function installSkill(agentId, skill, options) {
8459
+ const support = resolveAgentSupport(agentId);
8460
+ if (support.status !== "supported") {
8461
+ throw new UnsupportedAgentError(agentId);
8462
+ }
8463
+ const scope = options.scope ?? "local";
8464
+ const config = support.config;
8465
+ const skillDir = scope === "global" ? config.globalSkillDir : toHomeRelative(config.localSkillDir);
8466
+ const skillFolderPath = `${skillDir}/${skill.name}`;
8467
+ const skillFilePath = `${skillFolderPath}/SKILL.md`;
8468
+ const displayPath = `${scope === "global" ? config.globalSkillDir : config.localSkillDir}/${skill.name}/SKILL.md`;
8469
+ await runMutations(
8470
+ [
8471
+ fileMutation.ensureDirectory({
8472
+ path: skillFolderPath,
8473
+ label: `Ensure skill directory ${skill.name}`
8474
+ }),
8475
+ templateMutation.write({
8476
+ target: skillFilePath,
8477
+ templateId: SKILL_TEMPLATE_ID,
8478
+ label: `Write skill ${skill.name}`
8479
+ })
8480
+ ],
8481
+ {
8482
+ fs: options.fs,
8483
+ homeDir: scope === "global" ? options.homeDir : options.cwd,
8484
+ dryRun: options.dryRun,
8485
+ observers: options.observers,
8486
+ templates: async (templateId) => {
8487
+ if (templateId === SKILL_TEMPLATE_ID) {
8488
+ return skill.content;
8489
+ }
8490
+ throw new Error(`Unknown template: ${templateId}`);
8491
+ }
8492
+ }
8493
+ );
8494
+ return { skillPath: skillFilePath, displayPath };
8495
+ }
8496
+
8497
+ // packages/agent-skill-config/src/resolve-skill-reference.ts
8498
+ import { statSync } from "node:fs";
8499
+ import path38 from "node:path";
8500
+ function isMalformedSegment(segment) {
8501
+ return segment.length === 0 || segment !== segment.trim();
8502
+ }
8503
+ function isDirectory(targetPath) {
8504
+ try {
8505
+ return statSync(targetPath).isDirectory();
8506
+ } catch {
8507
+ return false;
8508
+ }
8509
+ }
8510
+ function findSkill(ref, name, tiers, sourceAgentId) {
8511
+ for (const tier of tiers) {
8512
+ if (isDirectory(tier.sourcePath)) {
8513
+ return {
8514
+ kind: "resolved",
8515
+ ref,
8516
+ name,
8517
+ ...sourceAgentId ? { sourceAgentId } : {},
8518
+ sourcePath: tier.sourcePath,
8519
+ scope: tier.scope
8520
+ };
8521
+ }
8522
+ }
8523
+ return {
8524
+ kind: "not-found",
8525
+ ref,
8526
+ searchedPaths: tiers.map((tier) => tier.sourcePath)
8527
+ };
8528
+ }
8529
+ function resolveSkillReference(ref, cwd, homeDir) {
8530
+ const slashIndex = ref.indexOf("/");
8531
+ const hasPrefix = slashIndex !== -1;
8532
+ if (ref.length === 0 || ref !== ref.trim() || hasPrefix && ref.indexOf("/", slashIndex + 1) !== -1) {
8533
+ return { kind: "malformed", ref };
8534
+ }
8535
+ if (!hasPrefix) {
8536
+ if (isMalformedSegment(ref)) {
8537
+ return { kind: "malformed", ref };
8538
+ }
8539
+ const tiers2 = [
8540
+ {
8541
+ scope: "project",
8542
+ sourcePath: path38.resolve(cwd, ".poe-code/skills", ref)
8543
+ },
8544
+ {
8545
+ scope: "user",
8546
+ sourcePath: path38.resolve(homeDir, ".poe-code/skills", ref)
8547
+ }
8548
+ ];
8549
+ return findSkill(ref, ref, tiers2);
8550
+ }
8551
+ const agentInput = ref.slice(0, slashIndex);
8552
+ const name = ref.slice(slashIndex + 1);
8553
+ if (isMalformedSegment(agentInput) || isMalformedSegment(name)) {
8554
+ return { kind: "malformed", ref };
8555
+ }
8556
+ const support = resolveAgentSupport(agentInput);
8557
+ if (support.status !== "supported" || !support.id) {
8558
+ return { kind: "unknown-agent", ref, agentInput };
8559
+ }
8560
+ const config = getAgentConfig(support.id);
8561
+ if (!config) {
8562
+ return { kind: "unknown-agent", ref, agentInput };
8563
+ }
8564
+ const tiers = [
8565
+ {
8566
+ scope: "project",
8567
+ sourcePath: path38.resolve(resolveSkillDir(config, "local", cwd), name)
8568
+ },
8569
+ {
8570
+ scope: "user",
8571
+ sourcePath: path38.resolve(resolveSkillDir(config, "global", cwd, homeDir), name)
8572
+ }
8573
+ ];
8574
+ return findSkill(ref, name, tiers, support.id);
8575
+ }
8576
+
8577
+ // packages/agent-skill-config/src/git-exclude.ts
8578
+ import { execFileSync } from "node:child_process";
8579
+ import * as fs10 from "node:fs";
8580
+ import path39 from "node:path";
8581
+ var markerPrefix = "# poe-code-spawn-skills:";
8582
+ function defaultGitDirRunner(cwd) {
8583
+ try {
8584
+ return execFileSync("git", ["rev-parse", "--git-dir"], {
8585
+ cwd,
8586
+ encoding: "utf8",
8587
+ stdio: ["ignore", "pipe", "ignore"]
8588
+ }).trim();
8589
+ } catch {
8590
+ return void 0;
8591
+ }
8592
+ }
8593
+ var gitDirRunner = defaultGitDirRunner;
8594
+ function resolveExcludePath(cwd) {
8595
+ const gitDir = gitDirRunner(cwd);
8596
+ if (gitDir === void 0 || gitDir.length === 0) {
8597
+ return void 0;
8598
+ }
8599
+ return path39.join(path39.isAbsolute(gitDir) ? gitDir : path39.resolve(cwd, gitDir), "info/exclude");
8600
+ }
8601
+ function markers(runId) {
8602
+ return {
8603
+ begin: `${markerPrefix}${runId} begin`,
8604
+ end: `${markerPrefix}${runId} end`
8605
+ };
8606
+ }
8607
+ function readExcludeFile(excludePath) {
8608
+ try {
8609
+ return fs10.readFileSync(excludePath, "utf8");
8610
+ } catch (error2) {
8611
+ if (isNodeError2(error2) && error2.code === "ENOENT") {
8612
+ return void 0;
8613
+ }
8614
+ throw error2;
8615
+ }
8616
+ }
8617
+ function isNodeError2(error2) {
8618
+ return error2 instanceof Error && "code" in error2;
8619
+ }
8620
+ function removeBlock(content, runId) {
8621
+ const { begin, end } = markers(runId);
8622
+ const lines = content.split("\n");
8623
+ const result = [];
8624
+ for (let index = 0; index < lines.length; index += 1) {
8625
+ if (lines[index] === begin) {
8626
+ const endIndex = lines.indexOf(end, index + 1);
8627
+ if (endIndex !== -1) {
8628
+ index = endIndex;
8629
+ continue;
8630
+ }
8631
+ }
8632
+ result.push(lines[index]);
8633
+ }
8634
+ return result.join("\n");
8635
+ }
8636
+ function appendBlock(content, runId, entries) {
8637
+ const { begin, end } = markers(runId);
8638
+ const existing = content ?? "";
8639
+ const prefix = existing.length === 0 || existing.endsWith("\n") ? existing : `${existing}
8640
+ `;
8641
+ return `${prefix}${[begin, ...entries, end, ""].join("\n")}`;
8642
+ }
8643
+ function appendExcludeBlock(cwd, runId, entries) {
8644
+ const excludePath = resolveExcludePath(cwd);
8645
+ if (excludePath === void 0) {
8646
+ return;
8647
+ }
8648
+ fs10.mkdirSync(path39.dirname(excludePath), { recursive: true });
8649
+ const content = readExcludeFile(excludePath);
8650
+ fs10.writeFileSync(excludePath, appendBlock(content, runId, entries), "utf8");
8651
+ }
8652
+ function removeExcludeBlock(cwd, runId) {
8653
+ const excludePath = resolveExcludePath(cwd);
8654
+ if (excludePath === void 0) {
8655
+ return;
8656
+ }
8657
+ const content = readExcludeFile(excludePath);
8658
+ if (content === void 0) {
8659
+ return;
8660
+ }
8661
+ fs10.writeFileSync(excludePath, removeBlock(content, runId), "utf8");
8662
+ }
8663
+
8664
+ // packages/agent-skill-config/src/bridge-active-skills.ts
8665
+ import * as fs11 from "node:fs";
8666
+ import path40 from "node:path";
8667
+ function isNodeError3(error2) {
8668
+ return error2 instanceof Error && "code" in error2;
8669
+ }
8670
+ function pathExists3(targetPath) {
8671
+ try {
8672
+ fs11.statSync(targetPath);
8673
+ return true;
8674
+ } catch (error2) {
8675
+ if (isNodeError3(error2) && error2.code === "ENOENT") {
8676
+ return false;
8677
+ }
8678
+ throw error2;
8679
+ }
8680
+ }
8681
+ function isDirectory2(targetPath) {
8682
+ try {
8683
+ return fs11.statSync(targetPath).isDirectory();
8684
+ } catch (error2) {
8685
+ if (isNodeError3(error2) && error2.code === "ENOENT") {
8686
+ return false;
8687
+ }
8688
+ throw error2;
8689
+ }
8690
+ }
8691
+ function formatResolutionFailureError(failures) {
8692
+ const malformed = failures.filter((failure) => failure.kind === "malformed");
8693
+ const unknownAgent = failures.filter((failure) => failure.kind === "unknown-agent");
8694
+ const notFound = failures.filter((failure) => failure.kind === "not-found");
8695
+ const lines = [
8696
+ `Failed to bridge active skills: ${failures.length} skill reference(s) could not be resolved.`
8697
+ ];
8698
+ if (malformed.length > 0) {
8699
+ lines.push("", "Malformed skill references:");
8700
+ for (const failure of malformed) {
8701
+ lines.push(`- ${failure.ref}`);
8702
+ }
8703
+ lines.push('Expected syntax: "<name>" or "<agentId>/<name>".');
8704
+ }
8705
+ if (unknownAgent.length > 0) {
8706
+ lines.push("", "Unknown agent references:");
8707
+ for (const failure of unknownAgent) {
8708
+ lines.push(`- ${failure.ref} (agent token: ${failure.agentInput})`);
8709
+ }
8710
+ lines.push(`Supported agents: ${supportedAgents2.join(", ")}.`);
8711
+ }
8712
+ if (notFound.length > 0) {
8713
+ lines.push("", "Not found skill references.");
8714
+ for (const failure of notFound) {
8715
+ lines.push(`- ${failure.ref}`);
8716
+ lines.push(" searched paths:");
8717
+ for (const searchedPath of failure.searchedPaths) {
8718
+ lines.push(` - ${searchedPath}`);
8719
+ }
8720
+ }
8721
+ }
8722
+ return new Error(lines.join("\n"));
8723
+ }
8724
+ function copyDirectory(sourcePath, targetPath) {
8725
+ fs11.mkdirSync(targetPath, { recursive: true });
8726
+ for (const dirent of fs11.readdirSync(sourcePath, { withFileTypes: true })) {
8727
+ const childSource = path40.join(sourcePath, dirent.name);
8728
+ const childTarget = path40.join(targetPath, dirent.name);
8729
+ if (dirent.isDirectory()) {
8730
+ copyDirectory(childSource, childTarget);
8731
+ continue;
8732
+ }
8733
+ if (dirent.isFile()) {
8734
+ fs11.copyFileSync(childSource, childTarget);
8735
+ }
8736
+ }
8737
+ }
8738
+ function collectMissingParents(targetPath) {
8739
+ const parents = [];
8740
+ let current = path40.dirname(targetPath);
8741
+ while (!pathExists3(current)) {
8742
+ parents.push(current);
8743
+ const parent = path40.dirname(current);
8744
+ if (parent === current) {
8745
+ break;
8746
+ }
8747
+ current = parent;
8748
+ }
8749
+ return parents.reverse();
8750
+ }
8751
+ function removeDirectoryIfEmpty(targetPath) {
8752
+ try {
8753
+ fs11.rmdirSync(targetPath);
8754
+ } catch (error2) {
8755
+ if (isNodeError3(error2) && (error2.code === "ENOENT" || error2.code === "ENOTEMPTY" || error2.code === "EEXIST")) {
8756
+ return;
8757
+ }
8758
+ throw error2;
8759
+ }
8760
+ }
8761
+ function removeTarget(targetPath) {
8762
+ fs11.rmSync(targetPath, { recursive: true, force: true });
8763
+ }
8764
+ function toCwdRelative(cwd, targetPath) {
8765
+ return path40.relative(cwd, targetPath);
8766
+ }
8767
+ function warning(kind, ref, sourcePath, conflictingPath) {
8768
+ const messages = {
8769
+ "intra-batch-collision": `Skipping ${ref}: an earlier bridged skill already targets ${conflictingPath}.`,
8770
+ "local-collision": `Skipping ${ref}: local skill already exists at ${conflictingPath}.`,
8771
+ "global-collision": `Skipping ${ref}: global skill already exists at ${conflictingPath}.`,
8772
+ "self-reference": `Skipping ${ref}: spawning agent already sees this native skill at ${conflictingPath}.`
8773
+ };
8774
+ return {
8775
+ kind,
8776
+ ref,
8777
+ sourcePath,
8778
+ conflictingPath,
8779
+ message: messages[kind]
8780
+ };
8781
+ }
8782
+ function bridgeActiveSkills(spawnAgentId, cwd, refs, homeDir, runId) {
8783
+ const spawnConfig = getAgentConfig(spawnAgentId);
8784
+ const spawnSupport = resolveAgentSupport(spawnAgentId);
8785
+ if (!spawnConfig || spawnSupport.status !== "supported" || !spawnSupport.id) {
8786
+ throw new Error(
8787
+ `Unsupported spawn agent "${spawnAgentId}". Supported agents: ${supportedAgents2.join(", ")}.`
8788
+ );
8789
+ }
8790
+ const targetDir = resolveSkillDir(spawnConfig, "local", cwd);
8791
+ const globalTargetDir = resolveSkillDir(spawnConfig, "global", cwd, homeDir);
8792
+ const resolutions = refs.map((ref) => resolveSkillReference(ref, cwd, homeDir));
8793
+ const failures = resolutions.filter(
8794
+ (resolution) => resolution.kind !== "resolved"
8795
+ );
8796
+ if (failures.length > 0) {
8797
+ throw formatResolutionFailureError(failures);
8798
+ }
8799
+ const sources = resolutions.map((source, index) => ({
8800
+ ref: refs[index],
8801
+ source,
8802
+ targetPath: path40.resolve(targetDir, source.name),
8803
+ globalTargetPath: path40.resolve(globalTargetDir, source.name)
8804
+ }));
8805
+ const entries = [];
8806
+ const warnings = [];
8807
+ const claimedTargets = /* @__PURE__ */ new Set();
8808
+ for (const item of sources) {
8809
+ if (claimedTargets.has(item.targetPath)) {
8810
+ warnings.push(
8811
+ warning("intra-batch-collision", item.ref, item.source.sourcePath, item.targetPath)
8812
+ );
8813
+ continue;
8814
+ }
8815
+ if (item.source.sourceAgentId === spawnSupport.id) {
8816
+ warnings.push(
8817
+ warning("self-reference", item.ref, item.source.sourcePath, item.source.sourcePath)
8818
+ );
8819
+ continue;
8820
+ }
8821
+ if (pathExists3(item.targetPath)) {
8822
+ warnings.push(warning("local-collision", item.ref, item.source.sourcePath, item.targetPath));
8823
+ continue;
8824
+ }
8825
+ if (isDirectory2(item.globalTargetPath)) {
8826
+ warnings.push(
8827
+ warning("global-collision", item.ref, item.source.sourcePath, item.globalTargetPath)
8828
+ );
8829
+ continue;
8830
+ }
8831
+ const createdParents = collectMissingParents(item.targetPath);
8832
+ fs11.mkdirSync(path40.dirname(item.targetPath), { recursive: true });
8833
+ copyDirectory(item.source.sourcePath, item.targetPath);
8834
+ claimedTargets.add(item.targetPath);
8835
+ entries.push({
8836
+ ref: item.ref,
8837
+ sourcePath: item.source.sourcePath,
8838
+ targetPath: item.targetPath,
8839
+ createdParents
8840
+ });
8841
+ }
8842
+ if (entries.length > 0) {
8843
+ appendExcludeBlock(
8844
+ cwd,
8845
+ runId,
8846
+ entries.map((entry) => toCwdRelative(cwd, entry.targetPath))
8847
+ );
8848
+ }
8849
+ return {
8850
+ spawnAgentId,
8851
+ cwd,
8852
+ runId,
8853
+ entries,
8854
+ warnings
8855
+ };
8856
+ }
8857
+ function cleanupBridgedSkills(manifest) {
8858
+ for (const entry of manifest.entries) {
8859
+ removeTarget(entry.targetPath);
8860
+ for (const parent of [...entry.createdParents].reverse()) {
8861
+ removeDirectoryIfEmpty(parent);
8862
+ }
8863
+ }
8864
+ removeExcludeBlock(manifest.cwd, manifest.runId);
8865
+ }
8866
+
8867
+ // packages/agent-spawn/src/skill-bridge.ts
8868
+ function bridgeSkillsForRun(agentId, cwd, skills) {
8869
+ if (!skills || skills.length === 0) {
8870
+ return void 0;
8871
+ }
8872
+ const manifest = bridgeActiveSkills(agentId, cwd, skills, os6.homedir(), crypto.randomUUID());
8873
+ for (const warning2 of manifest.warnings) {
8874
+ logger.warn(warning2.message);
8875
+ }
8876
+ return manifest;
8877
+ }
8878
+ function cleanupSkillsForRun(manifest) {
8879
+ if (!manifest) {
8880
+ return;
8881
+ }
8882
+ cleanupBridgedSkills(manifest);
8883
+ }
8884
+
8885
+ // packages/agent-spawn/src/adapters/utils.ts
8886
+ function truncate(text5, maxLength) {
8887
+ if (text5.length <= maxLength) return text5;
8888
+ if (maxLength <= 3) return text5.slice(0, maxLength);
8889
+ return `${text5.slice(0, maxLength - 3)}...`;
8890
+ }
8891
+ function isNonEmptyString(value) {
8892
+ return typeof value === "string" && value.length > 0;
8893
+ }
8894
+ function extractThreadId(value) {
8895
+ if (!value || typeof value !== "object") return;
8896
+ const obj = value;
8897
+ const maybeThreadId = isNonEmptyString(obj.thread_id) && obj.thread_id || isNonEmptyString(obj.threadId) && obj.threadId || isNonEmptyString(obj.threadID) && obj.threadID || isNonEmptyString(obj.session_id) && obj.session_id || isNonEmptyString(obj.sessionId) && obj.sessionId || isNonEmptyString(obj.sessionID) && obj.sessionID;
8898
+ return maybeThreadId || void 0;
8899
+ }
8900
+
8901
+ // packages/agent-spawn/src/adapters/claude.ts
8902
+ var TOOL_KIND_MAP = {
8903
+ Read: "read",
8904
+ Write: "edit",
8905
+ Edit: "edit",
8906
+ NotebookEdit: "edit",
8907
+ Bash: "exec",
8908
+ Glob: "search",
8909
+ Grep: "search",
8910
+ Task: "think"
8911
+ };
8912
+ var TITLE_KEYS = {
8913
+ Bash: ["command"],
8914
+ Read: ["file_path"],
8915
+ Write: ["file_path"],
8916
+ Edit: ["file_path"],
8917
+ NotebookEdit: ["notebook_path"],
8918
+ Glob: ["pattern"],
8919
+ Grep: ["pattern"],
8920
+ Task: ["description", "prompt"]
8921
+ };
8922
+ function extractTitle(name, input) {
8923
+ const keys = TITLE_KEYS[name];
8924
+ if (keys && input && typeof input === "object") {
8925
+ const obj = input;
8926
+ for (const key of keys) {
8927
+ const value = obj[key];
8928
+ if (typeof value === "string" && value.length > 0) {
8929
+ return truncate(value, 80);
8930
+ }
8931
+ }
8932
+ }
8933
+ return name;
8934
+ }
8935
+ async function* adaptClaude(lines) {
8936
+ const toolKindsById = /* @__PURE__ */ new Map();
8937
+ let emittedSessionStart = false;
8938
+ for await (const rawLine of lines) {
8939
+ const line = rawLine.trim();
8940
+ if (!line) continue;
8941
+ const firstChar = line[0];
8942
+ if (firstChar !== "{" && firstChar !== "[") {
8943
+ continue;
8944
+ }
8945
+ let event;
8946
+ try {
8947
+ event = JSON.parse(line);
8948
+ } catch (error2) {
8949
+ const stack = error2 instanceof Error ? error2.stack : void 0;
8950
+ yield {
8951
+ event: "error",
8952
+ message: `[adaptClaude] Malformed JSON line: ${truncate(line, 200)}`,
8953
+ stack
8954
+ };
8955
+ continue;
8956
+ }
8957
+ const eventType = event.type;
8958
+ if (!isNonEmptyString(eventType)) continue;
8959
+ if (!emittedSessionStart) {
8960
+ const threadId = extractThreadId(event);
8961
+ emittedSessionStart = true;
8962
+ yield { event: "session_start", threadId };
8963
+ }
8964
+ if (eventType === "result") {
8965
+ const usage = event.usage ?? {};
8966
+ const inputTokens = typeof usage.input_tokens === "number" ? usage.input_tokens : typeof event.input_tokens === "number" ? event.input_tokens : typeof event.num_input_tokens === "number" ? event.num_input_tokens : 0;
8967
+ const outputTokens = typeof usage.output_tokens === "number" ? usage.output_tokens : typeof event.output_tokens === "number" ? event.output_tokens : typeof event.num_output_tokens === "number" ? event.num_output_tokens : 0;
8968
+ const costUsd = typeof usage.cost_usd === "number" ? usage.cost_usd : typeof event.cost_usd === "number" ? event.cost_usd : void 0;
8969
+ yield { event: "usage", inputTokens, outputTokens, costUsd };
8970
+ continue;
8971
+ }
8972
+ if (eventType !== "assistant" && eventType !== "user") continue;
8973
+ const message2 = event.message ?? null;
8974
+ if (!message2 || typeof message2 !== "object") continue;
8975
+ const content = message2.content ?? null;
8976
+ if (!Array.isArray(content)) continue;
8977
+ for (const block of content) {
8978
+ const item = block;
8979
+ if (!item || typeof item !== "object") continue;
8980
+ const blockType = item.type;
8981
+ if (!isNonEmptyString(blockType)) continue;
8982
+ if (eventType === "assistant") {
8983
+ if (blockType === "text" && isNonEmptyString(item.text)) {
8984
+ yield {
8985
+ event: "agent_message",
8986
+ text: item.text
8987
+ };
8988
+ continue;
8989
+ }
8990
+ if (blockType === "tool_use" && isNonEmptyString(item.id) && isNonEmptyString(item.name)) {
8991
+ const kind = TOOL_KIND_MAP[item.name] ?? "other";
8992
+ toolKindsById.set(item.id, kind);
8993
+ yield {
8994
+ event: "tool_start",
8995
+ id: item.id,
8996
+ kind,
8997
+ title: extractTitle(item.name, item.input),
8998
+ input: item.input
8999
+ };
9000
+ }
9001
+ continue;
9002
+ }
9003
+ if (eventType === "user") {
9004
+ if (!isNonEmptyString(item.tool_use_id)) continue;
9005
+ if (blockType !== "tool_result") continue;
9006
+ const kind = toolKindsById.get(item.tool_use_id);
9007
+ toolKindsById.delete(item.tool_use_id);
9008
+ let path50;
9009
+ if (typeof item.content === "string") {
9010
+ path50 = item.content;
9011
+ } else {
9012
+ try {
9013
+ path50 = JSON.stringify(item.content);
9014
+ } catch {
9015
+ path50 = String(item.content);
9016
+ }
9017
+ }
9018
+ yield {
9019
+ event: "tool_complete",
9020
+ id: item.tool_use_id,
9021
+ kind,
9022
+ path: path50
9023
+ };
9024
+ }
9025
+ }
9026
+ }
9027
+ }
9028
+
9029
+ // packages/agent-spawn/src/adapters/codex.ts
9030
+ async function* adaptCodex(lines) {
9031
+ const toolTitleById = /* @__PURE__ */ new Map();
9032
+ const toolKindById = /* @__PURE__ */ new Map();
9033
+ for await (const rawLine of lines) {
9034
+ const line = rawLine.trim();
9035
+ if (!line) continue;
9036
+ let event;
9037
+ try {
9038
+ event = JSON.parse(line);
9039
+ } catch (error2) {
9040
+ const stack = error2 instanceof Error ? error2.stack : void 0;
9041
+ yield {
9042
+ event: "error",
9043
+ message: `[adaptCodex] Malformed JSON line: ${truncate(line, 200)}`,
9044
+ stack
9045
+ };
9046
+ continue;
9047
+ }
9048
+ const eventType = event.type;
9049
+ if (!isNonEmptyString(eventType)) continue;
9050
+ if (eventType === "thread.started") {
9051
+ const maybeThreadId = extractThreadId(event);
9052
+ yield { event: "session_start", threadId: maybeThreadId };
9053
+ continue;
9054
+ }
9055
+ if (eventType === "turn.started") {
9056
+ continue;
9057
+ }
9058
+ if (eventType === "turn.completed") {
9059
+ const usage = event.usage ?? {};
9060
+ const inputTokens = typeof usage.input_tokens === "number" ? usage.input_tokens : 0;
9061
+ const outputTokens = typeof usage.output_tokens === "number" ? usage.output_tokens : 0;
9062
+ const cachedTokens = typeof usage.cached_input_tokens === "number" ? usage.cached_input_tokens : 0;
9063
+ yield { event: "usage", inputTokens, outputTokens, cachedTokens };
9064
+ continue;
9065
+ }
9066
+ if (eventType === "turn.failed") {
9067
+ const message2 = extractErrorMessage(event) ?? "Turn failed";
9068
+ yield { event: "error", message: message2 };
9069
+ continue;
9070
+ }
9071
+ const item = event.item ?? null;
9072
+ if (!item || typeof item !== "object") continue;
9073
+ const itemType = item.type;
9074
+ if (!isNonEmptyString(itemType)) continue;
9075
+ if (eventType === "item.started") {
9076
+ if (!isNonEmptyString(item.id)) continue;
9077
+ let kind;
9078
+ let title;
9079
+ if (itemType === "command_execution") {
9080
+ kind = "exec";
9081
+ title = truncate(isNonEmptyString(item.command) ? item.command : "", 80);
9082
+ } else if (itemType === "file_edit") {
9083
+ kind = "edit";
9084
+ title = isNonEmptyString(item.path) ? item.path : "";
9085
+ } else if (itemType === "thinking") {
9086
+ kind = "think";
9087
+ title = "thinking...";
9088
+ } else if (itemType === "mcp_tool_call") {
9089
+ const server = isNonEmptyString(item.server) ? item.server : "unknown";
9090
+ const tool = isNonEmptyString(item.tool) ? item.tool : "unknown";
9091
+ kind = "other";
9092
+ title = `${server}.${tool}`;
9093
+ }
9094
+ if (kind && title !== void 0) {
9095
+ toolTitleById.set(item.id, title);
9096
+ toolKindById.set(item.id, kind);
9097
+ yield { event: "tool_start", id: item.id, kind, title };
9098
+ }
9099
+ continue;
9100
+ }
9101
+ if (eventType === "item.completed") {
9102
+ if (itemType === "agent_message") {
9103
+ if (!isNonEmptyString(item.text)) continue;
9104
+ yield { event: "agent_message", text: item.text };
9105
+ continue;
9106
+ }
9107
+ if (itemType === "reasoning") {
9108
+ const text5 = isNonEmptyString(item.text) ? item.text : isNonEmptyString(item.content) ? item.content : isNonEmptyString(item.summary) ? item.summary : void 0;
9109
+ if (!text5) continue;
9110
+ yield { event: "reasoning", text: text5 };
9111
+ continue;
9112
+ }
9113
+ if (!isNonEmptyString(item.id)) continue;
9114
+ if (itemType === "command_execution" || itemType === "file_edit" || itemType === "mcp_tool_call") {
9115
+ const kindFromStart = toolKindById.get(item.id);
9116
+ const kind = kindFromStart ?? (itemType === "command_execution" ? "exec" : itemType === "file_edit" ? "edit" : "other");
9117
+ 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;
9118
+ const path50 = titleFromEvent ?? toolTitleById.get(item.id) ?? "";
9119
+ toolTitleById.delete(item.id);
9120
+ toolKindById.delete(item.id);
9121
+ yield { event: "tool_complete", id: item.id, kind, path: path50 };
9122
+ }
9123
+ }
9124
+ }
9125
+ }
9126
+ function extractErrorMessage(event) {
9127
+ if (isNonEmptyString(event.message)) return event.message;
9128
+ const error2 = event.error;
9129
+ if (isNonEmptyString(error2)) return error2;
9130
+ if (typeof error2 === "object" && error2 !== null) {
9131
+ const errorObj = error2;
9132
+ if (isNonEmptyString(errorObj.message)) return errorObj.message;
9133
+ }
9134
+ if (isNonEmptyString(event.reason)) return event.reason;
9135
+ return void 0;
9136
+ }
9137
+
9138
+ // packages/agent-spawn/src/adapters/kimi.ts
9139
+ async function* adaptKimi(lines) {
9140
+ let emittedSessionStart = false;
9141
+ for await (const rawLine of lines) {
9142
+ const line = rawLine.trim();
9143
+ if (!line) continue;
9144
+ let event;
9145
+ try {
9146
+ event = JSON.parse(line);
9147
+ } catch (error2) {
9148
+ const stack = error2 instanceof Error ? error2.stack : void 0;
9149
+ yield {
9150
+ event: "error",
9151
+ message: `[adaptKimi] Malformed JSON line: ${truncate(line, 200)}`,
9152
+ stack
9153
+ };
9154
+ continue;
9155
+ }
9156
+ if (!event || typeof event !== "object") continue;
9157
+ if (!emittedSessionStart) {
9158
+ const threadId = extractThreadId(event);
9159
+ if (threadId) {
9160
+ emittedSessionStart = true;
9161
+ yield { event: "session_start", threadId };
9162
+ }
9163
+ }
9164
+ const role = event.role;
9165
+ if (!isNonEmptyString(role) || role !== "assistant") continue;
9166
+ const content = event.content;
9167
+ if (!isNonEmptyString(content)) continue;
9168
+ yield { event: "agent_message", text: content };
9169
+ }
9170
+ }
9171
+
9172
+ // packages/agent-spawn/src/adapters/native.ts
9173
+ async function* adaptNative(lines) {
9174
+ for await (const rawLine of lines) {
9175
+ const line = rawLine.trim();
9176
+ if (!line) continue;
9177
+ let event;
9178
+ try {
9179
+ event = JSON.parse(line);
9180
+ } catch (error2) {
9181
+ const stack = error2 instanceof Error ? error2.stack : void 0;
9182
+ yield {
9183
+ event: "error",
9184
+ message: `[adaptNative] Malformed JSON line: ${truncate(line, 200)}`,
9185
+ stack
9186
+ };
9187
+ continue;
9188
+ }
9189
+ const maybeEventType = event?.event;
9190
+ if (!isNonEmptyString(maybeEventType)) {
9191
+ yield {
9192
+ event: "error",
9193
+ message: `[adaptNative] Line missing string "event" field: ${truncate(line, 200)}`
9194
+ };
9195
+ continue;
9196
+ }
9197
+ yield event;
9198
+ }
9199
+ }
9200
+
9201
+ // packages/agent-spawn/src/adapters/opencode.ts
9202
+ function guessToolKind(toolName) {
9203
+ const normalized = toolName.toLowerCase();
9204
+ if (normalized === "bash" || normalized === "shell" || normalized === "sh") return "exec";
9205
+ if (normalized.includes("read")) return "read";
9206
+ if (normalized.includes("write") || normalized.includes("edit") || normalized.includes("patch")) {
9207
+ return "edit";
9208
+ }
9209
+ if (normalized.includes("search") || normalized.includes("grep") || normalized.includes("glob") || normalized.includes("find")) {
9210
+ return "search";
9211
+ }
9212
+ if (normalized.includes("think") || normalized.includes("task")) return "think";
9213
+ return "other";
9214
+ }
9215
+ function safeStringify(value) {
9216
+ if (typeof value === "string") return value;
9217
+ try {
9218
+ return JSON.stringify(value);
9219
+ } catch {
9220
+ return String(value);
9221
+ }
9222
+ }
9223
+ async function* adaptOpenCode(lines) {
9224
+ let emittedSessionStart = false;
9225
+ const toolKindById = /* @__PURE__ */ new Map();
9226
+ for await (const rawLine of lines) {
9227
+ const line = rawLine.trim();
9228
+ if (!line) continue;
9229
+ let event;
9230
+ try {
9231
+ event = JSON.parse(line);
9232
+ } catch (error2) {
9233
+ const stack = error2 instanceof Error ? error2.stack : void 0;
9234
+ yield {
9235
+ event: "error",
9236
+ message: `[adaptOpenCode] Malformed JSON line: ${truncate(line, 200)}`,
9237
+ stack
9238
+ };
9239
+ continue;
9240
+ }
9241
+ if (!event || typeof event !== "object") continue;
9242
+ const sessionID = extractThreadId(event);
9243
+ if (!emittedSessionStart && isNonEmptyString(sessionID)) {
9244
+ emittedSessionStart = true;
9245
+ yield { event: "session_start", threadId: sessionID };
9246
+ }
9247
+ const eventType = event.type;
9248
+ if (!isNonEmptyString(eventType)) continue;
9249
+ if (eventType === "text") {
9250
+ const part = event.part ?? null;
9251
+ if (!part || typeof part !== "object") continue;
9252
+ if (!isNonEmptyString(part.text)) continue;
9253
+ yield { event: "agent_message", text: part.text };
9254
+ continue;
9255
+ }
9256
+ if (eventType === "tool_use") {
9257
+ const part = event.part ?? null;
9258
+ if (!part || typeof part !== "object") continue;
9259
+ if (!isNonEmptyString(part.callID) || !isNonEmptyString(part.tool)) continue;
9260
+ const state = part.state ?? null;
9261
+ if (!state || typeof state !== "object") continue;
9262
+ const kind = guessToolKind(part.tool);
9263
+ const status = state.status;
9264
+ const terminal = status === "completed" || status === "failed";
9265
+ if (!toolKindById.has(part.callID)) {
9266
+ toolKindById.set(part.callID, kind);
9267
+ let title = part.tool;
9268
+ const maybeInput = state.input;
9269
+ if (kind === "exec" && maybeInput && typeof maybeInput === "object") {
9270
+ const command = maybeInput.command;
9271
+ if (isNonEmptyString(command)) {
9272
+ title = truncate(command, 80);
9273
+ }
9274
+ }
9275
+ yield {
9276
+ event: "tool_start",
9277
+ id: part.callID,
9278
+ kind,
9279
+ title,
9280
+ input: state.input
9281
+ };
9282
+ }
9283
+ if (terminal) {
9284
+ const kindFromStart = toolKindById.get(part.callID) ?? kind;
9285
+ toolKindById.delete(part.callID);
9286
+ yield {
9287
+ event: "tool_complete",
9288
+ id: part.callID,
9289
+ kind: kindFromStart,
9290
+ path: safeStringify(state.output)
9291
+ };
9292
+ }
9293
+ continue;
9294
+ }
9295
+ if (eventType === "step_finish") {
9296
+ const part = event.part ?? null;
9297
+ if (!part || typeof part !== "object") continue;
9298
+ const tokens = part.tokens ?? null;
9299
+ if (!tokens || typeof tokens !== "object") continue;
9300
+ const inputTokens = typeof tokens.input === "number" ? tokens.input : 0;
9301
+ const outputTokens = typeof tokens.output === "number" ? tokens.output : 0;
9302
+ const cache = tokens.cache ?? null;
9303
+ const cachedTokens = cache && typeof cache === "object" && typeof cache.read === "number" ? cache.read : void 0;
9304
+ if (inputTokens === 0 && outputTokens === 0 && cachedTokens === void 0) continue;
9305
+ yield { event: "usage", inputTokens, outputTokens, cachedTokens };
9306
+ continue;
9307
+ }
9308
+ }
9309
+ }
9310
+
9311
+ // packages/agent-spawn/src/adapters/index.ts
9312
+ var adapters = {
9313
+ codex: adaptCodex,
9314
+ claude: adaptClaude,
9315
+ kimi: adaptKimi,
9316
+ native: adaptNative,
9317
+ opencode: adaptOpenCode
9318
+ };
9319
+ function getAdapter(type) {
9320
+ const adapter = adapters[type];
9321
+ if (!adapter) {
9322
+ throw new Error(`Unknown adapter "${String(type)}".`);
9323
+ }
9324
+ return adapter;
9325
+ }
9326
+
9327
+ // packages/agent-spawn/src/acp/meta.ts
9328
+ function stampReceiveTime(event, ts) {
9329
+ if (event === null || typeof event !== "object") {
9330
+ return event;
9331
+ }
9332
+ const target = event;
9333
+ const existing = target._meta;
9334
+ if (existing && typeof existing.ts === "number") {
9335
+ return event;
9336
+ }
9337
+ target._meta = existing ? { ...existing, ts } : { ts };
9338
+ return event;
9339
+ }
9340
+
9341
+ // packages/agent-spawn/src/acp/middleware.ts
9342
+ async function applyMiddlewares(middlewares, ctx) {
9343
+ let index = -1;
9344
+ async function dispatch(position) {
9345
+ if (position <= index) {
9346
+ throw new Error("next() called multiple times");
9347
+ }
9348
+ index = position;
9349
+ if (position === middlewares.length) {
9350
+ return;
9351
+ }
9352
+ const middleware = middlewares[position];
9353
+ if (typeof middleware !== "function") {
9354
+ throw new Error(`Invalid ACP middleware at index ${position}`);
9355
+ }
9356
+ await middleware(ctx, () => dispatch(position + 1));
9357
+ }
9358
+ await dispatch(0);
9359
+ }
9360
+
9361
+ // packages/agent-spawn/src/acp/spawn.ts
9362
+ function createAbortError5() {
9363
+ const error2 = new Error("Agent spawn aborted");
9364
+ error2.name = "AbortError";
9365
+ return error2;
9366
+ }
9367
+ function isAcpEvent(value) {
9368
+ return !!value && typeof value === "object" && "event" in value;
9369
+ }
9370
+ function accumulateUsage(ctx, event) {
9371
+ if (event.event !== "usage") {
9372
+ return;
9373
+ }
9374
+ const usage = event;
9375
+ if (typeof usage.inputTokens === "number" && Number.isFinite(usage.inputTokens)) {
9376
+ ctx.usage.inputTokens += usage.inputTokens;
9377
+ }
9378
+ if (typeof usage.outputTokens === "number" && Number.isFinite(usage.outputTokens)) {
9379
+ ctx.usage.outputTokens += usage.outputTokens;
9380
+ }
9381
+ if (typeof usage.cachedTokens === "number" && Number.isFinite(usage.cachedTokens)) {
9382
+ ctx.usage.cachedTokens = (ctx.usage.cachedTokens ?? 0) + usage.cachedTokens;
9383
+ }
9384
+ if (typeof usage.costUsd === "number" && Number.isFinite(usage.costUsd)) {
9385
+ ctx.usage.costUsd = (ctx.usage.costUsd ?? 0) + usage.costUsd;
9386
+ }
9387
+ }
9388
+ function createLineQueue() {
9389
+ const lines = [];
9390
+ const waiters = [];
9391
+ let pending = "";
9392
+ let closed = false;
9393
+ const emit = (line) => {
9394
+ const waiter = waiters.shift();
9395
+ if (waiter) {
9396
+ waiter.resolve({ done: false, value: line });
9397
+ return;
9398
+ }
9399
+ lines.push(line);
9400
+ };
9401
+ const finishWaiters = () => {
9402
+ while (waiters.length > 0) {
9403
+ const waiter = waiters.shift();
9404
+ waiter.resolve({ done: true, value: void 0 });
9405
+ }
9406
+ };
9407
+ return {
9408
+ push(chunk) {
9409
+ if (closed) return;
9410
+ pending += chunk;
9411
+ let newlineIndex = pending.indexOf("\n");
9412
+ while (newlineIndex !== -1) {
9413
+ const raw = pending.slice(0, newlineIndex);
9414
+ emit(raw.endsWith("\r") ? raw.slice(0, -1) : raw);
9415
+ pending = pending.slice(newlineIndex + 1);
9416
+ newlineIndex = pending.indexOf("\n");
9417
+ }
9418
+ },
9419
+ close() {
9420
+ if (closed) return;
9421
+ if (pending.length > 0) {
9422
+ emit(pending.endsWith("\r") ? pending.slice(0, -1) : pending);
9423
+ pending = "";
9424
+ }
9425
+ closed = true;
9426
+ finishWaiters();
9427
+ },
9428
+ lines() {
9429
+ return {
9430
+ [Symbol.asyncIterator]() {
9431
+ return {
9432
+ next() {
9433
+ if (lines.length > 0) {
9434
+ return Promise.resolve({ done: false, value: lines.shift() });
9435
+ }
9436
+ if (closed) {
9437
+ return Promise.resolve({ done: true, value: void 0 });
9438
+ }
9439
+ return new Promise((resolve2) => {
9440
+ waiters.push({ resolve: resolve2 });
9441
+ });
9442
+ }
9443
+ };
9444
+ }
9445
+ };
9446
+ }
9447
+ };
9448
+ }
9449
+ function getDefaultArgsPosition(config) {
9450
+ return config.defaultArgsPosition ?? "afterPrompt";
9451
+ }
9452
+ function getMcpArgsPosition(config) {
9453
+ if (config.mcpArgsPosition) {
9454
+ return config.mcpArgsPosition;
9455
+ }
9456
+ return config.mcpArgsBeforeCommand ? "beforeCommand" : "afterCommand";
9457
+ }
9458
+ function getResumeArgs(config, options) {
9459
+ if (!options.resumeThreadId) {
9460
+ return [];
9461
+ }
9462
+ if (!config.resume) {
9463
+ throw new Error(`Agent "${config.agentId}" does not support resumeThreadId.`);
9464
+ }
9465
+ return config.resume.args(options.resumeThreadId, options.cwd ?? process.cwd());
9466
+ }
9467
+ function spawnStreaming(options) {
9468
+ if (options.signal?.aborted) {
9469
+ throw createAbortError5();
9470
+ }
9471
+ const { agentId, binaryName, spawnConfig } = resolveConfig(options.agentId);
9472
+ if (spawnConfig === void 0) {
9473
+ throw new Error(`Agent "${agentId}" has no spawn config.`);
9474
+ }
9475
+ if (spawnConfig.kind !== "cli") {
9476
+ throw new Error(`Agent "${agentId}" does not support CLI spawn.`);
9477
+ }
9478
+ if (!binaryName) {
9479
+ throw new Error(`Agent "${agentId}" has no binaryName.`);
9480
+ }
9481
+ const mcpArgs = getMcpArgs(spawnConfig, options.mcpServers);
9482
+ const mcpEnvVars = getMcpEnv(spawnConfig, options.mcpServers);
9483
+ const resumeArgs = getResumeArgs(spawnConfig, options);
9484
+ const defaultArgsPosition = getDefaultArgsPosition(spawnConfig);
9485
+ const mcpArgsPosition = getMcpArgsPosition(spawnConfig);
9486
+ const resumeArgsPosition = spawnConfig.resume?.position ?? "afterPrompt";
9487
+ const args = [];
9488
+ if (mcpArgsPosition === "beforeCommand") {
9489
+ args.push(...mcpArgs);
9490
+ }
9491
+ if (defaultArgsPosition === "beforePrompt") {
9492
+ args.push(...spawnConfig.defaultArgs);
9493
+ }
9494
+ if (mcpArgsPosition === "beforePrompt") {
9495
+ args.push(...mcpArgs);
9496
+ }
9497
+ args.push(spawnConfig.promptFlag);
9498
+ if (resumeArgsPosition === "beforePrompt") {
9499
+ args.push(...resumeArgs);
9500
+ }
9501
+ const useStdin = shouldSendPromptViaStdin(spawnConfig, options);
9502
+ if (!useStdin || !spawnConfig.stdinMode?.omitPrompt) {
9503
+ args.push(options.prompt);
9504
+ }
9505
+ if (options.model && spawnConfig.modelFlag) {
9506
+ let model = spawnConfig.modelStripProviderPrefix ? stripModelNamespace(options.model) : options.model;
9507
+ if (spawnConfig.modelTransform) model = spawnConfig.modelTransform(model);
9508
+ args.push(spawnConfig.modelFlag, model);
9509
+ }
9510
+ if (defaultArgsPosition === "afterPrompt") {
9511
+ args.push(...spawnConfig.defaultArgs);
9512
+ }
9513
+ if (mcpArgsPosition === "afterCommand") {
9514
+ args.push(...mcpArgs);
9515
+ }
9516
+ const modeResolved = resolveModeConfig(spawnConfig.modes[options.mode ?? "yolo"]);
9517
+ args.push(...modeResolved.args);
9518
+ if (useStdin) {
9519
+ args.push(...spawnConfig.stdinMode.extraArgs);
9520
+ }
9521
+ if (options.args && options.args.length > 0) {
9522
+ if (resumeArgsPosition === "afterPrompt") {
9523
+ args.push(...resumeArgs);
9524
+ }
9525
+ args.push(...options.args);
9526
+ } else if (resumeArgsPosition === "afterPrompt") {
9527
+ args.push(...resumeArgs);
9528
+ }
9529
+ const envOverrides = { ...mcpEnvVars, ...modeResolved.env };
9530
+ const processEnv = Object.keys(envOverrides).length > 0 ? { ...process.env, ...envOverrides } : void 0;
9531
+ const cwd = options.cwd ?? process.cwd();
9532
+ const queue = createLineQueue();
9533
+ const argv = [binaryName, ...args];
9534
+ const execution = resolvePoeCommandExecution({
9535
+ cwd,
9536
+ runtimeConfigCwd: options.runtimeConfigCwd,
9537
+ env: processEnv ?? process.env,
9538
+ argv,
9539
+ tool: agentId,
9540
+ runtime: {
9541
+ runtime: options.runtime,
9542
+ runtimeImage: options.runtimeImage,
9543
+ runtimeTemplate: options.runtimeTemplate,
9544
+ detach: options.detach,
9545
+ mountPoeCode: options.mountPoeCode,
9546
+ runnerSync: options.runnerSync
9547
+ },
9548
+ openSpec: {
9549
+ execution: {
9550
+ wrapForLogTee: false,
9551
+ stdin: "pipe",
9552
+ stdout: "pipe",
9553
+ stderr: "pipe",
9554
+ env: processEnv,
9555
+ input: useStdin ? options.prompt : "",
9556
+ captureOutput: true,
9557
+ activityTimeoutMs: options.activityTimeoutMs,
9558
+ onStdout(chunk) {
9559
+ queue.push(chunk);
9560
+ },
9561
+ onStderr(chunk) {
9562
+ if (options.tee?.stderr) options.tee.stderr.write(chunk);
9563
+ }
9564
+ }
9565
+ }
9566
+ });
9567
+ const result = { stdout: "", stderr: "", exitCode: 1 };
9568
+ const adapter = getAdapter(spawnConfig.adapter);
9569
+ let resolveEventStreamDone;
9570
+ let rejectEventStreamDone;
9571
+ const eventStreamDone = new Promise((resolve2, reject) => {
9572
+ resolveEventStreamDone = resolve2;
9573
+ rejectEventStreamDone = reject;
9574
+ });
9575
+ const eventQueue = [];
9576
+ const waiters = [];
9577
+ let eventsDone = false;
9578
+ let eventStreamError;
9579
+ const ctx = {
9580
+ sessionId: "unknown",
9581
+ agent: agentId,
9582
+ ...options.logPath !== void 0 ? { logPath: options.logPath } : {},
9583
+ ...options.logDir !== void 0 ? { logDir: options.logDir } : {},
9584
+ ...options.logFileName !== void 0 ? { logFileName: options.logFileName } : {},
9585
+ events: [],
9586
+ usage: {
9587
+ inputTokens: 0,
9588
+ outputTokens: 0
9589
+ },
9590
+ prompt: options.prompt,
9591
+ model: options.model,
9592
+ mode: options.mode,
9593
+ cwd: options.cwd ?? process.cwd(),
9594
+ startedAt: /* @__PURE__ */ new Date()
9595
+ };
9596
+ const pushEvent = (event) => {
9597
+ if (eventsDone) return;
9598
+ if (event.event === "session_start") {
9599
+ const threadId = event.threadId;
9600
+ if (typeof threadId === "string" && threadId.length > 0) {
9601
+ ctx.threadId = threadId;
9602
+ ctx.sessionId = threadId;
9603
+ }
9604
+ }
9605
+ ctx.events.push(event);
9606
+ accumulateUsage(ctx, event);
9607
+ const waiter = waiters.shift();
9608
+ if (waiter) {
9609
+ waiter.resolve({ done: false, value: event });
9610
+ return;
9611
+ }
9612
+ eventQueue.push(event);
9613
+ };
9614
+ const completeEventStream = () => {
9615
+ if (eventsDone) return;
9616
+ eventsDone = true;
9617
+ while (waiters.length > 0) {
9618
+ waiters.shift()?.resolve({ done: true, value: void 0 });
9619
+ }
9620
+ };
9621
+ const failEventStream = (error2) => {
9622
+ if (eventsDone) return;
9623
+ eventStreamError = error2;
9624
+ eventsDone = true;
9625
+ while (waiters.length > 0) {
9626
+ waiters.shift()?.reject(error2);
9627
+ }
9628
+ };
9629
+ ctx.eventStream = {
9630
+ [Symbol.asyncIterator]() {
9631
+ return {
9632
+ next() {
9633
+ if (eventQueue.length > 0) {
9634
+ return Promise.resolve({ done: false, value: eventQueue.shift() });
9635
+ }
9636
+ if (eventStreamError) {
9637
+ return Promise.reject(eventStreamError);
9638
+ }
9639
+ if (eventsDone) {
9640
+ return Promise.resolve({ done: true, value: void 0 });
9641
+ }
9642
+ return new Promise((resolve2, reject) => {
9643
+ waiters.push({ resolve: resolve2, reject });
9644
+ });
9645
+ }
9646
+ };
9647
+ }
9648
+ };
9649
+ const manifest = bridgeSkillsForRun(options.agentId, cwd, options.skills);
9650
+ void (async () => {
9651
+ try {
9652
+ for await (const output of adapter(queue.lines())) {
9653
+ if (!isAcpEvent(output)) continue;
9654
+ pushEvent(stampReceiveTime(output, Date.now()));
9655
+ }
9656
+ completeEventStream();
9657
+ resolveEventStreamDone?.();
9658
+ } catch (error2) {
9659
+ failEventStream(error2);
9660
+ rejectEventStreamDone?.(error2);
9661
+ }
9662
+ })();
9663
+ const done = (async () => {
9664
+ try {
9665
+ await applyMiddlewares(
9666
+ [
9667
+ ...options.middlewares ?? [],
9668
+ async (_ctx, next) => {
9669
+ try {
9670
+ const runResult = await runPoeCommand({
9671
+ factory: execution.factory,
9672
+ openSpec: execution.openSpec,
9673
+ detach: execution.detach,
9674
+ state: execution.state,
9675
+ signal: options.signal
9676
+ });
9677
+ if (runResult.kind === "detached") {
9678
+ result.stdout = "";
9679
+ result.stderr = "";
9680
+ result.exitCode = 0;
9681
+ result.detached = { jobId: runResult.jobId, envId: runResult.envId };
9682
+ } else {
9683
+ result.stderr = runResult.stderr ?? "";
9684
+ result.exitCode = runResult.exitCode;
9685
+ }
9686
+ } finally {
9687
+ queue.close();
9688
+ }
9689
+ await eventStreamDone;
9690
+ await next();
9691
+ }
9692
+ ],
9693
+ ctx
9694
+ );
9695
+ return {
9696
+ ...result,
9697
+ ...ctx.logFile && !result.logFile ? { logFile: ctx.logFile } : {}
9698
+ };
9699
+ } finally {
9700
+ cleanupSkillsForRun(manifest);
9701
+ }
9702
+ })();
9703
+ return {
9704
+ events: ctx.eventStream,
9705
+ done: observeAgentSpawn(
9706
+ {
9707
+ agent: agentId,
9708
+ cwd: options.cwd,
9709
+ mode: options.mode,
9710
+ otelSink: options.otelSink,
9711
+ prompt: options.prompt
9712
+ },
9713
+ () => done
9714
+ )
9715
+ };
9716
+ }
9717
+
9718
+ // packages/agent-spawn/src/spawn.ts
9719
+ function createAbortError6() {
9720
+ const error2 = new Error("Agent spawn aborted");
9721
+ error2.name = "AbortError";
9722
+ return error2;
9723
+ }
9724
+ function resolveCliConfig(agentId) {
9725
+ const resolved = resolveConfig(agentId);
9726
+ if (!resolved.spawnConfig) {
9727
+ throw new Error(`Agent "${resolved.agentId}" has no spawn config.`);
9728
+ }
9729
+ if (resolved.spawnConfig.kind !== "cli") {
9730
+ throw new Error(`Agent "${resolved.agentId}" does not support CLI spawn.`);
9731
+ }
9732
+ if (!resolved.binaryName) {
9733
+ throw new Error(`Agent "${resolved.agentId}" has no binaryName.`);
9734
+ }
9735
+ return {
9736
+ agentId: resolved.agentId,
9737
+ binaryName: resolved.binaryName,
9738
+ spawnConfig: resolved.spawnConfig
9739
+ };
9740
+ }
9741
+ function getDefaultArgsPosition2(config) {
9742
+ return config.defaultArgsPosition ?? "afterPrompt";
9743
+ }
9744
+ function getMcpArgsPosition2(config) {
9745
+ if (config.mcpArgsPosition) {
9746
+ return config.mcpArgsPosition;
9747
+ }
9748
+ return config.mcpArgsBeforeCommand ? "beforeCommand" : "afterCommand";
9749
+ }
9750
+ function buildCliArgs(config, options, stdinMode) {
9751
+ const mcpArgs = getMcpArgs(config, options.mcpServers);
9752
+ const resumeArgs = getResumeArgs2(config, options);
9753
+ const defaultArgsPosition = getDefaultArgsPosition2(config);
9754
+ const mcpArgsPosition = getMcpArgsPosition2(config);
9755
+ const resumeArgsPosition = config.resume?.position ?? "afterPrompt";
9756
+ const args = [];
9757
+ if (mcpArgsPosition === "beforeCommand") {
9758
+ args.push(...mcpArgs);
9759
+ }
9760
+ if (defaultArgsPosition === "beforePrompt") {
9761
+ args.push(...config.defaultArgs);
7701
9762
  }
7702
9763
  if (mcpArgsPosition === "beforePrompt") {
7703
9764
  args.push(...mcpArgs);
@@ -7738,7 +9799,7 @@ function buildCliArgs(config, options, stdinMode) {
7738
9799
  }
7739
9800
  return { args, env: mode.env };
7740
9801
  }
7741
- function getResumeArgs(config, options) {
9802
+ function getResumeArgs2(config, options) {
7742
9803
  if (!options.resumeThreadId) {
7743
9804
  return [];
7744
9805
  }
@@ -7747,59 +9808,74 @@ function getResumeArgs(config, options) {
7747
9808
  }
7748
9809
  return config.resume.args(options.resumeThreadId, options.cwd ?? process.cwd());
7749
9810
  }
7750
- async function spawn3(agentId, options, context) {
9811
+ async function spawn4(agentId, options, context) {
9812
+ return observeAgentSpawn(
9813
+ {
9814
+ agent: agentId,
9815
+ cwd: options.cwd,
9816
+ mode: options.mode,
9817
+ otelSink: options.otelSink,
9818
+ prompt: options.prompt
9819
+ },
9820
+ () => runSpawn(agentId, options, context)
9821
+ );
9822
+ }
9823
+ async function runSpawn(agentId, options, context) {
7751
9824
  if (options.signal?.aborted) {
7752
- throw createAbortError3();
9825
+ throw createAbortError6();
7753
9826
  }
7754
9827
  const { agentId: resolvedId, binaryName, spawnConfig } = resolveCliConfig(agentId);
7755
- const stdinMode = options.useStdin && spawnConfig.stdinMode ? spawnConfig.stdinMode : void 0;
9828
+ const stdinMode = shouldSendPromptViaStdin(spawnConfig, options) ? spawnConfig.stdinMode : void 0;
7756
9829
  const { args: spawnArgs, env: modeEnv } = buildCliArgs(spawnConfig, options, stdinMode);
7757
9830
  if (context?.dryRun) {
7758
9831
  const rendered = [binaryName, ...spawnArgs].join(" ");
7759
9832
  context.logger?.dryRun(rendered);
7760
9833
  return { stdout: "", stderr: "", exitCode: 0 };
7761
9834
  }
7762
- const logFilePath = resolveSpawnLogPath(options);
7763
- const logFd = logFilePath ? openSpawnLog(logFilePath) : void 0;
7764
- const processEnv = modeEnv ? { ...process.env, ...modeEnv } : void 0;
7765
- const argv = [binaryName, ...spawnArgs];
7766
- const execution = resolvePoeCommandExecution({
7767
- cwd: options.cwd ?? process.cwd(),
7768
- runtimeConfigCwd: options.runtimeConfigCwd,
7769
- env: processEnv ?? process.env,
7770
- argv,
7771
- tool: resolvedId,
7772
- runtime: {
7773
- runtime: options.runtime,
7774
- runtimeImage: options.runtimeImage,
7775
- runtimeTemplate: options.runtimeTemplate,
7776
- detach: options.detach,
7777
- mountPoeCode: options.mountPoeCode,
7778
- runnerSync: options.runnerSync
7779
- },
7780
- context,
7781
- openSpec: {
7782
- execution: {
7783
- wrapForLogTee: false,
7784
- stdin: stdinMode ? "pipe" : "inherit",
7785
- stdout: "pipe",
7786
- stderr: "pipe",
7787
- env: processEnv,
7788
- input: stdinMode ? options.prompt : void 0,
7789
- captureOutput: true,
7790
- activityTimeoutMs: options.activityTimeoutMs,
7791
- onStdout(chunk) {
7792
- options.tee?.stdout?.write(chunk);
7793
- appendSpawnLog(logFd, chunk);
7794
- },
7795
- onStderr(chunk) {
7796
- options.tee?.stderr?.write(chunk);
7797
- appendSpawnLog(logFd, chunk);
9835
+ const cwd = options.cwd ?? process.cwd();
9836
+ const manifest = bridgeSkillsForRun(agentId, cwd, options.skills);
9837
+ let logFd;
9838
+ try {
9839
+ const logFilePath = resolveSpawnLogPath(options);
9840
+ logFd = logFilePath ? openSpawnLog(logFilePath) : void 0;
9841
+ const processEnv = modeEnv ? { ...process.env, ...modeEnv } : void 0;
9842
+ const argv = [binaryName, ...spawnArgs];
9843
+ const execution = resolvePoeCommandExecution({
9844
+ cwd,
9845
+ runtimeConfigCwd: options.runtimeConfigCwd,
9846
+ env: processEnv ?? process.env,
9847
+ argv,
9848
+ tool: resolvedId,
9849
+ runtime: {
9850
+ runtime: options.runtime,
9851
+ runtimeImage: options.runtimeImage,
9852
+ runtimeTemplate: options.runtimeTemplate,
9853
+ detach: options.detach,
9854
+ mountPoeCode: options.mountPoeCode,
9855
+ runnerSync: options.runnerSync
9856
+ },
9857
+ context,
9858
+ openSpec: {
9859
+ execution: {
9860
+ wrapForLogTee: false,
9861
+ stdin: stdinMode ? "pipe" : "inherit",
9862
+ stdout: "pipe",
9863
+ stderr: "pipe",
9864
+ env: processEnv,
9865
+ input: stdinMode ? options.prompt : void 0,
9866
+ captureOutput: true,
9867
+ activityTimeoutMs: options.activityTimeoutMs,
9868
+ onStdout(chunk) {
9869
+ options.tee?.stdout?.write(chunk);
9870
+ appendSpawnLog(logFd, chunk);
9871
+ },
9872
+ onStderr(chunk) {
9873
+ options.tee?.stderr?.write(chunk);
9874
+ appendSpawnLog(logFd, chunk);
9875
+ }
7798
9876
  }
7799
9877
  }
7800
- }
7801
- });
7802
- try {
9878
+ });
7803
9879
  const result = await runPoeCommand({
7804
9880
  factory: execution.factory,
7805
9881
  openSpec: execution.openSpec,
@@ -7825,8 +9901,21 @@ async function spawn3(agentId, options, context) {
7825
9901
  };
7826
9902
  } finally {
7827
9903
  closeSpawnLog(logFd);
9904
+ cleanupSkillsForRun(manifest);
7828
9905
  }
7829
9906
  }
9907
+ spawn4.retry = createSpawnRetry((service, options) => {
9908
+ const handle = spawnStreaming({ ...options, agentId: service });
9909
+ return {
9910
+ events: handle.events,
9911
+ result: handle.done
9912
+ };
9913
+ });
9914
+ spawn4.parallel = createSpawnParallel((service, options) => ({
9915
+ events: (async function* () {
9916
+ })(),
9917
+ result: spawn4(service, options)
9918
+ }));
7830
9919
  function resolveSpawnLogPath(options) {
7831
9920
  if (options.logPath) {
7832
9921
  return options.logPath;
@@ -7834,11 +9923,11 @@ function resolveSpawnLogPath(options) {
7834
9923
  if (!options.logDir || !options.logFileName) {
7835
9924
  return void 0;
7836
9925
  }
7837
- return path34.join(options.logDir, options.logFileName);
9926
+ return path41.join(options.logDir, options.logFileName);
7838
9927
  }
7839
9928
  function openSpawnLog(filePath) {
7840
9929
  try {
7841
- mkdirSync(path34.dirname(filePath), { recursive: true });
9930
+ mkdirSync3(path41.dirname(filePath), { recursive: true });
7842
9931
  return openSync(filePath, "a");
7843
9932
  } catch {
7844
9933
  return void 0;
@@ -7863,7 +9952,7 @@ function closeSpawnLog(fd) {
7863
9952
  var DEFAULT_ACTIVITY_TIMEOUT_MS = 10 * 60 * 1e3;
7864
9953
 
7865
9954
  // packages/agent-spawn/src/acp/replay.ts
7866
- import path35 from "node:path";
9955
+ import path42 from "node:path";
7867
9956
  import { homedir as homedir2 } from "node:os";
7868
9957
  import { open as open2, readdir as readdir5 } from "node:fs/promises";
7869
9958
  import { createInterface } from "node:readline";
@@ -7882,13 +9971,13 @@ import { homedir } from "node:os";
7882
9971
  import { join } from "node:path";
7883
9972
 
7884
9973
  // packages/agent-spawn/src/acp/middlewares/spawn-log.ts
7885
- import path36 from "node:path";
9974
+ import path43 from "node:path";
7886
9975
  import { homedir as homedir3 } from "node:os";
7887
9976
  import { mkdir as mkdir5, open as open3 } from "node:fs/promises";
7888
9977
 
7889
9978
  // packages/memory/src/tokens.ts
7890
- import * as fs10 from "node:fs/promises";
7891
- import path37 from "node:path";
9979
+ import * as fs12 from "node:fs/promises";
9980
+ import path44 from "node:path";
7892
9981
 
7893
9982
  // packages/tokenfill/dist/tokenizer.js
7894
9983
  import { get_encoding } from "tiktoken";
@@ -7929,20 +10018,20 @@ function countTokens(text5) {
7929
10018
  }
7930
10019
 
7931
10020
  // packages/tokenfill/dist/corpus.js
7932
- import { readdirSync, readFileSync as readFileSync2 } from "node:fs";
10021
+ import { readdirSync as readdirSync2, readFileSync as readFileSync3 } from "node:fs";
7933
10022
  import { dirname, join as join2 } from "node:path";
7934
- import { fileURLToPath } from "node:url";
10023
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
7935
10024
  var CORPUS_ARTICLE_SEPARATOR = "\n\n";
7936
- var corpusDirectoryPath = join2(dirname(fileURLToPath(import.meta.url)), "corpus");
10025
+ var corpusDirectoryPath = join2(dirname(fileURLToPath2(import.meta.url)), "corpus");
7937
10026
  function getCorpusFileNames() {
7938
- return readdirSync(corpusDirectoryPath, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".md")).map((entry) => entry.name).sort((left, right) => left.localeCompare(right));
10027
+ return readdirSync2(corpusDirectoryPath, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".md")).map((entry) => entry.name).sort((left, right) => left.localeCompare(right));
7939
10028
  }
7940
10029
  function loadBuiltInCorpusArticles() {
7941
10030
  const corpusFileNames = getCorpusFileNames();
7942
10031
  if (corpusFileNames.length === 0) {
7943
10032
  throw new Error(`No built-in corpus markdown files found in ${corpusDirectoryPath}`);
7944
10033
  }
7945
- return corpusFileNames.map((fileName) => readFileSync2(join2(corpusDirectoryPath, fileName), "utf8").trim());
10034
+ return corpusFileNames.map((fileName) => readFileSync3(join2(corpusDirectoryPath, fileName), "utf8").trim());
7946
10035
  }
7947
10036
  var BUILT_IN_CORPUS_ARTICLES = loadBuiltInCorpusArticles();
7948
10037
 
@@ -7952,7 +10041,7 @@ var builtInCorpusByteLength = Buffer.byteLength(builtInCorpusText, "utf8");
7952
10041
 
7953
10042
  // packages/memory/src/tokens.ts
7954
10043
  async function computeTokenStats(root) {
7955
- if (!await pathExists3(root)) {
10044
+ if (!await pathExists4(root)) {
7956
10045
  return {
7957
10046
  memoryTokens: 0,
7958
10047
  sourceTokens: 0,
@@ -7972,13 +10061,13 @@ async function computeTokenStats(root) {
7972
10061
  }
7973
10062
  }
7974
10063
  }
7975
- const repoRoot = path37.resolve(root, "..", "..");
10064
+ const repoRoot = path44.resolve(root, "..", "..");
7976
10065
  let sourceTokens = 0;
7977
10066
  const missingSources = [];
7978
10067
  for (const sourcePath of sourcePaths) {
7979
- const absPath = path37.isAbsolute(sourcePath) ? sourcePath : path37.resolve(repoRoot, sourcePath);
10068
+ const absPath = path44.isAbsolute(sourcePath) ? sourcePath : path44.resolve(repoRoot, sourcePath);
7980
10069
  try {
7981
- const content = await fs10.readFile(absPath, "utf8");
10070
+ const content = await fs12.readFile(absPath, "utf8");
7982
10071
  sourceTokens += countTokens(content);
7983
10072
  } catch (error2) {
7984
10073
  if (isMissing4(error2)) {
@@ -7997,9 +10086,9 @@ async function computeTokenStats(root) {
7997
10086
  missingSources
7998
10087
  };
7999
10088
  }
8000
- async function pathExists3(targetPath) {
10089
+ async function pathExists4(targetPath) {
8001
10090
  try {
8002
- await fs10.stat(targetPath);
10091
+ await fs12.stat(targetPath);
8003
10092
  return true;
8004
10093
  } catch (error2) {
8005
10094
  if (isMissing4(error2)) {
@@ -8027,10 +10116,10 @@ function resolveRunners(overrides) {
8027
10116
  async function ingest(root, opts, runners) {
8028
10117
  const resolved = resolveRunners(runners);
8029
10118
  const source = await materializeSource(opts.source);
8030
- const indexMdBytes = await fs11.readFile(path38.join(root, MEMORY_INDEX_RELPATH));
10119
+ const indexMdBytes = await fs13.readFile(path45.join(root, MEMORY_INDEX_RELPATH));
8031
10120
  const configOptions = {
8032
- fs: fs11,
8033
- filePath: path38.join(inferRepoRoot(root), "poe-code.json")
10121
+ fs: fs13,
10122
+ filePath: path45.join(inferRepoRoot(root), "poe-code.json")
8034
10123
  };
8035
10124
  const agentId = await resolveAgent(configOptions, opts.agent ?? null) ?? opts.agent ?? "claude-code";
8036
10125
  const key = resolved.computeIngestKey({
@@ -8068,7 +10157,7 @@ async function ingest(root, opts, runners) {
8068
10157
  let timeoutError;
8069
10158
  try {
8070
10159
  const result = await runWithTimeout(
8071
- spawn3(agentId, { prompt }),
10160
+ spawn4(agentId, { prompt }),
8072
10161
  opts.timeoutMs ?? await configuredTimeout(configOptions)
8073
10162
  );
8074
10163
  exitCode = result.exitCode;
@@ -8110,7 +10199,7 @@ function buildIngestPrompt(root, sourceLabel, sourceText) {
8110
10199
  }
8111
10200
  async function materializeSource(source) {
8112
10201
  if (source.kind === "file") {
8113
- const bytes = await fs11.readFile(source.absPath);
10202
+ const bytes = await fs13.readFile(source.absPath);
8114
10203
  return {
8115
10204
  label: source.absPath,
8116
10205
  bytes,
@@ -8120,7 +10209,7 @@ async function materializeSource(source) {
8120
10209
  throw new Error("URL ingest not implemented yet.");
8121
10210
  }
8122
10211
  function inferRepoRoot(root) {
8123
- return path38.resolve(root, "..", "..");
10212
+ return path45.resolve(root, "..", "..");
8124
10213
  }
8125
10214
  async function runWithTimeout(promise, timeoutMs) {
8126
10215
  return await new Promise((resolve2, reject) => {
@@ -8877,99 +10966,6 @@ function printMcpConfig() {
8877
10966
  );
8878
10967
  }
8879
10968
 
8880
- // packages/agent-skill-config/src/configs.ts
8881
- import os5 from "node:os";
8882
- import path39 from "node:path";
8883
- var agentSkillConfigs = {
8884
- "claude-code": {
8885
- globalSkillDir: "~/.claude/skills",
8886
- localSkillDir: ".claude/skills"
8887
- },
8888
- codex: {
8889
- globalSkillDir: "~/.codex/skills",
8890
- localSkillDir: ".codex/skills"
8891
- },
8892
- opencode: {
8893
- globalSkillDir: "~/.config/opencode/skills",
8894
- localSkillDir: ".opencode/skills"
8895
- },
8896
- goose: {
8897
- globalSkillDir: "~/.agents/skills",
8898
- localSkillDir: ".agents/skills"
8899
- }
8900
- };
8901
- var supportedAgents2 = Object.keys(agentSkillConfigs);
8902
- function resolveAgentSupport(input, registry = agentSkillConfigs) {
8903
- const resolvedId = resolveAgentId(input);
8904
- if (!resolvedId) {
8905
- return { status: "unknown", input };
8906
- }
8907
- const config = registry[resolvedId];
8908
- if (!config) {
8909
- return { status: "unsupported", input, id: resolvedId };
8910
- }
8911
- return { status: "supported", input, id: resolvedId, config };
8912
- }
8913
-
8914
- // packages/agent-skill-config/src/templates.ts
8915
- import { readFile as readFile15, stat as stat6 } from "node:fs/promises";
8916
- import path40 from "node:path";
8917
- import { fileURLToPath as fileURLToPath2 } from "node:url";
8918
-
8919
- // packages/agent-skill-config/src/apply.ts
8920
- var UnsupportedAgentError = class extends Error {
8921
- constructor(agentId) {
8922
- super(`Unsupported agent: ${agentId}`);
8923
- this.name = "UnsupportedAgentError";
8924
- }
8925
- };
8926
- function toHomeRelative(localSkillDir) {
8927
- if (localSkillDir.startsWith("~/") || localSkillDir === "~") {
8928
- return localSkillDir;
8929
- }
8930
- const normalized = localSkillDir.startsWith("./") ? localSkillDir.slice(2) : localSkillDir;
8931
- return `~/${normalized}`;
8932
- }
8933
- var SKILL_TEMPLATE_ID = "__skill_content__";
8934
- async function installSkill(agentId, skill, options) {
8935
- const support = resolveAgentSupport(agentId);
8936
- if (support.status !== "supported") {
8937
- throw new UnsupportedAgentError(agentId);
8938
- }
8939
- const scope = options.scope ?? "local";
8940
- const config = support.config;
8941
- const skillDir = scope === "global" ? config.globalSkillDir : toHomeRelative(config.localSkillDir);
8942
- const skillFolderPath = `${skillDir}/${skill.name}`;
8943
- const skillFilePath = `${skillFolderPath}/SKILL.md`;
8944
- const displayPath = `${scope === "global" ? config.globalSkillDir : config.localSkillDir}/${skill.name}/SKILL.md`;
8945
- await runMutations(
8946
- [
8947
- fileMutation.ensureDirectory({
8948
- path: skillFolderPath,
8949
- label: `Ensure skill directory ${skill.name}`
8950
- }),
8951
- templateMutation.write({
8952
- target: skillFilePath,
8953
- templateId: SKILL_TEMPLATE_ID,
8954
- label: `Write skill ${skill.name}`
8955
- })
8956
- ],
8957
- {
8958
- fs: options.fs,
8959
- homeDir: scope === "global" ? options.homeDir : options.cwd,
8960
- dryRun: options.dryRun,
8961
- observers: options.observers,
8962
- templates: async (templateId) => {
8963
- if (templateId === SKILL_TEMPLATE_ID) {
8964
- return skill.content;
8965
- }
8966
- throw new Error(`Unknown template: ${templateId}`);
8967
- }
8968
- }
8969
- );
8970
- return { skillPath: skillFilePath, displayPath };
8971
- }
8972
-
8973
10969
  // packages/agent-mcp-config/src/configs.ts
8974
10970
  var agentMcpConfigs = {
8975
10971
  "claude-code": {
@@ -9046,7 +11042,7 @@ function resolveConfigPath2(config, platform) {
9046
11042
  }
9047
11043
 
9048
11044
  // packages/agent-mcp-config/src/apply.ts
9049
- import path41 from "node:path";
11045
+ import path46 from "node:path";
9050
11046
  import { parse as parseYaml3, stringify as stringifyYaml2 } from "yaml";
9051
11047
 
9052
11048
  // packages/agent-mcp-config/src/shapes.ts
@@ -9138,7 +11134,7 @@ function getShapeTransformer(shape) {
9138
11134
 
9139
11135
  // packages/agent-mcp-config/src/apply.ts
9140
11136
  function getConfigDirectory(configPath) {
9141
- return path41.dirname(configPath);
11137
+ return path46.dirname(configPath);
9142
11138
  }
9143
11139
  var UnsupportedAgentError2 = class extends Error {
9144
11140
  constructor(agentId) {
@@ -9164,9 +11160,9 @@ function expandHomePath(configPath, homeDir) {
9164
11160
  return homeDir;
9165
11161
  }
9166
11162
  if (configPath.startsWith("~/")) {
9167
- return path41.join(homeDir, configPath.slice(2));
11163
+ return path46.join(homeDir, configPath.slice(2));
9168
11164
  }
9169
- return path41.join(homeDir, configPath.slice(1));
11165
+ return path46.join(homeDir, configPath.slice(1));
9170
11166
  }
9171
11167
  function parseYamlDocument(content) {
9172
11168
  if (content.trim() === "") {
@@ -9199,7 +11195,7 @@ async function writeYamlConfig(configPath, document, options) {
9199
11195
  return;
9200
11196
  }
9201
11197
  const absolutePath = expandHomePath(configPath, options.homeDir);
9202
- const configDir = path41.dirname(absolutePath);
11198
+ const configDir = path46.dirname(absolutePath);
9203
11199
  await options.fs.mkdir(configDir, { recursive: true });
9204
11200
  await options.fs.writeFile(absolutePath, serializeYamlDocument(document), {
9205
11201
  encoding: "utf8"
@@ -9376,8 +11372,8 @@ async function installMemory(options) {
9376
11372
  }
9377
11373
 
9378
11374
  // packages/memory/src/query.ts
9379
- import * as fs12 from "node:fs/promises";
9380
- import path42 from "node:path";
11375
+ import * as fs14 from "node:fs/promises";
11376
+ import path47 from "node:path";
9381
11377
  async function queryMemory(root, options) {
9382
11378
  const pages = await listPages(root);
9383
11379
  if (pages.length === 0) {
@@ -9390,12 +11386,12 @@ async function queryMemory(root, options) {
9390
11386
  };
9391
11387
  }
9392
11388
  const configOptions = {
9393
- fs: fs12,
9394
- filePath: path42.join(inferRepoRoot2(root), "poe-code.json")
11389
+ fs: fs14,
11390
+ filePath: path47.join(inferRepoRoot2(root), "poe-code.json")
9395
11391
  };
9396
11392
  const agentId = await resolveAgent(configOptions, options.agent ?? null) ?? options.agent ?? "claude-code";
9397
11393
  const context = await selectQueryContext(root, options.question, options.budget);
9398
- const result = await spawn3(agentId, { prompt: context.prompt });
11394
+ const result = await spawn4(agentId, { prompt: context.prompt });
9399
11395
  return {
9400
11396
  answer: result.answer,
9401
11397
  citations: result.citations,
@@ -9406,7 +11402,7 @@ async function queryMemory(root, options) {
9406
11402
  }
9407
11403
  async function selectQueryContext(root, question, budget) {
9408
11404
  const [indexText, pages] = await Promise.all([
9409
- fs12.readFile(path42.join(root, MEMORY_INDEX_RELPATH), "utf8"),
11405
+ fs14.readFile(path47.join(root, MEMORY_INDEX_RELPATH), "utf8"),
9410
11406
  listPages(root)
9411
11407
  ]);
9412
11408
  const indexTokens = countTokens(indexText);
@@ -9485,12 +11481,12 @@ function tokenize(text5) {
9485
11481
  return text5.toLowerCase().split(/[^a-z0-9]+/).filter((token) => token.length > 0);
9486
11482
  }
9487
11483
  function inferRepoRoot2(root) {
9488
- return path42.resolve(root, "..", "..");
11484
+ return path47.resolve(root, "..", "..");
9489
11485
  }
9490
11486
 
9491
11487
  // packages/memory/src/explain.ts
9492
- import * as fs13 from "node:fs/promises";
9493
- import path43 from "node:path";
11488
+ import * as fs15 from "node:fs/promises";
11489
+ import path48 from "node:path";
9494
11490
  async function explainPage(root, options) {
9495
11491
  const targetPage = await readPageIfPresent(root, options.relPath);
9496
11492
  if (targetPage === void 0) {
@@ -9512,11 +11508,11 @@ async function explainPage(root, options) {
9512
11508
  throw new Error(`budget too small; needs at least ${tokensUsed} tokens`);
9513
11509
  }
9514
11510
  const configOptions = {
9515
- fs: fs13,
9516
- filePath: path43.join(inferRepoRoot3(root), "poe-code.json")
11511
+ fs: fs15,
11512
+ filePath: path48.join(inferRepoRoot3(root), "poe-code.json")
9517
11513
  };
9518
11514
  const agentId = await resolveAgent(configOptions, options.agent ?? null) ?? options.agent ?? "claude-code";
9519
- const response = await spawn3(agentId, { prompt });
11515
+ const response = await spawn4(agentId, { prompt });
9520
11516
  return {
9521
11517
  answer: response.answer,
9522
11518
  citations: response.citations,
@@ -9562,7 +11558,7 @@ async function readPageIfPresent(root, relPath) {
9562
11558
  }
9563
11559
  }
9564
11560
  function inferRepoRoot3(root) {
9565
- return path43.resolve(root, "..", "..");
11561
+ return path48.resolve(root, "..", "..");
9566
11562
  }
9567
11563
 
9568
11564
  // packages/memory/src/explain.cli.ts
@@ -9575,9 +11571,9 @@ async function runMemoryExplain(input) {
9575
11571
  }
9576
11572
 
9577
11573
  // packages/memory/src/handle.ts
9578
- import path44 from "node:path";
11574
+ import path49 from "node:path";
9579
11575
  function openMemory(opts) {
9580
- if (!path44.isAbsolute(opts.root)) {
11576
+ if (!path49.isAbsolute(opts.root)) {
9581
11577
  throw new Error(`openMemory: root must be absolute, got ${opts.root}`);
9582
11578
  }
9583
11579
  const root = opts.root;