@kody-ade/kody-engine 0.4.571 → 0.4.572

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 (2) hide show
  1. package/dist/bin/kody.js +428 -418
  2. package/package.json +1 -1
package/dist/bin/kody.js CHANGED
@@ -15,7 +15,7 @@ var init_package = __esm({
15
15
  "package.json"() {
16
16
  package_default = {
17
17
  name: "@kody-ade/kody-engine",
18
- version: "0.4.571",
18
+ version: "0.4.572",
19
19
  description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative implementation profiles.",
20
20
  license: "MIT",
21
21
  type: "module",
@@ -151,17 +151,23 @@ var init_claudeBinary = __esm({
151
151
  });
152
152
 
153
153
  // src/completionGuard.ts
154
+ import * as path2 from "path";
154
155
  function completionToolCutoffAt(startedAtMs, deadlineAtMs) {
155
156
  const availableMs = Math.max(0, deadlineAtMs - startedAtMs);
156
- const reserveMs = Math.min(MAX_COMPLETION_RESERVE_MS, Math.floor(availableMs / 3));
157
+ const reserveMs = Math.min(MAX_COMPLETION_RESERVE_MS, Math.floor(availableMs / 2));
157
158
  return deadlineAtMs - reserveMs;
158
159
  }
159
- function createCompletionToolGuard(cutoffAtMs, now = Date.now) {
160
- return async () => {
160
+ function createCompletionToolGuard(cutoffAtMs, now = Date.now, requiredOutputPath) {
161
+ return async (input) => {
161
162
  if (now() < cutoffAtMs) return {};
163
+ const toolInput = input?.tool_input;
164
+ const filePath = toolInput && typeof toolInput === "object" && !Array.isArray(toolInput) ? toolInput.file_path : void 0;
165
+ if (requiredOutputPath && input?.tool_name === "Write" && typeof filePath === "string" && path2.resolve(filePath) === path2.resolve(requiredOutputPath)) {
166
+ return {};
167
+ }
162
168
  return {
163
169
  decision: "block",
164
- reason: "The run has entered its reserved completion window. Do not call more tools. Use the evidence and changes already present, state any verification limits clearly, and return your final response now."
170
+ reason: "The run has entered its reserved completion window. Do not call more tools. " + (requiredOutputPath ? `If the required structured result is missing, write only ${requiredOutputPath}. ` : "") + "Use the evidence and changes already present, state any verification limits clearly, and return your final response now."
165
171
  };
166
172
  };
167
173
  }
@@ -169,13 +175,13 @@ var MAX_COMPLETION_RESERVE_MS;
169
175
  var init_completionGuard = __esm({
170
176
  "src/completionGuard.ts"() {
171
177
  "use strict";
172
- MAX_COMPLETION_RESERVE_MS = 10 * 6e4;
178
+ MAX_COMPLETION_RESERVE_MS = 15 * 6e4;
173
179
  }
174
180
  });
175
181
 
176
182
  // src/config.ts
177
183
  import * as fs2 from "fs";
178
- import * as path2 from "path";
184
+ import * as path3 from "path";
179
185
  function parseReasoningEffort(raw) {
180
186
  if (!raw) return null;
181
187
  const v = raw.trim().toLowerCase();
@@ -240,7 +246,7 @@ function needsLitellmProxy(model) {
240
246
  return model.provider !== "claude" && model.provider !== "anthropic";
241
247
  }
242
248
  function loadConfig(projectDir = process.cwd()) {
243
- const configPath = path2.join(projectDir, "kody.config.json");
249
+ const configPath = path3.join(projectDir, "kody.config.json");
244
250
  if (!fs2.existsSync(configPath)) {
245
251
  throw new Error(`kody.config.json not found at ${configPath}`);
246
252
  }
@@ -573,15 +579,15 @@ var init_config = __esm({
573
579
 
574
580
  // src/fileEditGuards.ts
575
581
  import * as fs3 from "fs";
576
- import * as path3 from "path";
582
+ import * as path4 from "path";
577
583
  function createMissingParentWriteGuard(cwd) {
578
584
  return async (input) => {
579
585
  const toolInput = input.tool_input;
580
586
  if (!toolInput || typeof toolInput !== "object" || Array.isArray(toolInput)) return {};
581
587
  const filePath = toolInput.file_path;
582
588
  if (typeof filePath !== "string" || filePath.length === 0) return {};
583
- const resolvedPath = path3.resolve(cwd, filePath);
584
- if (fs3.existsSync(path3.dirname(resolvedPath))) return {};
589
+ const resolvedPath = path4.resolve(cwd, filePath);
590
+ if (fs3.existsSync(path4.dirname(resolvedPath))) return {};
585
591
  return {
586
592
  decision: "block",
587
593
  reason: `Cannot write ${resolvedPath}: its parent directory does not exist. Locate and edit the real repository source path first. If this task genuinely requires a new directory, create that directory explicitly before writing the file.`
@@ -788,7 +794,7 @@ var init_capability_contract_validation = __esm({
788
794
 
789
795
  // src/outputContractHooks.ts
790
796
  import * as fs4 from "fs";
791
- import * as path4 from "path";
797
+ import * as path5 from "path";
792
798
  function outputContractError(contract) {
793
799
  let value;
794
800
  try {
@@ -807,12 +813,12 @@ function correctionMessage(contract, error) {
807
813
  return `The authoritative output does not match its required contract: ${error}. Please overwrite ${contract.path} with only the required JSON shape before finishing.`;
808
814
  }
809
815
  function createOutputContractPostWriteHook(contract) {
810
- const expectedPath = path4.resolve(contract.path);
816
+ const expectedPath = path5.resolve(contract.path);
811
817
  return async (input) => {
812
818
  const toolInput = input.tool_input;
813
819
  if (!toolInput || typeof toolInput !== "object" || Array.isArray(toolInput)) return {};
814
820
  const filePath = toolInput.file_path;
815
- if (typeof filePath !== "string" || path4.resolve(filePath) !== expectedPath) return {};
821
+ if (typeof filePath !== "string" || path5.resolve(filePath) !== expectedPath) return {};
816
822
  const error = outputContractError(contract);
817
823
  if (!error) return {};
818
824
  return {
@@ -856,21 +862,21 @@ __export(runtimePaths_exports, {
856
862
  });
857
863
  import { createHash } from "crypto";
858
864
  import * as os2 from "os";
859
- import * as path5 from "path";
865
+ import * as path6 from "path";
860
866
  function runtimeDirForCwd(cwd, ...parts) {
861
- const key = createHash("sha256").update(path5.resolve(cwd)).digest("hex").slice(0, 16);
862
- return path5.join(os2.tmpdir(), "kody-engine", key, ...parts);
867
+ const key = createHash("sha256").update(path6.resolve(cwd)).digest("hex").slice(0, 16);
868
+ return path6.join(os2.tmpdir(), "kody-engine", key, ...parts);
863
869
  }
864
870
  function runtimeStatePath(cwd, ...parts) {
865
871
  const configuredRoot = process.env.KODY_RUNTIME_DIR?.trim();
866
- const base = configuredRoot ? path5.resolve(configuredRoot) : runtimeDirForCwd(cwd);
867
- return path5.join(base, ...parts);
872
+ const base = configuredRoot ? path6.resolve(configuredRoot) : runtimeDirForCwd(cwd);
873
+ return path6.join(base, ...parts);
868
874
  }
869
875
  function agentRunDir(cwd) {
870
876
  return runtimeStatePath(cwd, "agent-runs");
871
877
  }
872
878
  function lastRunLogPath(cwd) {
873
- return path5.join(agentRunDir(cwd), "last-run.jsonl");
879
+ return path6.join(agentRunDir(cwd), "last-run.jsonl");
874
880
  }
875
881
  var init_runtimePaths = __esm({
876
882
  "src/runtimePaths.ts"() {
@@ -881,15 +887,15 @@ var init_runtimePaths = __esm({
881
887
  // src/scripts/buildSyntheticPlugin.ts
882
888
  import * as fs5 from "fs";
883
889
  import * as os3 from "os";
884
- import * as path6 from "path";
890
+ import * as path7 from "path";
885
891
  function getPluginsCatalogRoot() {
886
- const here = path6.dirname(new URL(import.meta.url).pathname);
892
+ const here = path7.dirname(new URL(import.meta.url).pathname);
887
893
  const candidates = [
888
- path6.join(here, "..", "plugins"),
894
+ path7.join(here, "..", "plugins"),
889
895
  // dev: src/scripts → src/plugins
890
- path6.join(here, "..", "..", "plugins"),
896
+ path7.join(here, "..", "..", "plugins"),
891
897
  // built: dist/scripts → dist/plugins
892
- path6.join(here, "..", "..", "src", "plugins")
898
+ path7.join(here, "..", "..", "src", "plugins")
893
899
  // fallback
894
900
  ];
895
901
  for (const c of candidates) {
@@ -900,8 +906,8 @@ function getPluginsCatalogRoot() {
900
906
  function copyDir(src, dst) {
901
907
  fs5.mkdirSync(dst, { recursive: true });
902
908
  for (const ent of fs5.readdirSync(src, { withFileTypes: true })) {
903
- const s = path6.join(src, ent.name);
904
- const d = path6.join(dst, ent.name);
909
+ const s = path7.join(src, ent.name);
910
+ const d = path7.join(dst, ent.name);
905
911
  if (ent.isDirectory()) copyDir(s, d);
906
912
  else if (ent.isFile()) fs5.copyFileSync(s, d);
907
913
  }
@@ -916,35 +922,35 @@ var init_buildSyntheticPlugin = __esm({
916
922
  if (!needsSynthetic) return;
917
923
  const catalog = getPluginsCatalogRoot();
918
924
  const runId = `${profile.name}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
919
- const root = path6.join(os3.tmpdir(), `kody-synth-${runId}`);
920
- fs5.mkdirSync(path6.join(root, ".claude-plugin"), { recursive: true });
925
+ const root = path7.join(os3.tmpdir(), `kody-synth-${runId}`);
926
+ fs5.mkdirSync(path7.join(root, ".claude-plugin"), { recursive: true });
921
927
  const resolvePart = (bucket, entry) => {
922
- const local = path6.join(profile.dir, bucket, entry);
928
+ const local = path7.join(profile.dir, bucket, entry);
923
929
  if (fs5.existsSync(local)) return local;
924
- const shared = path6.resolve(profile.dir, "..", "..", "shared", bucket, entry);
930
+ const shared = path7.resolve(profile.dir, "..", "..", "shared", bucket, entry);
925
931
  if (fs5.existsSync(shared)) return shared;
926
- const central = path6.join(catalog, bucket, entry);
932
+ const central = path7.join(catalog, bucket, entry);
927
933
  if (fs5.existsSync(central)) return central;
928
934
  throw new Error(
929
- `buildSyntheticPlugin: ${bucket} entry '${entry}' not found in implementation dir (${profile.dir}/${bucket}/), Store shared assets (${path6.dirname(shared)}/), or catalog (${catalog}/${bucket}/)`
935
+ `buildSyntheticPlugin: ${bucket} entry '${entry}' not found in implementation dir (${profile.dir}/${bucket}/), Store shared assets (${path7.dirname(shared)}/), or catalog (${catalog}/${bucket}/)`
930
936
  );
931
937
  };
932
938
  if (cc.skills.length > 0) {
933
- const dst = path6.join(root, "skills");
939
+ const dst = path7.join(root, "skills");
934
940
  fs5.mkdirSync(dst, { recursive: true });
935
941
  for (const name of cc.skills) {
936
- copyDir(resolvePart("skills", name), path6.join(dst, name));
942
+ copyDir(resolvePart("skills", name), path7.join(dst, name));
937
943
  }
938
944
  }
939
945
  if (cc.commands.length > 0) {
940
- const dst = path6.join(root, "commands");
946
+ const dst = path7.join(root, "commands");
941
947
  fs5.mkdirSync(dst, { recursive: true });
942
948
  for (const name of cc.commands) {
943
- fs5.copyFileSync(resolvePart("commands", `${name}.md`), path6.join(dst, `${name}.md`));
949
+ fs5.copyFileSync(resolvePart("commands", `${name}.md`), path7.join(dst, `${name}.md`));
944
950
  }
945
951
  }
946
952
  if (cc.hooks.length > 0) {
947
- const dst = path6.join(root, "hooks");
953
+ const dst = path7.join(root, "hooks");
948
954
  fs5.mkdirSync(dst, { recursive: true });
949
955
  const merged = { hooks: {} };
950
956
  for (const name of cc.hooks) {
@@ -956,7 +962,7 @@ var init_buildSyntheticPlugin = __esm({
956
962
  merged.hooks[event].push(...entries);
957
963
  }
958
964
  }
959
- fs5.writeFileSync(path6.join(dst, "hooks.json"), `${JSON.stringify(merged, null, 2)}
965
+ fs5.writeFileSync(path7.join(dst, "hooks.json"), `${JSON.stringify(merged, null, 2)}
960
966
  `);
961
967
  }
962
968
  const manifest = {
@@ -966,7 +972,7 @@ var init_buildSyntheticPlugin = __esm({
966
972
  };
967
973
  if (cc.skills.length > 0) manifest.skills = ["./skills/"];
968
974
  if (cc.commands.length > 0) manifest.commands = ["./commands/"];
969
- fs5.writeFileSync(path6.join(root, ".claude-plugin", "plugin.json"), `${JSON.stringify(manifest, null, 2)}
975
+ fs5.writeFileSync(path7.join(root, ".claude-plugin", "plugin.json"), `${JSON.stringify(manifest, null, 2)}
970
976
  `);
971
977
  ctx.data.syntheticPluginPath = root;
972
978
  };
@@ -975,7 +981,7 @@ var init_buildSyntheticPlugin = __esm({
975
981
 
976
982
  // src/subagents.ts
977
983
  import * as fs6 from "fs";
978
- import * as path7 from "path";
984
+ import * as path8 from "path";
979
985
  async function enforceSubagentModelInheritance(input) {
980
986
  const toolInput = input.tool_input;
981
987
  if (!toolInput || typeof toolInput !== "object" || Array.isArray(toolInput)) return {};
@@ -1010,11 +1016,11 @@ function splitFrontmatter(raw) {
1010
1016
  return { fm, body: (match[2] ?? "").trim() };
1011
1017
  }
1012
1018
  function resolveAgentFile(profileDir, name) {
1013
- const local = path7.join(profileDir, "agents", `${name}.md`);
1019
+ const local = path8.join(profileDir, "agents", `${name}.md`);
1014
1020
  if (fs6.existsSync(local)) return local;
1015
- const shared = path7.resolve(profileDir, "..", "..", "shared", "agents", `${name}.md`);
1021
+ const shared = path8.resolve(profileDir, "..", "..", "shared", "agents", `${name}.md`);
1016
1022
  if (fs6.existsSync(shared)) return shared;
1017
- const central = path7.join(getPluginsCatalogRoot(), "agents", `${name}.md`);
1023
+ const central = path8.join(getPluginsCatalogRoot(), "agents", `${name}.md`);
1018
1024
  if (fs6.existsSync(central)) return central;
1019
1025
  throw new Error(
1020
1026
  `loadSubagents: agent '${name}' not found in ${profileDir}/agents/, hydrated shared assets, or engine catalog`
@@ -1071,7 +1077,7 @@ __export(events_exports, {
1071
1077
  });
1072
1078
  import * as crypto from "crypto";
1073
1079
  import * as fs7 from "fs";
1074
- import * as path8 from "path";
1080
+ import * as path9 from "path";
1075
1081
  function resolveRunId() {
1076
1082
  if (process.env.KODY_RUN_ID) {
1077
1083
  cachedRunId = process.env.KODY_RUN_ID;
@@ -1104,7 +1110,7 @@ function emitEvent(cwd, ev) {
1104
1110
  ...ev
1105
1111
  };
1106
1112
  const file = eventsPath(cwd, runId);
1107
- fs7.mkdirSync(path8.dirname(file), { recursive: true });
1113
+ fs7.mkdirSync(path9.dirname(file), { recursive: true });
1108
1114
  fs7.appendFileSync(file, `${JSON.stringify(fullEvent)}
1109
1115
  `);
1110
1116
  } catch {
@@ -1130,7 +1136,7 @@ function listRuns(cwd) {
1130
1136
  if (!fs7.existsSync(runsDir)) return [];
1131
1137
  return fs7.readdirSync(runsDir).filter((name) => {
1132
1138
  try {
1133
- return fs7.statSync(path8.join(runsDir, name)).isDirectory();
1139
+ return fs7.statSync(path9.join(runsDir, name)).isDirectory();
1134
1140
  } catch {
1135
1141
  return false;
1136
1142
  }
@@ -1171,10 +1177,10 @@ function abortMessage(signal) {
1171
1177
  return reason instanceof Error ? reason.message : typeof reason === "string" ? reason : "verification aborted";
1172
1178
  }
1173
1179
  function runCommand(command, cwd, signal) {
1174
- return new Promise((resolve23) => {
1180
+ return new Promise((resolve24) => {
1175
1181
  const start = Date.now();
1176
1182
  if (signal?.aborted) {
1177
- resolve23({ exitCode: -1, durationMs: 0, tail: abortMessage(signal) });
1183
+ resolve24({ exitCode: -1, durationMs: 0, tail: abortMessage(signal) });
1178
1184
  return;
1179
1185
  }
1180
1186
  const child = spawn(command, {
@@ -1212,7 +1218,7 @@ function runCommand(command, cwd, signal) {
1212
1218
  signal?.removeEventListener("abort", onAbort);
1213
1219
  const output = Buffer.concat(buffers).toString("utf-8");
1214
1220
  const tail = [output, extraTail].filter(Boolean).join("\n").slice(-TAIL_CHARS);
1215
- resolve23({ exitCode, durationMs: Date.now() - start, tail });
1221
+ resolve24({ exitCode, durationMs: Date.now() - start, tail });
1216
1222
  };
1217
1223
  const terminate = () => {
1218
1224
  killTree("SIGTERM");
@@ -1541,7 +1547,7 @@ function cmsHeaders(opts) {
1541
1547
  }
1542
1548
  };
1543
1549
  }
1544
- async function callDashboardCms(opts, path58, init = {}) {
1550
+ async function callDashboardCms(opts, path59, init = {}) {
1545
1551
  const baseUrl = dashboardBaseUrl(opts);
1546
1552
  if (!baseUrl) {
1547
1553
  return {
@@ -1553,7 +1559,7 @@ async function callDashboardCms(opts, path58, init = {}) {
1553
1559
  const headerResult = cmsHeaders(opts);
1554
1560
  if (!headerResult.ok) return headerResult;
1555
1561
  try {
1556
- const res = await fetch(`${baseUrl}${path58}`, {
1562
+ const res = await fetch(`${baseUrl}${path59}`, {
1557
1563
  ...init,
1558
1564
  headers: {
1559
1565
  ...headerResult.headers,
@@ -1625,8 +1631,8 @@ function documentArg(value) {
1625
1631
  function normalizeCmsDocumentIdInput(input) {
1626
1632
  const trimmed = stripWrappingQuotes(input.trim());
1627
1633
  const withoutQuery = trimmed.split(/[?#]/, 1)[0] ?? trimmed;
1628
- const path58 = parseDocumentPath(withoutQuery);
1629
- return path58 ?? parseDocumentIdSegment(withoutQuery) ?? withoutQuery;
1634
+ const path59 = parseDocumentPath(withoutQuery);
1635
+ return path59 ?? parseDocumentIdSegment(withoutQuery) ?? withoutQuery;
1630
1636
  }
1631
1637
  function stripWrappingQuotes(value) {
1632
1638
  let current = value;
@@ -1637,9 +1643,9 @@ function stripWrappingQuotes(value) {
1637
1643
  }
1638
1644
  }
1639
1645
  function parseDocumentPath(value) {
1640
- const path58 = value.startsWith("http://") || value.startsWith("https://") ? urlPathname(value) : value;
1641
- if (!path58?.includes("/content/entries/")) return null;
1642
- const parts = path58.split("/").filter(Boolean).map(decodePathPart);
1646
+ const path59 = value.startsWith("http://") || value.startsWith("https://") ? urlPathname(value) : value;
1647
+ if (!path59?.includes("/content/entries/")) return null;
1648
+ const parts = path59.split("/").filter(Boolean).map(decodePathPart);
1643
1649
  const entriesIndex = parts.findIndex((part, index) => part === "content" && parts[index + 1] === "entries");
1644
1650
  const idPart = parts[entriesIndex + 3];
1645
1651
  if (!idPart || idPart === "new") return null;
@@ -2085,7 +2091,7 @@ var init_issue = __esm({
2085
2091
 
2086
2092
  // src/capabilityFolders.ts
2087
2093
  import * as fs8 from "fs";
2088
- import * as path9 from "path";
2094
+ import * as path10 from "path";
2089
2095
  function capabilityOutputConditionPaths(config) {
2090
2096
  if (config.outputSchema) {
2091
2097
  return new Set(schemaPropertyPaths(config.outputSchema, "result"));
@@ -2107,35 +2113,35 @@ function listCapabilityFolderSlugs(absDir) {
2107
2113
  } catch {
2108
2114
  return [];
2109
2115
  }
2110
- return entries.filter((e) => e.isDirectory() && !e.name.startsWith("_") && !e.name.startsWith(".")).filter((e) => isCapabilityFolder(path9.join(absDir, e.name))).map((e) => e.name).sort();
2116
+ return entries.filter((e) => e.isDirectory() && !e.name.startsWith("_") && !e.name.startsWith(".")).filter((e) => isCapabilityFolder(path10.join(absDir, e.name))).map((e) => e.name).sort();
2111
2117
  }
2112
2118
  function isCapabilityFolder(dir) {
2113
2119
  const entries = fs8.readdirSync(dir, { withFileTypes: true });
2114
- const legacyBody = path9.join(dir, CAPABILITY_BODY_FILE);
2120
+ const legacyBody = path10.join(dir, CAPABILITY_BODY_FILE);
2115
2121
  if (fs8.existsSync(legacyBody)) {
2116
2122
  return entries.every(
2117
2123
  (entry) => entry.name === CAPABILITY_BODY_FILE || entry.name === CAPABILITY_CONTRACT_FILE || entry.isDirectory() && (entry.name === "skills" || entry.name === "tools")
2118
2124
  );
2119
2125
  }
2120
- const canonicalBody = path9.join(dir, CANONICAL_CAPABILITY_BODY_FILE);
2121
- const canonicalDefinition = path9.join(dir, CANONICAL_CAPABILITY_DEFINITION_FILE);
2126
+ const canonicalBody = path10.join(dir, CANONICAL_CAPABILITY_BODY_FILE);
2127
+ const canonicalDefinition = path10.join(dir, CANONICAL_CAPABILITY_DEFINITION_FILE);
2122
2128
  if (!fs8.existsSync(canonicalBody) || !fs8.existsSync(canonicalDefinition)) return false;
2123
2129
  return entries.every(
2124
2130
  (entry) => entry.name === CANONICAL_CAPABILITY_BODY_FILE || entry.name === CANONICAL_CAPABILITY_DEFINITION_FILE
2125
2131
  );
2126
2132
  }
2127
2133
  function readCapabilityFolder(root, slug) {
2128
- const dir = path9.join(root, slug);
2129
- const legacyBodyPath = path9.join(dir, CAPABILITY_BODY_FILE);
2130
- const canonicalBodyPath = path9.join(dir, CANONICAL_CAPABILITY_BODY_FILE);
2134
+ const dir = path10.join(root, slug);
2135
+ const legacyBodyPath = path10.join(dir, CAPABILITY_BODY_FILE);
2136
+ const canonicalBodyPath = path10.join(dir, CANONICAL_CAPABILITY_BODY_FILE);
2131
2137
  const bodyPath = fs8.existsSync(legacyBodyPath) ? legacyBodyPath : canonicalBodyPath;
2132
- const contractPath = path9.join(dir, CAPABILITY_CONTRACT_FILE);
2138
+ const contractPath = path10.join(dir, CAPABILITY_CONTRACT_FILE);
2133
2139
  if (!fs8.existsSync(bodyPath) || !fs8.statSync(bodyPath).isFile()) return null;
2134
2140
  if (!isCapabilityFolder(dir)) return null;
2135
2141
  try {
2136
2142
  const rawBody = fs8.readFileSync(bodyPath, "utf-8");
2137
2143
  if (bodyPath === canonicalBodyPath) {
2138
- const definitionPath = path9.join(dir, CANONICAL_CAPABILITY_DEFINITION_FILE);
2144
+ const definitionPath = path10.join(dir, CANONICAL_CAPABILITY_DEFINITION_FILE);
2139
2145
  const definition = JSON.parse(fs8.readFileSync(definitionPath, "utf-8"));
2140
2146
  if (definition.id !== slug || typeof definition.action !== "string") return null;
2141
2147
  const { title: title2, body: body2 } = parseCapabilityBody(rawBody, slug);
@@ -2157,7 +2163,7 @@ function readCapabilityFolder(root, slug) {
2157
2163
  };
2158
2164
  }
2159
2165
  const contract = fs8.existsSync(contractPath) ? parseCapabilityContract(fs8.readFileSync(contractPath, "utf-8")) : void 0;
2160
- if (contract?.execution === "script" && !isRegularFile(path9.join(dir, "tools", "run.sh"))) {
2166
+ if (contract?.execution === "script" && !isRegularFile(path10.join(dir, "tools", "run.sh"))) {
2161
2167
  throw new Error('script-backed Capability requires a regular "tools/run.sh" file');
2162
2168
  }
2163
2169
  const { title, body } = parseCapabilityBody(rawBody, slug);
@@ -2279,8 +2285,8 @@ function isRegularFile(filePath) {
2279
2285
  function schemaPropertyPaths(schema, prefix) {
2280
2286
  const properties = isPlainObject(schema.properties) ? schema.properties : {};
2281
2287
  return Object.entries(properties).flatMap(([name, property]) => {
2282
- const path58 = `${prefix}.${name}`;
2283
- return isPlainObject(property) ? [path58, ...schemaPropertyPaths(property, path58)] : [path58];
2288
+ const path59 = `${prefix}.${name}`;
2289
+ return isPlainObject(property) ? [path59, ...schemaPropertyPaths(property, path59)] : [path59];
2284
2290
  });
2285
2291
  }
2286
2292
  function parseCapabilityBody(raw, slug) {
@@ -2447,47 +2453,47 @@ var init_capabilityFolders = __esm({
2447
2453
 
2448
2454
  // src/definition-paths.ts
2449
2455
  import * as fs9 from "fs";
2450
- import * as path10 from "path";
2456
+ import * as path11 from "path";
2451
2457
  function definitionsRoot(cwd = process.cwd()) {
2452
2458
  const override = process.env.KODY_DEFINITIONS_ROOT?.trim();
2453
2459
  const overrideCwd = process.env.KODY_DEFINITIONS_ROOT_CWD?.trim();
2454
- if (override && overrideCwd && path10.resolve(cwd) === path10.resolve(overrideCwd)) {
2455
- return storeCatalogRoot(path10.resolve(override));
2460
+ if (override && overrideCwd && path11.resolve(cwd) === path11.resolve(overrideCwd)) {
2461
+ return storeCatalogRoot(path11.resolve(override));
2456
2462
  }
2457
- const hydrated = path10.join(cwd, ".kody-engine", "definitions");
2463
+ const hydrated = path11.join(cwd, ".kody-engine", "definitions");
2458
2464
  if (fs9.existsSync(hydrated)) return hydrated;
2459
- return override ? storeCatalogRoot(path10.resolve(override)) : hydrated;
2465
+ return override ? storeCatalogRoot(path11.resolve(override)) : hydrated;
2460
2466
  }
2461
2467
  function hasExplicitDefinitionsRoot(cwd = process.cwd(), env = process.env) {
2462
2468
  const root = env.KODY_DEFINITIONS_ROOT?.trim();
2463
2469
  const rootCwd = env.KODY_DEFINITIONS_ROOT_CWD?.trim();
2464
- return Boolean(root && rootCwd && path10.resolve(cwd) === path10.resolve(rootCwd));
2470
+ return Boolean(root && rootCwd && path11.resolve(cwd) === path11.resolve(rootCwd));
2465
2471
  }
2466
2472
  function capabilitiesRoot(cwd = process.cwd()) {
2467
- return storeAssetRoot(cwd, "capabilities") ?? path10.join(definitionsRoot(cwd), "capabilities");
2473
+ return storeAssetRoot(cwd, "capabilities") ?? path11.join(definitionsRoot(cwd), "capabilities");
2468
2474
  }
2469
2475
  function implementationsRoot(cwd = process.cwd()) {
2470
- return path10.join(definitionsRoot(cwd), "implementations");
2476
+ return path11.join(definitionsRoot(cwd), "implementations");
2471
2477
  }
2472
2478
  function agentsRoot(cwd = process.cwd()) {
2473
- return storeAssetRoot(cwd, "agent") ?? path10.join(definitionsRoot(cwd), "agents");
2479
+ return storeAssetRoot(cwd, "agent") ?? path11.join(definitionsRoot(cwd), "agents");
2474
2480
  }
2475
2481
  function storeCatalogRoot(root) {
2476
2482
  const manifest = readStoreManifest(root);
2477
- const roots = ["capabilities", "workflows", "loops"].map((kind) => manifest?.assetRoots?.[kind]).filter((value) => typeof value === "string" && Boolean(value.trim())).map((value) => path10.dirname(value));
2478
- return roots.length === 3 && new Set(roots).size === 1 ? path10.join(root, roots[0]) : root;
2483
+ const roots = ["capabilities", "workflows", "loops"].map((kind) => manifest?.assetRoots?.[kind]).filter((value) => typeof value === "string" && Boolean(value.trim())).map((value) => path11.dirname(value));
2484
+ return roots.length === 3 && new Set(roots).size === 1 ? path11.join(root, roots[0]) : root;
2479
2485
  }
2480
2486
  function storeAssetRoot(cwd, kind) {
2481
2487
  const override = process.env.KODY_DEFINITIONS_ROOT?.trim();
2482
2488
  if (!override) return null;
2483
2489
  const overrideCwd = process.env.KODY_DEFINITIONS_ROOT_CWD?.trim();
2484
- if (overrideCwd && path10.resolve(cwd) !== path10.resolve(overrideCwd)) return null;
2485
- const root = path10.resolve(override);
2490
+ if (overrideCwd && path11.resolve(cwd) !== path11.resolve(overrideCwd)) return null;
2491
+ const root = path11.resolve(override);
2486
2492
  const configured = readStoreManifest(root)?.assetRoots?.[kind];
2487
- return typeof configured === "string" && configured.trim() ? path10.join(root, configured) : null;
2493
+ return typeof configured === "string" && configured.trim() ? path11.join(root, configured) : null;
2488
2494
  }
2489
2495
  function readStoreManifest(root) {
2490
- const file = path10.join(root, "kody-store.json");
2496
+ const file = path11.join(root, "kody-store.json");
2491
2497
  if (!fs9.existsSync(file)) return null;
2492
2498
  try {
2493
2499
  return JSON.parse(fs9.readFileSync(file, "utf8"));
@@ -2503,15 +2509,15 @@ var init_definition_paths = __esm({
2503
2509
 
2504
2510
  // src/registry.ts
2505
2511
  import * as fs10 from "fs";
2506
- import * as path11 from "path";
2512
+ import * as path12 from "path";
2507
2513
  function getImplementationsRoot() {
2508
- const here = path11.dirname(new URL(import.meta.url).pathname);
2514
+ const here = path12.dirname(new URL(import.meta.url).pathname);
2509
2515
  const candidates = [
2510
- path11.join(here, "implementations"),
2516
+ path12.join(here, "implementations"),
2511
2517
  // dev: src/
2512
- path11.join(here, "..", "implementations"),
2518
+ path12.join(here, "..", "implementations"),
2513
2519
  // built: dist/bin → dist/implementations
2514
- path11.join(here, "..", "src", "implementations")
2520
+ path12.join(here, "..", "src", "implementations")
2515
2521
  // fallback
2516
2522
  ];
2517
2523
  for (const c of candidates) {
@@ -2520,11 +2526,11 @@ function getImplementationsRoot() {
2520
2526
  return candidates[0];
2521
2527
  }
2522
2528
  function getRuntimeServicesRoot() {
2523
- const here = path11.dirname(new URL(import.meta.url).pathname);
2529
+ const here = path12.dirname(new URL(import.meta.url).pathname);
2524
2530
  const candidates = [
2525
- path11.join(here, "runtime-services"),
2526
- path11.join(here, "..", "runtime-services"),
2527
- path11.join(here, "..", "src", "runtime-services")
2531
+ path12.join(here, "runtime-services"),
2532
+ path12.join(here, "..", "runtime-services"),
2533
+ path12.join(here, "..", "src", "runtime-services")
2528
2534
  ];
2529
2535
  for (const candidate of candidates) {
2530
2536
  if (fs10.existsSync(candidate) && fs10.statSync(candidate).isDirectory()) return candidate;
@@ -2535,13 +2541,13 @@ function getProjectCapabilitiesRoot() {
2535
2541
  return capabilitiesRoot();
2536
2542
  }
2537
2543
  function getBuiltinCapabilitiesRoot() {
2538
- const here = path11.dirname(new URL(import.meta.url).pathname);
2544
+ const here = path12.dirname(new URL(import.meta.url).pathname);
2539
2545
  const candidates = [
2540
- path11.join(here, "capabilities"),
2546
+ path12.join(here, "capabilities"),
2541
2547
  // dev: src/
2542
- path11.join(here, "..", "capabilities"),
2548
+ path12.join(here, "..", "capabilities"),
2543
2549
  // built: dist/bin → dist/capabilities
2544
- path11.join(here, "..", "src", "capabilities")
2550
+ path12.join(here, "..", "src", "capabilities")
2545
2551
  // fallback
2546
2552
  ];
2547
2553
  for (const c of candidates) {
@@ -2685,17 +2691,17 @@ function isSafeName(name) {
2685
2691
  return /^[a-z][a-z0-9-]*$/.test(name) && !name.includes("..");
2686
2692
  }
2687
2693
  function isCapabilityRoot(root) {
2688
- const normalized = path11.normalize(root);
2689
- if (path11.basename(normalized) === "capabilities") return true;
2694
+ const normalized = path12.normalize(root);
2695
+ if (path12.basename(normalized) === "capabilities") return true;
2690
2696
  const knownRoots = [getProjectCapabilitiesRoot(), getBuiltinCapabilitiesRoot()];
2691
- return knownRoots.some((candidate) => candidate && path11.normalize(candidate) === normalized);
2697
+ return knownRoots.some((candidate) => candidate && path12.normalize(candidate) === normalized);
2692
2698
  }
2693
2699
  function implementationRuntimePath(root, name) {
2694
- const runtimePath = path11.join(root, name, "runtime.json");
2700
+ const runtimePath = path12.join(root, name, "runtime.json");
2695
2701
  if (fs10.existsSync(runtimePath)) return runtimePath;
2696
- const internalProfilePath = path11.join(root, name, "profile.json");
2702
+ const internalProfilePath = path12.join(root, name, "profile.json");
2697
2703
  if (fs10.existsSync(internalProfilePath)) return internalProfilePath;
2698
- return path11.join(root, name, CAPABILITY_PROFILE_FILE);
2704
+ return path12.join(root, name, CAPABILITY_PROFILE_FILE);
2699
2705
  }
2700
2706
  function isImplementationProfile(profilePath, requireImplementationProfile) {
2701
2707
  if (!requireImplementationProfile) return true;
@@ -3862,7 +3868,7 @@ var init_capabilityMcp = __esm({
3862
3868
  // src/repoWorkspace.ts
3863
3869
  import { spawn as spawn2, spawnSync } from "child_process";
3864
3870
  import * as fs11 from "fs";
3865
- import * as path12 from "path";
3871
+ import * as path13 from "path";
3866
3872
  function buildCloneProcess(repo, token, baseEnv = process.env) {
3867
3873
  const url = `https://github.com/${repo}.git`;
3868
3874
  const env = { ...baseEnv };
@@ -3877,10 +3883,10 @@ function buildCloneProcess(repo, token, baseEnv = process.env) {
3877
3883
  async function resolveAndClone(reposRoot, repo, repoToken, cloneRepo) {
3878
3884
  const name = repo?.trim();
3879
3885
  if (!name || !REPO_RE.test(name)) return null;
3880
- const root = path12.resolve(reposRoot);
3881
- const dir = path12.resolve(root, name);
3882
- if (dir !== root && !dir.startsWith(root + path12.sep)) return null;
3883
- if (fs11.existsSync(path12.join(dir, ".git"))) return dir;
3886
+ const root = path13.resolve(reposRoot);
3887
+ const dir = path13.resolve(root, name);
3888
+ if (dir !== root && !dir.startsWith(root + path13.sep)) return null;
3889
+ if (fs11.existsSync(path13.join(dir, ".git"))) return dir;
3884
3890
  const inflight = repoClones.get(dir);
3885
3891
  if (inflight) {
3886
3892
  await inflight;
@@ -3912,9 +3918,9 @@ var init_repoWorkspace = __esm({
3912
3918
  repoClones = /* @__PURE__ */ new Map();
3913
3919
  GIT_CREDENTIAL_HELPER = `!f() { if [ "$1" = get ] && [ -n "$GITHUB_TOKEN" ]; then printf '%s\\n' username=x-access-token "password=$GITHUB_TOKEN"; fi; }; f`;
3914
3920
  defaultCloneRepo = (repo, token, dir) => {
3915
- fs11.mkdirSync(path12.dirname(dir), { recursive: true });
3921
+ fs11.mkdirSync(path13.dirname(dir), { recursive: true });
3916
3922
  const clone = buildCloneProcess(repo, token);
3917
- return new Promise((resolve23, reject) => {
3923
+ return new Promise((resolve24, reject) => {
3918
3924
  const child = spawn2("git", ["clone", "--depth=1", clone.url, dir], {
3919
3925
  env: clone.env,
3920
3926
  stdio: "inherit"
@@ -3934,7 +3940,7 @@ var init_repoWorkspace = __esm({
3934
3940
  }
3935
3941
  } catch {
3936
3942
  }
3937
- resolve23();
3943
+ resolve24();
3938
3944
  });
3939
3945
  child.on("error", reject);
3940
3946
  });
@@ -4007,7 +4013,7 @@ var init_fetchRepoMcp = __esm({
4007
4013
 
4008
4014
  // src/agent.ts
4009
4015
  import * as fs12 from "fs";
4010
- import * as path13 from "path";
4016
+ import * as path14 from "path";
4011
4017
  import { query } from "@anthropic-ai/claude-agent-sdk";
4012
4018
  function classifySubtype(subtype) {
4013
4019
  if (!subtype) return "generic_failed";
@@ -4077,7 +4083,7 @@ function buildAgentEnvironment(baseEnv, repoToken, requestEnvironment) {
4077
4083
  async function runAgent(opts) {
4078
4084
  const ndjsonDir = opts.ndjsonDir ?? agentRunDir(opts.cwd);
4079
4085
  fs12.mkdirSync(ndjsonDir, { recursive: true });
4080
- const ndjsonPath = path13.join(ndjsonDir, "last-run.jsonl");
4086
+ const ndjsonPath = path14.join(ndjsonDir, "last-run.jsonl");
4081
4087
  const env = buildAgentEnvironment(process.env, opts.repoToken, opts.environment);
4082
4088
  if (opts.litellmUrl) {
4083
4089
  env.ANTHROPIC_BASE_URL = opts.litellmUrl;
@@ -4085,7 +4091,11 @@ async function runAgent(opts) {
4085
4091
  }
4086
4092
  const startedAt = Date.now();
4087
4093
  const turnTimeoutMs = resolveTurnTimeoutMs(opts);
4088
- const completionGuard = typeof opts.deadlineAtMs === "number" ? createCompletionToolGuard(completionToolCutoffAt(startedAt, opts.deadlineAtMs)) : null;
4094
+ const completionGuard = typeof opts.deadlineAtMs === "number" ? createCompletionToolGuard(
4095
+ completionToolCutoffAt(startedAt, opts.deadlineAtMs),
4096
+ Date.now,
4097
+ opts.outputContract?.path
4098
+ ) : null;
4089
4099
  let outcome = "failed";
4090
4100
  let outcomeKind = "generic_failed";
4091
4101
  let errorMessage2;
@@ -4294,10 +4304,10 @@ async function runAgent(opts) {
4294
4304
  let timer;
4295
4305
  let next;
4296
4306
  if (turnTimeoutMs > 0) {
4297
- const timeoutPromise = new Promise((resolve23) => {
4307
+ const timeoutPromise = new Promise((resolve24) => {
4298
4308
  timer = setTimeout(() => {
4299
4309
  timedOut = true;
4300
- resolve23({ done: true, value: void 0 });
4310
+ resolve24({ done: true, value: void 0 });
4301
4311
  }, turnTimeoutMs);
4302
4312
  });
4303
4313
  next = await Promise.race([nextPromise, timeoutPromise]);
@@ -4313,7 +4323,7 @@ async function runAgent(opts) {
4313
4323
  try {
4314
4324
  await Promise.race([
4315
4325
  iterator.return(void 0).catch(() => void 0),
4316
- new Promise((resolve23) => setTimeout(resolve23, 1e4).unref())
4326
+ new Promise((resolve24) => setTimeout(resolve24, 1e4).unref())
4317
4327
  ]);
4318
4328
  } catch {
4319
4329
  }
@@ -4520,7 +4530,7 @@ var init_agent = __esm({
4520
4530
 
4521
4531
  // src/agents.ts
4522
4532
  import * as fs13 from "fs";
4523
- import * as path14 from "path";
4533
+ import * as path15 from "path";
4524
4534
  function stripFrontmatter(raw) {
4525
4535
  const match = /^---\n[\s\S]*?\n---\n?([\s\S]*)$/.exec(raw);
4526
4536
  return (match ? match[1] : raw).trim();
@@ -4541,7 +4551,7 @@ function loadAgentIdentity(cwd, slug, agentsDir = agentsRoot(cwd)) {
4541
4551
  throw new Error(`loadAgentIdentity: agent '${trimmed}' declared but ${agentPath} does not exist`);
4542
4552
  }
4543
4553
  function resolveAgentFile2(cwd, slug, agentsDir = agentsRoot(cwd)) {
4544
- const localPath = path14.resolve(cwd, agentsDir, `${slug}.md`);
4554
+ const localPath = path15.resolve(cwd, agentsDir, `${slug}.md`);
4545
4555
  if (fs13.existsSync(localPath)) return localPath;
4546
4556
  return localPath;
4547
4557
  }
@@ -4575,7 +4585,7 @@ var init_agents = __esm({
4575
4585
 
4576
4586
  // src/task-artifacts.ts
4577
4587
  import fs14 from "fs";
4578
- import path15 from "path";
4588
+ import path16 from "path";
4579
4589
  import posixPath from "path/posix";
4580
4590
  function prepareTaskArtifactsDir(cwd, taskId) {
4581
4591
  const safeId = String(taskId).replace(/[^a-zA-Z0-9._-]/g, "_");
@@ -4611,14 +4621,14 @@ function initializeTaskArtifacts(artifacts, metadata = { taskType: "job" }) {
4611
4621
  "handoff-notes.md": "Baseline handoff: the agent did not provide additional notes.\n"
4612
4622
  };
4613
4623
  for (const file of TASK_ARTIFACT_FILES) {
4614
- const full = path15.join(artifacts.absDir, file);
4624
+ const full = path16.join(artifacts.absDir, file);
4615
4625
  if (!fs14.existsSync(full)) fs14.writeFileSync(full, defaults[file], "utf8");
4616
4626
  }
4617
4627
  }
4618
4628
  function verifyTaskArtifacts(absDir) {
4619
4629
  const missing = [];
4620
4630
  for (const name of TASK_ARTIFACT_FILES) {
4621
- const full = path15.join(absDir, name);
4631
+ const full = path16.join(absDir, name);
4622
4632
  try {
4623
4633
  const stat = fs14.statSync(full);
4624
4634
  if (!stat.isFile() || stat.size === 0) missing.push(name);
@@ -4636,7 +4646,7 @@ async function persistTaskArtifactsToState(config, _cwd, artifacts) {
4636
4646
  if (hasStateBackendConfig() && tenantId2) {
4637
4647
  const backend = createStateBackendFromEnv();
4638
4648
  for (const file of TASK_ARTIFACT_FILES) {
4639
- const full = path15.join(artifacts.absDir, file);
4649
+ const full = path16.join(artifacts.absDir, file);
4640
4650
  if (!fs14.existsSync(full)) continue;
4641
4651
  const stat = fs14.statSync(full);
4642
4652
  if (!stat.isFile() || stat.size === 0) continue;
@@ -4949,15 +4959,15 @@ function validateWorkflow(value, options = {}) {
4949
4959
  }
4950
4960
  return issues;
4951
4961
  }
4952
- function validateInputBindings(value, path58, issues, declaredInputs) {
4962
+ function validateInputBindings(value, path59, issues, declaredInputs) {
4953
4963
  if (value === void 0) return;
4954
4964
  const bindings = asRecord(value);
4955
4965
  if (!bindings || Object.keys(bindings).length === 0) {
4956
- issue(issues, "invalid_inputs", path58, "workflow step inputs must contain at least one named mapping");
4966
+ issue(issues, "invalid_inputs", path59, "workflow step inputs must contain at least one named mapping");
4957
4967
  return;
4958
4968
  }
4959
4969
  for (const [name, value2] of Object.entries(bindings)) {
4960
- const bindingPath = `${path58}.${name}`;
4970
+ const bindingPath = `${path59}.${name}`;
4961
4971
  if (!/^[A-Za-z_][A-Za-z0-9_-]*$/.test(name)) {
4962
4972
  issue(issues, "invalid_input_name", bindingPath, `workflow input name ${name} is invalid`);
4963
4973
  }
@@ -4976,7 +4986,7 @@ function validateInputBindings(value, path58, issues, declaredInputs) {
4976
4986
  }
4977
4987
  }
4978
4988
  }
4979
- function validateInputBindingSources(value, path58, issues, capabilitiesByStep, capabilityOutputs) {
4989
+ function validateInputBindingSources(value, path59, issues, capabilitiesByStep, capabilityOutputs) {
4980
4990
  const bindings = asRecord(value);
4981
4991
  if (!bindings) return;
4982
4992
  for (const [name, rawBinding] of Object.entries(bindings)) {
@@ -4989,7 +4999,7 @@ function validateInputBindingSources(value, path58, issues, capabilitiesByStep,
4989
4999
  issue(
4990
5000
  issues,
4991
5001
  "missing_input_step",
4992
- `${path58}.${name}.from`,
5002
+ `${path59}.${name}.from`,
4993
5003
  `workflow input mapping references missing step ${sourceStep ?? "<none>"}`
4994
5004
  );
4995
5005
  continue;
@@ -5000,7 +5010,7 @@ function validateInputBindingSources(value, path58, issues, capabilitiesByStep,
5000
5010
  issue(
5001
5011
  issues,
5002
5012
  "undeclared_step_output",
5003
- `${path58}.${name}.from`,
5013
+ `${path59}.${name}.from`,
5004
5014
  `workflow input mapping reads ${outputPath}, but step ${sourceStep} does not declare it`
5005
5015
  );
5006
5016
  }
@@ -5009,11 +5019,11 @@ function validateInputBindingSources(value, path58, issues, capabilitiesByStep,
5009
5019
  function formatWorkflowValidationIssues(issues) {
5010
5020
  return issues.map((entry) => `${entry.path}: ${entry.message}`);
5011
5021
  }
5012
- function validateDataMatch(value, path58, issues, capabilityOutputs) {
5022
+ function validateDataMatch(value, path59, issues, capabilityOutputs) {
5013
5023
  if (value === void 0) return;
5014
5024
  const match = asRecord(value);
5015
5025
  if (!match || Object.keys(match).length === 0) {
5016
- issue(issues, "invalid_condition", path58, "workflow condition must contain at least one match");
5026
+ issue(issues, "invalid_condition", path59, "workflow condition must contain at least one match");
5017
5027
  return;
5018
5028
  }
5019
5029
  for (const [field, expected] of Object.entries(match)) {
@@ -5021,7 +5031,7 @@ function validateDataMatch(value, path58, issues, capabilityOutputs) {
5021
5031
  issue(
5022
5032
  issues,
5023
5033
  "invalid_data_path",
5024
- `${path58}.${field}`,
5034
+ `${path59}.${field}`,
5025
5035
  `workflow condition must read from facts, evidence, artifacts, result, workflow, or lastOutcome`
5026
5036
  );
5027
5037
  }
@@ -5029,12 +5039,12 @@ function validateDataMatch(value, path58, issues, capabilityOutputs) {
5029
5039
  issue(
5030
5040
  issues,
5031
5041
  "undeclared_result_path",
5032
- `${path58}.${field}`,
5042
+ `${path59}.${field}`,
5033
5043
  `workflow condition reads ${field}, but the source capability does not declare it`
5034
5044
  );
5035
5045
  }
5036
5046
  if (!isComparable(expected)) {
5037
- issue(issues, "invalid_condition_value", `${path58}.${field}`, "workflow condition value must be a JSON scalar");
5047
+ issue(issues, "invalid_condition_value", `${path59}.${field}`, "workflow condition value must be a JSON scalar");
5038
5048
  }
5039
5049
  }
5040
5050
  }
@@ -5058,8 +5068,8 @@ function isJsonValue(value) {
5058
5068
  if (!value || typeof value !== "object") return false;
5059
5069
  return Object.values(value).every(isJsonValue);
5060
5070
  }
5061
- function issue(issues, code, path58, message) {
5062
- issues.push({ code, path: path58, message });
5071
+ function issue(issues, code, path59, message) {
5072
+ issues.push({ code, path: path59, message });
5063
5073
  }
5064
5074
  var SAFE_NAME, SAFE_STEP_ID, SAFE_DATA_PATH, SAFE_INPUT_SOURCE, SUPPORTED_STEP_FIELDS, SUPPORTED_TRANSITION_FIELDS;
5065
5075
  var init_workflowValidation = __esm({
@@ -5093,7 +5103,7 @@ var init_workflowValidation = __esm({
5093
5103
 
5094
5104
  // src/workflowDefinitions.ts
5095
5105
  import * as fs20 from "fs";
5096
- import * as path21 from "path";
5106
+ import * as path22 from "path";
5097
5107
  function isWorkflowDefinitionId(value) {
5098
5108
  return WORKFLOW_ID_PATTERN.test(value);
5099
5109
  }
@@ -5138,8 +5148,8 @@ function readWorkflowDefinition(_config, cwd, id) {
5138
5148
  const root = cwd ?? process.cwd();
5139
5149
  const relativePath = workflowDefinitionPath(id);
5140
5150
  const candidates = [
5141
- path21.join(root, ".kody-engine", "runtime", relativePath),
5142
- path21.join(definitionsRoot(root), relativePath)
5151
+ path22.join(root, ".kody-engine", "runtime", relativePath),
5152
+ path22.join(definitionsRoot(root), relativePath)
5143
5153
  ];
5144
5154
  for (const filePath of candidates) {
5145
5155
  if (!fs20.existsSync(filePath)) continue;
@@ -5151,7 +5161,7 @@ function readWorkflowDefinition(_config, cwd, id) {
5151
5161
  function workflowDefinitionToCapabilityFolder(id, workflow, source = workflowDefinitionPath(id)) {
5152
5162
  return {
5153
5163
  slug: id,
5154
- dir: path21.dirname(source),
5164
+ dir: path22.dirname(source),
5155
5165
  profilePath: source,
5156
5166
  bodyPath: source,
5157
5167
  title: workflow.name,
@@ -5752,7 +5762,7 @@ var init_lifecycles = __esm({
5752
5762
  // src/profile.ts
5753
5763
  import { createHash as createHash3 } from "crypto";
5754
5764
  import * as fs24 from "fs";
5755
- import * as path23 from "path";
5765
+ import * as path24 from "path";
5756
5766
  function loadProfile(profilePath) {
5757
5767
  if (!fs24.existsSync(profilePath)) {
5758
5768
  throw new ProfileError(profilePath, "file not found");
@@ -5771,7 +5781,7 @@ function loadProfile(profilePath) {
5771
5781
  const unknownKeys = Object.keys(r).filter((k) => !KNOWN_PROFILE_KEYS.has(k));
5772
5782
  if (unknownKeys.length > 0) {
5773
5783
  process.stderr.write(
5774
- `[kody profile] ${path23.basename(path23.dirname(profilePath))}: unknown top-level keys ignored: ${unknownKeys.join(", ")}
5784
+ `[kody profile] ${path24.basename(path24.dirname(profilePath))}: unknown top-level keys ignored: ${unknownKeys.join(", ")}
5775
5785
  `
5776
5786
  );
5777
5787
  }
@@ -5781,7 +5791,7 @@ function loadProfile(profilePath) {
5781
5791
  if (!refPath) {
5782
5792
  throw new ProfileError(profilePath, `capability references unknown implementation '${execRef}'`);
5783
5793
  }
5784
- if (path23.resolve(refPath) === path23.resolve(profilePath)) {
5794
+ if (path24.resolve(refPath) === path24.resolve(profilePath)) {
5785
5795
  } else {
5786
5796
  const base = loadProfile(refPath);
5787
5797
  return {
@@ -5879,8 +5889,8 @@ function loadProfile(profilePath) {
5879
5889
  // Phase 5 in-process handoff opt-in. Default false; containers
5880
5890
  // flip to true after end-to-end verification.
5881
5891
  preloadContext: r.preloadContext === true,
5882
- dir: path23.dirname(profilePath),
5883
- promptTemplates: readPromptTemplates(path23.dirname(profilePath))
5892
+ dir: path24.dirname(profilePath),
5893
+ promptTemplates: readPromptTemplates(path24.dirname(profilePath))
5884
5894
  };
5885
5895
  if (lifecycle) {
5886
5896
  applyLifecycle(profile, profilePath);
@@ -5915,19 +5925,19 @@ function loadProfile(profilePath) {
5915
5925
  return profile;
5916
5926
  }
5917
5927
  function compileRuntimeDocument(runtimePath, document) {
5918
- if (path23.basename(runtimePath) !== "runtime.json") return document;
5928
+ if (path24.basename(runtimePath) !== "runtime.json") return document;
5919
5929
  if (document.adapter !== "kody-engine-profile") {
5920
5930
  throw new ProfileError(runtimePath, "unsupported runtime adapter document");
5921
5931
  }
5922
- const implementationDir = path23.dirname(runtimePath);
5923
- const implementation = readJsonObject(path23.join(implementationDir, "definition.json"), "Implementation definition");
5924
- const definitionsRoot2 = path23.dirname(path23.dirname(implementationDir));
5932
+ const implementationDir = path24.dirname(runtimePath);
5933
+ const implementation = readJsonObject(path24.join(implementationDir, "definition.json"), "Implementation definition");
5934
+ const definitionsRoot2 = path24.dirname(path24.dirname(implementationDir));
5925
5935
  const capabilityId = implementation.capabilityRef && typeof implementation.capabilityRef === "object" && !Array.isArray(implementation.capabilityRef) ? implementation.capabilityRef.id : void 0;
5926
5936
  if (typeof capabilityId !== "string" || !capabilityId) {
5927
5937
  throw new ProfileError(runtimePath, "Implementation capabilityRef is invalid");
5928
5938
  }
5929
5939
  const capability = readJsonObject(
5930
- path23.join(definitionsRoot2, "capabilities", capabilityId, "definition.json"),
5940
+ path24.join(definitionsRoot2, "capabilities", capabilityId, "definition.json"),
5931
5941
  "Capability definition"
5932
5942
  );
5933
5943
  const {
@@ -5988,13 +5998,13 @@ function readPromptTemplates(dir) {
5988
5998
  } catch {
5989
5999
  }
5990
6000
  };
5991
- read(path23.join(dir, "prompt.md"));
5992
- read(path23.join(dir, "capability.md"));
5993
- read(path23.join(dir, "capability.md"));
6001
+ read(path24.join(dir, "prompt.md"));
6002
+ read(path24.join(dir, "capability.md"));
6003
+ read(path24.join(dir, "capability.md"));
5994
6004
  try {
5995
- const promptsDir = path23.join(dir, "prompts");
6005
+ const promptsDir = path24.join(dir, "prompts");
5996
6006
  for (const ent of fs24.readdirSync(promptsDir)) {
5997
- if (ent.endsWith(".md")) read(path23.join(promptsDir, ent));
6007
+ if (ent.endsWith(".md")) read(path24.join(promptsDir, ent));
5998
6008
  }
5999
6009
  } catch {
6000
6010
  }
@@ -6772,11 +6782,11 @@ var init_state = __esm({
6772
6782
 
6773
6783
  // src/prompt.ts
6774
6784
  import * as fs25 from "fs";
6775
- import * as path24 from "path";
6785
+ import * as path25 from "path";
6776
6786
  function loadProjectConventions(projectDir) {
6777
6787
  const out = [];
6778
6788
  for (const rel of CONVENTION_FILES) {
6779
- const abs = path24.join(projectDir, rel);
6789
+ const abs = path25.join(projectDir, rel);
6780
6790
  if (!fs25.existsSync(abs)) continue;
6781
6791
  let content;
6782
6792
  try {
@@ -7016,7 +7026,7 @@ __export(loadMemoryContext_exports, {
7016
7026
  loadMemoryContext: () => loadMemoryContext
7017
7027
  });
7018
7028
  import * as fs26 from "fs";
7019
- import * as path25 from "path";
7029
+ import * as path26 from "path";
7020
7030
  function formatBlockFromBackend(docs) {
7021
7031
  const pages = docs.flatMap((record2) => {
7022
7032
  if (!record2.doc || typeof record2.doc !== "object") return [];
@@ -7050,10 +7060,10 @@ function collectPages(memoryAbs) {
7050
7060
  return;
7051
7061
  }
7052
7062
  const fm = raw.match(/^---\s*\n([\s\S]*?)\n---/);
7053
- const title = fm?.[1]?.match(/^title:\s*(.+)$/m)?.[1]?.trim() ?? path25.basename(file, ".md");
7063
+ const title = fm?.[1]?.match(/^title:\s*(.+)$/m)?.[1]?.trim() ?? path26.basename(file, ".md");
7054
7064
  const updated = fm?.[1]?.match(/^updated:\s*([0-9T:.+\-Z]+)/m)?.[1]?.trim() ?? "";
7055
7065
  out.push({
7056
- relPath: path25.relative(memoryAbs, file),
7066
+ relPath: path26.relative(memoryAbs, file),
7057
7067
  title,
7058
7068
  updated,
7059
7069
  content: raw.length > PER_PAGE_MAX_BYTES ? raw.slice(0, PER_PAGE_MAX_BYTES) + TRUNCATED_SUFFIX2 : raw,
@@ -7127,7 +7137,7 @@ function walkMd(root, visit) {
7127
7137
  }
7128
7138
  for (const name of names) {
7129
7139
  if (name.startsWith(".")) continue;
7130
- const full = path25.join(dir, name);
7140
+ const full = path26.join(dir, name);
7131
7141
  let stat;
7132
7142
  try {
7133
7143
  stat = fs26.statSync(full);
@@ -7165,7 +7175,7 @@ var init_loadMemoryContext = __esm({
7165
7175
  }
7166
7176
  return;
7167
7177
  }
7168
- const memoryAbs = path25.join(ctx.cwd, MEMORY_DIR_RELATIVE);
7178
+ const memoryAbs = path26.join(ctx.cwd, MEMORY_DIR_RELATIVE);
7169
7179
  if (!fs26.existsSync(memoryAbs)) {
7170
7180
  ctx.data.memoryContext = "";
7171
7181
  return;
@@ -7681,7 +7691,7 @@ import { execFileSync as execFileSync4, spawn as spawn4 } from "child_process";
7681
7691
  import * as fs28 from "fs";
7682
7692
  import * as net from "net";
7683
7693
  import * as os4 from "os";
7684
- import * as path26 from "path";
7694
+ import * as path27 from "path";
7685
7695
  async function checkLitellmHealth(url) {
7686
7696
  try {
7687
7697
  const response = await fetch(`${url}/health`, { signal: AbortSignal.timeout(3e3) });
@@ -7794,10 +7804,10 @@ async function startLitellmIfNeeded(model, projectDir, url = LITELLM_DEFAULT_URL
7794
7804
  const spawnProxy = () => {
7795
7805
  const portMatch = activeUrl.match(/:(\d+)/);
7796
7806
  const port = portMatch ? portMatch[1] : "4000";
7797
- const configPath = path26.join(os4.tmpdir(), `kody-local-litellm-${Date.now()}.yaml`);
7807
+ const configPath = path27.join(os4.tmpdir(), `kody-local-litellm-${Date.now()}.yaml`);
7798
7808
  fs28.writeFileSync(configPath, generateLitellmConfigYaml(model));
7799
7809
  const args = ["--config", configPath, "--port", port];
7800
- const nextLogPath = path26.join(os4.tmpdir(), `kody-local-litellm-${Date.now()}.log`);
7810
+ const nextLogPath = path27.join(os4.tmpdir(), `kody-local-litellm-${Date.now()}.log`);
7801
7811
  const outFd = fs28.openSync(nextLogPath, "w");
7802
7812
  child = spawn4(cmd, args, { stdio: ["ignore", outFd, outFd], detached: true, env: childEnv });
7803
7813
  fs28.closeSync(outFd);
@@ -7887,17 +7897,17 @@ async function nextAvailableLitellmUrl(url) {
7887
7897
  throw new Error(`no free LiteLLM port found after ${startPort}`);
7888
7898
  }
7889
7899
  function canListen(port, host) {
7890
- return new Promise((resolve23) => {
7900
+ return new Promise((resolve24) => {
7891
7901
  const server = net.createServer();
7892
- server.once("error", () => resolve23(false));
7902
+ server.once("error", () => resolve24(false));
7893
7903
  server.once("listening", () => {
7894
- server.close(() => resolve23(true));
7904
+ server.close(() => resolve24(true));
7895
7905
  });
7896
7906
  server.listen(port, host);
7897
7907
  });
7898
7908
  }
7899
7909
  function readDotenvApiKeys(projectDir) {
7900
- const dotenvPath = path26.join(projectDir, ".env");
7910
+ const dotenvPath = path27.join(projectDir, ".env");
7901
7911
  if (!fs28.existsSync(dotenvPath)) return {};
7902
7912
  const result = {};
7903
7913
  for (const rawLine of fs28.readFileSync(dotenvPath, "utf-8").split("\n")) {
@@ -8560,7 +8570,7 @@ var init_pushWithRetry = __esm({
8560
8570
  // src/commit.ts
8561
8571
  import { execFileSync as execFileSync6 } from "child_process";
8562
8572
  import * as fs29 from "fs";
8563
- import * as path27 from "path";
8573
+ import * as path28 from "path";
8564
8574
  function isGitHubYamlPath(filePath) {
8565
8575
  const normalized = filePath.replace(/^\.\/+/, "");
8566
8576
  return normalized.startsWith(".github/") && /\.ya?ml$/i.test(normalized);
@@ -8602,18 +8612,18 @@ function ensureGitIdentity(cwd) {
8602
8612
  }
8603
8613
  function abortUnfinishedGitOps(cwd) {
8604
8614
  const aborted = [];
8605
- const gitDir = path27.join(cwd ?? process.cwd(), ".git");
8615
+ const gitDir = path28.join(cwd ?? process.cwd(), ".git");
8606
8616
  if (!fs29.existsSync(gitDir)) return aborted;
8607
- if (fs29.existsSync(path27.join(gitDir, "MERGE_HEAD"))) {
8617
+ if (fs29.existsSync(path28.join(gitDir, "MERGE_HEAD"))) {
8608
8618
  if (tryGit(["merge", "--abort"], cwd)) aborted.push("merge");
8609
8619
  }
8610
- if (fs29.existsSync(path27.join(gitDir, "CHERRY_PICK_HEAD"))) {
8620
+ if (fs29.existsSync(path28.join(gitDir, "CHERRY_PICK_HEAD"))) {
8611
8621
  if (tryGit(["cherry-pick", "--abort"], cwd)) aborted.push("cherry-pick");
8612
8622
  }
8613
- if (fs29.existsSync(path27.join(gitDir, "REVERT_HEAD"))) {
8623
+ if (fs29.existsSync(path28.join(gitDir, "REVERT_HEAD"))) {
8614
8624
  if (tryGit(["revert", "--abort"], cwd)) aborted.push("revert");
8615
8625
  }
8616
- if (fs29.existsSync(path27.join(gitDir, "rebase-merge")) || fs29.existsSync(path27.join(gitDir, "rebase-apply"))) {
8626
+ if (fs29.existsSync(path28.join(gitDir, "rebase-merge")) || fs29.existsSync(path28.join(gitDir, "rebase-apply"))) {
8617
8627
  if (tryGit(["rebase", "--abort"], cwd)) aborted.push("rebase");
8618
8628
  }
8619
8629
  try {
@@ -8670,7 +8680,7 @@ function normalizeCommitMessage(raw) {
8670
8680
  function commitAndPush(branch, agentMessage, cwd) {
8671
8681
  const allChanged = listChangedFiles(cwd);
8672
8682
  const allowedFiles = allChanged.filter((f) => !isForbiddenPath(f));
8673
- const mergeHeadExists = fs29.existsSync(path27.join(cwd ?? process.cwd(), ".git", "MERGE_HEAD"));
8683
+ const mergeHeadExists = fs29.existsSync(path28.join(cwd ?? process.cwd(), ".git", "MERGE_HEAD"));
8674
8684
  if (allowedFiles.length === 0 && !mergeHeadExists) {
8675
8685
  return { committed: false, pushed: false, sha: "", message: "" };
8676
8686
  }
@@ -9314,9 +9324,9 @@ import * as fs30 from "fs";
9314
9324
  function stageGoalRunLogEvent(data, goalId, event, at = nowIso()) {
9315
9325
  const logs = goalRunLogs(data);
9316
9326
  const existing = logs[goalId];
9317
- const path58 = existing?.path ?? goalRunLogPath(goalId, data);
9327
+ const path59 = existing?.path ?? goalRunLogPath(goalId, data);
9318
9328
  logs[goalId] = {
9319
- path: path58,
9329
+ path: path59,
9320
9330
  events: [...existing?.events ?? [], buildGoalRunLogEvent(data, goalId, event, at)]
9321
9331
  };
9322
9332
  }
@@ -9764,7 +9774,7 @@ var init_stateStore = __esm({
9764
9774
 
9765
9775
  // src/goal/targetLoopResolution.ts
9766
9776
  import * as fs31 from "fs";
9767
- import * as path28 from "path";
9777
+ import * as path29 from "path";
9768
9778
  async function resolveActiveGoalLoopTarget(config, cwd, loopGoalId, loopGoal) {
9769
9779
  const targetId = loopGoal.loopTarget?.id.trim() ?? "";
9770
9780
  assertSafeGoalId(targetId, "loop target");
@@ -9842,7 +9852,7 @@ function goalInstanceTime(state) {
9842
9852
  return Number.isNaN(parsed) ? 0 : parsed;
9843
9853
  }
9844
9854
  function loadGoalTemplate(cwd, targetId) {
9845
- return readJsonObject2(path28.join(cwd, ".kody-engine", "definitions", "goals", targetId, "state.json"));
9855
+ return readJsonObject2(path29.join(cwd, ".kody-engine", "definitions", "goals", targetId, "state.json"));
9846
9856
  }
9847
9857
  function readJsonObject2(filePath) {
9848
9858
  if (!fs31.existsSync(filePath)) return null;
@@ -10193,15 +10203,15 @@ var init_backendStateBackend = __esm({
10193
10203
  this.jobsDir = opts.jobsDir.replace(/\/+$/, "");
10194
10204
  }
10195
10205
  async load(slug) {
10196
- const path58 = stateFilePath(this.jobsDir, slug);
10206
+ const path59 = stateFilePath(this.jobsDir, slug);
10197
10207
  const loaded = await createStateBackendFromEnv().get(this.tenantId, `capabilities/${slug}`, "job-state");
10198
10208
  if (!loaded) {
10199
- return { path: path58, handle: null, state: initialStateEnvelope("seed"), created: true };
10209
+ return { path: path59, handle: null, state: initialStateEnvelope("seed"), created: true };
10200
10210
  }
10201
10211
  if (!isStateEnvelope(loaded.doc)) {
10202
10212
  throw new Error(`BackendStateBackend: capabilities/${slug} is not a StateEnvelope`);
10203
10213
  }
10204
- return { path: path58, handle: loaded.updatedAt, state: loaded.doc, created: false };
10214
+ return { path: path59, handle: loaded.updatedAt, state: loaded.doc, created: false };
10205
10215
  }
10206
10216
  async save(loaded, next) {
10207
10217
  if (!loaded.created && isStateUnchanged(loaded.state, next)) return false;
@@ -10222,7 +10232,7 @@ var init_backendStateBackend = __esm({
10222
10232
 
10223
10233
  // src/scripts/jobState/localFileBackend.ts
10224
10234
  import * as fs32 from "fs";
10225
- import * as path29 from "path";
10235
+ import * as path30 from "path";
10226
10236
  function sanitizeKey(s) {
10227
10237
  return s.replace(/[^A-Za-z0-9._-]/g, "-");
10228
10238
  }
@@ -10278,7 +10288,7 @@ var init_localFileBackend = __esm({
10278
10288
  if (!opts.owner || !opts.repo) throw new Error("LocalFileBackend: owner and repo are required");
10279
10289
  this.cwd = opts.cwd;
10280
10290
  this.jobsDir = opts.jobsDir;
10281
- this.absDir = path29.resolve(opts.cwd, opts.jobsDir);
10291
+ this.absDir = path30.resolve(opts.cwd, opts.jobsDir);
10282
10292
  this.owner = opts.owner;
10283
10293
  this.repo = opts.repo;
10284
10294
  this.cache = opts.cache ?? defaultCacheAdapter();
@@ -10338,7 +10348,7 @@ var init_localFileBackend = __esm({
10338
10348
  }
10339
10349
  load(slug) {
10340
10350
  const relPath = stateFilePath(this.jobsDir, slug);
10341
- const absPath = path29.resolve(this.cwd, relPath);
10351
+ const absPath = path30.resolve(this.cwd, relPath);
10342
10352
  if (!fs32.existsSync(absPath)) {
10343
10353
  return { path: relPath, handle: null, state: initialStateEnvelope("seed"), created: true };
10344
10354
  }
@@ -10359,8 +10369,8 @@ var init_localFileBackend = __esm({
10359
10369
  if (!loaded.created && isStateUnchanged(loaded.state, next)) {
10360
10370
  return false;
10361
10371
  }
10362
- const absPath = path29.resolve(this.cwd, loaded.path);
10363
- fs32.mkdirSync(path29.dirname(absPath), { recursive: true });
10372
+ const absPath = path30.resolve(this.cwd, loaded.path);
10373
+ fs32.mkdirSync(path30.dirname(absPath), { recursive: true });
10364
10374
  const body = `${JSON.stringify(next, null, 2)}
10365
10375
  `;
10366
10376
  const tmpPath = `${absPath}.${process.pid}.tmp`;
@@ -10397,7 +10407,7 @@ var init_jobState = __esm({
10397
10407
  });
10398
10408
 
10399
10409
  // src/scripts/goalCapabilityScheduling.ts
10400
- import * as path30 from "path";
10410
+ import * as path31 from "path";
10401
10411
  function isCapabilityCadenceGoal(goal, extra) {
10402
10412
  return extra.scheduleMode === "agentLoop" || extra.scheduler === "agentLoop" || goal.type === "standing" && goal.capabilities.length > 0;
10403
10413
  }
@@ -10453,7 +10463,7 @@ function planTargetLoopSchedule(opts) {
10453
10463
  }
10454
10464
  async function planGoalCapabilitySchedule(opts) {
10455
10465
  const jobsDir = opts.jobsDir ?? capabilitiesRoot(opts.cwd);
10456
- const jobsRoot = path30.resolve(opts.cwd, jobsDir);
10466
+ const jobsRoot = path31.resolve(opts.cwd, jobsDir);
10457
10467
  const now = opts.now ?? /* @__PURE__ */ new Date();
10458
10468
  const at = now.toISOString();
10459
10469
  const backend = resolveBackend({ config: opts.config, cwd: opts.cwd, jobsDir });
@@ -12270,7 +12280,7 @@ var init_classifyByLabel = __esm({
12270
12280
  // src/scripts/commitAndPush.ts
12271
12281
  import { createHash as createHash5 } from "crypto";
12272
12282
  import * as fs33 from "fs";
12273
- import * as path31 from "path";
12283
+ import * as path32 from "path";
12274
12284
  function sentinelPathForStage(cwd, profileName, workflowExecutionKey) {
12275
12285
  const runId = resolveRunId();
12276
12286
  const executionSuffix = typeof workflowExecutionKey === "string" && workflowExecutionKey.length > 0 ? `-${createHash5("sha256").update(workflowExecutionKey).digest("hex").slice(0, 16)}` : "";
@@ -12354,7 +12364,7 @@ var init_commitAndPush = __esm({
12354
12364
  const result = ctx.data.commitResult;
12355
12365
  if (sentinel && result?.committed) {
12356
12366
  try {
12357
- fs33.mkdirSync(path31.dirname(sentinel), { recursive: true });
12367
+ fs33.mkdirSync(path32.dirname(sentinel), { recursive: true });
12358
12368
  fs33.writeFileSync(
12359
12369
  sentinel,
12360
12370
  JSON.stringify(
@@ -12450,7 +12460,7 @@ var init_commitGoalState = __esm({
12450
12460
 
12451
12461
  // src/scripts/composePrompt.ts
12452
12462
  import * as fs34 from "fs";
12453
- import * as path32 from "path";
12463
+ import * as path33 from "path";
12454
12464
  function fenceUntrusted(value) {
12455
12465
  if (value.trim().length === 0) return value;
12456
12466
  const safe = value.replace(/-{3,}\s*END UNTRUSTED INPUT\s*-{3,}/gi, "[END UNTRUSTED INPUT]");
@@ -12574,10 +12584,10 @@ var init_composePrompt = __esm({
12574
12584
  const explicit = ctx.data.promptTemplate;
12575
12585
  const mode = ctx.args.mode;
12576
12586
  const candidates = [
12577
- explicit ? path32.join(profile.dir, explicit) : null,
12578
- mode ? path32.join(profile.dir, "prompts", `${mode}.md`) : null,
12579
- path32.join(profile.dir, "prompt.md"),
12580
- path32.join(profile.dir, "capability.md")
12587
+ explicit ? path33.join(profile.dir, explicit) : null,
12588
+ mode ? path33.join(profile.dir, "prompts", `${mode}.md`) : null,
12589
+ path33.join(profile.dir, "prompt.md"),
12590
+ path33.join(profile.dir, "capability.md")
12581
12591
  ].filter(Boolean);
12582
12592
  let templatePath = "";
12583
12593
  let template = "";
@@ -13337,14 +13347,14 @@ var init_deriveQaScopeFromIssue = __esm({
13337
13347
  import { execFileSync as execFileSync9 } from "child_process";
13338
13348
  import * as fs35 from "fs";
13339
13349
  import * as os5 from "os";
13340
- import * as path33 from "path";
13350
+ import * as path34 from "path";
13341
13351
  var diagMcp;
13342
13352
  var init_diagMcp = __esm({
13343
13353
  "src/scripts/diagMcp.ts"() {
13344
13354
  "use strict";
13345
13355
  diagMcp = async (_ctx) => {
13346
13356
  const home = os5.homedir();
13347
- const cacheDir = path33.join(home, ".cache", "ms-playwright");
13357
+ const cacheDir = path34.join(home, ".cache", "ms-playwright");
13348
13358
  let entries = [];
13349
13359
  try {
13350
13360
  entries = fs35.readdirSync(cacheDir);
@@ -13376,12 +13386,12 @@ var init_diagMcp = __esm({
13376
13386
 
13377
13387
  // src/scripts/frameworkDetectors.ts
13378
13388
  import * as fs36 from "fs";
13379
- import * as path34 from "path";
13389
+ import * as path35 from "path";
13380
13390
  function detectFrameworks(cwd) {
13381
13391
  const out = [];
13382
13392
  let deps = {};
13383
13393
  try {
13384
- const pkg = JSON.parse(fs36.readFileSync(path34.join(cwd, "package.json"), "utf-8"));
13394
+ const pkg = JSON.parse(fs36.readFileSync(path35.join(cwd, "package.json"), "utf-8"));
13385
13395
  deps = { ...pkg.dependencies, ...pkg.devDependencies };
13386
13396
  } catch {
13387
13397
  return out;
@@ -13418,14 +13428,14 @@ function detectFrameworks(cwd) {
13418
13428
  }
13419
13429
  function findFile(cwd, candidates) {
13420
13430
  for (const c of candidates) {
13421
- if (fs36.existsSync(path34.join(cwd, c))) return c;
13431
+ if (fs36.existsSync(path35.join(cwd, c))) return c;
13422
13432
  }
13423
13433
  return null;
13424
13434
  }
13425
13435
  function discoverPayloadCollections(cwd) {
13426
13436
  const out = [];
13427
13437
  for (const dir of COLLECTION_DIRS) {
13428
- const full = path34.join(cwd, dir);
13438
+ const full = path35.join(cwd, dir);
13429
13439
  if (!fs36.existsSync(full)) continue;
13430
13440
  let files;
13431
13441
  try {
@@ -13435,7 +13445,7 @@ function discoverPayloadCollections(cwd) {
13435
13445
  }
13436
13446
  for (const file of files) {
13437
13447
  try {
13438
- const filePath = path34.join(full, file);
13448
+ const filePath = path35.join(full, file);
13439
13449
  const content = fs36.readFileSync(filePath, "utf-8").slice(0, 1e4);
13440
13450
  const slugMatch = content.match(/slug:\s*['"]([a-z0-9-]+)['"]/);
13441
13451
  if (!slugMatch) continue;
@@ -13450,7 +13460,7 @@ function discoverPayloadCollections(cwd) {
13450
13460
  out.push({
13451
13461
  name,
13452
13462
  slug,
13453
- filePath: path34.relative(cwd, filePath),
13463
+ filePath: path35.relative(cwd, filePath),
13454
13464
  fields: fields.slice(0, 20),
13455
13465
  hasAdmin
13456
13466
  });
@@ -13463,7 +13473,7 @@ function discoverPayloadCollections(cwd) {
13463
13473
  function discoverAdminComponents(cwd, collections) {
13464
13474
  const out = [];
13465
13475
  for (const dir of ADMIN_COMPONENT_DIRS) {
13466
- const full = path34.join(cwd, dir);
13476
+ const full = path35.join(cwd, dir);
13467
13477
  if (!fs36.existsSync(full)) continue;
13468
13478
  let entries;
13469
13479
  try {
@@ -13472,19 +13482,19 @@ function discoverAdminComponents(cwd, collections) {
13472
13482
  continue;
13473
13483
  }
13474
13484
  for (const entry of entries) {
13475
- const entryPath = path34.join(full, entry.name);
13485
+ const entryPath = path35.join(full, entry.name);
13476
13486
  let name;
13477
13487
  let filePath;
13478
13488
  if (entry.isDirectory()) {
13479
13489
  const indexFile = ["index.tsx", "index.ts", "index.jsx", "index.js"].find(
13480
- (f) => fs36.existsSync(path34.join(entryPath, f))
13490
+ (f) => fs36.existsSync(path35.join(entryPath, f))
13481
13491
  );
13482
13492
  if (!indexFile) continue;
13483
13493
  name = entry.name;
13484
- filePath = path34.relative(cwd, path34.join(entryPath, indexFile));
13494
+ filePath = path35.relative(cwd, path35.join(entryPath, indexFile));
13485
13495
  } else if (/\.(tsx?|jsx?)$/.test(entry.name)) {
13486
13496
  name = entry.name.replace(/\.(tsx?|jsx?)$/, "");
13487
- filePath = path34.relative(cwd, entryPath);
13497
+ filePath = path35.relative(cwd, entryPath);
13488
13498
  } else {
13489
13499
  continue;
13490
13500
  }
@@ -13492,7 +13502,7 @@ function discoverAdminComponents(cwd, collections) {
13492
13502
  if (collections) {
13493
13503
  for (const col of collections) {
13494
13504
  try {
13495
- const colContent = fs36.readFileSync(path34.join(cwd, col.filePath), "utf-8");
13505
+ const colContent = fs36.readFileSync(path35.join(cwd, col.filePath), "utf-8");
13496
13506
  if (colContent.includes(name)) {
13497
13507
  usedInCollection = col.slug;
13498
13508
  break;
@@ -13510,7 +13520,7 @@ function scanApiRoutes(cwd) {
13510
13520
  const out = [];
13511
13521
  const appDirs = ["src/app", "app"];
13512
13522
  for (const appDir of appDirs) {
13513
- const apiDir = path34.join(cwd, appDir, "api");
13523
+ const apiDir = path35.join(cwd, appDir, "api");
13514
13524
  if (!fs36.existsSync(apiDir)) continue;
13515
13525
  walkApiRoutes(apiDir, "/api", cwd, out);
13516
13526
  break;
@@ -13527,7 +13537,7 @@ function walkApiRoutes(dir, prefix, cwd, out) {
13527
13537
  const routeFile = entries.find((e) => e.isFile() && /^route\.(ts|js|tsx|jsx)$/.test(e.name));
13528
13538
  if (routeFile) {
13529
13539
  try {
13530
- const content = fs36.readFileSync(path34.join(dir, routeFile.name), "utf-8").slice(0, 5e3);
13540
+ const content = fs36.readFileSync(path35.join(dir, routeFile.name), "utf-8").slice(0, 5e3);
13531
13541
  const methods = HTTP_METHODS.filter(
13532
13542
  (m) => new RegExp(`export\\s+(?:async\\s+)?function\\s+${m}\\b`).test(content)
13533
13543
  );
@@ -13535,7 +13545,7 @@ function walkApiRoutes(dir, prefix, cwd, out) {
13535
13545
  out.push({
13536
13546
  path: prefix,
13537
13547
  methods,
13538
- filePath: path34.relative(cwd, path34.join(dir, routeFile.name))
13548
+ filePath: path35.relative(cwd, path35.join(dir, routeFile.name))
13539
13549
  });
13540
13550
  }
13541
13551
  } catch {
@@ -13546,7 +13556,7 @@ function walkApiRoutes(dir, prefix, cwd, out) {
13546
13556
  if (entry.name === "node_modules" || entry.name === ".next") continue;
13547
13557
  let segment = entry.name;
13548
13558
  if (segment.startsWith("(") && segment.endsWith(")")) {
13549
- walkApiRoutes(path34.join(dir, entry.name), prefix, cwd, out);
13559
+ walkApiRoutes(path35.join(dir, entry.name), prefix, cwd, out);
13550
13560
  continue;
13551
13561
  }
13552
13562
  if (segment.startsWith("[[") && segment.endsWith("]]")) {
@@ -13554,13 +13564,13 @@ function walkApiRoutes(dir, prefix, cwd, out) {
13554
13564
  } else if (segment.startsWith("[") && segment.endsWith("]")) {
13555
13565
  segment = `:${segment.slice(1, -1)}`;
13556
13566
  }
13557
- walkApiRoutes(path34.join(dir, entry.name), `${prefix}/${segment}`, cwd, out);
13567
+ walkApiRoutes(path35.join(dir, entry.name), `${prefix}/${segment}`, cwd, out);
13558
13568
  }
13559
13569
  }
13560
13570
  function scanEnvVars(cwd) {
13561
13571
  const candidates = [".env.example", ".env.local.example", ".env.template"];
13562
13572
  for (const envFile of candidates) {
13563
- const envPath = path34.join(cwd, envFile);
13573
+ const envPath = path35.join(cwd, envFile);
13564
13574
  if (!fs36.existsSync(envPath)) continue;
13565
13575
  try {
13566
13576
  const content = fs36.readFileSync(envPath, "utf-8");
@@ -13609,7 +13619,7 @@ var init_frameworkDetectors = __esm({
13609
13619
 
13610
13620
  // src/scripts/discoverQaContext.ts
13611
13621
  import * as fs37 from "fs";
13612
- import * as path35 from "path";
13622
+ import * as path36 from "path";
13613
13623
  function runQaDiscovery(cwd) {
13614
13624
  const out = {
13615
13625
  routes: [],
@@ -13640,9 +13650,9 @@ function runQaDiscovery(cwd) {
13640
13650
  }
13641
13651
  function detectDevServer(cwd, out) {
13642
13652
  try {
13643
- const pkg = JSON.parse(fs37.readFileSync(path35.join(cwd, "package.json"), "utf-8"));
13653
+ const pkg = JSON.parse(fs37.readFileSync(path36.join(cwd, "package.json"), "utf-8"));
13644
13654
  const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
13645
- const pm = fs37.existsSync(path35.join(cwd, "pnpm-lock.yaml")) ? "pnpm" : fs37.existsSync(path35.join(cwd, "yarn.lock")) ? "yarn" : fs37.existsSync(path35.join(cwd, "bun.lockb")) ? "bun" : "npm";
13655
+ const pm = fs37.existsSync(path36.join(cwd, "pnpm-lock.yaml")) ? "pnpm" : fs37.existsSync(path36.join(cwd, "yarn.lock")) ? "yarn" : fs37.existsSync(path36.join(cwd, "bun.lockb")) ? "bun" : "npm";
13646
13656
  if (pkg.scripts?.dev) out.devCommand = `${pm} dev`;
13647
13657
  if (allDeps.next || allDeps.nuxt) out.devPort = 3e3;
13648
13658
  else if (allDeps.vite) out.devPort = 5173;
@@ -13652,7 +13662,7 @@ function detectDevServer(cwd, out) {
13652
13662
  function scanFrontendRoutes(cwd, out) {
13653
13663
  const appDirs = ["src/app", "app"];
13654
13664
  for (const appDir of appDirs) {
13655
- const full = path35.join(cwd, appDir);
13665
+ const full = path36.join(cwd, appDir);
13656
13666
  if (!fs37.existsSync(full)) continue;
13657
13667
  walkFrontendRoutes(full, "", out);
13658
13668
  break;
@@ -13678,7 +13688,7 @@ function walkFrontendRoutes(dir, prefix, out) {
13678
13688
  if (entry.name === "node_modules" || entry.name === ".next") continue;
13679
13689
  let segment = entry.name;
13680
13690
  if (segment.startsWith("(") && segment.endsWith(")")) {
13681
- walkFrontendRoutes(path35.join(dir, entry.name), prefix, out);
13691
+ walkFrontendRoutes(path36.join(dir, entry.name), prefix, out);
13682
13692
  continue;
13683
13693
  }
13684
13694
  if (segment.startsWith("[[") && segment.endsWith("]]")) {
@@ -13686,7 +13696,7 @@ function walkFrontendRoutes(dir, prefix, out) {
13686
13696
  } else if (segment.startsWith("[") && segment.endsWith("]")) {
13687
13697
  segment = `:${segment.slice(1, -1)}`;
13688
13698
  }
13689
- walkFrontendRoutes(path35.join(dir, entry.name), `${prefix}/${segment}`, out);
13699
+ walkFrontendRoutes(path36.join(dir, entry.name), `${prefix}/${segment}`, out);
13690
13700
  }
13691
13701
  }
13692
13702
  function detectAuthFiles(cwd, out) {
@@ -13703,13 +13713,13 @@ function detectAuthFiles(cwd, out) {
13703
13713
  "src/app/api/oauth"
13704
13714
  ];
13705
13715
  for (const c of candidates) {
13706
- if (fs37.existsSync(path35.join(cwd, c))) out.authFiles.push(c);
13716
+ if (fs37.existsSync(path36.join(cwd, c))) out.authFiles.push(c);
13707
13717
  }
13708
13718
  }
13709
13719
  function detectRoles(cwd, out) {
13710
13720
  const rolePaths = ["src/types", "src/lib", "src/utils", "src/constants", "src/access", "src/collections"];
13711
13721
  for (const rp of rolePaths) {
13712
- const dir = path35.join(cwd, rp);
13722
+ const dir = path36.join(cwd, rp);
13713
13723
  if (!fs37.existsSync(dir)) continue;
13714
13724
  let files;
13715
13725
  try {
@@ -13719,7 +13729,7 @@ function detectRoles(cwd, out) {
13719
13729
  }
13720
13730
  for (const f of files) {
13721
13731
  try {
13722
- const content = fs37.readFileSync(path35.join(dir, f), "utf-8").slice(0, 5e3);
13732
+ const content = fs37.readFileSync(path36.join(dir, f), "utf-8").slice(0, 5e3);
13723
13733
  const roleMatches = content.match(/(?:role|Role|ROLE)\s*[=:]\s*['"](\w+)['"]/g);
13724
13734
  if (roleMatches) {
13725
13735
  for (const m of roleMatches) {
@@ -13981,7 +13991,7 @@ var init_dispatchClassified = __esm({
13981
13991
 
13982
13992
  // src/loopDefinitions.ts
13983
13993
  import * as fs38 from "fs";
13984
- import * as path36 from "path";
13994
+ import * as path37 from "path";
13985
13995
  function normalizeLoopDefinition(value) {
13986
13996
  if (!value || typeof value !== "object" || Array.isArray(value)) return null;
13987
13997
  const raw = value;
@@ -14008,7 +14018,7 @@ function readLoopDefinition(cwd, id) {
14008
14018
  if (!ID.test(id)) return null;
14009
14019
  const roots = loopRoots(cwd);
14010
14020
  for (const root of roots) {
14011
- const filePath = path36.join(root, "loops", id, "loop.json");
14021
+ const filePath = path37.join(root, "loops", id, "loop.json");
14012
14022
  if (!fs38.existsSync(filePath)) continue;
14013
14023
  try {
14014
14024
  const loop = normalizeLoopDefinition(JSON.parse(fs38.readFileSync(filePath, "utf8")));
@@ -14021,7 +14031,7 @@ function readLoopDefinition(cwd, id) {
14021
14031
  }
14022
14032
  }
14023
14033
  process.stderr.write(
14024
- `[kody] Loop not found: ${id} (${roots.map((root) => path36.join(root, "loops", id, "loop.json")).join(", ")})
14034
+ `[kody] Loop not found: ${id} (${roots.map((root) => path37.join(root, "loops", id, "loop.json")).join(", ")})
14025
14035
  `
14026
14036
  );
14027
14037
  return null;
@@ -14030,11 +14040,11 @@ function listLoopDefinitions(cwd) {
14030
14040
  const roots = loopRoots(cwd);
14031
14041
  const byId = /* @__PURE__ */ new Map();
14032
14042
  for (const root of roots.reverse()) {
14033
- const loopsDir = path36.join(root, "loops");
14043
+ const loopsDir = path37.join(root, "loops");
14034
14044
  if (!fs38.existsSync(loopsDir)) continue;
14035
14045
  for (const id of fs38.readdirSync(loopsDir).sort()) {
14036
14046
  if (!ID.test(id)) continue;
14037
- const filePath = path36.join(loopsDir, id, "loop.json");
14047
+ const filePath = path37.join(loopsDir, id, "loop.json");
14038
14048
  if (!fs38.existsSync(filePath)) continue;
14039
14049
  try {
14040
14050
  const loop = normalizeLoopDefinition(JSON.parse(fs38.readFileSync(filePath, "utf8")));
@@ -14049,8 +14059,8 @@ function listLoopDefinitions(cwd) {
14049
14059
  }
14050
14060
  function loopRoots(cwd) {
14051
14061
  return [
14052
- path36.join(cwd, ".kody-engine", "runtime"),
14053
- path36.join(cwd, ".kody-engine", "definitions"),
14062
+ path37.join(cwd, ".kody-engine", "runtime"),
14063
+ path37.join(cwd, ".kody-engine", "definitions"),
14054
14064
  definitionsRoot(cwd)
14055
14065
  ].filter((root, index, roots) => roots.indexOf(root) === index);
14056
14066
  }
@@ -15329,11 +15339,11 @@ var init_fixFlow = __esm({
15329
15339
 
15330
15340
  // src/workflow-template.ts
15331
15341
  import * as fs39 from "fs";
15332
- import * as path37 from "path";
15342
+ import * as path38 from "path";
15333
15343
  import { fileURLToPath } from "url";
15334
15344
  function loadKodyWorkflowTemplate() {
15335
- const here = path37.dirname(fileURLToPath(import.meta.url));
15336
- const candidates = [path37.resolve(here, "../templates/kody.yml"), path37.resolve(here, "../../templates/kody.yml")];
15345
+ const here = path38.dirname(fileURLToPath(import.meta.url));
15346
+ const candidates = [path38.resolve(here, "../templates/kody.yml"), path38.resolve(here, "../../templates/kody.yml")];
15337
15347
  const source = candidates.find((candidate) => fs39.existsSync(candidate));
15338
15348
  if (!source) throw new Error(`Kody workflow template is missing: ${KODY_WORKFLOW_TEMPLATE_PATH}`);
15339
15349
  return fs39.readFileSync(source, "utf8");
@@ -15349,11 +15359,11 @@ var init_workflow_template = __esm({
15349
15359
  // src/scripts/initFlow.ts
15350
15360
  import { execFileSync as execFileSync14 } from "child_process";
15351
15361
  import * as fs40 from "fs";
15352
- import * as path38 from "path";
15362
+ import * as path39 from "path";
15353
15363
  function detectPackageManager(cwd) {
15354
- if (fs40.existsSync(path38.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
15355
- if (fs40.existsSync(path38.join(cwd, "yarn.lock"))) return "yarn";
15356
- if (fs40.existsSync(path38.join(cwd, "bun.lockb"))) return "bun";
15364
+ if (fs40.existsSync(path39.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
15365
+ if (fs40.existsSync(path39.join(cwd, "yarn.lock"))) return "yarn";
15366
+ if (fs40.existsSync(path39.join(cwd, "bun.lockb"))) return "bun";
15357
15367
  return "npm";
15358
15368
  }
15359
15369
  function qualityCommandsFor(pm) {
@@ -15425,7 +15435,7 @@ function performInit(cwd, force) {
15425
15435
  const pm = detectPackageManager(cwd);
15426
15436
  const ownerRepo = detectOwnerRepo(cwd);
15427
15437
  const defaultBranch = defaultBranchFromGit(cwd);
15428
- const configPath = path38.join(cwd, "kody.config.json");
15438
+ const configPath = path39.join(cwd, "kody.config.json");
15429
15439
  if (fs40.existsSync(configPath) && !force) {
15430
15440
  skipped.push("kody.config.json");
15431
15441
  } else {
@@ -15434,8 +15444,8 @@ function performInit(cwd, force) {
15434
15444
  `);
15435
15445
  wrote.push("kody.config.json");
15436
15446
  }
15437
- const workflowDir = path38.join(cwd, ".github", "workflows");
15438
- const workflowPath = path38.join(workflowDir, "kody.yml");
15447
+ const workflowDir = path39.join(cwd, ".github", "workflows");
15448
+ const workflowPath = path39.join(workflowDir, "kody.yml");
15439
15449
  if (fs40.existsSync(workflowPath) && !force) {
15440
15450
  skipped.push(".github/workflows/kody.yml");
15441
15451
  } else {
@@ -15630,13 +15640,13 @@ var init_loadCapabilityState = __esm({
15630
15640
  function isCompanyIntentId(value) {
15631
15641
  return SLUG_RE2.test(value);
15632
15642
  }
15633
- function normalizeCompanyIntent(path58, raw) {
15643
+ function normalizeCompanyIntent(path59, raw) {
15634
15644
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
15635
- throw new Error(`${path58}: intent must be JSON object`);
15645
+ throw new Error(`${path59}: intent must be JSON object`);
15636
15646
  }
15637
15647
  const input = raw;
15638
15648
  const id = stringField4(input.id);
15639
- if (!id || !isCompanyIntentId(id)) throw new Error(`${path58}: invalid intent id`);
15649
+ if (!id || !isCompanyIntentId(id)) throw new Error(`${path59}: invalid intent id`);
15640
15650
  const createdAt = stringField4(input.createdAt) || nowIso();
15641
15651
  const updatedAt = stringField4(input.updatedAt) || createdAt;
15642
15652
  const description = stringField4(input.description);
@@ -15798,7 +15808,7 @@ function retryDelaysMs() {
15798
15808
  }
15799
15809
  function sleep(ms) {
15800
15810
  if (ms <= 0) return Promise.resolve();
15801
- return new Promise((resolve23) => setTimeout(resolve23, ms));
15811
+ return new Promise((resolve24) => setTimeout(resolve24, ms));
15802
15812
  }
15803
15813
  async function fetchGoalStateWithRetry(config, goalId, cwd) {
15804
15814
  let state = await fetchGoalStateAsync(config, goalId, cwd);
@@ -15928,7 +15938,7 @@ var init_loadIssueStateComment = __esm({
15928
15938
 
15929
15939
  // src/scripts/loadJobFromFile.ts
15930
15940
  import * as fs42 from "fs";
15931
- import * as path39 from "path";
15941
+ import * as path40 from "path";
15932
15942
  function parseJobFile(raw, slug) {
15933
15943
  let stripped = raw;
15934
15944
  if (stripped.startsWith("---\n")) {
@@ -15967,10 +15977,10 @@ var init_loadJobFromFile = __esm({
15967
15977
  if (!slug) {
15968
15978
  throw new Error(`loadJobFromFile: ctx.args.${slugArg} must be a non-empty slug`);
15969
15979
  }
15970
- const capability = resolveCapabilityFolder(slug, path39.resolve(ctx.cwd, jobsDir));
15980
+ const capability = resolveCapabilityFolder(slug, path40.resolve(ctx.cwd, jobsDir));
15971
15981
  if (!capability) {
15972
15982
  throw new Error(
15973
- `loadJobFromFile: capability folder not found or incomplete: ${path39.resolve(ctx.cwd, jobsDir, slug)}`
15983
+ `loadJobFromFile: capability folder not found or incomplete: ${path40.resolve(ctx.cwd, jobsDir, slug)}`
15974
15984
  );
15975
15985
  }
15976
15986
  const { title, body, config } = capability;
@@ -16066,9 +16076,9 @@ ${truncate2(issue2.body, FINDING_BODY_MAX_BYTES)}`;
16066
16076
 
16067
16077
  // src/scripts/kodyVariables.ts
16068
16078
  import * as fs43 from "fs";
16069
- import * as path40 from "path";
16079
+ import * as path41 from "path";
16070
16080
  function readKodyVariables(cwd) {
16071
- const full = path40.join(cwd, KODY_VARIABLES_REL_PATH);
16081
+ const full = path41.join(cwd, KODY_VARIABLES_REL_PATH);
16072
16082
  let raw;
16073
16083
  try {
16074
16084
  raw = fs43.readFileSync(full, "utf-8");
@@ -16097,7 +16107,7 @@ var init_kodyVariables = __esm({
16097
16107
 
16098
16108
  // src/scripts/loadQaContext.ts
16099
16109
  import * as fs44 from "fs";
16100
- import * as path41 from "path";
16110
+ import * as path42 from "path";
16101
16111
  function parseSlugList(value) {
16102
16112
  const inner = value.startsWith("[") && value.endsWith("]") ? value.slice(1, -1) : value;
16103
16113
  return inner.split(",").map(
@@ -16126,7 +16136,7 @@ function readProfileAgents(raw) {
16126
16136
  return { agent: agent ?? legacy ?? ["kody"], body };
16127
16137
  }
16128
16138
  function readProfile(cwd) {
16129
- const dir = path41.join(cwd, CONTEXT_DIR_REL_PATH);
16139
+ const dir = path42.join(cwd, CONTEXT_DIR_REL_PATH);
16130
16140
  if (!fs44.existsSync(dir)) return "";
16131
16141
  let entries;
16132
16142
  try {
@@ -16137,7 +16147,7 @@ function readProfile(cwd) {
16137
16147
  const blocks = [];
16138
16148
  for (const file of entries) {
16139
16149
  try {
16140
- const raw = fs44.readFileSync(path41.join(dir, file), "utf-8");
16150
+ const raw = fs44.readFileSync(path42.join(dir, file), "utf-8");
16141
16151
  const { agent, body } = readProfileAgents(raw);
16142
16152
  if (!agent.includes(QA_AGENT) && !agent.includes(ALL_AGENTS)) continue;
16143
16153
  blocks.push(`## ${file}
@@ -16189,7 +16199,7 @@ var init_loadQaContext = __esm({
16189
16199
  import { randomUUID as randomUUID2 } from "crypto";
16190
16200
  import * as fs45 from "fs";
16191
16201
  import * as os6 from "os";
16192
- import * as path42 from "path";
16202
+ import * as path43 from "path";
16193
16203
  function registerCapabilitySubagents(profile, toolRoot, toolFiles) {
16194
16204
  const subagentFiles = toolFiles.flatMap((file) => {
16195
16205
  const match = /^agents\/([a-z][a-z0-9-]{0,63})\.md$/.exec(file);
@@ -16202,7 +16212,7 @@ function registerCapabilitySubagents(profile, toolRoot, toolFiles) {
16202
16212
  profile.subagentTemplates = {
16203
16213
  ...profile.subagentTemplates ?? {},
16204
16214
  ...Object.fromEntries(
16205
- subagentFiles.map(({ name, file }) => [name, fs45.readFileSync(path42.join(toolRoot, file), "utf-8")])
16215
+ subagentFiles.map(({ name, file }) => [name, fs45.readFileSync(path43.join(toolRoot, file), "utf-8")])
16206
16216
  )
16207
16217
  };
16208
16218
  if (!profile.claudeCode.tools.includes("Agent")) {
@@ -16247,10 +16257,10 @@ function listFiles(root) {
16247
16257
  const files = [];
16248
16258
  const visit = (dir) => {
16249
16259
  for (const entry of fs45.readdirSync(dir, { withFileTypes: true })) {
16250
- const absolute = path42.join(dir, entry.name);
16260
+ const absolute = path43.join(dir, entry.name);
16251
16261
  if (entry.isSymbolicLink()) continue;
16252
16262
  if (entry.isDirectory()) visit(absolute);
16253
- else if (entry.isFile()) files.push(path42.relative(root, absolute));
16263
+ else if (entry.isFile()) files.push(path43.relative(root, absolute));
16254
16264
  }
16255
16265
  };
16256
16266
  visit(root);
@@ -16273,8 +16283,8 @@ var init_loadSimpleCapability = __esm({
16273
16283
  if (!capability) {
16274
16284
  throw new Error(`Capability "${slug}" is not a valid simple capability folder`);
16275
16285
  }
16276
- const toolRoot = path42.join(capability.dir, "tools");
16277
- const skillRoot = path42.join(capability.dir, "skills");
16286
+ const toolRoot = path43.join(capability.dir, "tools");
16287
+ const skillRoot = path43.join(capability.dir, "skills");
16278
16288
  const toolFiles = listFiles(toolRoot);
16279
16289
  const skillFiles = listFiles(skillRoot);
16280
16290
  const parsedInput = parseInput(ctx.args.input);
@@ -16299,14 +16309,14 @@ var init_loadSimpleCapability = __esm({
16299
16309
  }
16300
16310
  if (requiredSubagents.length > 0) ctx.data.requiredSubagents = requiredSubagents;
16301
16311
  if (capability.contract?.execution === "script") {
16302
- ctx.data.capabilityScriptPath = path42.join(capability.dir, "tools", "run.sh");
16312
+ ctx.data.capabilityScriptPath = path43.join(capability.dir, "tools", "run.sh");
16303
16313
  ctx.data.capabilitySecretNames = capability.contract.secrets ?? [];
16304
16314
  ctx.data.capabilityScriptTimeoutMs = capability.contract.timeoutMs;
16305
16315
  }
16306
16316
  if (capability.config.outputSchema) {
16307
16317
  ctx.data.capabilityOutputSchema = capability.config.outputSchema;
16308
16318
  }
16309
- const outputPath = ctx.data.capabilityExecution === "agent" && capability.config.outputSchema ? path42.join(os6.tmpdir(), `kody-capability-output-${randomUUID2()}.json`) : void 0;
16319
+ const outputPath = ctx.data.capabilityExecution === "agent" && capability.config.outputSchema ? path43.join(os6.tmpdir(), `kody-capability-output-${randomUUID2()}.json`) : void 0;
16310
16320
  if (outputPath) ctx.data.capabilityOutputPath = outputPath;
16311
16321
  ctx.data.capabilityEnvironment = {
16312
16322
  ...capabilityInputEnvironment(input),
@@ -16329,7 +16339,7 @@ var init_loadSimpleCapability = __esm({
16329
16339
  ...skillFiles.flatMap((file) => [
16330
16340
  `### ${file}`,
16331
16341
  "",
16332
- fs45.readFileSync(path42.join(skillRoot, file), "utf-8"),
16342
+ fs45.readFileSync(path43.join(skillRoot, file), "utf-8"),
16333
16343
  ""
16334
16344
  ])
16335
16345
  ] : [],
@@ -16338,7 +16348,7 @@ var init_loadSimpleCapability = __esm({
16338
16348
  "## Tools",
16339
16349
  "",
16340
16350
  "Inspect or run these capability-owned files when needed:",
16341
- ...toolFiles.map((file) => `- ${path42.join(toolRoot, file)}`)
16351
+ ...toolFiles.map((file) => `- ${path43.join(toolRoot, file)}`)
16342
16352
  ] : [],
16343
16353
  "",
16344
16354
  ...capability.config.outputSchema ? [
@@ -16370,7 +16380,7 @@ var init_loadSimpleCapability = __esm({
16370
16380
 
16371
16381
  // src/taskContext.ts
16372
16382
  import * as fs46 from "fs";
16373
- import * as path43 from "path";
16383
+ import * as path44 from "path";
16374
16384
  function buildTaskContext(args) {
16375
16385
  return {
16376
16386
  schemaVersion: TASK_CONTEXT_SCHEMA_VERSION,
@@ -16387,7 +16397,7 @@ function persistTaskContext(cwd, ctx) {
16387
16397
  try {
16388
16398
  const dir = runtimeStatePath(cwd, "agent-runs", ctx.runId);
16389
16399
  fs46.mkdirSync(dir, { recursive: true });
16390
- const file = path43.join(dir, "task-context.json");
16400
+ const file = path44.join(dir, "task-context.json");
16391
16401
  fs46.writeFileSync(file, `${JSON.stringify(ctx, null, 2)}
16392
16402
  `);
16393
16403
  return file;
@@ -16815,19 +16825,19 @@ function parseAgencyModelProposal(raw) {
16815
16825
  function normalizeBundleFiles(bundle) {
16816
16826
  const seen = /* @__PURE__ */ new Set();
16817
16827
  return bundle.files.map((file, index) => {
16818
- const path58 = file.path.replace(/^\/+/, "");
16819
- const parts = path58.split("/");
16820
- if (!path58 || file.path.startsWith("/") || file.path.includes("\\") || parts.some((part) => !part || part === "." || part === "..")) {
16828
+ const path59 = file.path.replace(/^\/+/, "");
16829
+ const parts = path59.split("/");
16830
+ if (!path59 || file.path.startsWith("/") || file.path.includes("\\") || parts.some((part) => !part || part === "." || part === "..")) {
16821
16831
  throw new Error(`openAgencyModelReviewPr: files[${index}].path is unsafe`);
16822
16832
  }
16823
16833
  if (!/^(agents\/[^/]+\.md|capabilities\/[^/]+\/.+|goals\/(?:templates\/)?[^/]+\/.+|workflows\/[^/]+\.json)$/.test(
16824
- path58
16834
+ path59
16825
16835
  )) {
16826
16836
  throw new Error(`openAgencyModelReviewPr: files[${index}].path is not a supported definition path`);
16827
16837
  }
16828
- if (seen.has(path58)) throw new Error(`openAgencyModelReviewPr: duplicate generated file path: ${path58}`);
16829
- seen.add(path58);
16830
- return { path: path58, content: file.content.replace(/\r\n?/g, "\n") };
16838
+ if (seen.has(path59)) throw new Error(`openAgencyModelReviewPr: duplicate generated file path: ${path59}`);
16839
+ seen.add(path59);
16840
+ return { path: path59, content: file.content.replace(/\r\n?/g, "\n") };
16831
16841
  });
16832
16842
  }
16833
16843
  function buildProposalId(issueNumber, bundle, sourceLabel) {
@@ -17939,7 +17949,7 @@ var init_postResearchComment = __esm({
17939
17949
  // src/scripts/prepareBrowserAuth.ts
17940
17950
  import * as fs48 from "fs";
17941
17951
  import * as os7 from "os";
17942
- import * as path44 from "path";
17952
+ import * as path45 from "path";
17943
17953
  function appendAuthMessage(ctx, message) {
17944
17954
  const current = typeof ctx.data.qaAuthBlock === "string" ? ctx.data.qaAuthBlock.trim() : "";
17945
17955
  ctx.data.qaAuthBlock = current ? `${current}
@@ -17978,9 +17988,9 @@ async function githubJson(url, token) {
17978
17988
  return await response.json();
17979
17989
  }
17980
17990
  function writeKodyStorageState(input) {
17981
- const directory = fs48.mkdtempSync(path44.join(os7.tmpdir(), "kody-browser-auth-"));
17991
+ const directory = fs48.mkdtempSync(path45.join(os7.tmpdir(), "kody-browser-auth-"));
17982
17992
  fs48.chmodSync(directory, 448);
17983
- const file = path44.join(directory, "storage-state.json");
17993
+ const file = path45.join(directory, "storage-state.json");
17984
17994
  const now = Date.now();
17985
17995
  const repoEntry = {
17986
17996
  repoUrl: input.repoUrl,
@@ -18239,7 +18249,7 @@ var init_prepareCapabilityDelivery = __esm({
18239
18249
 
18240
18250
  // src/scripts/prepareSimpleCapabilityRuntime.ts
18241
18251
  import { isIP } from "net";
18242
- import * as path45 from "path";
18252
+ import * as path46 from "path";
18243
18253
  function requirementsFrom(ctx) {
18244
18254
  const raw = ctx.data.capabilityRequirements;
18245
18255
  return raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
@@ -18283,7 +18293,7 @@ function browserRuntime(ctx, requirements) {
18283
18293
  "--allowed-origins",
18284
18294
  origin,
18285
18295
  "--output-dir",
18286
- path45.resolve(ctx.cwd, "test-results", "quality-runs", qualityRunId)
18296
+ path46.resolve(ctx.cwd, "test-results", "quality-runs", qualityRunId)
18287
18297
  ]
18288
18298
  };
18289
18299
  }
@@ -18648,9 +18658,9 @@ function latestResult(raw, agentResult) {
18648
18658
  function recordField4(value) {
18649
18659
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
18650
18660
  }
18651
- function resolveDotted(root, path58) {
18652
- if (!path58) return void 0;
18653
- return path58.split(".").reduce((value, key) => recordField4(value)?.[key], root);
18661
+ function resolveDotted(root, path59) {
18662
+ if (!path59) return void 0;
18663
+ return path59.split(".").reduce((value, key) => recordField4(value)?.[key], root);
18654
18664
  }
18655
18665
  function stringValue5(value) {
18656
18666
  return typeof value === "string" && value.trim() ? value.trim() : null;
@@ -19492,7 +19502,7 @@ var init_previewBuildHelpers = __esm({
19492
19502
  // src/scripts/previewBuildRun.ts
19493
19503
  import { spawn as spawn5 } from "child_process";
19494
19504
  async function runCmd(cmd, args, opts = {}) {
19495
- await new Promise((resolve23, reject) => {
19505
+ await new Promise((resolve24, reject) => {
19496
19506
  const child = spawn5(cmd, args, {
19497
19507
  cwd: opts.cwd,
19498
19508
  env: { ...process.env, ...opts.env ?? {} },
@@ -19504,7 +19514,7 @@ async function runCmd(cmd, args, opts = {}) {
19504
19514
  }
19505
19515
  child.on("error", reject);
19506
19516
  child.on("close", (code) => {
19507
- if (code === 0) resolve23();
19517
+ if (code === 0) resolve24();
19508
19518
  else reject(new Error(`${cmd} ${args.join(" ")} exited ${code}`));
19509
19519
  });
19510
19520
  });
@@ -19576,12 +19586,12 @@ fi
19576
19586
 
19577
19587
  // src/scripts/runPreviewBuild.ts
19578
19588
  import { copyFile, writeFile } from "fs/promises";
19579
- import * as path46 from "path";
19589
+ import * as path47 from "path";
19580
19590
  import { fileURLToPath as fileURLToPath2 } from "url";
19581
19591
  function bundledDockerfilePath(mode) {
19582
- const here = path46.dirname(fileURLToPath2(import.meta.url));
19592
+ const here = path47.dirname(fileURLToPath2(import.meta.url));
19583
19593
  const file = mode === "dev" ? "default-Dockerfile.preview.dev" : "default-Dockerfile.preview.prod";
19584
- return path46.join(here, "preview-build-templates", file);
19594
+ return path47.join(here, "preview-build-templates", file);
19585
19595
  }
19586
19596
  function required(name) {
19587
19597
  const v = (process.env[name] ?? "").trim();
@@ -19816,10 +19826,10 @@ var init_runPreviewBuild = __esm({
19816
19826
  console.log(`[preview-build] vault: ${Object.keys(buildEnv).length} secrets, mode=${buildMode}`);
19817
19827
  if (Object.keys(buildEnv).length > 0) {
19818
19828
  const lines = Object.entries(buildEnv).map(([k, v]) => `${k}=${JSON.stringify(v)}`);
19819
- await writeFile(path46.join(ctx.cwd, ".env.production.local"), `${lines.join("\n")}
19829
+ await writeFile(path47.join(ctx.cwd, ".env.production.local"), `${lines.join("\n")}
19820
19830
  `, "utf8");
19821
19831
  }
19822
- const consumerDockerfile = path46.join(ctx.cwd, "Dockerfile.preview");
19832
+ const consumerDockerfile = path47.join(ctx.cwd, "Dockerfile.preview");
19823
19833
  const { stat } = await import("fs/promises");
19824
19834
  let hasConsumerDockerfile = false;
19825
19835
  try {
@@ -20004,7 +20014,7 @@ var init_tickShellRunner = __esm({
20004
20014
 
20005
20015
  // src/scripts/runScheduledImplementationTick.ts
20006
20016
  import * as fs49 from "fs";
20007
- import * as path47 from "path";
20017
+ import * as path48 from "path";
20008
20018
  var runScheduledImplementationTick;
20009
20019
  var init_runScheduledImplementationTick = __esm({
20010
20020
  "src/scripts/runScheduledImplementationTick.ts"() {
@@ -20025,13 +20035,13 @@ var init_runScheduledImplementationTick = __esm({
20025
20035
  ctx.output.reason = `runScheduledImplementationTick: args.slug or ctx.args.${slugArg} must be non-empty capability slug`;
20026
20036
  return;
20027
20037
  }
20028
- const capability = resolveCapabilityFolder(slug, path47.resolve(ctx.cwd, jobsDir));
20038
+ const capability = resolveCapabilityFolder(slug, path48.resolve(ctx.cwd, jobsDir));
20029
20039
  if (!capability) {
20030
20040
  ctx.output.exitCode = 99;
20031
20041
  ctx.output.reason = `runScheduledImplementationTick: capability folder not found or incomplete: ${slug} (searched ${jobsDir} and company store)`;
20032
20042
  return;
20033
20043
  }
20034
- const shellPath = path47.join(profile.dir, shell);
20044
+ const shellPath = path48.join(profile.dir, shell);
20035
20045
  if (!fs49.existsSync(shellPath)) {
20036
20046
  ctx.output.exitCode = 99;
20037
20047
  ctx.output.reason = `runScheduledImplementationTick: shell not found: ${shell} (looked in ${profile.dir})`;
@@ -20150,7 +20160,7 @@ var init_runSimpleCapabilityScript = __esm({
20150
20160
 
20151
20161
  // src/scripts/runTickScript.ts
20152
20162
  import * as fs51 from "fs";
20153
- import * as path48 from "path";
20163
+ import * as path49 from "path";
20154
20164
  var runTickScript;
20155
20165
  var init_runTickScript = __esm({
20156
20166
  "src/scripts/runTickScript.ts"() {
@@ -20170,10 +20180,10 @@ var init_runTickScript = __esm({
20170
20180
  ctx.output.reason = `runTickScript: ctx.args.${slugArg} must be a non-empty slug`;
20171
20181
  return;
20172
20182
  }
20173
- const capability = readCapabilityFolder(path48.resolve(ctx.cwd, jobsDir), slug);
20183
+ const capability = readCapabilityFolder(path49.resolve(ctx.cwd, jobsDir), slug);
20174
20184
  if (!capability) {
20175
20185
  ctx.output.exitCode = 99;
20176
- ctx.output.reason = `runTickScript: capability folder not found or incomplete: ${path48.resolve(ctx.cwd, jobsDir, slug)}`;
20186
+ ctx.output.reason = `runTickScript: capability folder not found or incomplete: ${path49.resolve(ctx.cwd, jobsDir, slug)}`;
20177
20187
  return;
20178
20188
  }
20179
20189
  const tickScript = capability.config.tickScript;
@@ -20182,7 +20192,7 @@ var init_runTickScript = __esm({
20182
20192
  ctx.output.reason = `runTickScript: capability ${slug} has no \`tickScript\` in profile.json \u2014 route via capability-tick instead`;
20183
20193
  return;
20184
20194
  }
20185
- const scriptPath = path48.isAbsolute(tickScript) ? tickScript : path48.join(ctx.cwd, tickScript);
20195
+ const scriptPath = path49.isAbsolute(tickScript) ? tickScript : path49.join(ctx.cwd, tickScript);
20186
20196
  if (!fs51.existsSync(scriptPath)) {
20187
20197
  ctx.output.exitCode = 99;
20188
20198
  ctx.output.reason = `runTickScript: tickScript not found: ${scriptPath}`;
@@ -20465,7 +20475,7 @@ var init_syncFlow = __esm({
20465
20475
  });
20466
20476
 
20467
20477
  // src/scripts/validateAgencyModelProposal.ts
20468
- import * as path49 from "path";
20478
+ import * as path50 from "path";
20469
20479
  function validateModelBundle(bundle, expectedKind, options = {}) {
20470
20480
  const failures = [];
20471
20481
  validateOneModel(bundle.model, bundle.files, "model", true, failures, expectedKind, options);
@@ -20783,7 +20793,7 @@ var init_validateAgencyModelProposal = __esm({
20783
20793
  const bundle = parseAgencyModelProposal(raw);
20784
20794
  const expectedKind = readExpectedModelKind(args);
20785
20795
  const failures = validateModelBundle(bundle, expectedKind, {
20786
- capabilityRoot: path49.join(ctx.cwd, ".kody", "capabilities")
20796
+ capabilityRoot: path50.join(ctx.cwd, ".kody", "capabilities")
20787
20797
  });
20788
20798
  if (failures.length > 0) {
20789
20799
  throw new Error(`validateAgencyModelProposal: ${failures.join("; ")}`);
@@ -20846,7 +20856,7 @@ function stripAnsi2(s) {
20846
20856
  return s.replace(ANSI_RE2, "");
20847
20857
  }
20848
20858
  function runCommand2(command, cwd) {
20849
- return new Promise((resolve23) => {
20859
+ return new Promise((resolve24) => {
20850
20860
  const child = spawn6(command, {
20851
20861
  cwd,
20852
20862
  shell: true,
@@ -20873,11 +20883,11 @@ function runCommand2(command, cwd) {
20873
20883
  }, TEST_TIMEOUT_MS);
20874
20884
  child.on("exit", (code) => {
20875
20885
  clearTimeout(timer);
20876
- resolve23({ exitCode: code ?? -1, output: Buffer.concat(buffers).toString("utf-8") });
20886
+ resolve24({ exitCode: code ?? -1, output: Buffer.concat(buffers).toString("utf-8") });
20877
20887
  });
20878
20888
  child.on("error", (err) => {
20879
20889
  clearTimeout(timer);
20880
- resolve23({ exitCode: -1, output: err.message });
20890
+ resolve24({ exitCode: -1, output: err.message });
20881
20891
  });
20882
20892
  });
20883
20893
  }
@@ -21291,21 +21301,21 @@ function lineStream(stream) {
21291
21301
  tryDeliver();
21292
21302
  });
21293
21303
  return {
21294
- next: (timeoutMs) => new Promise((resolve23) => {
21304
+ next: (timeoutMs) => new Promise((resolve24) => {
21295
21305
  if (queue.length > 0) {
21296
- resolve23(queue.shift());
21306
+ resolve24(queue.shift());
21297
21307
  return;
21298
21308
  }
21299
21309
  if (ended) {
21300
- resolve23(null);
21310
+ resolve24(null);
21301
21311
  return;
21302
21312
  }
21303
- waiter = resolve23;
21313
+ waiter = resolve24;
21304
21314
  const t = setTimeout(
21305
21315
  () => {
21306
- if (waiter === resolve23) {
21316
+ if (waiter === resolve24) {
21307
21317
  waiter = null;
21308
- resolve23(null);
21318
+ resolve24(null);
21309
21319
  }
21310
21320
  },
21311
21321
  Math.max(0, timeoutMs)
@@ -21707,15 +21717,15 @@ var init_scripts = __esm({
21707
21717
 
21708
21718
  // src/stateWorkspace.ts
21709
21719
  import * as fs53 from "fs";
21710
- import * as path50 from "path";
21720
+ import * as path51 from "path";
21711
21721
  function tenantId(config) {
21712
21722
  const owner = config.github?.owner?.trim() || process.env.GITHUB_REPOSITORY?.split("/")[0]?.trim();
21713
21723
  const repo = config.github?.repo?.trim() || process.env.GITHUB_REPOSITORY?.split("/")[1]?.trim();
21714
21724
  return owner && repo ? `${owner}/${repo}` : null;
21715
21725
  }
21716
21726
  function writeRuntimeFile(cwd, relativePath, content) {
21717
- const target = path50.join(cwd, RUNTIME_ROOT, relativePath);
21718
- fs53.mkdirSync(path50.dirname(target), { recursive: true });
21727
+ const target = path51.join(cwd, RUNTIME_ROOT, relativePath);
21728
+ fs53.mkdirSync(path51.dirname(target), { recursive: true });
21719
21729
  fs53.writeFileSync(target, content, "utf8");
21720
21730
  }
21721
21731
  function record(value) {
@@ -21781,10 +21791,10 @@ async function hydrateStateWorkspace(config, cwd, backendOverride) {
21781
21791
  throw new Error("Kody backend access is required for runtime workspace documents");
21782
21792
  return;
21783
21793
  }
21784
- const key = `${path50.resolve(cwd)}|${tenant}`;
21794
+ const key = `${path51.resolve(cwd)}|${tenant}`;
21785
21795
  if (hydratedWorkspaces.has(key)) return;
21786
21796
  const backend = backendOverride ?? createStateBackendFromEnv();
21787
- const root = path50.join(cwd, RUNTIME_ROOT);
21797
+ const root = path51.join(cwd, RUNTIME_ROOT);
21788
21798
  fs53.rmSync(root, { recursive: true, force: true });
21789
21799
  await Promise.all([
21790
21800
  hydratePrefix(backend, tenant, cwd, "context:"),
@@ -21801,7 +21811,7 @@ var init_stateWorkspace = __esm({
21801
21811
  "src/stateWorkspace.ts"() {
21802
21812
  "use strict";
21803
21813
  init_state_backend();
21804
- RUNTIME_ROOT = path50.join(".kody-engine", "runtime");
21814
+ RUNTIME_ROOT = path51.join(".kody-engine", "runtime");
21805
21815
  hydratedWorkspaces = /* @__PURE__ */ new Set();
21806
21816
  }
21807
21817
  });
@@ -21874,7 +21884,7 @@ var init_tools = __esm({
21874
21884
  import { spawn as spawn8 } from "child_process";
21875
21885
  import * as fs54 from "fs";
21876
21886
  import * as os8 from "os";
21877
- import * as path51 from "path";
21887
+ import * as path52 from "path";
21878
21888
  function isMutatingPostflight(scriptName) {
21879
21889
  return MUTATING_POSTFLIGHTS.has(scriptName ?? "");
21880
21890
  }
@@ -22131,7 +22141,7 @@ async function runImplementation(profileName, input) {
22131
22141
  const reason = input.abortController.signal.reason;
22132
22142
  throw reason instanceof Error ? reason : new Error("agent invocation aborted");
22133
22143
  }
22134
- const externalPlugins = (profile.claudeCode.plugins ?? []).map((p) => path51.isAbsolute(p) ? p : path51.resolve(profile.dir, p)).filter((p) => p.length > 0);
22144
+ const externalPlugins = (profile.claudeCode.plugins ?? []).map((p) => path52.isAbsolute(p) ? p : path52.resolve(profile.dir, p)).filter((p) => p.length > 0);
22135
22145
  const syntheticPath = ctx.data.syntheticPluginPath;
22136
22146
  const pluginPaths = [...externalPlugins, ...syntheticPath ? [syntheticPath] : []];
22137
22147
  const agents = loadSubagents(profile);
@@ -22613,13 +22623,13 @@ function clearStampedLifecycleLabels(profile, ctx) {
22613
22623
  function resolveProfilePath(profileName, cwd = process.cwd()) {
22614
22624
  const found = resolveImplementation(profileName, getRuntimeProfileRootsForCwd(cwd));
22615
22625
  if (found) return found;
22616
- const here = path51.dirname(new URL(import.meta.url).pathname);
22626
+ const here = path52.dirname(new URL(import.meta.url).pathname);
22617
22627
  const candidates = [
22618
- path51.join(here, "implementations", profileName, "profile.json"),
22628
+ path52.join(here, "implementations", profileName, "profile.json"),
22619
22629
  // same-dir sibling (dev)
22620
- path51.join(here, "..", "implementations", profileName, "profile.json"),
22630
+ path52.join(here, "..", "implementations", profileName, "profile.json"),
22621
22631
  // up one (prod: dist/bin → dist/implementations)
22622
- path51.join(here, "..", "src", "implementations", profileName, "profile.json")
22632
+ path52.join(here, "..", "src", "implementations", profileName, "profile.json")
22623
22633
  // fallback
22624
22634
  ];
22625
22635
  for (const c of candidates) {
@@ -22738,7 +22748,7 @@ function resolveShellTimeoutMs(entry) {
22738
22748
  }
22739
22749
  async function runShellEntry(entry, ctx, profile) {
22740
22750
  const shellName = entry.shell;
22741
- const shellPath = path51.join(profile.dir, shellName);
22751
+ const shellPath = path52.join(profile.dir, shellName);
22742
22752
  if (!fs54.existsSync(shellPath)) {
22743
22753
  ctx.skipAgent = true;
22744
22754
  ctx.output.exitCode = 99;
@@ -22746,7 +22756,7 @@ async function runShellEntry(entry, ctx, profile) {
22746
22756
  return;
22747
22757
  }
22748
22758
  const positional = entry.with ? Object.values(entry.with).map((v) => String(v)) : [];
22749
- const outputFile = path51.join(
22759
+ const outputFile = path52.join(
22750
22760
  os8.tmpdir(),
22751
22761
  `kody-shell-output-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`
22752
22762
  );
@@ -22776,14 +22786,14 @@ async function runShellEntry(entry, ctx, profile) {
22776
22786
  let killTimer;
22777
22787
  let escalateTimer;
22778
22788
  const result = await new Promise(
22779
- (resolve23) => {
22789
+ (resolve24) => {
22780
22790
  let settled = false;
22781
22791
  const settle = (code, signal, spawnErr) => {
22782
22792
  if (settled) return;
22783
22793
  settled = true;
22784
22794
  if (killTimer) clearTimeout(killTimer);
22785
22795
  if (escalateTimer) clearTimeout(escalateTimer);
22786
- resolve23({ code, signal, spawnErr });
22796
+ resolve24({ code, signal, spawnErr });
22787
22797
  };
22788
22798
  child.on("error", (err) => settle(null, null, err));
22789
22799
  child.on("close", (code, signal) => settle(code, signal));
@@ -23828,11 +23838,11 @@ function exhaustedWorkflowTransitions(step, data, counts) {
23828
23838
  }
23829
23839
  function workflowResultConditionPaths(transitions) {
23830
23840
  return transitions.flatMap(
23831
- (transition) => Object.keys(transition.when ?? {}).filter((path58) => path58.startsWith("result."))
23841
+ (transition) => Object.keys(transition.when ?? {}).filter((path59) => path59.startsWith("result."))
23832
23842
  );
23833
23843
  }
23834
23844
  function conditionMatches(condition, context) {
23835
- return Object.entries(condition).every(([path58, expected]) => valueMatches(resolveDottedPath2(context, path58), expected));
23845
+ return Object.entries(condition).every(([path59, expected]) => valueMatches(resolveDottedPath2(context, path59), expected));
23836
23846
  }
23837
23847
  function withWorkflowBoundaryEval(capability, result) {
23838
23848
  const capabilityKind = capability.config.capabilityKind;
@@ -24307,7 +24317,7 @@ function translateOpenAISseToBrain(opts) {
24307
24317
 
24308
24318
  // src/servers/brain-serve.ts
24309
24319
  import { createServer as createServer2 } from "http";
24310
- import * as path54 from "path";
24320
+ import * as path55 from "path";
24311
24321
 
24312
24322
  // src/chat/loop.ts
24313
24323
  init_agent();
@@ -24316,12 +24326,12 @@ init_config();
24316
24326
  init_registry();
24317
24327
  init_task_artifacts();
24318
24328
  import * as fs18 from "fs";
24319
- import * as path19 from "path";
24329
+ import * as path20 from "path";
24320
24330
 
24321
24331
  // src/chat/attachments.ts
24322
24332
  init_runtimePaths();
24323
24333
  import * as fs15 from "fs";
24324
- import * as path16 from "path";
24334
+ import * as path17 from "path";
24325
24335
  var INLINE_ATTACHMENT_RE = /(?:\[(?:Image|File): ([^\]]*)\]\n)?data:([\w.+-]+\/[\w.+-]+);base64,([A-Za-z0-9+/=]+)/g;
24326
24336
  var EXT_BY_MIME = {
24327
24337
  "image/png": "png",
@@ -24357,7 +24367,7 @@ function prepareAttachments(turns, cwd, sessionId) {
24357
24367
  fs15.mkdirSync(dir, { recursive: true });
24358
24368
  dirEnsured = true;
24359
24369
  }
24360
- const filePath = path16.join(dir, `${imageCounter}.${extFor(mime)}`);
24370
+ const filePath = path17.join(dir, `${imageCounter}.${extFor(mime)}`);
24361
24371
  fs15.writeFileSync(filePath, Buffer.from(data, "base64"));
24362
24372
  imageCounter += 1;
24363
24373
  imagePaths.push(filePath);
@@ -24376,7 +24386,7 @@ function prepareAttachments(turns, cwd, sessionId) {
24376
24386
  // src/chat/codex-app-server.ts
24377
24387
  import { spawn as spawn3 } from "child_process";
24378
24388
  import * as fs16 from "fs";
24379
- import * as path17 from "path";
24389
+ import * as path18 from "path";
24380
24390
  import { createInterface } from "readline";
24381
24391
  function codexThreadStartParams(args) {
24382
24392
  return {
@@ -24461,9 +24471,9 @@ var CodexAppServerClient = class {
24461
24471
  await this.request("thread/resume", { threadId });
24462
24472
  }
24463
24473
  async runTurn(args) {
24464
- await new Promise((resolve23, reject) => {
24474
+ await new Promise((resolve24, reject) => {
24465
24475
  this.process.turnWaiters.set(args.threadId, {
24466
- resolve: resolve23,
24476
+ resolve: resolve24,
24467
24477
  reject,
24468
24478
  onNotification: args.onNotification,
24469
24479
  queue: Promise.resolve()
@@ -24480,8 +24490,8 @@ var CodexAppServerClient = class {
24480
24490
  }
24481
24491
  request(method, params) {
24482
24492
  const id = this.process.nextId++;
24483
- return new Promise((resolve23, reject) => {
24484
- this.process.pending.set(id, { resolve: resolve23, reject });
24493
+ return new Promise((resolve24, reject) => {
24494
+ this.process.pending.set(id, { resolve: resolve24, reject });
24485
24495
  this.process.child.stdin.write(`${JSON.stringify({ method, id, params })}
24486
24496
  `);
24487
24497
  });
@@ -24547,7 +24557,7 @@ var CodexAppServerClient = class {
24547
24557
  };
24548
24558
  var clients = /* @__PURE__ */ new Map();
24549
24559
  function threadMapPath(cwd) {
24550
- return path17.join(cwd, ".kody-engine", "runtime", "codex-threads.json");
24560
+ return path18.join(cwd, ".kody-engine", "runtime", "codex-threads.json");
24551
24561
  }
24552
24562
  function readThreadMap(cwd) {
24553
24563
  try {
@@ -24564,7 +24574,7 @@ function readThreadMap(cwd) {
24564
24574
  }
24565
24575
  function writeThreadMap(cwd, map) {
24566
24576
  const file = threadMapPath(cwd);
24567
- fs16.mkdirSync(path17.dirname(file), { recursive: true });
24577
+ fs16.mkdirSync(path18.dirname(file), { recursive: true });
24568
24578
  fs16.writeFileSync(file, `${JSON.stringify(map, null, 2)}
24569
24579
  `);
24570
24580
  }
@@ -24656,7 +24666,7 @@ async function runCodexChatTurn(args) {
24656
24666
 
24657
24667
  // src/chat/events.ts
24658
24668
  import * as fs17 from "fs";
24659
- import * as path18 from "path";
24669
+ import * as path19 from "path";
24660
24670
  import posixPath2 from "path/posix";
24661
24671
  var BackendEventSink = class {
24662
24672
  constructor(append, tenantId2, sessionId) {
@@ -24672,7 +24682,7 @@ var BackendEventSink = class {
24672
24682
  }
24673
24683
  };
24674
24684
  function eventsFilePath(cwd, sessionId) {
24675
- return path18.join(cwd, ".kody-engine", "runtime", "events", `${sessionId}.jsonl`);
24685
+ return path19.join(cwd, ".kody-engine", "runtime", "events", `${sessionId}.jsonl`);
24676
24686
  }
24677
24687
  var FileSink = class {
24678
24688
  constructor(file) {
@@ -24680,7 +24690,7 @@ var FileSink = class {
24680
24690
  }
24681
24691
  file;
24682
24692
  async emit(event) {
24683
- fs17.mkdirSync(path18.dirname(this.file), { recursive: true });
24693
+ fs17.mkdirSync(path19.dirname(this.file), { recursive: true });
24684
24694
  fs17.appendFileSync(this.file, `${JSON.stringify(event)}
24685
24695
  `);
24686
24696
  }
@@ -25068,7 +25078,7 @@ async function runChatTurn(opts) {
25068
25078
  quiet: opts.quiet,
25069
25079
  additionalDirectories: [
25070
25080
  taskArtifactsPaths.absDir,
25071
- ...Array.from(new Set(imagePaths.map((p2) => path19.dirname(p2))))
25081
+ ...Array.from(new Set(imagePaths.map((p2) => path20.dirname(p2))))
25072
25082
  ],
25073
25083
  systemPromptAppend: systemPrompt,
25074
25084
  ...opts.reasoningEffort ? { reasoningEffort: opts.reasoningEffort } : {},
@@ -25256,7 +25266,7 @@ async function emit(sink, type, sessionId, suffix, payload) {
25256
25266
  var MEMORY_INDEX_REL = ".kody-engine/runtime/memory/INDEX.md";
25257
25267
  var MAX_INDEX_BYTES = 8e3;
25258
25268
  function readMemoryIndexBlock(cwd) {
25259
- const indexPath = path19.join(cwd, MEMORY_INDEX_REL);
25269
+ const indexPath = path20.join(cwd, MEMORY_INDEX_REL);
25260
25270
  let raw;
25261
25271
  try {
25262
25272
  raw = fs18.readFileSync(indexPath, "utf-8");
@@ -25279,7 +25289,7 @@ _\u2026 (memory index truncated; use recall_search to read more)_` : trimmed;
25279
25289
  var CONTEXT_DIR_REL = ".kody-engine/runtime/context";
25280
25290
  var MAX_CONTEXT_BYTES = 12e3;
25281
25291
  function readContextBlock(cwd) {
25282
- const dir = path19.join(cwd, CONTEXT_DIR_REL);
25292
+ const dir = path20.join(cwd, CONTEXT_DIR_REL);
25283
25293
  let files;
25284
25294
  try {
25285
25295
  files = fs18.readdirSync(dir).filter((f) => f.endsWith(".md")).sort();
@@ -25289,7 +25299,7 @@ function readContextBlock(cwd) {
25289
25299
  const sections = [];
25290
25300
  for (const file of files) {
25291
25301
  try {
25292
- const content = fs18.readFileSync(path19.join(dir, file), "utf-8").trim();
25302
+ const content = fs18.readFileSync(path20.join(dir, file), "utf-8").trim();
25293
25303
  if (content) sections.push(`### ${file.replace(/\.md$/, "")}
25294
25304
 
25295
25305
  ${content}`);
@@ -25315,7 +25325,7 @@ var SYSTEM_PROMPT_OVERRIDE_REL = ".kody-engine/runtime/system-prompt.md";
25315
25325
  function readSystemPromptOverride(cwd) {
25316
25326
  let raw;
25317
25327
  try {
25318
- raw = fs18.readFileSync(path19.join(cwd, SYSTEM_PROMPT_OVERRIDE_REL), "utf-8");
25328
+ raw = fs18.readFileSync(path20.join(cwd, SYSTEM_PROMPT_OVERRIDE_REL), "utf-8");
25319
25329
  } catch {
25320
25330
  return null;
25321
25331
  }
@@ -25323,7 +25333,7 @@ function readSystemPromptOverride(cwd) {
25323
25333
  return trimmed.length > 0 ? trimmed : null;
25324
25334
  }
25325
25335
  function readInstructionsBlock(cwd) {
25326
- const instructionsPath = path19.join(cwd, INSTRUCTIONS_REL);
25336
+ const instructionsPath = path20.join(cwd, INSTRUCTIONS_REL);
25327
25337
  let raw;
25328
25338
  try {
25329
25339
  raw = fs18.readFileSync(instructionsPath, "utf-8");
@@ -25361,10 +25371,10 @@ function resolveBrainDriver(runtime) {
25361
25371
 
25362
25372
  // src/chat/session.ts
25363
25373
  import * as fs19 from "fs";
25364
- import * as path20 from "path";
25374
+ import * as path21 from "path";
25365
25375
  import posixPath3 from "path/posix";
25366
25376
  function sessionFilePath(cwd, sessionId) {
25367
- return path20.join(cwd, ".kody-engine", "runtime", "sessions", `${sessionId}.jsonl`);
25377
+ return path21.join(cwd, ".kody-engine", "runtime", "sessions", `${sessionId}.jsonl`);
25368
25378
  }
25369
25379
  function readSession(file) {
25370
25380
  if (!fs19.existsSync(file)) return [];
@@ -25392,7 +25402,7 @@ init_state_backend();
25392
25402
  init_workflowDefinitions();
25393
25403
  import { createHash as createHash2 } from "crypto";
25394
25404
  import * as fs21 from "fs";
25395
- import * as path22 from "path";
25405
+ import * as path23 from "path";
25396
25406
  var SLUG_RE = /^[a-z0-9][a-z0-9_-]{0,127}$/;
25397
25407
  var REPOSITORY_OWNED_NAMESPACES = ["loops"];
25398
25408
  function assertSafeDefinitionPath(filePath) {
@@ -25424,8 +25434,8 @@ function verifyDefinition(definition) {
25424
25434
  }
25425
25435
  function writeBundle(root, bundle) {
25426
25436
  for (const [filePath, contents] of Object.entries(bundle.files)) {
25427
- const target = path22.join(root, filePath);
25428
- fs21.mkdirSync(path22.dirname(target), { recursive: true });
25437
+ const target = path23.join(root, filePath);
25438
+ fs21.mkdirSync(path23.dirname(target), { recursive: true });
25429
25439
  fs21.writeFileSync(target, contents, "utf8");
25430
25440
  }
25431
25441
  }
@@ -25434,22 +25444,22 @@ function writeDefinition(root, kind, definition) {
25434
25444
  if (kind === "agent") {
25435
25445
  const raw = bundle.files["agent.md"];
25436
25446
  if (typeof raw !== "string") throw new Error(`agent definition ${definition.slug} is missing agent.md`);
25437
- fs21.writeFileSync(path22.join(root, "agents", `${definition.slug}.md`), raw, "utf8");
25447
+ fs21.writeFileSync(path23.join(root, "agents", `${definition.slug}.md`), raw, "utf8");
25438
25448
  return;
25439
25449
  }
25440
25450
  if (kind === "goal") {
25441
- writeBundle(path22.join(root, "goals", definition.slug), bundle);
25451
+ writeBundle(path23.join(root, "goals", definition.slug), bundle);
25442
25452
  return;
25443
25453
  }
25444
25454
  if (kind === "implementation") {
25445
- writeBundle(path22.join(root, "implementations", definition.slug), bundle);
25455
+ writeBundle(path23.join(root, "implementations", definition.slug), bundle);
25446
25456
  return;
25447
25457
  }
25448
25458
  if (kind === "asset") {
25449
- writeBundle(path22.join(root, "shared"), bundle);
25459
+ writeBundle(path23.join(root, "shared"), bundle);
25450
25460
  return;
25451
25461
  }
25452
- writeBundle(path22.join(root, "capabilities", definition.slug), bundle);
25462
+ writeBundle(path23.join(root, "capabilities", definition.slug), bundle);
25453
25463
  }
25454
25464
  function writeWorkflow(root, document) {
25455
25465
  const workflow = normalizeWorkflowDefinition(document.definition);
@@ -25457,28 +25467,28 @@ function writeWorkflow(root, document) {
25457
25467
  const contents = `${JSON.stringify(workflow, null, 2)}
25458
25468
  `;
25459
25469
  const bundle = { schemaVersion: 1, files: { "workflow.json": contents } };
25460
- const target = path22.join(root, workflowDefinitionPath(document.workflowId));
25461
- fs21.mkdirSync(path22.dirname(target), { recursive: true });
25470
+ const target = path23.join(root, workflowDefinitionPath(document.workflowId));
25471
+ fs21.mkdirSync(path23.dirname(target), { recursive: true });
25462
25472
  fs21.writeFileSync(target, contents, "utf8");
25463
25473
  return definitionVersion(bundle);
25464
25474
  }
25465
25475
  function preserveRepositoryDefinitions(root, staging) {
25466
25476
  for (const namespace of REPOSITORY_OWNED_NAMESPACES) {
25467
- const source = path22.join(root, namespace);
25477
+ const source = path23.join(root, namespace);
25468
25478
  if (!fs21.existsSync(source)) continue;
25469
- fs21.cpSync(source, path22.join(staging, namespace), { recursive: true });
25479
+ fs21.cpSync(source, path23.join(staging, namespace), { recursive: true });
25470
25480
  }
25471
25481
  }
25472
25482
  async function hydrateDefinitions(options) {
25473
- const root = path22.join(options.cwd, ".kody-engine", "definitions");
25483
+ const root = path23.join(options.cwd, ".kody-engine", "definitions");
25474
25484
  const staging = `${root}.tmp-${process.pid}-${Date.now()}`;
25475
25485
  fs21.rmSync(staging, { recursive: true, force: true });
25476
- fs21.mkdirSync(path22.join(staging, "agents"), { recursive: true });
25477
- fs21.mkdirSync(path22.join(staging, "capabilities"), { recursive: true });
25478
- fs21.mkdirSync(path22.join(staging, "goals"), { recursive: true });
25479
- fs21.mkdirSync(path22.join(staging, "implementations"), { recursive: true });
25480
- fs21.mkdirSync(path22.join(staging, "shared"), { recursive: true });
25481
- fs21.mkdirSync(path22.join(staging, "workflows"), { recursive: true });
25486
+ fs21.mkdirSync(path23.join(staging, "agents"), { recursive: true });
25487
+ fs21.mkdirSync(path23.join(staging, "capabilities"), { recursive: true });
25488
+ fs21.mkdirSync(path23.join(staging, "goals"), { recursive: true });
25489
+ fs21.mkdirSync(path23.join(staging, "implementations"), { recursive: true });
25490
+ fs21.mkdirSync(path23.join(staging, "shared"), { recursive: true });
25491
+ fs21.mkdirSync(path23.join(staging, "workflows"), { recursive: true });
25482
25492
  try {
25483
25493
  const [capabilities, agents, goals, implementations, assets, workflows] = await Promise.all([
25484
25494
  options.backend.listDefinitions(options.tenantId, "capability"),
@@ -25519,7 +25529,7 @@ async function hydrateDefinitions(options) {
25519
25529
  hydratedAt: (/* @__PURE__ */ new Date()).toISOString(),
25520
25530
  versions: Object.fromEntries(Object.entries(versions).sort(([left], [right]) => left.localeCompare(right)))
25521
25531
  };
25522
- fs21.writeFileSync(path22.join(staging, "manifest.json"), `${JSON.stringify(manifest, null, 2)}
25532
+ fs21.writeFileSync(path23.join(staging, "manifest.json"), `${JSON.stringify(manifest, null, 2)}
25523
25533
  `, "utf8");
25524
25534
  fs21.rmSync(root, { recursive: true, force: true });
25525
25535
  fs21.renameSync(staging, root);
@@ -25548,7 +25558,7 @@ async function hydrateDefinitionsFromEnv(cwd = process.cwd(), env = process.env)
25548
25558
  // src/kody-cli.ts
25549
25559
  import { execFileSync as execFileSync24 } from "child_process";
25550
25560
  import * as fs55 from "fs";
25551
- import * as path52 from "path";
25561
+ import * as path53 from "path";
25552
25562
 
25553
25563
  // src/app-auth.ts
25554
25564
  import { createSign } from "crypto";
@@ -26350,9 +26360,9 @@ async function resolveAuthToken(env = process.env) {
26350
26360
  return void 0;
26351
26361
  }
26352
26362
  function detectPackageManager2(cwd) {
26353
- if (fs55.existsSync(path52.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
26354
- if (fs55.existsSync(path52.join(cwd, "yarn.lock"))) return "yarn";
26355
- if (fs55.existsSync(path52.join(cwd, "bun.lockb"))) return "bun";
26363
+ if (fs55.existsSync(path53.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
26364
+ if (fs55.existsSync(path53.join(cwd, "yarn.lock"))) return "yarn";
26365
+ if (fs55.existsSync(path53.join(cwd, "bun.lockb"))) return "bun";
26356
26366
  return "npm";
26357
26367
  }
26358
26368
  function shouldChainScheduledWatch(match) {
@@ -26485,7 +26495,7 @@ async function runCi(argv) {
26485
26495
  return 0;
26486
26496
  }
26487
26497
  const args = parseCiArgs(argv);
26488
- const cwd = args.cwd ? path52.resolve(args.cwd) : process.cwd();
26498
+ const cwd = args.cwd ? path53.resolve(args.cwd) : process.cwd();
26489
26499
  try {
26490
26500
  const n = unpackAllSecrets();
26491
26501
  if (n > 0) process.stdout.write(`\u2192 kody: unpacked ${n} secret(s) from ALL_SECRETS
@@ -26969,7 +26979,7 @@ init_repoWorkspace();
26969
26979
  // src/scripts/brainTurnLog.ts
26970
26980
  init_runtimePaths();
26971
26981
  import * as fs56 from "fs";
26972
- import * as path53 from "path";
26982
+ import * as path54 from "path";
26973
26983
  import posixPath4 from "path/posix";
26974
26984
  var live = /* @__PURE__ */ new Map();
26975
26985
  function brainEventsFilePath(dir, chatId) {
@@ -27016,7 +27026,7 @@ function beginTurn(dir, chatId) {
27016
27026
  };
27017
27027
  live.set(chatId, state);
27018
27028
  const p = brainEventsFilePath(dir, chatId);
27019
- fs56.mkdirSync(path53.dirname(p), { recursive: true });
27029
+ fs56.mkdirSync(path54.dirname(p), { recursive: true });
27020
27030
  return (event) => {
27021
27031
  state.seq += 1;
27022
27032
  const rec = { seq: state.seq, turn, ts: Date.now(), event };
@@ -27154,17 +27164,17 @@ function authOk(req, expected) {
27154
27164
  return false;
27155
27165
  }
27156
27166
  function readJsonBody(req) {
27157
- return new Promise((resolve23, reject) => {
27167
+ return new Promise((resolve24, reject) => {
27158
27168
  const chunks = [];
27159
27169
  req.on("data", (c) => chunks.push(c));
27160
27170
  req.on("end", () => {
27161
27171
  const raw = Buffer.concat(chunks).toString("utf-8");
27162
27172
  if (!raw.trim()) {
27163
- resolve23({});
27173
+ resolve24({});
27164
27174
  return;
27165
27175
  }
27166
27176
  try {
27167
- resolve23(JSON.parse(raw));
27177
+ resolve24(JSON.parse(raw));
27168
27178
  } catch (err) {
27169
27179
  reject(err instanceof Error ? err : new Error(String(err)));
27170
27180
  }
@@ -27456,7 +27466,7 @@ function buildServer(opts) {
27456
27466
  const runTurn = opts.runTurn ?? runChatTurn;
27457
27467
  const createStore = opts.createStore ?? createSessionStore;
27458
27468
  const cloneRepo = opts.cloneRepo ?? defaultCloneRepo;
27459
- const reposRoot = opts.reposRoot ?? path54.join(path54.dirname(path54.resolve(opts.cwd)), "repos");
27469
+ const reposRoot = opts.reposRoot ?? path55.join(path55.dirname(path55.resolve(opts.cwd)), "repos");
27460
27470
  return createServer2(async (req, res) => {
27461
27471
  if (!req.method || !req.url) {
27462
27472
  sendJson(res, 400, { error: "bad request" });
@@ -27537,11 +27547,11 @@ async function brainServe(opts) {
27537
27547
  litellmUrl,
27538
27548
  driver
27539
27549
  });
27540
- await new Promise((resolve23) => {
27550
+ await new Promise((resolve24) => {
27541
27551
  server.listen(port, "0.0.0.0", () => {
27542
27552
  process.stdout.write(`[brain-serve] listening on 0.0.0.0:${port} (cwd=${opts.cwd})
27543
27553
  `);
27544
- resolve23();
27554
+ resolve24();
27545
27555
  });
27546
27556
  });
27547
27557
  const shutdown = (signal) => {
@@ -27796,14 +27806,14 @@ async function startBrainProxy(opts) {
27796
27806
  const { httpServer, handler } = buildBrainProxy(opts);
27797
27807
  const port = opts.port ?? 0;
27798
27808
  const host = opts.host ?? "127.0.0.1";
27799
- await new Promise((resolve23) => httpServer.listen(port, host, () => resolve23()));
27809
+ await new Promise((resolve24) => httpServer.listen(port, host, () => resolve24()));
27800
27810
  const addr = httpServer.address();
27801
27811
  return {
27802
27812
  httpServer,
27803
27813
  port: addr.port,
27804
27814
  url: `http://${host}:${addr.port}`,
27805
- stop: () => new Promise((resolve23) => {
27806
- httpServer.close(() => resolve23());
27815
+ stop: () => new Promise((resolve24) => {
27816
+ httpServer.close(() => resolve24());
27807
27817
  }),
27808
27818
  handler
27809
27819
  };
@@ -27953,23 +27963,23 @@ function buildMcpHttpServer(opts) {
27953
27963
  httpServer,
27954
27964
  routes,
27955
27965
  port,
27956
- stop: () => new Promise((resolve23) => {
27966
+ stop: () => new Promise((resolve24) => {
27957
27967
  let pending = transports.size;
27958
27968
  if (pending === 0) {
27959
- httpServer.close(() => resolve23());
27969
+ httpServer.close(() => resolve24());
27960
27970
  return;
27961
27971
  }
27962
27972
  for (const transport of transports.values()) {
27963
27973
  void transport.close().finally(() => {
27964
27974
  pending--;
27965
- if (pending === 0) httpServer.close(() => resolve23());
27975
+ if (pending === 0) httpServer.close(() => resolve24());
27966
27976
  });
27967
27977
  }
27968
27978
  })
27969
27979
  };
27970
27980
  }
27971
27981
  function listenMcpHttpServer(server, host = "127.0.0.1") {
27972
- return new Promise((resolve23, reject) => {
27982
+ return new Promise((resolve24, reject) => {
27973
27983
  server.httpServer.once("error", reject);
27974
27984
  server.httpServer.listen(server.port, host, () => {
27975
27985
  server.httpServer.off("error", reject);
@@ -27977,7 +27987,7 @@ function listenMcpHttpServer(server, host = "127.0.0.1") {
27977
27987
  if (addr && typeof addr === "object") {
27978
27988
  server.port = addr.port;
27979
27989
  }
27980
- resolve23();
27990
+ resolve24();
27981
27991
  });
27982
27992
  });
27983
27993
  }
@@ -28060,7 +28070,7 @@ async function loadConfigSafe() {
28060
28070
  }
28061
28071
 
28062
28072
  // src/chat-cli.ts
28063
- import * as path55 from "path";
28073
+ import * as path56 from "path";
28064
28074
 
28065
28075
  // src/chat/inbox.ts
28066
28076
  import { execFileSync as execFileSync25 } from "child_process";
@@ -28127,7 +28137,7 @@ async function waitForNextUserMessage(opts) {
28127
28137
  }
28128
28138
  }
28129
28139
  function sleep3(ms) {
28130
- return new Promise((resolve23) => setTimeout(resolve23, ms));
28140
+ return new Promise((resolve24) => setTimeout(resolve24, ms));
28131
28141
  }
28132
28142
  function currentBranch(cwd) {
28133
28143
  try {
@@ -28351,7 +28361,7 @@ async function runChat(argv) {
28351
28361
  ${CHAT_HELP}`);
28352
28362
  return 64;
28353
28363
  }
28354
- const cwd = args.cwd ? path55.resolve(args.cwd) : process.cwd();
28364
+ const cwd = args.cwd ? path56.resolve(args.cwd) : process.cwd();
28355
28365
  const sessionId = args.sessionId;
28356
28366
  const runRequest = readRunRequestFromEnv();
28357
28367
  if (runRequest && "request" in runRequest) {
@@ -28478,7 +28488,7 @@ init_registry();
28478
28488
 
28479
28489
  // src/servers/brain-terminal-agent.ts
28480
28490
  init_repoWorkspace();
28481
- import * as path57 from "path";
28491
+ import * as path58 from "path";
28482
28492
  import { createInterface as createInterface2 } from "readline";
28483
28493
 
28484
28494
  // src/terminal/brain-terminal-session.ts
@@ -28792,10 +28802,10 @@ var BrainTerminalSessionAgent = class {
28792
28802
  // src/terminal/brain-terminal-adapters.ts
28793
28803
  import { createHash as createHash10, randomBytes as randomBytes2 } from "crypto";
28794
28804
  import { mkdir, readFile, rename, writeFile as writeFile2 } from "fs/promises";
28795
- import * as path56 from "path";
28805
+ import * as path57 from "path";
28796
28806
  import { spawn as spawn9 } from "child_process";
28797
28807
  function runTerminalCommand(command, args, input) {
28798
- return new Promise((resolve23, reject) => {
28808
+ return new Promise((resolve24, reject) => {
28799
28809
  const child = spawn9(command, args, { stdio: ["pipe", "pipe", "pipe"] });
28800
28810
  const stdout = [];
28801
28811
  const stderr = [];
@@ -28803,7 +28813,7 @@ function runTerminalCommand(command, args, input) {
28803
28813
  child.stderr.on("data", (chunk) => stderr.push(chunk));
28804
28814
  child.on("error", reject);
28805
28815
  child.on("close", (code) => {
28806
- resolve23({
28816
+ resolve24({
28807
28817
  code: code ?? 1,
28808
28818
  stdout: Buffer.concat(stdout).toString("utf8"),
28809
28819
  stderr: Buffer.concat(stderr).toString("utf8")
@@ -28827,7 +28837,7 @@ var FileBrainTerminalMetadataStore = class {
28827
28837
  }
28828
28838
  root;
28829
28839
  file(id) {
28830
- return path56.join(this.root, `${storeKey(id)}.json`);
28840
+ return path57.join(this.root, `${storeKey(id)}.json`);
28831
28841
  }
28832
28842
  async read(id) {
28833
28843
  try {
@@ -28948,8 +28958,8 @@ async function brainTerminalAgent(options) {
28948
28958
  const input = options.input ?? process.stdin;
28949
28959
  const output = options.output ?? process.stdout;
28950
28960
  const error = options.error ?? process.stderr;
28951
- const reposRoot = process.env.BRAIN_REPOS_ROOT?.trim() || path57.join(path57.dirname(path57.resolve(options.cwd)), "repos");
28952
- const stateRoot = process.env.BRAIN_TERMINAL_STATE_ROOT?.trim() || path57.join(path57.dirname(reposRoot), ".kody", "terminal-sessions");
28961
+ const reposRoot = process.env.BRAIN_REPOS_ROOT?.trim() || path58.join(path58.dirname(path58.resolve(options.cwd)), "repos");
28962
+ const stateRoot = process.env.BRAIN_TERMINAL_STATE_ROOT?.trim() || path58.join(path58.dirname(reposRoot), ".kody", "terminal-sessions");
28953
28963
  const agent = new BrainTerminalSessionAgent({
28954
28964
  store: new FileBrainTerminalMetadataStore(stateRoot),
28955
28965
  runtime: new TmuxBrainTerminalRuntime()
@@ -29116,8 +29126,8 @@ var FlyClient = class {
29116
29126
  get fetch() {
29117
29127
  return this.opts.fetchImpl ?? fetch;
29118
29128
  }
29119
- async call(path58, init = {}) {
29120
- const res = await this.fetch(`${FLY_API_BASE}${path58}`, {
29129
+ async call(path59, init = {}) {
29130
+ const res = await this.fetch(`${FLY_API_BASE}${path59}`, {
29121
29131
  method: init.method ?? "GET",
29122
29132
  headers: {
29123
29133
  Authorization: `Bearer ${this.opts.token}`,
@@ -29128,7 +29138,7 @@ var FlyClient = class {
29128
29138
  if (res.status === 404 && init.allow404) return null;
29129
29139
  if (!res.ok) {
29130
29140
  const text2 = await res.text().catch(() => "");
29131
- throw new Error(`Fly API ${res.status} on ${path58}: ${text2.slice(0, 200) || res.statusText}`);
29141
+ throw new Error(`Fly API ${res.status} on ${path59}: ${text2.slice(0, 200) || res.statusText}`);
29132
29142
  }
29133
29143
  if (res.status === 204) return null;
29134
29144
  const raw = await res.text();
@@ -29641,14 +29651,14 @@ function sendJson2(res, status, body) {
29641
29651
  res.end(JSON.stringify(body));
29642
29652
  }
29643
29653
  function readJsonBody2(req) {
29644
- return new Promise((resolve23, reject) => {
29654
+ return new Promise((resolve24, reject) => {
29645
29655
  const chunks = [];
29646
29656
  req.on("data", (c) => chunks.push(c));
29647
29657
  req.on("end", () => {
29648
29658
  const raw = Buffer.concat(chunks).toString("utf-8");
29649
- if (!raw.trim()) return resolve23({});
29659
+ if (!raw.trim()) return resolve24({});
29650
29660
  try {
29651
- resolve23(JSON.parse(raw));
29661
+ resolve24(JSON.parse(raw));
29652
29662
  } catch (err) {
29653
29663
  reject(err instanceof Error ? err : new Error(String(err)));
29654
29664
  }
@@ -29802,10 +29812,10 @@ async function poolServe() {
29802
29812
  }
29803
29813
  });
29804
29814
  const apiHost = process.env.POOL_API_HOST ?? "::";
29805
- await new Promise((resolve23) => {
29815
+ await new Promise((resolve24) => {
29806
29816
  server.listen(apiPort, apiHost, () => {
29807
29817
  log(`listening on ${apiHost}:${apiPort} (min=${min}, app=${app}, region=${region})`);
29808
- resolve23();
29818
+ resolve24();
29809
29819
  });
29810
29820
  });
29811
29821
  if (loopTickEnabled) void runLoopTick();
@@ -29845,17 +29855,17 @@ function authOk2(req, expected) {
29845
29855
  return false;
29846
29856
  }
29847
29857
  function readJsonBody3(req) {
29848
- return new Promise((resolve23, reject) => {
29858
+ return new Promise((resolve24, reject) => {
29849
29859
  const chunks = [];
29850
29860
  req.on("data", (c) => chunks.push(c));
29851
29861
  req.on("end", () => {
29852
29862
  const raw = Buffer.concat(chunks).toString("utf-8");
29853
29863
  if (!raw.trim()) {
29854
- resolve23({});
29864
+ resolve24({});
29855
29865
  return;
29856
29866
  }
29857
29867
  try {
29858
- resolve23(JSON.parse(raw));
29868
+ resolve24(JSON.parse(raw));
29859
29869
  } catch (err) {
29860
29870
  reject(err instanceof Error ? err : new Error(String(err)));
29861
29871
  }
@@ -29930,13 +29940,13 @@ async function defaultRunJob(job) {
29930
29940
  ...interactive && job.idleExitMs ? { KODY_IDLE_EXIT_MS: String(job.idleExitMs) } : {},
29931
29941
  ...interactive && job.hardCapMs ? { KODY_HARD_CAP_MS: String(job.hardCapMs) } : {}
29932
29942
  };
29933
- const run = (cmd, args, cwd) => new Promise((resolve23) => {
29943
+ const run = (cmd, args, cwd) => new Promise((resolve24) => {
29934
29944
  const child = spawn10(cmd, args, { stdio: "inherit", env: childEnv, cwd });
29935
- child.on("exit", (code) => resolve23(code ?? 0));
29945
+ child.on("exit", (code) => resolve24(code ?? 0));
29936
29946
  child.on("error", (err) => {
29937
29947
  process.stderr.write(`[runner-serve] ${cmd} failed: ${err.message}
29938
29948
  `);
29939
- resolve23(1);
29949
+ resolve24(1);
29940
29950
  });
29941
29951
  });
29942
29952
  process.stdout.write(`[runner-serve] job ${job.jobId}: cloning ${job.repo}@${branch}
@@ -30012,11 +30022,11 @@ async function runnerServe() {
30012
30022
  const port = Number(process.env.PORT ?? DEFAULT_PORT2);
30013
30023
  const server = buildServer2({ apiKey });
30014
30024
  const host = process.env.RUNNER_HOST ?? "::";
30015
- await new Promise((resolve23) => {
30025
+ await new Promise((resolve24) => {
30016
30026
  server.listen(port, host, () => {
30017
30027
  process.stdout.write(`[runner-serve] listening on ${host}:${port} (idle, awaiting job)
30018
30028
  `);
30019
- resolve23();
30029
+ resolve24();
30020
30030
  });
30021
30031
  });
30022
30032
  const shutdown = (signal) => {
@@ -30085,14 +30095,14 @@ async function serve(opts) {
30085
30095
  `);
30086
30096
  const args = ["--dangerously-skip-permissions", "--model", model.model];
30087
30097
  const child = spawn11("claude", args, { stdio: "inherit", env: editorEnv, cwd: opts.cwd });
30088
- const exitCode = await new Promise((resolve23) => {
30089
- child.on("exit", (code) => resolve23(code ?? 0));
30098
+ const exitCode = await new Promise((resolve24) => {
30099
+ child.on("exit", (code) => resolve24(code ?? 0));
30090
30100
  child.on("error", (err) => {
30091
30101
  process.stderr.write(`[kody serve] failed to launch Claude Code: ${err.message}
30092
30102
  `);
30093
30103
  process.stderr.write(` Install: https://docs.anthropic.com/claude/docs/claude-code
30094
30104
  `);
30095
- resolve23(1);
30105
+ resolve24(1);
30096
30106
  });
30097
30107
  });
30098
30108
  killProxy();