@kody-ade/kody-engine 0.4.433 → 0.4.434

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 +504 -476
  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.433",
18
+ version: "0.4.434",
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",
@@ -4194,7 +4194,7 @@ var init_task_artifacts = __esm({
4194
4194
 
4195
4195
  // src/gha.ts
4196
4196
  import { execFileSync as execFileSync2 } from "child_process";
4197
- import * as fs17 from "fs";
4197
+ import * as fs18 from "fs";
4198
4198
  function getRunUrl() {
4199
4199
  const server = process.env.GITHUB_SERVER_URL;
4200
4200
  const repo = process.env.GITHUB_REPOSITORY;
@@ -4205,10 +4205,10 @@ function getRunUrl() {
4205
4205
  function reactToTriggerComment(cwd) {
4206
4206
  if (process.env.GITHUB_EVENT_NAME !== "issue_comment") return;
4207
4207
  const eventPath = process.env.GITHUB_EVENT_PATH;
4208
- if (!eventPath || !fs17.existsSync(eventPath)) return;
4208
+ if (!eventPath || !fs18.existsSync(eventPath)) return;
4209
4209
  let event = null;
4210
4210
  try {
4211
- event = JSON.parse(fs17.readFileSync(eventPath, "utf-8"));
4211
+ event = JSON.parse(fs18.readFileSync(eventPath, "utf-8"));
4212
4212
  } catch {
4213
4213
  return;
4214
4214
  }
@@ -4771,31 +4771,31 @@ var init_lifecycles = __esm({
4771
4771
  });
4772
4772
 
4773
4773
  // src/scripts/buildSyntheticPlugin.ts
4774
- import * as fs18 from "fs";
4774
+ import * as fs19 from "fs";
4775
4775
  import * as os3 from "os";
4776
- import * as path17 from "path";
4776
+ import * as path18 from "path";
4777
4777
  function getPluginsCatalogRoot() {
4778
- const here = path17.dirname(new URL(import.meta.url).pathname);
4778
+ const here = path18.dirname(new URL(import.meta.url).pathname);
4779
4779
  const candidates = [
4780
- path17.join(here, "..", "plugins"),
4780
+ path18.join(here, "..", "plugins"),
4781
4781
  // dev: src/scripts → src/plugins
4782
- path17.join(here, "..", "..", "plugins"),
4782
+ path18.join(here, "..", "..", "plugins"),
4783
4783
  // built: dist/scripts → dist/plugins
4784
- path17.join(here, "..", "..", "src", "plugins")
4784
+ path18.join(here, "..", "..", "src", "plugins")
4785
4785
  // fallback
4786
4786
  ];
4787
4787
  for (const c of candidates) {
4788
- if (fs18.existsSync(c) && fs18.statSync(c).isDirectory()) return c;
4788
+ if (fs19.existsSync(c) && fs19.statSync(c).isDirectory()) return c;
4789
4789
  }
4790
4790
  return candidates[0];
4791
4791
  }
4792
4792
  function copyDir(src, dst) {
4793
- fs18.mkdirSync(dst, { recursive: true });
4794
- for (const ent of fs18.readdirSync(src, { withFileTypes: true })) {
4795
- const s = path17.join(src, ent.name);
4796
- const d = path17.join(dst, ent.name);
4793
+ fs19.mkdirSync(dst, { recursive: true });
4794
+ for (const ent of fs19.readdirSync(src, { withFileTypes: true })) {
4795
+ const s = path18.join(src, ent.name);
4796
+ const d = path18.join(dst, ent.name);
4797
4797
  if (ent.isDirectory()) copyDir(s, d);
4798
- else if (ent.isFile()) fs18.copyFileSync(s, d);
4798
+ else if (ent.isFile()) fs19.copyFileSync(s, d);
4799
4799
  }
4800
4800
  }
4801
4801
  var buildSyntheticPlugin;
@@ -4808,47 +4808,47 @@ var init_buildSyntheticPlugin = __esm({
4808
4808
  if (!needsSynthetic) return;
4809
4809
  const catalog = getPluginsCatalogRoot();
4810
4810
  const runId = `${profile.name}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
4811
- const root = path17.join(os3.tmpdir(), `kody-synth-${runId}`);
4812
- fs18.mkdirSync(path17.join(root, ".claude-plugin"), { recursive: true });
4811
+ const root = path18.join(os3.tmpdir(), `kody-synth-${runId}`);
4812
+ fs19.mkdirSync(path18.join(root, ".claude-plugin"), { recursive: true });
4813
4813
  const resolvePart = (bucket, entry) => {
4814
- const local = path17.join(profile.dir, bucket, entry);
4815
- if (fs18.existsSync(local)) return local;
4816
- const shared = path17.resolve(profile.dir, "..", "..", "shared", bucket, entry);
4817
- if (fs18.existsSync(shared)) return shared;
4818
- const central = path17.join(catalog, bucket, entry);
4819
- if (fs18.existsSync(central)) return central;
4814
+ const local = path18.join(profile.dir, bucket, entry);
4815
+ if (fs19.existsSync(local)) return local;
4816
+ const shared = path18.resolve(profile.dir, "..", "..", "shared", bucket, entry);
4817
+ if (fs19.existsSync(shared)) return shared;
4818
+ const central = path18.join(catalog, bucket, entry);
4819
+ if (fs19.existsSync(central)) return central;
4820
4820
  throw new Error(
4821
- `buildSyntheticPlugin: ${bucket} entry '${entry}' not found in implementation dir (${profile.dir}/${bucket}/), Store shared assets (${path17.dirname(shared)}/), or catalog (${catalog}/${bucket}/)`
4821
+ `buildSyntheticPlugin: ${bucket} entry '${entry}' not found in implementation dir (${profile.dir}/${bucket}/), Store shared assets (${path18.dirname(shared)}/), or catalog (${catalog}/${bucket}/)`
4822
4822
  );
4823
4823
  };
4824
4824
  if (cc.skills.length > 0) {
4825
- const dst = path17.join(root, "skills");
4826
- fs18.mkdirSync(dst, { recursive: true });
4825
+ const dst = path18.join(root, "skills");
4826
+ fs19.mkdirSync(dst, { recursive: true });
4827
4827
  for (const name of cc.skills) {
4828
- copyDir(resolvePart("skills", name), path17.join(dst, name));
4828
+ copyDir(resolvePart("skills", name), path18.join(dst, name));
4829
4829
  }
4830
4830
  }
4831
4831
  if (cc.commands.length > 0) {
4832
- const dst = path17.join(root, "commands");
4833
- fs18.mkdirSync(dst, { recursive: true });
4832
+ const dst = path18.join(root, "commands");
4833
+ fs19.mkdirSync(dst, { recursive: true });
4834
4834
  for (const name of cc.commands) {
4835
- fs18.copyFileSync(resolvePart("commands", `${name}.md`), path17.join(dst, `${name}.md`));
4835
+ fs19.copyFileSync(resolvePart("commands", `${name}.md`), path18.join(dst, `${name}.md`));
4836
4836
  }
4837
4837
  }
4838
4838
  if (cc.hooks.length > 0) {
4839
- const dst = path17.join(root, "hooks");
4840
- fs18.mkdirSync(dst, { recursive: true });
4839
+ const dst = path18.join(root, "hooks");
4840
+ fs19.mkdirSync(dst, { recursive: true });
4841
4841
  const merged = { hooks: {} };
4842
4842
  for (const name of cc.hooks) {
4843
4843
  const src = resolvePart("hooks", `${name}.json`);
4844
- const parsed = JSON.parse(fs18.readFileSync(src, "utf-8"));
4844
+ const parsed = JSON.parse(fs19.readFileSync(src, "utf-8"));
4845
4845
  for (const [event, entries] of Object.entries(parsed.hooks ?? {})) {
4846
4846
  if (!Array.isArray(entries)) continue;
4847
4847
  if (!merged.hooks[event]) merged.hooks[event] = [];
4848
4848
  merged.hooks[event].push(...entries);
4849
4849
  }
4850
4850
  }
4851
- fs18.writeFileSync(path17.join(dst, "hooks.json"), `${JSON.stringify(merged, null, 2)}
4851
+ fs19.writeFileSync(path18.join(dst, "hooks.json"), `${JSON.stringify(merged, null, 2)}
4852
4852
  `);
4853
4853
  }
4854
4854
  const manifest = {
@@ -4858,7 +4858,7 @@ var init_buildSyntheticPlugin = __esm({
4858
4858
  };
4859
4859
  if (cc.skills.length > 0) manifest.skills = ["./skills/"];
4860
4860
  if (cc.commands.length > 0) manifest.commands = ["./commands/"];
4861
- fs18.writeFileSync(path17.join(root, ".claude-plugin", "plugin.json"), `${JSON.stringify(manifest, null, 2)}
4861
+ fs19.writeFileSync(path18.join(root, ".claude-plugin", "plugin.json"), `${JSON.stringify(manifest, null, 2)}
4862
4862
  `);
4863
4863
  ctx.data.syntheticPluginPath = root;
4864
4864
  };
@@ -4866,8 +4866,8 @@ var init_buildSyntheticPlugin = __esm({
4866
4866
  });
4867
4867
 
4868
4868
  // src/subagents.ts
4869
- import * as fs19 from "fs";
4870
- import * as path18 from "path";
4869
+ import * as fs20 from "fs";
4870
+ import * as path19 from "path";
4871
4871
  function splitFrontmatter(raw) {
4872
4872
  const match = /^---\n([\s\S]*?)\n---\n?([\s\S]*)$/.exec(raw);
4873
4873
  if (!match) return { fm: {}, body: raw.trim() };
@@ -4880,12 +4880,12 @@ function splitFrontmatter(raw) {
4880
4880
  return { fm, body: (match[2] ?? "").trim() };
4881
4881
  }
4882
4882
  function resolveAgentFile2(profileDir, name) {
4883
- const local = path18.join(profileDir, "agents", `${name}.md`);
4884
- if (fs19.existsSync(local)) return local;
4885
- const shared = path18.resolve(profileDir, "..", "..", "shared", "agents", `${name}.md`);
4886
- if (fs19.existsSync(shared)) return shared;
4887
- const central = path18.join(getPluginsCatalogRoot(), "agents", `${name}.md`);
4888
- if (fs19.existsSync(central)) return central;
4883
+ const local = path19.join(profileDir, "agents", `${name}.md`);
4884
+ if (fs20.existsSync(local)) return local;
4885
+ const shared = path19.resolve(profileDir, "..", "..", "shared", "agents", `${name}.md`);
4886
+ if (fs20.existsSync(shared)) return shared;
4887
+ const central = path19.join(getPluginsCatalogRoot(), "agents", `${name}.md`);
4888
+ if (fs20.existsSync(central)) return central;
4889
4889
  throw new Error(
4890
4890
  `loadSubagents: agent '${name}' not found in ${profileDir}/agents/, hydrated shared assets, or engine catalog`
4891
4891
  );
@@ -4896,7 +4896,7 @@ function captureSubagentTemplates(profile) {
4896
4896
  const out = {};
4897
4897
  for (const name of names) {
4898
4898
  try {
4899
- out[name] = fs19.readFileSync(resolveAgentFile2(profile.dir, name), "utf-8");
4899
+ out[name] = fs20.readFileSync(resolveAgentFile2(profile.dir, name), "utf-8");
4900
4900
  } catch {
4901
4901
  }
4902
4902
  }
@@ -4907,7 +4907,7 @@ function loadSubagents(profile) {
4907
4907
  if (!names || names.length === 0) return void 0;
4908
4908
  const agents = {};
4909
4909
  for (const name of names) {
4910
- const raw = profile.subagentTemplates?.[name] ?? fs19.readFileSync(resolveAgentFile2(profile.dir, name), "utf-8");
4910
+ const raw = profile.subagentTemplates?.[name] ?? fs20.readFileSync(resolveAgentFile2(profile.dir, name), "utf-8");
4911
4911
  const { fm, body } = splitFrontmatter(raw);
4912
4912
  if (!body) throw new Error(`loadSubagents: agent '${name}' has an empty prompt body`);
4913
4913
  const def = {
@@ -4931,16 +4931,16 @@ var init_subagents = __esm({
4931
4931
  });
4932
4932
 
4933
4933
  // src/profile.ts
4934
- import { createHash as createHash3 } from "crypto";
4935
- import * as fs20 from "fs";
4936
- import * as path19 from "path";
4934
+ import { createHash as createHash4 } from "crypto";
4935
+ import * as fs21 from "fs";
4936
+ import * as path20 from "path";
4937
4937
  function loadProfile(profilePath) {
4938
- if (!fs20.existsSync(profilePath)) {
4938
+ if (!fs21.existsSync(profilePath)) {
4939
4939
  throw new ProfileError(profilePath, "file not found");
4940
4940
  }
4941
4941
  let raw;
4942
4942
  try {
4943
- raw = JSON.parse(fs20.readFileSync(profilePath, "utf-8"));
4943
+ raw = JSON.parse(fs21.readFileSync(profilePath, "utf-8"));
4944
4944
  } catch (err) {
4945
4945
  throw new ProfileError(profilePath, `invalid JSON: ${err instanceof Error ? err.message : String(err)}`);
4946
4946
  }
@@ -4952,7 +4952,7 @@ function loadProfile(profilePath) {
4952
4952
  const unknownKeys = Object.keys(r).filter((k) => !KNOWN_PROFILE_KEYS.has(k));
4953
4953
  if (unknownKeys.length > 0) {
4954
4954
  process.stderr.write(
4955
- `[kody profile] ${path19.basename(path19.dirname(profilePath))}: unknown top-level keys ignored: ${unknownKeys.join(", ")}
4955
+ `[kody profile] ${path20.basename(path20.dirname(profilePath))}: unknown top-level keys ignored: ${unknownKeys.join(", ")}
4956
4956
  `
4957
4957
  );
4958
4958
  }
@@ -4962,7 +4962,7 @@ function loadProfile(profilePath) {
4962
4962
  if (!refPath) {
4963
4963
  throw new ProfileError(profilePath, `capability references unknown implementation '${execRef}'`);
4964
4964
  }
4965
- if (path19.resolve(refPath) === path19.resolve(profilePath)) {
4965
+ if (path20.resolve(refPath) === path20.resolve(profilePath)) {
4966
4966
  } else {
4967
4967
  const base = loadProfile(refPath);
4968
4968
  return {
@@ -5060,8 +5060,8 @@ function loadProfile(profilePath) {
5060
5060
  // Phase 5 in-process handoff opt-in. Default false; containers
5061
5061
  // flip to true after end-to-end verification.
5062
5062
  preloadContext: r.preloadContext === true,
5063
- dir: path19.dirname(profilePath),
5064
- promptTemplates: readPromptTemplates(path19.dirname(profilePath))
5063
+ dir: path20.dirname(profilePath),
5064
+ promptTemplates: readPromptTemplates(path20.dirname(profilePath))
5065
5065
  };
5066
5066
  if (lifecycle) {
5067
5067
  applyLifecycle(profile, profilePath);
@@ -5096,19 +5096,19 @@ function loadProfile(profilePath) {
5096
5096
  return profile;
5097
5097
  }
5098
5098
  function compileRuntimeDocument(runtimePath, document) {
5099
- if (path19.basename(runtimePath) !== "runtime.json") return document;
5099
+ if (path20.basename(runtimePath) !== "runtime.json") return document;
5100
5100
  if (document.adapter !== "kody-engine-profile") {
5101
5101
  throw new ProfileError(runtimePath, "unsupported runtime adapter document");
5102
5102
  }
5103
- const implementationDir = path19.dirname(runtimePath);
5104
- const implementation = readJsonObject(path19.join(implementationDir, "definition.json"), "Implementation definition");
5105
- const definitionsRoot2 = path19.dirname(path19.dirname(implementationDir));
5103
+ const implementationDir = path20.dirname(runtimePath);
5104
+ const implementation = readJsonObject(path20.join(implementationDir, "definition.json"), "Implementation definition");
5105
+ const definitionsRoot2 = path20.dirname(path20.dirname(implementationDir));
5106
5106
  const capabilityId = implementation.capabilityRef && typeof implementation.capabilityRef === "object" && !Array.isArray(implementation.capabilityRef) ? implementation.capabilityRef.id : void 0;
5107
5107
  if (typeof capabilityId !== "string" || !capabilityId) {
5108
5108
  throw new ProfileError(runtimePath, "Implementation capabilityRef is invalid");
5109
5109
  }
5110
5110
  const capability = readJsonObject(
5111
- path19.join(definitionsRoot2, "capabilities", capabilityId, "definition.json"),
5111
+ path20.join(definitionsRoot2, "capabilities", capabilityId, "definition.json"),
5112
5112
  "Capability definition"
5113
5113
  );
5114
5114
  const {
@@ -5130,9 +5130,9 @@ function compileRuntimeDocument(runtimePath, document) {
5130
5130
  agent: agentRef,
5131
5131
  canonicalContract: {
5132
5132
  capabilityId,
5133
- capabilityRevision: createHash3("sha256").update(canonical2(capability)).digest("hex"),
5133
+ capabilityRevision: createHash4("sha256").update(canonical2(capability)).digest("hex"),
5134
5134
  implementationId: String(implementation.id),
5135
- implementationRevision: createHash3("sha256").update(canonical2(implementation)).digest("hex"),
5135
+ implementationRevision: createHash4("sha256").update(canonical2(implementation)).digest("hex"),
5136
5136
  inputSchema: capability.inputSchema,
5137
5137
  outputSchema: capability.outputSchema
5138
5138
  }
@@ -5147,7 +5147,7 @@ function canonical2(value) {
5147
5147
  }
5148
5148
  function readJsonObject(filePath, label) {
5149
5149
  try {
5150
- const value = JSON.parse(fs20.readFileSync(filePath, "utf-8"));
5150
+ const value = JSON.parse(fs21.readFileSync(filePath, "utf-8"));
5151
5151
  if (!value || typeof value !== "object" || Array.isArray(value)) {
5152
5152
  throw new Error("must be an object");
5153
5153
  }
@@ -5165,17 +5165,17 @@ function readPromptTemplates(dir) {
5165
5165
  const out = {};
5166
5166
  const read = (p) => {
5167
5167
  try {
5168
- out[p] = fs20.readFileSync(p, "utf-8");
5168
+ out[p] = fs21.readFileSync(p, "utf-8");
5169
5169
  } catch {
5170
5170
  }
5171
5171
  };
5172
- read(path19.join(dir, "prompt.md"));
5173
- read(path19.join(dir, "capability.md"));
5174
- read(path19.join(dir, "capability.md"));
5172
+ read(path20.join(dir, "prompt.md"));
5173
+ read(path20.join(dir, "capability.md"));
5174
+ read(path20.join(dir, "capability.md"));
5175
5175
  try {
5176
- const promptsDir = path19.join(dir, "prompts");
5177
- for (const ent of fs20.readdirSync(promptsDir)) {
5178
- if (ent.endsWith(".md")) read(path19.join(promptsDir, ent));
5176
+ const promptsDir = path20.join(dir, "prompts");
5177
+ for (const ent of fs21.readdirSync(promptsDir)) {
5178
+ if (ent.endsWith(".md")) read(path20.join(promptsDir, ent));
5179
5179
  }
5180
5180
  } catch {
5181
5181
  }
@@ -5950,16 +5950,16 @@ var init_state = __esm({
5950
5950
  });
5951
5951
 
5952
5952
  // src/prompt.ts
5953
- import * as fs21 from "fs";
5954
- import * as path20 from "path";
5953
+ import * as fs22 from "fs";
5954
+ import * as path21 from "path";
5955
5955
  function loadProjectConventions(projectDir) {
5956
5956
  const out = [];
5957
5957
  for (const rel of CONVENTION_FILES) {
5958
- const abs = path20.join(projectDir, rel);
5959
- if (!fs21.existsSync(abs)) continue;
5958
+ const abs = path21.join(projectDir, rel);
5959
+ if (!fs22.existsSync(abs)) continue;
5960
5960
  let content;
5961
5961
  try {
5962
- content = fs21.readFileSync(abs, "utf-8");
5962
+ content = fs22.readFileSync(abs, "utf-8");
5963
5963
  } catch {
5964
5964
  continue;
5965
5965
  }
@@ -6194,8 +6194,8 @@ var loadMemoryContext_exports = {};
6194
6194
  __export(loadMemoryContext_exports, {
6195
6195
  loadMemoryContext: () => loadMemoryContext
6196
6196
  });
6197
- import * as fs22 from "fs";
6198
- import * as path21 from "path";
6197
+ import * as fs23 from "fs";
6198
+ import * as path22 from "path";
6199
6199
  function formatBlockFromBackend(docs) {
6200
6200
  const pages = docs.flatMap((record2) => {
6201
6201
  if (!record2.doc || typeof record2.doc !== "object") return [];
@@ -6218,21 +6218,21 @@ function collectPages(memoryAbs) {
6218
6218
  walkMd(memoryAbs, (file) => {
6219
6219
  let stat;
6220
6220
  try {
6221
- stat = fs22.statSync(file);
6221
+ stat = fs23.statSync(file);
6222
6222
  } catch {
6223
6223
  return;
6224
6224
  }
6225
6225
  let raw;
6226
6226
  try {
6227
- raw = fs22.readFileSync(file, "utf-8");
6227
+ raw = fs23.readFileSync(file, "utf-8");
6228
6228
  } catch {
6229
6229
  return;
6230
6230
  }
6231
6231
  const fm = raw.match(/^---\s*\n([\s\S]*?)\n---/);
6232
- const title = fm?.[1]?.match(/^title:\s*(.+)$/m)?.[1]?.trim() ?? path21.basename(file, ".md");
6232
+ const title = fm?.[1]?.match(/^title:\s*(.+)$/m)?.[1]?.trim() ?? path22.basename(file, ".md");
6233
6233
  const updated = fm?.[1]?.match(/^updated:\s*([0-9T:.+\-Z]+)/m)?.[1]?.trim() ?? "";
6234
6234
  out.push({
6235
- relPath: path21.relative(memoryAbs, file),
6235
+ relPath: path22.relative(memoryAbs, file),
6236
6236
  title,
6237
6237
  updated,
6238
6238
  content: raw.length > PER_PAGE_MAX_BYTES ? raw.slice(0, PER_PAGE_MAX_BYTES) + TRUNCATED_SUFFIX2 : raw,
@@ -6300,16 +6300,16 @@ function walkMd(root, visit) {
6300
6300
  const dir = stack.pop();
6301
6301
  let names;
6302
6302
  try {
6303
- names = fs22.readdirSync(dir);
6303
+ names = fs23.readdirSync(dir);
6304
6304
  } catch {
6305
6305
  continue;
6306
6306
  }
6307
6307
  for (const name of names) {
6308
6308
  if (name.startsWith(".")) continue;
6309
- const full = path21.join(dir, name);
6309
+ const full = path22.join(dir, name);
6310
6310
  let stat;
6311
6311
  try {
6312
- stat = fs22.statSync(full);
6312
+ stat = fs23.statSync(full);
6313
6313
  } catch {
6314
6314
  continue;
6315
6315
  }
@@ -6344,8 +6344,8 @@ var init_loadMemoryContext = __esm({
6344
6344
  }
6345
6345
  return;
6346
6346
  }
6347
- const memoryAbs = path21.join(ctx.cwd, MEMORY_DIR_RELATIVE);
6348
- if (!fs22.existsSync(memoryAbs)) {
6347
+ const memoryAbs = path22.join(ctx.cwd, MEMORY_DIR_RELATIVE);
6348
+ if (!fs23.existsSync(memoryAbs)) {
6349
6349
  ctx.data.memoryContext = "";
6350
6350
  return;
6351
6351
  }
@@ -6389,11 +6389,11 @@ var init_loadCoverageRules = __esm({
6389
6389
 
6390
6390
  // src/container.ts
6391
6391
  import { execFileSync as execFileSync3 } from "child_process";
6392
- import * as fs23 from "fs";
6392
+ import * as fs24 from "fs";
6393
6393
  function getProfileInputsForChild(profileName, _cwd) {
6394
6394
  try {
6395
6395
  const profilePath = resolveProfilePath(profileName);
6396
- if (!fs23.existsSync(profilePath)) return null;
6396
+ if (!fs24.existsSync(profilePath)) return null;
6397
6397
  return loadProfile(profilePath).inputs;
6398
6398
  } catch {
6399
6399
  return null;
@@ -6857,10 +6857,10 @@ var init_lifecycleLabels = __esm({
6857
6857
 
6858
6858
  // src/litellm.ts
6859
6859
  import { execFileSync as execFileSync4, spawn as spawn4 } from "child_process";
6860
- import * as fs24 from "fs";
6860
+ import * as fs25 from "fs";
6861
6861
  import * as net from "net";
6862
6862
  import * as os4 from "os";
6863
- import * as path22 from "path";
6863
+ import * as path23 from "path";
6864
6864
  async function checkLitellmHealth(url) {
6865
6865
  try {
6866
6866
  const response = await fetch(`${url}/health`, { signal: AbortSignal.timeout(3e3) });
@@ -6930,7 +6930,7 @@ function locateLitellmScript() {
6930
6930
  }
6931
6931
  function resolveLitellmCommand() {
6932
6932
  const imageScript = "/opt/venv/bin/litellm";
6933
- if (fs24.existsSync(imageScript)) return imageScript;
6933
+ if (fs25.existsSync(imageScript)) return imageScript;
6934
6934
  try {
6935
6935
  execFileSync4("which", ["litellm"], { timeout: 3e3, stdio: "pipe" });
6936
6936
  return "litellm";
@@ -6966,13 +6966,13 @@ async function startLitellmIfNeeded(model, projectDir, url = LITELLM_DEFAULT_URL
6966
6966
  const spawnProxy = () => {
6967
6967
  const portMatch = activeUrl.match(/:(\d+)/);
6968
6968
  const port = portMatch ? portMatch[1] : "4000";
6969
- const configPath = path22.join(os4.tmpdir(), `kody-local-litellm-${Date.now()}.yaml`);
6970
- fs24.writeFileSync(configPath, generateLitellmConfigYaml(model));
6969
+ const configPath = path23.join(os4.tmpdir(), `kody-local-litellm-${Date.now()}.yaml`);
6970
+ fs25.writeFileSync(configPath, generateLitellmConfigYaml(model));
6971
6971
  const args = ["--config", configPath, "--port", port];
6972
- const nextLogPath = path22.join(os4.tmpdir(), `kody-local-litellm-${Date.now()}.log`);
6973
- const outFd = fs24.openSync(nextLogPath, "w");
6972
+ const nextLogPath = path23.join(os4.tmpdir(), `kody-local-litellm-${Date.now()}.log`);
6973
+ const outFd = fs25.openSync(nextLogPath, "w");
6974
6974
  child = spawn4(cmd, args, { stdio: ["ignore", outFd, outFd], detached: true, env: childEnv });
6975
- fs24.closeSync(outFd);
6975
+ fs25.closeSync(outFd);
6976
6976
  logPath = nextLogPath;
6977
6977
  };
6978
6978
  const waitForHealth = async () => {
@@ -6986,7 +6986,7 @@ async function startLitellmIfNeeded(model, projectDir, url = LITELLM_DEFAULT_URL
6986
6986
  const readLogTail = () => {
6987
6987
  if (!logPath) return "";
6988
6988
  try {
6989
- return fs24.readFileSync(logPath, "utf-8").slice(-2e3);
6989
+ return fs25.readFileSync(logPath, "utf-8").slice(-2e3);
6990
6990
  } catch {
6991
6991
  return "";
6992
6992
  }
@@ -7069,10 +7069,10 @@ function canListen(port, host) {
7069
7069
  });
7070
7070
  }
7071
7071
  function readDotenvApiKeys(projectDir) {
7072
- const dotenvPath = path22.join(projectDir, ".env");
7073
- if (!fs24.existsSync(dotenvPath)) return {};
7072
+ const dotenvPath = path23.join(projectDir, ".env");
7073
+ if (!fs25.existsSync(dotenvPath)) return {};
7074
7074
  const result = {};
7075
- for (const rawLine of fs24.readFileSync(dotenvPath, "utf-8").split("\n")) {
7075
+ for (const rawLine of fs25.readFileSync(dotenvPath, "utf-8").split("\n")) {
7076
7076
  const line = rawLine.trim();
7077
7077
  if (!line || line.startsWith("#")) continue;
7078
7078
  const match = line.match(/^([A-Z_][A-Z0-9_]*_API_KEY)=(.*)$/);
@@ -7472,8 +7472,8 @@ var init_pushWithRetry = __esm({
7472
7472
 
7473
7473
  // src/commit.ts
7474
7474
  import { execFileSync as execFileSync6 } from "child_process";
7475
- import * as fs25 from "fs";
7476
- import * as path23 from "path";
7475
+ import * as fs26 from "fs";
7476
+ import * as path24 from "path";
7477
7477
  function isGitHubYamlPath(filePath) {
7478
7478
  const normalized = filePath.replace(/^\.\/+/, "");
7479
7479
  return normalized.startsWith(".github/") && /\.ya?ml$/i.test(normalized);
@@ -7515,18 +7515,18 @@ function ensureGitIdentity(cwd) {
7515
7515
  }
7516
7516
  function abortUnfinishedGitOps(cwd) {
7517
7517
  const aborted = [];
7518
- const gitDir = path23.join(cwd ?? process.cwd(), ".git");
7519
- if (!fs25.existsSync(gitDir)) return aborted;
7520
- if (fs25.existsSync(path23.join(gitDir, "MERGE_HEAD"))) {
7518
+ const gitDir = path24.join(cwd ?? process.cwd(), ".git");
7519
+ if (!fs26.existsSync(gitDir)) return aborted;
7520
+ if (fs26.existsSync(path24.join(gitDir, "MERGE_HEAD"))) {
7521
7521
  if (tryGit(["merge", "--abort"], cwd)) aborted.push("merge");
7522
7522
  }
7523
- if (fs25.existsSync(path23.join(gitDir, "CHERRY_PICK_HEAD"))) {
7523
+ if (fs26.existsSync(path24.join(gitDir, "CHERRY_PICK_HEAD"))) {
7524
7524
  if (tryGit(["cherry-pick", "--abort"], cwd)) aborted.push("cherry-pick");
7525
7525
  }
7526
- if (fs25.existsSync(path23.join(gitDir, "REVERT_HEAD"))) {
7526
+ if (fs26.existsSync(path24.join(gitDir, "REVERT_HEAD"))) {
7527
7527
  if (tryGit(["revert", "--abort"], cwd)) aborted.push("revert");
7528
7528
  }
7529
- if (fs25.existsSync(path23.join(gitDir, "rebase-merge")) || fs25.existsSync(path23.join(gitDir, "rebase-apply"))) {
7529
+ if (fs26.existsSync(path24.join(gitDir, "rebase-merge")) || fs26.existsSync(path24.join(gitDir, "rebase-apply"))) {
7530
7530
  if (tryGit(["rebase", "--abort"], cwd)) aborted.push("rebase");
7531
7531
  }
7532
7532
  try {
@@ -7583,7 +7583,7 @@ function normalizeCommitMessage(raw) {
7583
7583
  function commitAndPush(branch, agentMessage, cwd) {
7584
7584
  const allChanged = listChangedFiles(cwd);
7585
7585
  const allowedFiles = allChanged.filter((f) => !isForbiddenPath(f));
7586
- const mergeHeadExists = fs25.existsSync(path23.join(cwd ?? process.cwd(), ".git", "MERGE_HEAD"));
7586
+ const mergeHeadExists = fs26.existsSync(path24.join(cwd ?? process.cwd(), ".git", "MERGE_HEAD"));
7587
7587
  if (allowedFiles.length === 0 && !mergeHeadExists) {
7588
7588
  return { committed: false, pushed: false, sha: "", message: "" };
7589
7589
  }
@@ -8223,7 +8223,7 @@ var init_state2 = __esm({
8223
8223
  });
8224
8224
 
8225
8225
  // src/goal/runLog.ts
8226
- import * as fs26 from "fs";
8226
+ import * as fs27 from "fs";
8227
8227
  function stageGoalRunLogEvent(data, goalId, event, at = nowIso()) {
8228
8228
  const logs = goalRunLogs(data);
8229
8229
  const existing = logs[goalId];
@@ -8565,8 +8565,8 @@ function readGithubEvent() {
8565
8565
  const eventPath = process.env.GITHUB_EVENT_PATH;
8566
8566
  if (!eventPath) return null;
8567
8567
  try {
8568
- if (!fs26.existsSync(eventPath)) return null;
8569
- const parsed = JSON.parse(fs26.readFileSync(eventPath, "utf-8"));
8568
+ if (!fs27.existsSync(eventPath)) return null;
8569
+ const parsed = JSON.parse(fs27.readFileSync(eventPath, "utf-8"));
8570
8570
  return recordValue3(parsed);
8571
8571
  } catch {
8572
8572
  return null;
@@ -8676,8 +8676,8 @@ var init_stateStore = __esm({
8676
8676
  });
8677
8677
 
8678
8678
  // src/goal/targetLoopResolution.ts
8679
- import * as fs27 from "fs";
8680
- import * as path24 from "path";
8679
+ import * as fs28 from "fs";
8680
+ import * as path25 from "path";
8681
8681
  async function resolveActiveGoalLoopTarget(config, cwd, loopGoalId, loopGoal) {
8682
8682
  const targetId = loopGoal.loopTarget?.id.trim() ?? "";
8683
8683
  assertSafeGoalId(targetId, "loop target");
@@ -8755,11 +8755,11 @@ function goalInstanceTime(state) {
8755
8755
  return Number.isNaN(parsed) ? 0 : parsed;
8756
8756
  }
8757
8757
  function loadGoalTemplate(cwd, targetId) {
8758
- return readJsonObject2(path24.join(cwd, ".kody-engine", "definitions", "goals", targetId, "state.json"));
8758
+ return readJsonObject2(path25.join(cwd, ".kody-engine", "definitions", "goals", targetId, "state.json"));
8759
8759
  }
8760
8760
  function readJsonObject2(filePath) {
8761
- if (!fs27.existsSync(filePath)) return null;
8762
- const parsed = JSON.parse(fs27.readFileSync(filePath, "utf8"));
8761
+ if (!fs28.existsSync(filePath)) return null;
8762
+ const parsed = JSON.parse(fs28.readFileSync(filePath, "utf8"));
8763
8763
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
8764
8764
  throw new Error(`goal template ${filePath} must be a JSON object`);
8765
8765
  }
@@ -9278,8 +9278,8 @@ var init_workflowValidation = __esm({
9278
9278
  });
9279
9279
 
9280
9280
  // src/workflowDefinitions.ts
9281
- import * as fs28 from "fs";
9282
- import * as path25 from "path";
9281
+ import * as fs29 from "fs";
9282
+ import * as path26 from "path";
9283
9283
  function isWorkflowDefinitionId(value) {
9284
9284
  return WORKFLOW_ID_PATTERN.test(value);
9285
9285
  }
@@ -9323,12 +9323,12 @@ function readWorkflowDefinition(_config, cwd, id) {
9323
9323
  const root = cwd ?? process.cwd();
9324
9324
  const relativePath = workflowDefinitionPath(id);
9325
9325
  const candidates = [
9326
- path25.join(root, ".kody-engine", "runtime", relativePath),
9327
- path25.join(root, ".kody-engine", "definitions", relativePath)
9326
+ path26.join(root, ".kody-engine", "runtime", relativePath),
9327
+ path26.join(root, ".kody-engine", "definitions", relativePath)
9328
9328
  ];
9329
9329
  for (const filePath of candidates) {
9330
- if (!fs28.existsSync(filePath)) continue;
9331
- const workflow = parseWorkflowDefinition(fs28.readFileSync(filePath, "utf8"));
9330
+ if (!fs29.existsSync(filePath)) continue;
9331
+ const workflow = parseWorkflowDefinition(fs29.readFileSync(filePath, "utf8"));
9332
9332
  if (workflow) return workflow;
9333
9333
  }
9334
9334
  return null;
@@ -9336,7 +9336,7 @@ function readWorkflowDefinition(_config, cwd, id) {
9336
9336
  function workflowDefinitionToCapabilityFolder(id, workflow, source = workflowDefinitionPath(id)) {
9337
9337
  return {
9338
9338
  slug: id,
9339
- dir: path25.dirname(source),
9339
+ dir: path26.dirname(source),
9340
9340
  profilePath: source,
9341
9341
  bodyPath: source,
9342
9342
  title: workflow.name,
@@ -9541,8 +9541,8 @@ var init_backendStateBackend = __esm({
9541
9541
  });
9542
9542
 
9543
9543
  // src/scripts/jobState/localFileBackend.ts
9544
- import * as fs29 from "fs";
9545
- import * as path26 from "path";
9544
+ import * as fs30 from "fs";
9545
+ import * as path27 from "path";
9546
9546
  function sanitizeKey(s) {
9547
9547
  return s.replace(/[^A-Za-z0-9._-]/g, "-");
9548
9548
  }
@@ -9598,7 +9598,7 @@ var init_localFileBackend = __esm({
9598
9598
  if (!opts.owner || !opts.repo) throw new Error("LocalFileBackend: owner and repo are required");
9599
9599
  this.cwd = opts.cwd;
9600
9600
  this.jobsDir = opts.jobsDir;
9601
- this.absDir = path26.resolve(opts.cwd, opts.jobsDir);
9601
+ this.absDir = path27.resolve(opts.cwd, opts.jobsDir);
9602
9602
  this.owner = opts.owner;
9603
9603
  this.repo = opts.repo;
9604
9604
  this.cache = opts.cache ?? defaultCacheAdapter();
@@ -9613,7 +9613,7 @@ var init_localFileBackend = __esm({
9613
9613
  `);
9614
9614
  return;
9615
9615
  }
9616
- fs29.mkdirSync(this.absDir, { recursive: true });
9616
+ fs30.mkdirSync(this.absDir, { recursive: true });
9617
9617
  const prefix = this.cacheKeyPrefix();
9618
9618
  const probeKey = `${prefix}probe-${Date.now()}`;
9619
9619
  try {
@@ -9642,7 +9642,7 @@ var init_localFileBackend = __esm({
9642
9642
  `);
9643
9643
  return;
9644
9644
  }
9645
- if (!fs29.existsSync(this.absDir)) {
9645
+ if (!fs30.existsSync(this.absDir)) {
9646
9646
  return;
9647
9647
  }
9648
9648
  const key = `${this.cacheKeyPrefix()}${process.env.GITHUB_RUN_ID ?? "norunid"}-${Date.now()}`;
@@ -9658,11 +9658,11 @@ var init_localFileBackend = __esm({
9658
9658
  }
9659
9659
  load(slug) {
9660
9660
  const relPath = stateFilePath(this.jobsDir, slug);
9661
- const absPath = path26.resolve(this.cwd, relPath);
9662
- if (!fs29.existsSync(absPath)) {
9661
+ const absPath = path27.resolve(this.cwd, relPath);
9662
+ if (!fs30.existsSync(absPath)) {
9663
9663
  return { path: relPath, handle: null, state: initialStateEnvelope("seed"), created: true };
9664
9664
  }
9665
- const raw = fs29.readFileSync(absPath, "utf-8");
9665
+ const raw = fs30.readFileSync(absPath, "utf-8");
9666
9666
  let parsed;
9667
9667
  try {
9668
9668
  parsed = JSON.parse(raw);
@@ -9679,13 +9679,13 @@ var init_localFileBackend = __esm({
9679
9679
  if (!loaded.created && isStateUnchanged(loaded.state, next)) {
9680
9680
  return false;
9681
9681
  }
9682
- const absPath = path26.resolve(this.cwd, loaded.path);
9683
- fs29.mkdirSync(path26.dirname(absPath), { recursive: true });
9682
+ const absPath = path27.resolve(this.cwd, loaded.path);
9683
+ fs30.mkdirSync(path27.dirname(absPath), { recursive: true });
9684
9684
  const body = `${JSON.stringify(next, null, 2)}
9685
9685
  `;
9686
9686
  const tmpPath = `${absPath}.${process.pid}.tmp`;
9687
- fs29.writeFileSync(tmpPath, body, "utf-8");
9688
- fs29.renameSync(tmpPath, absPath);
9687
+ fs30.writeFileSync(tmpPath, body, "utf-8");
9688
+ fs30.renameSync(tmpPath, absPath);
9689
9689
  return true;
9690
9690
  }
9691
9691
  cacheKeyPrefix() {
@@ -9717,7 +9717,7 @@ var init_jobState = __esm({
9717
9717
  });
9718
9718
 
9719
9719
  // src/scripts/goalCapabilityScheduling.ts
9720
- import * as path27 from "path";
9720
+ import * as path28 from "path";
9721
9721
  function isCapabilityCadenceGoal(goal, extra) {
9722
9722
  return extra.scheduleMode === "agentLoop" || extra.scheduler === "agentLoop" || goal.type === "standing" && goal.capabilities.length > 0;
9723
9723
  }
@@ -9773,7 +9773,7 @@ function planTargetLoopSchedule(opts) {
9773
9773
  }
9774
9774
  async function planGoalCapabilitySchedule(opts) {
9775
9775
  const jobsDir = opts.jobsDir ?? capabilitiesRoot(opts.cwd);
9776
- const jobsRoot = path27.resolve(opts.cwd, jobsDir);
9776
+ const jobsRoot = path28.resolve(opts.cwd, jobsDir);
9777
9777
  const now = opts.now ?? /* @__PURE__ */ new Date();
9778
9778
  const at = now.toISOString();
9779
9779
  const backend = resolveBackend({ config: opts.config, cwd: opts.cwd, jobsDir });
@@ -11588,8 +11588,8 @@ var init_classifyByLabel = __esm({
11588
11588
  });
11589
11589
 
11590
11590
  // src/scripts/commitAndPush.ts
11591
- import * as fs30 from "fs";
11592
- import * as path28 from "path";
11591
+ import * as fs31 from "fs";
11592
+ import * as path29 from "path";
11593
11593
  function sentinelPathForStage(cwd, profileName) {
11594
11594
  const runId = resolveRunId();
11595
11595
  return runtimeStatePath(cwd, "agent-runs", runId, `commit-${profileName}.lock`);
@@ -11610,9 +11610,9 @@ var init_commitAndPush = __esm({
11610
11610
  }
11611
11611
  const idempotencyEnabled = process.env.KODY_COMMIT_IDEMPOTENCY !== "0";
11612
11612
  const sentinel = idempotencyEnabled ? sentinelPathForStage(ctx.cwd, profile.name) : null;
11613
- if (sentinel && fs30.existsSync(sentinel)) {
11613
+ if (sentinel && fs31.existsSync(sentinel)) {
11614
11614
  try {
11615
- const replay = JSON.parse(fs30.readFileSync(sentinel, "utf-8"));
11615
+ const replay = JSON.parse(fs31.readFileSync(sentinel, "utf-8"));
11616
11616
  ctx.data.commitResult = replay.commitResult ?? { committed: false, pushed: false };
11617
11617
  if (Array.isArray(replay.changedFiles)) ctx.data.changedFiles = replay.changedFiles;
11618
11618
  if (typeof replay.hasCommitsAhead === "boolean") ctx.data.hasCommitsAhead = replay.hasCommitsAhead;
@@ -11672,8 +11672,8 @@ var init_commitAndPush = __esm({
11672
11672
  const result = ctx.data.commitResult;
11673
11673
  if (sentinel && result?.committed) {
11674
11674
  try {
11675
- fs30.mkdirSync(path28.dirname(sentinel), { recursive: true });
11676
- fs30.writeFileSync(
11675
+ fs31.mkdirSync(path29.dirname(sentinel), { recursive: true });
11676
+ fs31.writeFileSync(
11677
11677
  sentinel,
11678
11678
  JSON.stringify(
11679
11679
  {
@@ -11767,8 +11767,8 @@ var init_commitGoalState = __esm({
11767
11767
  });
11768
11768
 
11769
11769
  // src/scripts/composePrompt.ts
11770
- import * as fs31 from "fs";
11771
- import * as path29 from "path";
11770
+ import * as fs32 from "fs";
11771
+ import * as path30 from "path";
11772
11772
  function fenceUntrusted(value) {
11773
11773
  if (value.trim().length === 0) return value;
11774
11774
  const safe = value.replace(/-{3,}\s*END UNTRUSTED INPUT\s*-{3,}/gi, "[END UNTRUSTED INPUT]");
@@ -11892,10 +11892,10 @@ var init_composePrompt = __esm({
11892
11892
  const explicit = ctx.data.promptTemplate;
11893
11893
  const mode = ctx.args.mode;
11894
11894
  const candidates = [
11895
- explicit ? path29.join(profile.dir, explicit) : null,
11896
- mode ? path29.join(profile.dir, "prompts", `${mode}.md`) : null,
11897
- path29.join(profile.dir, "prompt.md"),
11898
- path29.join(profile.dir, "capability.md")
11895
+ explicit ? path30.join(profile.dir, explicit) : null,
11896
+ mode ? path30.join(profile.dir, "prompts", `${mode}.md`) : null,
11897
+ path30.join(profile.dir, "prompt.md"),
11898
+ path30.join(profile.dir, "capability.md")
11899
11899
  ].filter(Boolean);
11900
11900
  let templatePath = "";
11901
11901
  let template = "";
@@ -11908,7 +11908,7 @@ var init_composePrompt = __esm({
11908
11908
  break;
11909
11909
  }
11910
11910
  try {
11911
- template = fs31.readFileSync(c, "utf-8");
11911
+ template = fs32.readFileSync(c, "utf-8");
11912
11912
  templatePath = c;
11913
11913
  break;
11914
11914
  } catch (err) {
@@ -11919,7 +11919,7 @@ var init_composePrompt = __esm({
11919
11919
  if (!templatePath) {
11920
11920
  let dirState;
11921
11921
  try {
11922
- dirState = `dir contents: [${fs31.readdirSync(profile.dir).join(", ")}]`;
11922
+ dirState = `dir contents: [${fs32.readdirSync(profile.dir).join(", ")}]`;
11923
11923
  } catch (err) {
11924
11924
  dirState = `readdir(${profile.dir}) failed: ${err?.code ?? String(err)}`;
11925
11925
  }
@@ -12653,19 +12653,19 @@ var init_deriveQaScopeFromIssue = __esm({
12653
12653
 
12654
12654
  // src/scripts/diagMcp.ts
12655
12655
  import { execFileSync as execFileSync9 } from "child_process";
12656
- import * as fs32 from "fs";
12656
+ import * as fs33 from "fs";
12657
12657
  import * as os5 from "os";
12658
- import * as path30 from "path";
12658
+ import * as path31 from "path";
12659
12659
  var diagMcp;
12660
12660
  var init_diagMcp = __esm({
12661
12661
  "src/scripts/diagMcp.ts"() {
12662
12662
  "use strict";
12663
12663
  diagMcp = async (_ctx) => {
12664
12664
  const home = os5.homedir();
12665
- const cacheDir = path30.join(home, ".cache", "ms-playwright");
12665
+ const cacheDir = path31.join(home, ".cache", "ms-playwright");
12666
12666
  let entries = [];
12667
12667
  try {
12668
- entries = fs32.readdirSync(cacheDir);
12668
+ entries = fs33.readdirSync(cacheDir);
12669
12669
  } catch {
12670
12670
  }
12671
12671
  const hasChromium = entries.some((e) => e.startsWith("chromium"));
@@ -12693,13 +12693,13 @@ var init_diagMcp = __esm({
12693
12693
  });
12694
12694
 
12695
12695
  // src/scripts/frameworkDetectors.ts
12696
- import * as fs33 from "fs";
12697
- import * as path31 from "path";
12696
+ import * as fs34 from "fs";
12697
+ import * as path32 from "path";
12698
12698
  function detectFrameworks(cwd) {
12699
12699
  const out = [];
12700
12700
  let deps = {};
12701
12701
  try {
12702
- const pkg = JSON.parse(fs33.readFileSync(path31.join(cwd, "package.json"), "utf-8"));
12702
+ const pkg = JSON.parse(fs34.readFileSync(path32.join(cwd, "package.json"), "utf-8"));
12703
12703
  deps = { ...pkg.dependencies, ...pkg.devDependencies };
12704
12704
  } catch {
12705
12705
  return out;
@@ -12736,25 +12736,25 @@ function detectFrameworks(cwd) {
12736
12736
  }
12737
12737
  function findFile(cwd, candidates) {
12738
12738
  for (const c of candidates) {
12739
- if (fs33.existsSync(path31.join(cwd, c))) return c;
12739
+ if (fs34.existsSync(path32.join(cwd, c))) return c;
12740
12740
  }
12741
12741
  return null;
12742
12742
  }
12743
12743
  function discoverPayloadCollections(cwd) {
12744
12744
  const out = [];
12745
12745
  for (const dir of COLLECTION_DIRS) {
12746
- const full = path31.join(cwd, dir);
12747
- if (!fs33.existsSync(full)) continue;
12746
+ const full = path32.join(cwd, dir);
12747
+ if (!fs34.existsSync(full)) continue;
12748
12748
  let files;
12749
12749
  try {
12750
- files = fs33.readdirSync(full).filter((f) => f.endsWith(".ts") || f.endsWith(".tsx"));
12750
+ files = fs34.readdirSync(full).filter((f) => f.endsWith(".ts") || f.endsWith(".tsx"));
12751
12751
  } catch {
12752
12752
  continue;
12753
12753
  }
12754
12754
  for (const file of files) {
12755
12755
  try {
12756
- const filePath = path31.join(full, file);
12757
- const content = fs33.readFileSync(filePath, "utf-8").slice(0, 1e4);
12756
+ const filePath = path32.join(full, file);
12757
+ const content = fs34.readFileSync(filePath, "utf-8").slice(0, 1e4);
12758
12758
  const slugMatch = content.match(/slug:\s*['"]([a-z0-9-]+)['"]/);
12759
12759
  if (!slugMatch) continue;
12760
12760
  const slug = slugMatch[1];
@@ -12768,7 +12768,7 @@ function discoverPayloadCollections(cwd) {
12768
12768
  out.push({
12769
12769
  name,
12770
12770
  slug,
12771
- filePath: path31.relative(cwd, filePath),
12771
+ filePath: path32.relative(cwd, filePath),
12772
12772
  fields: fields.slice(0, 20),
12773
12773
  hasAdmin
12774
12774
  });
@@ -12781,28 +12781,28 @@ function discoverPayloadCollections(cwd) {
12781
12781
  function discoverAdminComponents(cwd, collections) {
12782
12782
  const out = [];
12783
12783
  for (const dir of ADMIN_COMPONENT_DIRS) {
12784
- const full = path31.join(cwd, dir);
12785
- if (!fs33.existsSync(full)) continue;
12784
+ const full = path32.join(cwd, dir);
12785
+ if (!fs34.existsSync(full)) continue;
12786
12786
  let entries;
12787
12787
  try {
12788
- entries = fs33.readdirSync(full, { withFileTypes: true });
12788
+ entries = fs34.readdirSync(full, { withFileTypes: true });
12789
12789
  } catch {
12790
12790
  continue;
12791
12791
  }
12792
12792
  for (const entry of entries) {
12793
- const entryPath = path31.join(full, entry.name);
12793
+ const entryPath = path32.join(full, entry.name);
12794
12794
  let name;
12795
12795
  let filePath;
12796
12796
  if (entry.isDirectory()) {
12797
12797
  const indexFile = ["index.tsx", "index.ts", "index.jsx", "index.js"].find(
12798
- (f) => fs33.existsSync(path31.join(entryPath, f))
12798
+ (f) => fs34.existsSync(path32.join(entryPath, f))
12799
12799
  );
12800
12800
  if (!indexFile) continue;
12801
12801
  name = entry.name;
12802
- filePath = path31.relative(cwd, path31.join(entryPath, indexFile));
12802
+ filePath = path32.relative(cwd, path32.join(entryPath, indexFile));
12803
12803
  } else if (/\.(tsx?|jsx?)$/.test(entry.name)) {
12804
12804
  name = entry.name.replace(/\.(tsx?|jsx?)$/, "");
12805
- filePath = path31.relative(cwd, entryPath);
12805
+ filePath = path32.relative(cwd, entryPath);
12806
12806
  } else {
12807
12807
  continue;
12808
12808
  }
@@ -12810,7 +12810,7 @@ function discoverAdminComponents(cwd, collections) {
12810
12810
  if (collections) {
12811
12811
  for (const col of collections) {
12812
12812
  try {
12813
- const colContent = fs33.readFileSync(path31.join(cwd, col.filePath), "utf-8");
12813
+ const colContent = fs34.readFileSync(path32.join(cwd, col.filePath), "utf-8");
12814
12814
  if (colContent.includes(name)) {
12815
12815
  usedInCollection = col.slug;
12816
12816
  break;
@@ -12828,8 +12828,8 @@ function scanApiRoutes(cwd) {
12828
12828
  const out = [];
12829
12829
  const appDirs = ["src/app", "app"];
12830
12830
  for (const appDir of appDirs) {
12831
- const apiDir = path31.join(cwd, appDir, "api");
12832
- if (!fs33.existsSync(apiDir)) continue;
12831
+ const apiDir = path32.join(cwd, appDir, "api");
12832
+ if (!fs34.existsSync(apiDir)) continue;
12833
12833
  walkApiRoutes(apiDir, "/api", cwd, out);
12834
12834
  break;
12835
12835
  }
@@ -12838,14 +12838,14 @@ function scanApiRoutes(cwd) {
12838
12838
  function walkApiRoutes(dir, prefix, cwd, out) {
12839
12839
  let entries;
12840
12840
  try {
12841
- entries = fs33.readdirSync(dir, { withFileTypes: true });
12841
+ entries = fs34.readdirSync(dir, { withFileTypes: true });
12842
12842
  } catch {
12843
12843
  return;
12844
12844
  }
12845
12845
  const routeFile = entries.find((e) => e.isFile() && /^route\.(ts|js|tsx|jsx)$/.test(e.name));
12846
12846
  if (routeFile) {
12847
12847
  try {
12848
- const content = fs33.readFileSync(path31.join(dir, routeFile.name), "utf-8").slice(0, 5e3);
12848
+ const content = fs34.readFileSync(path32.join(dir, routeFile.name), "utf-8").slice(0, 5e3);
12849
12849
  const methods = HTTP_METHODS.filter(
12850
12850
  (m) => new RegExp(`export\\s+(?:async\\s+)?function\\s+${m}\\b`).test(content)
12851
12851
  );
@@ -12853,7 +12853,7 @@ function walkApiRoutes(dir, prefix, cwd, out) {
12853
12853
  out.push({
12854
12854
  path: prefix,
12855
12855
  methods,
12856
- filePath: path31.relative(cwd, path31.join(dir, routeFile.name))
12856
+ filePath: path32.relative(cwd, path32.join(dir, routeFile.name))
12857
12857
  });
12858
12858
  }
12859
12859
  } catch {
@@ -12864,7 +12864,7 @@ function walkApiRoutes(dir, prefix, cwd, out) {
12864
12864
  if (entry.name === "node_modules" || entry.name === ".next") continue;
12865
12865
  let segment = entry.name;
12866
12866
  if (segment.startsWith("(") && segment.endsWith(")")) {
12867
- walkApiRoutes(path31.join(dir, entry.name), prefix, cwd, out);
12867
+ walkApiRoutes(path32.join(dir, entry.name), prefix, cwd, out);
12868
12868
  continue;
12869
12869
  }
12870
12870
  if (segment.startsWith("[[") && segment.endsWith("]]")) {
@@ -12872,16 +12872,16 @@ function walkApiRoutes(dir, prefix, cwd, out) {
12872
12872
  } else if (segment.startsWith("[") && segment.endsWith("]")) {
12873
12873
  segment = `:${segment.slice(1, -1)}`;
12874
12874
  }
12875
- walkApiRoutes(path31.join(dir, entry.name), `${prefix}/${segment}`, cwd, out);
12875
+ walkApiRoutes(path32.join(dir, entry.name), `${prefix}/${segment}`, cwd, out);
12876
12876
  }
12877
12877
  }
12878
12878
  function scanEnvVars(cwd) {
12879
12879
  const candidates = [".env.example", ".env.local.example", ".env.template"];
12880
12880
  for (const envFile of candidates) {
12881
- const envPath = path31.join(cwd, envFile);
12882
- if (!fs33.existsSync(envPath)) continue;
12881
+ const envPath = path32.join(cwd, envFile);
12882
+ if (!fs34.existsSync(envPath)) continue;
12883
12883
  try {
12884
- const content = fs33.readFileSync(envPath, "utf-8");
12884
+ const content = fs34.readFileSync(envPath, "utf-8");
12885
12885
  const vars = [];
12886
12886
  for (const line of content.split("\n")) {
12887
12887
  const trimmed = line.trim();
@@ -12926,8 +12926,8 @@ var init_frameworkDetectors = __esm({
12926
12926
  });
12927
12927
 
12928
12928
  // src/scripts/discoverQaContext.ts
12929
- import * as fs34 from "fs";
12930
- import * as path32 from "path";
12929
+ import * as fs35 from "fs";
12930
+ import * as path33 from "path";
12931
12931
  function runQaDiscovery(cwd) {
12932
12932
  const out = {
12933
12933
  routes: [],
@@ -12958,9 +12958,9 @@ function runQaDiscovery(cwd) {
12958
12958
  }
12959
12959
  function detectDevServer(cwd, out) {
12960
12960
  try {
12961
- const pkg = JSON.parse(fs34.readFileSync(path32.join(cwd, "package.json"), "utf-8"));
12961
+ const pkg = JSON.parse(fs35.readFileSync(path33.join(cwd, "package.json"), "utf-8"));
12962
12962
  const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
12963
- const pm = fs34.existsSync(path32.join(cwd, "pnpm-lock.yaml")) ? "pnpm" : fs34.existsSync(path32.join(cwd, "yarn.lock")) ? "yarn" : fs34.existsSync(path32.join(cwd, "bun.lockb")) ? "bun" : "npm";
12963
+ const pm = fs35.existsSync(path33.join(cwd, "pnpm-lock.yaml")) ? "pnpm" : fs35.existsSync(path33.join(cwd, "yarn.lock")) ? "yarn" : fs35.existsSync(path33.join(cwd, "bun.lockb")) ? "bun" : "npm";
12964
12964
  if (pkg.scripts?.dev) out.devCommand = `${pm} dev`;
12965
12965
  if (allDeps.next || allDeps.nuxt) out.devPort = 3e3;
12966
12966
  else if (allDeps.vite) out.devPort = 5173;
@@ -12970,8 +12970,8 @@ function detectDevServer(cwd, out) {
12970
12970
  function scanFrontendRoutes(cwd, out) {
12971
12971
  const appDirs = ["src/app", "app"];
12972
12972
  for (const appDir of appDirs) {
12973
- const full = path32.join(cwd, appDir);
12974
- if (!fs34.existsSync(full)) continue;
12973
+ const full = path33.join(cwd, appDir);
12974
+ if (!fs35.existsSync(full)) continue;
12975
12975
  walkFrontendRoutes(full, "", out);
12976
12976
  break;
12977
12977
  }
@@ -12979,7 +12979,7 @@ function scanFrontendRoutes(cwd, out) {
12979
12979
  function walkFrontendRoutes(dir, prefix, out) {
12980
12980
  let entries;
12981
12981
  try {
12982
- entries = fs34.readdirSync(dir, { withFileTypes: true });
12982
+ entries = fs35.readdirSync(dir, { withFileTypes: true });
12983
12983
  } catch {
12984
12984
  return;
12985
12985
  }
@@ -12996,7 +12996,7 @@ function walkFrontendRoutes(dir, prefix, out) {
12996
12996
  if (entry.name === "node_modules" || entry.name === ".next") continue;
12997
12997
  let segment = entry.name;
12998
12998
  if (segment.startsWith("(") && segment.endsWith(")")) {
12999
- walkFrontendRoutes(path32.join(dir, entry.name), prefix, out);
12999
+ walkFrontendRoutes(path33.join(dir, entry.name), prefix, out);
13000
13000
  continue;
13001
13001
  }
13002
13002
  if (segment.startsWith("[[") && segment.endsWith("]]")) {
@@ -13004,7 +13004,7 @@ function walkFrontendRoutes(dir, prefix, out) {
13004
13004
  } else if (segment.startsWith("[") && segment.endsWith("]")) {
13005
13005
  segment = `:${segment.slice(1, -1)}`;
13006
13006
  }
13007
- walkFrontendRoutes(path32.join(dir, entry.name), `${prefix}/${segment}`, out);
13007
+ walkFrontendRoutes(path33.join(dir, entry.name), `${prefix}/${segment}`, out);
13008
13008
  }
13009
13009
  }
13010
13010
  function detectAuthFiles(cwd, out) {
@@ -13021,23 +13021,23 @@ function detectAuthFiles(cwd, out) {
13021
13021
  "src/app/api/oauth"
13022
13022
  ];
13023
13023
  for (const c of candidates) {
13024
- if (fs34.existsSync(path32.join(cwd, c))) out.authFiles.push(c);
13024
+ if (fs35.existsSync(path33.join(cwd, c))) out.authFiles.push(c);
13025
13025
  }
13026
13026
  }
13027
13027
  function detectRoles(cwd, out) {
13028
13028
  const rolePaths = ["src/types", "src/lib", "src/utils", "src/constants", "src/access", "src/collections"];
13029
13029
  for (const rp of rolePaths) {
13030
- const dir = path32.join(cwd, rp);
13031
- if (!fs34.existsSync(dir)) continue;
13030
+ const dir = path33.join(cwd, rp);
13031
+ if (!fs35.existsSync(dir)) continue;
13032
13032
  let files;
13033
13033
  try {
13034
- files = fs34.readdirSync(dir).filter((f) => f.endsWith(".ts") || f.endsWith(".tsx"));
13034
+ files = fs35.readdirSync(dir).filter((f) => f.endsWith(".ts") || f.endsWith(".tsx"));
13035
13035
  } catch {
13036
13036
  continue;
13037
13037
  }
13038
13038
  for (const f of files) {
13039
13039
  try {
13040
- const content = fs34.readFileSync(path32.join(dir, f), "utf-8").slice(0, 5e3);
13040
+ const content = fs35.readFileSync(path33.join(dir, f), "utf-8").slice(0, 5e3);
13041
13041
  const roleMatches = content.match(/(?:role|Role|ROLE)\s*[=:]\s*['"](\w+)['"]/g);
13042
13042
  if (roleMatches) {
13043
13043
  for (const m of roleMatches) {
@@ -13524,7 +13524,7 @@ var init_triggerDispatcher = __esm({
13524
13524
  });
13525
13525
 
13526
13526
  // src/goal/policyResolver.ts
13527
- import { createHash as createHash4 } from "crypto";
13527
+ import { createHash as createHash5 } from "crypto";
13528
13528
  function resolveDispatchPolicy(input) {
13529
13529
  const operation = input.catalog.operations.get(input.owner.definition.operationId);
13530
13530
  if (!operation) throw new Error(`Dispatch blocked: Operation "${input.owner.definition.operationId}" is unresolved`);
@@ -13542,7 +13542,7 @@ function resolveDispatchPolicy(input) {
13542
13542
  const snapshotValue = { policy, constraints };
13543
13543
  return {
13544
13544
  snapshot: {
13545
- hash: createHash4("sha256").update(stableJson(snapshotValue)).digest("hex"),
13545
+ hash: createHash5("sha256").update(stableJson(snapshotValue)).digest("hex"),
13546
13546
  ...snapshotValue
13547
13547
  },
13548
13548
  operation,
@@ -14992,15 +14992,15 @@ var init_fixFlow = __esm({
14992
14992
  });
14993
14993
 
14994
14994
  // src/workflow-template.ts
14995
- import * as fs35 from "fs";
14996
- import * as path33 from "path";
14995
+ import * as fs36 from "fs";
14996
+ import * as path34 from "path";
14997
14997
  import { fileURLToPath } from "url";
14998
14998
  function loadKodyWorkflowTemplate() {
14999
- const here = path33.dirname(fileURLToPath(import.meta.url));
15000
- const candidates = [path33.resolve(here, "../templates/kody.yml"), path33.resolve(here, "../../templates/kody.yml")];
15001
- const source = candidates.find((candidate) => fs35.existsSync(candidate));
14999
+ const here = path34.dirname(fileURLToPath(import.meta.url));
15000
+ const candidates = [path34.resolve(here, "../templates/kody.yml"), path34.resolve(here, "../../templates/kody.yml")];
15001
+ const source = candidates.find((candidate) => fs36.existsSync(candidate));
15002
15002
  if (!source) throw new Error(`Kody workflow template is missing: ${KODY_WORKFLOW_TEMPLATE_PATH}`);
15003
- return fs35.readFileSync(source, "utf8");
15003
+ return fs36.readFileSync(source, "utf8");
15004
15004
  }
15005
15005
  var KODY_WORKFLOW_TEMPLATE_PATH;
15006
15006
  var init_workflow_template = __esm({
@@ -15012,12 +15012,12 @@ var init_workflow_template = __esm({
15012
15012
 
15013
15013
  // src/scripts/initFlow.ts
15014
15014
  import { execFileSync as execFileSync14 } from "child_process";
15015
- import * as fs36 from "fs";
15016
- import * as path34 from "path";
15015
+ import * as fs37 from "fs";
15016
+ import * as path35 from "path";
15017
15017
  function detectPackageManager(cwd) {
15018
- if (fs36.existsSync(path34.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
15019
- if (fs36.existsSync(path34.join(cwd, "yarn.lock"))) return "yarn";
15020
- if (fs36.existsSync(path34.join(cwd, "bun.lockb"))) return "bun";
15018
+ if (fs37.existsSync(path35.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
15019
+ if (fs37.existsSync(path35.join(cwd, "yarn.lock"))) return "yarn";
15020
+ if (fs37.existsSync(path35.join(cwd, "bun.lockb"))) return "bun";
15021
15021
  return "npm";
15022
15022
  }
15023
15023
  function qualityCommandsFor(pm) {
@@ -15089,22 +15089,22 @@ function performInit(cwd, force) {
15089
15089
  const pm = detectPackageManager(cwd);
15090
15090
  const ownerRepo = detectOwnerRepo(cwd);
15091
15091
  const defaultBranch = defaultBranchFromGit(cwd);
15092
- const configPath = path34.join(cwd, "kody.config.json");
15093
- if (fs36.existsSync(configPath) && !force) {
15092
+ const configPath = path35.join(cwd, "kody.config.json");
15093
+ if (fs37.existsSync(configPath) && !force) {
15094
15094
  skipped.push("kody.config.json");
15095
15095
  } else {
15096
15096
  const cfg = makeConfig(pm, ownerRepo, defaultBranch);
15097
- fs36.writeFileSync(configPath, `${JSON.stringify(cfg, null, 2)}
15097
+ fs37.writeFileSync(configPath, `${JSON.stringify(cfg, null, 2)}
15098
15098
  `);
15099
15099
  wrote.push("kody.config.json");
15100
15100
  }
15101
- const workflowDir = path34.join(cwd, ".github", "workflows");
15102
- const workflowPath = path34.join(workflowDir, "kody.yml");
15103
- if (fs36.existsSync(workflowPath) && !force) {
15101
+ const workflowDir = path35.join(cwd, ".github", "workflows");
15102
+ const workflowPath = path35.join(workflowDir, "kody.yml");
15103
+ if (fs37.existsSync(workflowPath) && !force) {
15104
15104
  skipped.push(".github/workflows/kody.yml");
15105
15105
  } else {
15106
- fs36.mkdirSync(workflowDir, { recursive: true });
15107
- fs36.writeFileSync(workflowPath, loadKodyWorkflowTemplate());
15106
+ fs37.mkdirSync(workflowDir, { recursive: true });
15107
+ fs37.writeFileSync(workflowPath, loadKodyWorkflowTemplate());
15108
15108
  wrote.push(".github/workflows/kody.yml");
15109
15109
  }
15110
15110
  for (const exe of listRuntimeProfilesForCwd(cwd)) {
@@ -15115,12 +15115,12 @@ function performInit(cwd, force) {
15115
15115
  continue;
15116
15116
  }
15117
15117
  if (profile.kind !== "scheduled" || !profile.schedule) continue;
15118
- const target = path34.join(workflowDir, `kody-${exe.name}.yml`);
15119
- if (fs36.existsSync(target) && !force) {
15118
+ const target = path35.join(workflowDir, `kody-${exe.name}.yml`);
15119
+ if (fs37.existsSync(target) && !force) {
15120
15120
  skipped.push(`.github/workflows/kody-${exe.name}.yml`);
15121
15121
  continue;
15122
15122
  }
15123
- fs36.writeFileSync(target, renderScheduledWorkflow(exe.name, profile.schedule));
15123
+ fs37.writeFileSync(target, renderScheduledWorkflow(exe.name, profile.schedule));
15124
15124
  wrote.push(`.github/workflows/kody-${exe.name}.yml`);
15125
15125
  }
15126
15126
  let labels;
@@ -15208,7 +15208,7 @@ Nothing to do. All files already present. (Use --force to overwrite.)
15208
15208
  });
15209
15209
 
15210
15210
  // src/scripts/loadAgentAdhoc.ts
15211
- import * as fs37 from "fs";
15211
+ import * as fs38 from "fs";
15212
15212
  function resolveMessage(messageArg) {
15213
15213
  const fromComment = readCommentBody();
15214
15214
  if (fromComment) return stripDirective(fromComment);
@@ -15216,9 +15216,9 @@ function resolveMessage(messageArg) {
15216
15216
  }
15217
15217
  function readCommentBody() {
15218
15218
  const eventPath = process.env.GITHUB_EVENT_PATH;
15219
- if (!eventPath || !fs37.existsSync(eventPath)) return "";
15219
+ if (!eventPath || !fs38.existsSync(eventPath)) return "";
15220
15220
  try {
15221
- const event = JSON.parse(fs37.readFileSync(eventPath, "utf-8"));
15221
+ const event = JSON.parse(fs38.readFileSync(eventPath, "utf-8"));
15222
15222
  return String(event.comment?.body ?? "");
15223
15223
  } catch {
15224
15224
  return "";
@@ -15272,10 +15272,10 @@ var init_loadAgentAdhoc = __esm({
15272
15272
  throw new Error("loadAgentAdhoc: ctx.args.agent must be a non-empty slug");
15273
15273
  }
15274
15274
  const agentPath = resolveAgentFile(ctx.cwd, agentSlug, agentsDir);
15275
- if (!fs37.existsSync(agentPath)) {
15275
+ if (!fs38.existsSync(agentPath)) {
15276
15276
  throw new Error(`loadAgentAdhoc: agent identity not found: ${agentPath}`);
15277
15277
  }
15278
- const { title, body } = parseAgentFile(fs37.readFileSync(agentPath, "utf-8"), agentSlug);
15278
+ const { title, body } = parseAgentFile(fs38.readFileSync(agentPath, "utf-8"), agentSlug);
15279
15279
  const message = resolveMessage(ctx.args.message);
15280
15280
  if (!message) {
15281
15281
  throw new Error(
@@ -15345,7 +15345,7 @@ var init_loadCapabilityState = __esm({
15345
15345
 
15346
15346
  // src/companyIntent.ts
15347
15347
  function isCompanyIntentId(value) {
15348
- return SLUG_RE.test(value);
15348
+ return SLUG_RE2.test(value);
15349
15349
  }
15350
15350
  function normalizeCompanyIntent(path52, raw) {
15351
15351
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
@@ -15459,14 +15459,14 @@ function normalizeAutomationPolicy(raw) {
15459
15459
  requiresHumanFor: stringArray2(raw?.requiresHumanFor)
15460
15460
  };
15461
15461
  }
15462
- var SLUG_RE;
15462
+ var SLUG_RE2;
15463
15463
  var init_companyIntent = __esm({
15464
15464
  "src/companyIntent.ts"() {
15465
15465
  "use strict";
15466
15466
  init_state2();
15467
15467
  init_stateStore();
15468
15468
  init_state_backend();
15469
- SLUG_RE = /^[a-z][a-z0-9-]{0,63}$/;
15469
+ SLUG_RE2 = /^[a-z][a-z0-9-]{0,63}$/;
15470
15470
  }
15471
15471
  });
15472
15472
 
@@ -15644,8 +15644,8 @@ var init_loadIssueStateComment = __esm({
15644
15644
  });
15645
15645
 
15646
15646
  // src/scripts/loadJobFromFile.ts
15647
- import * as fs38 from "fs";
15648
- import * as path35 from "path";
15647
+ import * as fs39 from "fs";
15648
+ import * as path36 from "path";
15649
15649
  function parseJobFile(raw, slug) {
15650
15650
  let stripped = raw;
15651
15651
  if (stripped.startsWith("---\n")) {
@@ -15684,10 +15684,10 @@ var init_loadJobFromFile = __esm({
15684
15684
  if (!slug) {
15685
15685
  throw new Error(`loadJobFromFile: ctx.args.${slugArg} must be a non-empty slug`);
15686
15686
  }
15687
- const capability = resolveCapabilityFolder(slug, path35.resolve(ctx.cwd, jobsDir));
15687
+ const capability = resolveCapabilityFolder(slug, path36.resolve(ctx.cwd, jobsDir));
15688
15688
  if (!capability) {
15689
15689
  throw new Error(
15690
- `loadJobFromFile: capability folder not found or incomplete: ${path35.resolve(ctx.cwd, jobsDir, slug)}`
15690
+ `loadJobFromFile: capability folder not found or incomplete: ${path36.resolve(ctx.cwd, jobsDir, slug)}`
15691
15691
  );
15692
15692
  }
15693
15693
  const { title, body, config } = capability;
@@ -15697,12 +15697,12 @@ var init_loadJobFromFile = __esm({
15697
15697
  let agentIdentity = "";
15698
15698
  if (agentSlug) {
15699
15699
  const agentPath = resolveAgentFile(ctx.cwd, agentSlug, agentsDir);
15700
- if (!fs38.existsSync(agentPath)) {
15700
+ if (!fs39.existsSync(agentPath)) {
15701
15701
  throw new Error(
15702
15702
  `loadJobFromFile: capability '${slug}' declares agent '${agentSlug}' but ${agentPath} does not exist`
15703
15703
  );
15704
15704
  }
15705
- const agentRaw = fs38.readFileSync(agentPath, "utf-8");
15705
+ const agentRaw = fs39.readFileSync(agentPath, "utf-8");
15706
15706
  const parsed = parseJobFile(agentRaw, agentSlug);
15707
15707
  agentTitle = parsed.title;
15708
15708
  agentIdentity = parsed.body;
@@ -15782,13 +15782,13 @@ ${truncate2(issue2.body, FINDING_BODY_MAX_BYTES)}`;
15782
15782
  });
15783
15783
 
15784
15784
  // src/scripts/kodyVariables.ts
15785
- import * as fs39 from "fs";
15786
- import * as path36 from "path";
15785
+ import * as fs40 from "fs";
15786
+ import * as path37 from "path";
15787
15787
  function readKodyVariables(cwd) {
15788
- const full = path36.join(cwd, KODY_VARIABLES_REL_PATH);
15788
+ const full = path37.join(cwd, KODY_VARIABLES_REL_PATH);
15789
15789
  let raw;
15790
15790
  try {
15791
- raw = fs39.readFileSync(full, "utf-8");
15791
+ raw = fs40.readFileSync(full, "utf-8");
15792
15792
  } catch {
15793
15793
  return {};
15794
15794
  }
@@ -15813,9 +15813,9 @@ var init_kodyVariables = __esm({
15813
15813
  });
15814
15814
 
15815
15815
  // src/backendVault.ts
15816
- import { createDecipheriv, createHash as createHash5 } from "crypto";
15816
+ import { createDecipheriv, createHash as createHash6 } from "crypto";
15817
15817
  function cacheKey(owner, repo, masterKey) {
15818
- const keyHash = createHash5("sha256").update(masterKey).digest("hex").slice(0, 16);
15818
+ const keyHash = createHash6("sha256").update(masterKey).digest("hex").slice(0, 16);
15819
15819
  return `${owner}/${repo}:${keyHash}`.toLowerCase();
15820
15820
  }
15821
15821
  function decryptVault(payload, masterKey) {
@@ -15964,8 +15964,8 @@ var init_runtimeSecrets = __esm({
15964
15964
  });
15965
15965
 
15966
15966
  // src/scripts/loadQaContext.ts
15967
- import * as fs40 from "fs";
15968
- import * as path37 from "path";
15967
+ import * as fs41 from "fs";
15968
+ import * as path38 from "path";
15969
15969
  function parseSlugList(value) {
15970
15970
  const inner = value.startsWith("[") && value.endsWith("]") ? value.slice(1, -1) : value;
15971
15971
  return inner.split(",").map(
@@ -15994,18 +15994,18 @@ function readProfileAgents(raw) {
15994
15994
  return { agent: agent ?? legacy ?? ["kody"], body };
15995
15995
  }
15996
15996
  function readProfile(cwd) {
15997
- const dir = path37.join(cwd, CONTEXT_DIR_REL_PATH);
15998
- if (!fs40.existsSync(dir)) return "";
15997
+ const dir = path38.join(cwd, CONTEXT_DIR_REL_PATH);
15998
+ if (!fs41.existsSync(dir)) return "";
15999
15999
  let entries;
16000
16000
  try {
16001
- entries = fs40.readdirSync(dir).filter((f) => f.endsWith(".md")).sort();
16001
+ entries = fs41.readdirSync(dir).filter((f) => f.endsWith(".md")).sort();
16002
16002
  } catch {
16003
16003
  return "";
16004
16004
  }
16005
16005
  const blocks = [];
16006
16006
  for (const file of entries) {
16007
16007
  try {
16008
- const raw = fs40.readFileSync(path37.join(dir, file), "utf-8");
16008
+ const raw = fs41.readFileSync(path38.join(dir, file), "utf-8");
16009
16009
  const { agent, body } = readProfileAgents(raw);
16010
16010
  if (!agent.includes(QA_AGENT) && !agent.includes(ALL_AGENTS)) continue;
16011
16011
  blocks.push(`## ${file}
@@ -16054,8 +16054,8 @@ var init_loadQaContext = __esm({
16054
16054
  });
16055
16055
 
16056
16056
  // src/taskContext.ts
16057
- import * as fs41 from "fs";
16058
- import * as path38 from "path";
16057
+ import * as fs42 from "fs";
16058
+ import * as path39 from "path";
16059
16059
  function buildTaskContext(args) {
16060
16060
  return {
16061
16061
  schemaVersion: TASK_CONTEXT_SCHEMA_VERSION,
@@ -16071,9 +16071,9 @@ function buildTaskContext(args) {
16071
16071
  function persistTaskContext(cwd, ctx) {
16072
16072
  try {
16073
16073
  const dir = runtimeStatePath(cwd, "agent-runs", ctx.runId);
16074
- fs41.mkdirSync(dir, { recursive: true });
16075
- const file = path38.join(dir, "task-context.json");
16076
- fs41.writeFileSync(file, `${JSON.stringify(ctx, null, 2)}
16074
+ fs42.mkdirSync(dir, { recursive: true });
16075
+ const file = path39.join(dir, "task-context.json");
16076
+ fs42.writeFileSync(file, `${JSON.stringify(ctx, null, 2)}
16077
16077
  `);
16078
16078
  return file;
16079
16079
  } catch (err) {
@@ -16464,7 +16464,7 @@ var init_notifyTerminal = __esm({
16464
16464
  });
16465
16465
 
16466
16466
  // src/scripts/openAgencyModelReviewPr.ts
16467
- import { createHash as createHash6 } from "crypto";
16467
+ import { createHash as createHash7 } from "crypto";
16468
16468
  function parseAgencyModelProposal(raw) {
16469
16469
  const text2 = raw.trim();
16470
16470
  const jsonText = (text2.match(/^```(?:json)?\s*\n([\s\S]*?)\n```$/i)?.[1] ?? text2).trim();
@@ -16516,7 +16516,7 @@ function normalizeBundleFiles(bundle) {
16516
16516
  });
16517
16517
  }
16518
16518
  function buildProposalId(issueNumber, bundle, sourceLabel) {
16519
- const digest = createHash6("sha256").update(JSON.stringify({ issueNumber, sourceLabel, title: bundle.title, files: normalizeBundleFiles(bundle) })).digest("hex").slice(0, 16);
16519
+ const digest = createHash7("sha256").update(JSON.stringify({ issueNumber, sourceLabel, title: bundle.title, files: normalizeBundleFiles(bundle) })).digest("hex").slice(0, 16);
16520
16520
  return `issue-${issueNumber}-${digest}`;
16521
16521
  }
16522
16522
  function isDryRun(ctx) {
@@ -17456,9 +17456,9 @@ var init_postResearchComment = __esm({
17456
17456
  });
17457
17457
 
17458
17458
  // src/scripts/prepareBrowserAuth.ts
17459
- import * as fs42 from "fs";
17459
+ import * as fs43 from "fs";
17460
17460
  import * as os6 from "os";
17461
- import * as path39 from "path";
17461
+ import * as path40 from "path";
17462
17462
  function appendAuthMessage(ctx, message) {
17463
17463
  const current = typeof ctx.data.qaAuthBlock === "string" ? ctx.data.qaAuthBlock.trim() : "";
17464
17464
  ctx.data.qaAuthBlock = current ? `${current}
@@ -17497,9 +17497,9 @@ async function githubJson(url, token) {
17497
17497
  return await response.json();
17498
17498
  }
17499
17499
  function writeKodyStorageState(input) {
17500
- const directory = fs42.mkdtempSync(path39.join(os6.tmpdir(), "kody-browser-auth-"));
17501
- fs42.chmodSync(directory, 448);
17502
- const file = path39.join(directory, "storage-state.json");
17500
+ const directory = fs43.mkdtempSync(path40.join(os6.tmpdir(), "kody-browser-auth-"));
17501
+ fs43.chmodSync(directory, 448);
17502
+ const file = path40.join(directory, "storage-state.json");
17503
17503
  const now = Date.now();
17504
17504
  const repoEntry = {
17505
17505
  repoUrl: input.repoUrl,
@@ -17529,7 +17529,7 @@ function writeKodyStorageState(input) {
17529
17529
  }
17530
17530
  ]
17531
17531
  };
17532
- fs42.writeFileSync(file, JSON.stringify(storageState), { mode: 384 });
17532
+ fs43.writeFileSync(file, JSON.stringify(storageState), { mode: 384 });
17533
17533
  return { directory, file };
17534
17534
  }
17535
17535
  function configurePlaywright(profile, storageStatePath) {
@@ -17611,7 +17611,7 @@ async function prepareMethod(ctx, profile, method) {
17611
17611
  configurePlaywright(profile, state.file);
17612
17612
  const authDirectory = state.directory;
17613
17613
  registerRuntimeCleanup(ctx, () => {
17614
- fs42.rmSync(authDirectory, { recursive: true, force: true });
17614
+ fs43.rmSync(authDirectory, { recursive: true, force: true });
17615
17615
  });
17616
17616
  appendAuthMessage(
17617
17617
  ctx,
@@ -17619,7 +17619,7 @@ async function prepareMethod(ctx, profile, method) {
17619
17619
  );
17620
17620
  return true;
17621
17621
  } catch (error) {
17622
- if (state) fs42.rmSync(state.directory, { recursive: true, force: true });
17622
+ if (state) fs43.rmSync(state.directory, { recursive: true, force: true });
17623
17623
  const reason = error instanceof Error ? error.message : String(error);
17624
17624
  appendAuthMessage(
17625
17625
  ctx,
@@ -18588,9 +18588,9 @@ var init_runFlow = __esm({
18588
18588
  });
18589
18589
 
18590
18590
  // src/scripts/previewBuildHelpers.ts
18591
- import { createDecipheriv as createDecipheriv2, createHash as createHash7, hkdfSync as hkdfSync2 } from "crypto";
18591
+ import { createDecipheriv as createDecipheriv2, createHash as createHash8, hkdfSync as hkdfSync2 } from "crypto";
18592
18592
  function shortHash(s) {
18593
- return createHash7("sha256").update(s).digest("hex").slice(0, 6);
18593
+ return createHash8("sha256").update(s).digest("hex").slice(0, 6);
18594
18594
  }
18595
18595
  function previewAppName(repo, pr) {
18596
18596
  const [owner, name] = repo.split("/");
@@ -18623,7 +18623,7 @@ function formatPreviewComment(args) {
18623
18623
  ].join("\n");
18624
18624
  }
18625
18625
  function defaultImageTag(repo, ref) {
18626
- return createHash7("sha256").update(`${repo}@${ref}`).digest("hex").slice(0, 12);
18626
+ return createHash8("sha256").update(`${repo}@${ref}`).digest("hex").slice(0, 12);
18627
18627
  }
18628
18628
  var init_previewBuildHelpers = __esm({
18629
18629
  "src/scripts/previewBuildHelpers.ts"() {
@@ -18718,12 +18718,12 @@ fi
18718
18718
 
18719
18719
  // src/scripts/runPreviewBuild.ts
18720
18720
  import { copyFile, writeFile } from "fs/promises";
18721
- import * as path40 from "path";
18721
+ import * as path41 from "path";
18722
18722
  import { fileURLToPath as fileURLToPath2 } from "url";
18723
18723
  function bundledDockerfilePath(mode) {
18724
- const here = path40.dirname(fileURLToPath2(import.meta.url));
18724
+ const here = path41.dirname(fileURLToPath2(import.meta.url));
18725
18725
  const file = mode === "dev" ? "default-Dockerfile.preview.dev" : "default-Dockerfile.preview.prod";
18726
- return path40.join(here, "preview-build-templates", file);
18726
+ return path41.join(here, "preview-build-templates", file);
18727
18727
  }
18728
18728
  function required(name) {
18729
18729
  const v = (process.env[name] ?? "").trim();
@@ -18958,10 +18958,10 @@ var init_runPreviewBuild = __esm({
18958
18958
  console.log(`[preview-build] vault: ${Object.keys(buildEnv).length} secrets, mode=${buildMode}`);
18959
18959
  if (Object.keys(buildEnv).length > 0) {
18960
18960
  const lines = Object.entries(buildEnv).map(([k, v]) => `${k}=${JSON.stringify(v)}`);
18961
- await writeFile(path40.join(ctx.cwd, ".env.production.local"), `${lines.join("\n")}
18961
+ await writeFile(path41.join(ctx.cwd, ".env.production.local"), `${lines.join("\n")}
18962
18962
  `, "utf8");
18963
18963
  }
18964
- const consumerDockerfile = path40.join(ctx.cwd, "Dockerfile.preview");
18964
+ const consumerDockerfile = path41.join(ctx.cwd, "Dockerfile.preview");
18965
18965
  const { stat } = await import("fs/promises");
18966
18966
  let hasConsumerDockerfile = false;
18967
18967
  try {
@@ -19145,8 +19145,8 @@ var init_tickShellRunner = __esm({
19145
19145
  });
19146
19146
 
19147
19147
  // src/scripts/runScheduledImplementationTick.ts
19148
- import * as fs43 from "fs";
19149
- import * as path41 from "path";
19148
+ import * as fs44 from "fs";
19149
+ import * as path42 from "path";
19150
19150
  var runScheduledImplementationTick;
19151
19151
  var init_runScheduledImplementationTick = __esm({
19152
19152
  "src/scripts/runScheduledImplementationTick.ts"() {
@@ -19167,14 +19167,14 @@ var init_runScheduledImplementationTick = __esm({
19167
19167
  ctx.output.reason = `runScheduledImplementationTick: args.slug or ctx.args.${slugArg} must be non-empty capability slug`;
19168
19168
  return;
19169
19169
  }
19170
- const capability = resolveCapabilityFolder(slug, path41.resolve(ctx.cwd, jobsDir));
19170
+ const capability = resolveCapabilityFolder(slug, path42.resolve(ctx.cwd, jobsDir));
19171
19171
  if (!capability) {
19172
19172
  ctx.output.exitCode = 99;
19173
19173
  ctx.output.reason = `runScheduledImplementationTick: capability folder not found or incomplete: ${slug} (searched ${jobsDir} and company store)`;
19174
19174
  return;
19175
19175
  }
19176
- const shellPath = path41.join(profile.dir, shell);
19177
- if (!fs43.existsSync(shellPath)) {
19176
+ const shellPath = path42.join(profile.dir, shell);
19177
+ if (!fs44.existsSync(shellPath)) {
19178
19178
  ctx.output.exitCode = 99;
19179
19179
  ctx.output.reason = `runScheduledImplementationTick: shell not found: ${shell} (looked in ${profile.dir})`;
19180
19180
  return;
@@ -19205,8 +19205,8 @@ var init_runScheduledImplementationTick = __esm({
19205
19205
  });
19206
19206
 
19207
19207
  // src/scripts/runTickScript.ts
19208
- import * as fs44 from "fs";
19209
- import * as path42 from "path";
19208
+ import * as fs45 from "fs";
19209
+ import * as path43 from "path";
19210
19210
  var runTickScript;
19211
19211
  var init_runTickScript = __esm({
19212
19212
  "src/scripts/runTickScript.ts"() {
@@ -19226,10 +19226,10 @@ var init_runTickScript = __esm({
19226
19226
  ctx.output.reason = `runTickScript: ctx.args.${slugArg} must be a non-empty slug`;
19227
19227
  return;
19228
19228
  }
19229
- const capability = readCapabilityFolder(path42.resolve(ctx.cwd, jobsDir), slug);
19229
+ const capability = readCapabilityFolder(path43.resolve(ctx.cwd, jobsDir), slug);
19230
19230
  if (!capability) {
19231
19231
  ctx.output.exitCode = 99;
19232
- ctx.output.reason = `runTickScript: capability folder not found or incomplete: ${path42.resolve(ctx.cwd, jobsDir, slug)}`;
19232
+ ctx.output.reason = `runTickScript: capability folder not found or incomplete: ${path43.resolve(ctx.cwd, jobsDir, slug)}`;
19233
19233
  return;
19234
19234
  }
19235
19235
  const tickScript = capability.config.tickScript;
@@ -19238,8 +19238,8 @@ var init_runTickScript = __esm({
19238
19238
  ctx.output.reason = `runTickScript: capability ${slug} has no \`tickScript\` in profile.json \u2014 route via capability-tick instead`;
19239
19239
  return;
19240
19240
  }
19241
- const scriptPath = path42.isAbsolute(tickScript) ? tickScript : path42.join(ctx.cwd, tickScript);
19242
- if (!fs44.existsSync(scriptPath)) {
19241
+ const scriptPath = path43.isAbsolute(tickScript) ? tickScript : path43.join(ctx.cwd, tickScript);
19242
+ if (!fs45.existsSync(scriptPath)) {
19243
19243
  ctx.output.exitCode = 99;
19244
19244
  ctx.output.reason = `runTickScript: tickScript not found: ${scriptPath}`;
19245
19245
  return;
@@ -19521,7 +19521,7 @@ var init_syncFlow = __esm({
19521
19521
  });
19522
19522
 
19523
19523
  // src/scripts/validateAgencyModelProposal.ts
19524
- import * as path43 from "path";
19524
+ import * as path44 from "path";
19525
19525
  function validateModelBundle(bundle, expectedKind, options = {}) {
19526
19526
  const failures = [];
19527
19527
  validateOneModel(bundle.model, bundle.files, "model", true, failures, expectedKind, options);
@@ -19847,7 +19847,7 @@ var init_validateAgencyModelProposal = __esm({
19847
19847
  const bundle = parseAgencyModelProposal(raw);
19848
19848
  const expectedKind = readExpectedModelKind(args);
19849
19849
  const failures = validateModelBundle(bundle, expectedKind, {
19850
- capabilityRoot: path43.join(ctx.cwd, ".kody", "capabilities")
19850
+ capabilityRoot: path44.join(ctx.cwd, ".kody", "capabilities")
19851
19851
  });
19852
19852
  if (failures.length > 0) {
19853
19853
  throw new Error(`validateAgencyModelProposal: ${failures.join("; ")}`);
@@ -20398,7 +20398,7 @@ var init_warmupMcp = __esm({
20398
20398
  });
20399
20399
 
20400
20400
  // src/scripts/writeAgentRunSummary.ts
20401
- import * as fs45 from "fs";
20401
+ import * as fs46 from "fs";
20402
20402
  var writeAgentRunSummary;
20403
20403
  var init_writeAgentRunSummary = __esm({
20404
20404
  "src/scripts/writeAgentRunSummary.ts"() {
@@ -20424,7 +20424,7 @@ var init_writeAgentRunSummary = __esm({
20424
20424
  if (reason) lines.push(`- **Reason:** ${reason}`);
20425
20425
  lines.push("");
20426
20426
  try {
20427
- fs45.appendFileSync(summaryPath, `${lines.join("\n")}
20427
+ fs46.appendFileSync(summaryPath, `${lines.join("\n")}
20428
20428
  `);
20429
20429
  } catch {
20430
20430
  }
@@ -20752,17 +20752,17 @@ var init_scripts = __esm({
20752
20752
  });
20753
20753
 
20754
20754
  // src/stateWorkspace.ts
20755
- import * as fs46 from "fs";
20756
- import * as path44 from "path";
20755
+ import * as fs47 from "fs";
20756
+ import * as path45 from "path";
20757
20757
  function tenantId(config) {
20758
20758
  const owner = config.github?.owner?.trim() || process.env.GITHUB_REPOSITORY?.split("/")[0]?.trim();
20759
20759
  const repo = config.github?.repo?.trim() || process.env.GITHUB_REPOSITORY?.split("/")[1]?.trim();
20760
20760
  return owner && repo ? `${owner}/${repo}` : null;
20761
20761
  }
20762
20762
  function writeRuntimeFile(cwd, relativePath, content) {
20763
- const target = path44.join(cwd, RUNTIME_ROOT, relativePath);
20764
- fs46.mkdirSync(path44.dirname(target), { recursive: true });
20765
- fs46.writeFileSync(target, content, "utf8");
20763
+ const target = path45.join(cwd, RUNTIME_ROOT, relativePath);
20764
+ fs47.mkdirSync(path45.dirname(target), { recursive: true });
20765
+ fs47.writeFileSync(target, content, "utf8");
20766
20766
  }
20767
20767
  function record(value) {
20768
20768
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
@@ -20827,11 +20827,11 @@ async function hydrateStateWorkspace(config, cwd, backendOverride) {
20827
20827
  throw new Error("Kody backend access is required for runtime workspace documents");
20828
20828
  return;
20829
20829
  }
20830
- const key = `${path44.resolve(cwd)}|${tenant}`;
20830
+ const key = `${path45.resolve(cwd)}|${tenant}`;
20831
20831
  if (hydratedWorkspaces.has(key)) return;
20832
20832
  const backend = backendOverride ?? createStateBackendFromEnv();
20833
- const root = path44.join(cwd, RUNTIME_ROOT);
20834
- fs46.rmSync(root, { recursive: true, force: true });
20833
+ const root = path45.join(cwd, RUNTIME_ROOT);
20834
+ fs47.rmSync(root, { recursive: true, force: true });
20835
20835
  await Promise.all([
20836
20836
  hydratePrefix(backend, tenant, cwd, "context:"),
20837
20837
  hydratePrefix(backend, tenant, cwd, "memory:"),
@@ -20847,7 +20847,7 @@ var init_stateWorkspace = __esm({
20847
20847
  "src/stateWorkspace.ts"() {
20848
20848
  "use strict";
20849
20849
  init_state_backend();
20850
- RUNTIME_ROOT = path44.join(".kody-engine", "runtime");
20850
+ RUNTIME_ROOT = path45.join(".kody-engine", "runtime");
20851
20851
  hydratedWorkspaces = /* @__PURE__ */ new Set();
20852
20852
  }
20853
20853
  });
@@ -20918,9 +20918,9 @@ var init_tools = __esm({
20918
20918
 
20919
20919
  // src/executor.ts
20920
20920
  import { spawn as spawn8 } from "child_process";
20921
- import * as fs47 from "fs";
20921
+ import * as fs48 from "fs";
20922
20922
  import * as os7 from "os";
20923
- import * as path45 from "path";
20923
+ import * as path46 from "path";
20924
20924
  function isMutatingPostflight(scriptName) {
20925
20925
  return MUTATING_POSTFLIGHTS.has(scriptName ?? "");
20926
20926
  }
@@ -21161,7 +21161,7 @@ async function runImplementation(profileName, input) {
21161
21161
  const jobWhyBlock = typeof ctx.data.jobWhy === "string" ? operatorRequestBlock(ctx.data.jobWhy) : null;
21162
21162
  const jobRefBlock = jobReferenceBlock(profileName, profile, ctx.data);
21163
21163
  const invokeAgent = async (prompt) => {
21164
- const externalPlugins = (profile.claudeCode.plugins ?? []).map((p) => path45.isAbsolute(p) ? p : path45.resolve(profile.dir, p)).filter((p) => p.length > 0);
21164
+ const externalPlugins = (profile.claudeCode.plugins ?? []).map((p) => path46.isAbsolute(p) ? p : path46.resolve(profile.dir, p)).filter((p) => p.length > 0);
21165
21165
  const syntheticPath = ctx.data.syntheticPluginPath;
21166
21166
  const pluginPaths = [...externalPlugins, ...syntheticPath ? [syntheticPath] : []];
21167
21167
  const agents = loadSubagents(profile);
@@ -21623,17 +21623,17 @@ function clearStampedLifecycleLabels(profile, ctx) {
21623
21623
  function resolveProfilePath(profileName, cwd = process.cwd()) {
21624
21624
  const found = resolveImplementation(profileName, getRuntimeProfileRootsForCwd(cwd));
21625
21625
  if (found) return found;
21626
- const here = path45.dirname(new URL(import.meta.url).pathname);
21626
+ const here = path46.dirname(new URL(import.meta.url).pathname);
21627
21627
  const candidates = [
21628
- path45.join(here, "implementations", profileName, "profile.json"),
21628
+ path46.join(here, "implementations", profileName, "profile.json"),
21629
21629
  // same-dir sibling (dev)
21630
- path45.join(here, "..", "implementations", profileName, "profile.json"),
21630
+ path46.join(here, "..", "implementations", profileName, "profile.json"),
21631
21631
  // up one (prod: dist/bin → dist/implementations)
21632
- path45.join(here, "..", "src", "implementations", profileName, "profile.json")
21632
+ path46.join(here, "..", "src", "implementations", profileName, "profile.json")
21633
21633
  // fallback
21634
21634
  ];
21635
21635
  for (const c of candidates) {
21636
- if (fs47.existsSync(c)) return c;
21636
+ if (fs48.existsSync(c)) return c;
21637
21637
  }
21638
21638
  return candidates[0];
21639
21639
  }
@@ -21748,15 +21748,15 @@ function resolveShellTimeoutMs(entry) {
21748
21748
  }
21749
21749
  async function runShellEntry(entry, ctx, profile) {
21750
21750
  const shellName = entry.shell;
21751
- const shellPath = path45.join(profile.dir, shellName);
21752
- if (!fs47.existsSync(shellPath)) {
21751
+ const shellPath = path46.join(profile.dir, shellName);
21752
+ if (!fs48.existsSync(shellPath)) {
21753
21753
  ctx.skipAgent = true;
21754
21754
  ctx.output.exitCode = 99;
21755
21755
  ctx.output.reason = `shell script not found: ${shellName} (looked in ${profile.dir})`;
21756
21756
  return;
21757
21757
  }
21758
21758
  const positional = entry.with ? Object.values(entry.with).map((v) => String(v)) : [];
21759
- const outputFile = path45.join(
21759
+ const outputFile = path46.join(
21760
21760
  os7.tmpdir(),
21761
21761
  `kody-shell-output-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`
21762
21762
  );
@@ -21828,9 +21828,9 @@ async function runShellEntry(entry, ctx, profile) {
21828
21828
  }
21829
21829
  let sideChannelText = "";
21830
21830
  try {
21831
- if (fs47.existsSync(outputFile)) {
21832
- sideChannelText = fs47.readFileSync(outputFile, "utf-8");
21833
- fs47.rmSync(outputFile, { force: true });
21831
+ if (fs48.existsSync(outputFile)) {
21832
+ sideChannelText = fs48.readFileSync(outputFile, "utf-8");
21833
+ fs48.rmSync(outputFile, { force: true });
21834
21834
  }
21835
21835
  } catch {
21836
21836
  }
@@ -22002,7 +22002,7 @@ __export(job_exports, {
22002
22002
  stableJobKey: () => stableJobKey,
22003
22003
  validateJob: () => validateJob
22004
22004
  });
22005
- import * as path46 from "path";
22005
+ import * as path47 from "path";
22006
22006
  function newJobId(flavor) {
22007
22007
  localJobSeq += 1;
22008
22008
  const runId = process.env.GITHUB_RUN_ID;
@@ -22679,7 +22679,7 @@ function loadCapabilityContext(slug, cwd) {
22679
22679
  return resolveCapabilityFolder(slug, hydratedCapabilitiesRoot(cwd));
22680
22680
  }
22681
22681
  function hydratedCapabilitiesRoot(cwd) {
22682
- return path46.join(cwd, ".kody-engine", "definitions", "capabilities");
22682
+ return path47.join(cwd, ".kody-engine", "definitions", "capabilities");
22683
22683
  }
22684
22684
  function loadWorkflowContext(slug, base) {
22685
22685
  if (!slug || !isWorkflowDefinitionId(slug)) return null;
@@ -22844,7 +22844,7 @@ function translateOpenAISseToBrain(opts) {
22844
22844
 
22845
22845
  // src/servers/brain-serve.ts
22846
22846
  import { createServer as createServer2 } from "http";
22847
- import * as path49 from "path";
22847
+ import * as path50 from "path";
22848
22848
 
22849
22849
  // src/chat/loop.ts
22850
22850
  init_agent();
@@ -23884,10 +23884,142 @@ function readSession(file) {
23884
23884
  // src/servers/brain-serve.ts
23885
23885
  init_config();
23886
23886
 
23887
+ // src/definition-hydration.ts
23888
+ init_state_backend();
23889
+ import { createHash as createHash3 } from "crypto";
23890
+ import * as fs16 from "fs";
23891
+ import * as path17 from "path";
23892
+ var SLUG_RE = /^[a-z0-9][a-z0-9_-]{0,127}$/;
23893
+ function assertSafeDefinitionPath(filePath) {
23894
+ const segments = filePath.split("/");
23895
+ if (!filePath || filePath.startsWith("/") || filePath.includes("\\") || filePath.includes("\0") || segments.some((segment) => !segment || segment === "." || segment === "..")) {
23896
+ throw new Error(`unsafe definition path: ${filePath}`);
23897
+ }
23898
+ }
23899
+ function normalizeDefinitionBundle(bundle) {
23900
+ if (bundle.schemaVersion !== 1) throw new Error("unsupported definition bundle schema");
23901
+ const files = Object.fromEntries(
23902
+ Object.entries(bundle.files).sort(([left], [right]) => left.localeCompare(right)).map(([filePath, content]) => {
23903
+ assertSafeDefinitionPath(filePath);
23904
+ return [filePath, content.replace(/\r\n?/g, "\n")];
23905
+ })
23906
+ );
23907
+ return { schemaVersion: 1, files };
23908
+ }
23909
+ function definitionVersion(bundle) {
23910
+ return `sha256:${createHash3("sha256").update(JSON.stringify(normalizeDefinitionBundle(bundle))).digest("hex")}`;
23911
+ }
23912
+ function verifyDefinition(definition) {
23913
+ if (!SLUG_RE.test(definition.slug)) throw new Error(`invalid definition slug: ${definition.slug}`);
23914
+ const bundle = normalizeDefinitionBundle(definition.bundle);
23915
+ if (definitionVersion(bundle) !== definition.version) {
23916
+ throw new Error(`definition version mismatch for ${definition.slug}: ${definition.version}`);
23917
+ }
23918
+ return bundle;
23919
+ }
23920
+ function writeBundle(root, bundle) {
23921
+ for (const [filePath, contents] of Object.entries(bundle.files)) {
23922
+ const target = path17.join(root, filePath);
23923
+ fs16.mkdirSync(path17.dirname(target), { recursive: true });
23924
+ fs16.writeFileSync(target, contents, "utf8");
23925
+ }
23926
+ }
23927
+ function writeDefinition(root, kind, definition) {
23928
+ const bundle = verifyDefinition(definition);
23929
+ if (kind === "agent") {
23930
+ const raw = bundle.files["agent.md"];
23931
+ if (typeof raw !== "string") throw new Error(`agent definition ${definition.slug} is missing agent.md`);
23932
+ fs16.writeFileSync(path17.join(root, "agents", `${definition.slug}.md`), raw, "utf8");
23933
+ return;
23934
+ }
23935
+ if (kind === "goal") {
23936
+ writeBundle(path17.join(root, "goals", definition.slug), bundle);
23937
+ return;
23938
+ }
23939
+ if (kind === "implementation") {
23940
+ writeBundle(path17.join(root, "implementations", definition.slug), bundle);
23941
+ return;
23942
+ }
23943
+ if (kind === "asset") {
23944
+ writeBundle(path17.join(root, "shared"), bundle);
23945
+ return;
23946
+ }
23947
+ writeBundle(path17.join(root, "capabilities", definition.slug), bundle);
23948
+ }
23949
+ async function hydrateDefinitions(options) {
23950
+ const root = path17.join(options.cwd, ".kody-engine", "definitions");
23951
+ const staging = `${root}.tmp-${process.pid}-${Date.now()}`;
23952
+ fs16.rmSync(staging, { recursive: true, force: true });
23953
+ fs16.mkdirSync(path17.join(staging, "agents"), { recursive: true });
23954
+ fs16.mkdirSync(path17.join(staging, "capabilities"), { recursive: true });
23955
+ fs16.mkdirSync(path17.join(staging, "goals"), { recursive: true });
23956
+ fs16.mkdirSync(path17.join(staging, "implementations"), { recursive: true });
23957
+ fs16.mkdirSync(path17.join(staging, "shared"), { recursive: true });
23958
+ try {
23959
+ const [capabilities, agents, goals, implementations, assets] = await Promise.all([
23960
+ options.backend.listDefinitions(options.tenantId, "capability"),
23961
+ options.backend.listDefinitions(options.tenantId, "agent"),
23962
+ options.backend.listDefinitions(options.tenantId, "goal"),
23963
+ options.backend.listDefinitions(options.tenantId, "implementation"),
23964
+ options.backend.listDefinitions(options.tenantId, "asset")
23965
+ ]);
23966
+ const versions = {};
23967
+ for (const definition of capabilities) {
23968
+ writeDefinition(staging, "capability", definition);
23969
+ versions[`capability:${definition.slug}`] = definition.version;
23970
+ }
23971
+ for (const definition of agents) {
23972
+ writeDefinition(staging, "agent", definition);
23973
+ versions[`agent:${definition.slug}`] = definition.version;
23974
+ }
23975
+ for (const definition of goals) {
23976
+ writeDefinition(staging, "goal", definition);
23977
+ versions[`goal:${definition.slug}`] = definition.version;
23978
+ }
23979
+ for (const definition of implementations) {
23980
+ writeDefinition(staging, "implementation", definition);
23981
+ versions[`implementation:${definition.slug}`] = definition.version;
23982
+ }
23983
+ for (const definition of assets) {
23984
+ writeDefinition(staging, "asset", definition);
23985
+ versions[`asset:${definition.slug}`] = definition.version;
23986
+ }
23987
+ const manifest = {
23988
+ schemaVersion: 1,
23989
+ tenantId: options.tenantId,
23990
+ hydratedAt: (/* @__PURE__ */ new Date()).toISOString(),
23991
+ versions: Object.fromEntries(Object.entries(versions).sort(([left], [right]) => left.localeCompare(right)))
23992
+ };
23993
+ fs16.writeFileSync(path17.join(staging, "manifest.json"), `${JSON.stringify(manifest, null, 2)}
23994
+ `, "utf8");
23995
+ fs16.rmSync(root, { recursive: true, force: true });
23996
+ fs16.renameSync(staging, root);
23997
+ return { root, tenantId: options.tenantId, versions: manifest.versions };
23998
+ } catch (error) {
23999
+ fs16.rmSync(staging, { recursive: true, force: true });
24000
+ throw error;
24001
+ }
24002
+ }
24003
+ async function hydrateDefinitionsFromEnv(cwd = process.cwd(), env = process.env) {
24004
+ const tenantId2 = env.GITHUB_REPOSITORY?.trim();
24005
+ if (!hasStateBackendConfig(env)) {
24006
+ if (env.GITHUB_ACTIONS === "true") {
24007
+ throw new Error("GitHub Actions workflow identity is required for backend definitions");
24008
+ }
24009
+ return null;
24010
+ }
24011
+ if (!tenantId2) throw new Error("GITHUB_REPOSITORY is required for backend definitions");
24012
+ return hydrateDefinitions({
24013
+ cwd,
24014
+ tenantId: tenantId2,
24015
+ backend: createStateBackendFromEnv(env)
24016
+ });
24017
+ }
24018
+
23887
24019
  // src/kody-cli.ts
23888
24020
  import { execFileSync as execFileSync24 } from "child_process";
23889
- import * as fs48 from "fs";
23890
- import * as path47 from "path";
24021
+ import * as fs49 from "fs";
24022
+ import * as path48 from "path";
23891
24023
 
23892
24024
  // src/app-auth.ts
23893
24025
  import { createSign } from "crypto";
@@ -24014,7 +24146,7 @@ init_config();
24014
24146
 
24015
24147
  // src/dispatch.ts
24016
24148
  init_config();
24017
- import * as fs16 from "fs";
24149
+ import * as fs17 from "fs";
24018
24150
 
24019
24151
  // src/cron-match.ts
24020
24152
  var FIELD_BOUNDS = [
@@ -24116,10 +24248,10 @@ function autoDispatch(opts) {
24116
24248
  }
24117
24249
  const eventName = process.env.GITHUB_EVENT_NAME;
24118
24250
  const eventPath = process.env.GITHUB_EVENT_PATH;
24119
- if (!eventName || !eventPath || !fs16.existsSync(eventPath)) return null;
24251
+ if (!eventName || !eventPath || !fs17.existsSync(eventPath)) return null;
24120
24252
  let event = {};
24121
24253
  try {
24122
- event = JSON.parse(fs16.readFileSync(eventPath, "utf-8"));
24254
+ event = JSON.parse(fs17.readFileSync(eventPath, "utf-8"));
24123
24255
  } catch {
24124
24256
  return null;
24125
24257
  }
@@ -24243,7 +24375,7 @@ function autoDispatchTyped(opts) {
24243
24375
  if (legacy) return { kind: "route", ...legacy };
24244
24376
  const eventName = process.env.GITHUB_EVENT_NAME;
24245
24377
  const eventPath = process.env.GITHUB_EVENT_PATH;
24246
- if (!eventName || !eventPath || !fs16.existsSync(eventPath)) {
24378
+ if (!eventName || !eventPath || !fs17.existsSync(eventPath)) {
24247
24379
  return { kind: "silent", reason: "no GHA event context" };
24248
24380
  }
24249
24381
  if (eventName !== "issue_comment") {
@@ -24251,7 +24383,7 @@ function autoDispatchTyped(opts) {
24251
24383
  }
24252
24384
  let event = {};
24253
24385
  try {
24254
- event = JSON.parse(fs16.readFileSync(eventPath, "utf-8"));
24386
+ event = JSON.parse(fs17.readFileSync(eventPath, "utf-8"));
24255
24387
  } catch {
24256
24388
  return { kind: "silent", reason: "GHA event payload unreadable" };
24257
24389
  }
@@ -24305,7 +24437,7 @@ function dispatchScheduledWatches(opts) {
24305
24437
  for (const exe of listRuntimeProfilesForCwd(opts?.cwd ?? process.cwd())) {
24306
24438
  let raw;
24307
24439
  try {
24308
- raw = fs16.readFileSync(exe.profilePath, "utf-8");
24440
+ raw = fs17.readFileSync(exe.profilePath, "utf-8");
24309
24441
  } catch {
24310
24442
  continue;
24311
24443
  }
@@ -24700,9 +24832,9 @@ async function resolveAuthToken(env = process.env) {
24700
24832
  return void 0;
24701
24833
  }
24702
24834
  function detectPackageManager2(cwd) {
24703
- if (fs48.existsSync(path47.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
24704
- if (fs48.existsSync(path47.join(cwd, "yarn.lock"))) return "yarn";
24705
- if (fs48.existsSync(path47.join(cwd, "bun.lockb"))) return "bun";
24835
+ if (fs49.existsSync(path48.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
24836
+ if (fs49.existsSync(path48.join(cwd, "yarn.lock"))) return "yarn";
24837
+ if (fs49.existsSync(path48.join(cwd, "bun.lockb"))) return "bun";
24706
24838
  return "npm";
24707
24839
  }
24708
24840
  function shouldChainScheduledWatch(match) {
@@ -24795,8 +24927,8 @@ function postFailureTail(issueNumber, cwd, reason) {
24795
24927
  const logPath = lastRunLogPath(cwd);
24796
24928
  let tail = "";
24797
24929
  try {
24798
- if (fs48.existsSync(logPath)) {
24799
- const content = fs48.readFileSync(logPath, "utf-8");
24930
+ if (fs49.existsSync(logPath)) {
24931
+ const content = fs49.readFileSync(logPath, "utf-8");
24800
24932
  tail = content.slice(-3e3);
24801
24933
  }
24802
24934
  } catch {
@@ -24825,7 +24957,7 @@ async function runCi(argv) {
24825
24957
  return 0;
24826
24958
  }
24827
24959
  const args = parseCiArgs(argv);
24828
- const cwd = args.cwd ? path47.resolve(args.cwd) : process.cwd();
24960
+ const cwd = args.cwd ? path48.resolve(args.cwd) : process.cwd();
24829
24961
  try {
24830
24962
  const n = unpackAllSecrets();
24831
24963
  if (n > 0) process.stdout.write(`\u2192 kody: unpacked ${n} secret(s) from ALL_SECRETS
@@ -24884,9 +25016,9 @@ async function runCi(argv) {
24884
25016
  forceRunCliArgs = { goal: envForceMessage };
24885
25017
  }
24886
25018
  }
24887
- if (!args.issueNumber && !autoFallback && !forceRunAction && !runRequestFanOut && eventName === "workflow_dispatch" && dispatchEventPath && fs48.existsSync(dispatchEventPath)) {
25019
+ if (!args.issueNumber && !autoFallback && !forceRunAction && !runRequestFanOut && eventName === "workflow_dispatch" && dispatchEventPath && fs49.existsSync(dispatchEventPath)) {
24888
25020
  try {
24889
- const evt = JSON.parse(fs48.readFileSync(dispatchEventPath, "utf-8"));
25021
+ const evt = JSON.parse(fs49.readFileSync(dispatchEventPath, "utf-8"));
24890
25022
  const inputs = objectValue2(evt.inputs);
24891
25023
  const issueInput = parseInt(String(inputs?.issue_number ?? ""), 10);
24892
25024
  const sessionInput = String(inputs?.sessionId ?? "");
@@ -25293,8 +25425,8 @@ init_repoWorkspace();
25293
25425
 
25294
25426
  // src/scripts/brainTurnLog.ts
25295
25427
  init_runtimePaths();
25296
- import * as fs49 from "fs";
25297
- import * as path48 from "path";
25428
+ import * as fs50 from "fs";
25429
+ import * as path49 from "path";
25298
25430
  import posixPath4 from "path/posix";
25299
25431
  var live = /* @__PURE__ */ new Map();
25300
25432
  function brainEventsFilePath(dir, chatId) {
@@ -25302,8 +25434,8 @@ function brainEventsFilePath(dir, chatId) {
25302
25434
  }
25303
25435
  function lastPersistedSeq(dir, chatId) {
25304
25436
  const p = brainEventsFilePath(dir, chatId);
25305
- if (!fs49.existsSync(p)) return 0;
25306
- const lines = fs49.readFileSync(p, "utf-8").split("\n").filter(Boolean);
25437
+ if (!fs50.existsSync(p)) return 0;
25438
+ const lines = fs50.readFileSync(p, "utf-8").split("\n").filter(Boolean);
25307
25439
  if (lines.length === 0) return 0;
25308
25440
  try {
25309
25441
  return JSON.parse(lines[lines.length - 1]).seq || 0;
@@ -25313,9 +25445,9 @@ function lastPersistedSeq(dir, chatId) {
25313
25445
  }
25314
25446
  function readSince(dir, chatId, since) {
25315
25447
  const p = brainEventsFilePath(dir, chatId);
25316
- if (!fs49.existsSync(p)) return [];
25448
+ if (!fs50.existsSync(p)) return [];
25317
25449
  const out = [];
25318
- for (const line of fs49.readFileSync(p, "utf-8").split("\n")) {
25450
+ for (const line of fs50.readFileSync(p, "utf-8").split("\n")) {
25319
25451
  if (!line) continue;
25320
25452
  try {
25321
25453
  const rec = JSON.parse(line);
@@ -25341,12 +25473,12 @@ function beginTurn(dir, chatId) {
25341
25473
  };
25342
25474
  live.set(chatId, state);
25343
25475
  const p = brainEventsFilePath(dir, chatId);
25344
- fs49.mkdirSync(path48.dirname(p), { recursive: true });
25476
+ fs50.mkdirSync(path49.dirname(p), { recursive: true });
25345
25477
  return (event) => {
25346
25478
  state.seq += 1;
25347
25479
  const rec = { seq: state.seq, turn, ts: Date.now(), event };
25348
25480
  try {
25349
- fs49.appendFileSync(p, `${JSON.stringify(rec)}
25481
+ fs50.appendFileSync(p, `${JSON.stringify(rec)}
25350
25482
  `);
25351
25483
  } catch (err) {
25352
25484
  process.stderr.write(
@@ -25385,7 +25517,7 @@ function endTurnIfUnterminated(dir, chatId, errMessage) {
25385
25517
  event: { type: "error", error: errMessage || "turn ended unexpectedly", chatId }
25386
25518
  };
25387
25519
  try {
25388
- fs49.appendFileSync(brainEventsFilePath(dir, chatId), `${JSON.stringify(rec)}
25520
+ fs50.appendFileSync(brainEventsFilePath(dir, chatId), `${JSON.stringify(rec)}
25389
25521
  `);
25390
25522
  } catch {
25391
25523
  }
@@ -25590,6 +25722,25 @@ var BrokerSink = class {
25590
25722
  function hasStateBackendConfig2(env = process.env) {
25591
25723
  return Boolean(env.CONVEX_URL?.trim() && env.KODY_SERVICE_KEY?.trim());
25592
25724
  }
25725
+ var definitionHydrations = /* @__PURE__ */ new Map();
25726
+ async function hydrateBrainDefinitions(options) {
25727
+ const env = options.env ?? process.env;
25728
+ if (!options.repo || !hasStateBackendConfig2(env)) return;
25729
+ const key = `${options.cwd}\0${options.repo}`;
25730
+ const running = definitionHydrations.get(key);
25731
+ if (running) return running;
25732
+ const hydration = hydrateDefinitions({
25733
+ cwd: options.cwd,
25734
+ tenantId: options.repo,
25735
+ backend: options.backend ?? createStateBackendFromEnv(env)
25736
+ }).then(() => void 0).finally(() => {
25737
+ if (definitionHydrations.get(key) === hydration) {
25738
+ definitionHydrations.delete(key);
25739
+ }
25740
+ });
25741
+ definitionHydrations.set(key, hydration);
25742
+ return hydration;
25743
+ }
25593
25744
  var chatQueues = /* @__PURE__ */ new Map();
25594
25745
  function enqueue(chatId, fn) {
25595
25746
  const prev = chatQueues.get(chatId) ?? Promise.resolve();
@@ -25689,6 +25840,17 @@ async function handleChatTurn(req, res, chatId, opts) {
25689
25840
  res.end();
25690
25841
  return;
25691
25842
  }
25843
+ try {
25844
+ await hydrateBrainDefinitions({ cwd: agentCwd, repo });
25845
+ } catch (err) {
25846
+ emitSse(res, {
25847
+ type: "error",
25848
+ chatId,
25849
+ error: `Definition hydration failed: ${err instanceof Error ? err.message : String(err)}`
25850
+ });
25851
+ res.end();
25852
+ return;
25853
+ }
25692
25854
  const stateToken = repoToken || envGithubToken();
25693
25855
  const sessionFile = sessionFilePath(agentCwd, chatId);
25694
25856
  const sessionStore = opts.createStore({
@@ -25748,7 +25910,7 @@ function buildServer(opts) {
25748
25910
  const runTurn = opts.runTurn ?? runChatTurn;
25749
25911
  const createStore = opts.createStore ?? createSessionStore;
25750
25912
  const cloneRepo = opts.cloneRepo ?? defaultCloneRepo;
25751
- const reposRoot = opts.reposRoot ?? path49.join(path49.dirname(path49.resolve(opts.cwd)), "repos");
25913
+ const reposRoot = opts.reposRoot ?? path50.join(path50.dirname(path50.resolve(opts.cwd)), "repos");
25752
25914
  return createServer2(async (req, res) => {
25753
25915
  if (!req.method || !req.url) {
25754
25916
  sendJson(res, 400, { error: "bad request" });
@@ -26352,7 +26514,7 @@ async function loadConfigSafe() {
26352
26514
  }
26353
26515
 
26354
26516
  // src/chat-cli.ts
26355
- import * as path50 from "path";
26517
+ import * as path51 from "path";
26356
26518
 
26357
26519
  // src/chat/inbox.ts
26358
26520
  import { execFileSync as execFileSync25 } from "child_process";
@@ -26633,7 +26795,7 @@ async function runChat(argv) {
26633
26795
  ${CHAT_HELP}`);
26634
26796
  return 64;
26635
26797
  }
26636
- const cwd = args.cwd ? path50.resolve(args.cwd) : process.cwd();
26798
+ const cwd = args.cwd ? path51.resolve(args.cwd) : process.cwd();
26637
26799
  const sessionId = args.sessionId;
26638
26800
  const runRequest = readRunRequestFromEnv();
26639
26801
  if (runRequest && "request" in runRequest) {
@@ -26751,140 +26913,6 @@ ${CHAT_HELP}`);
26751
26913
  // src/entry.ts
26752
26914
  init_config();
26753
26915
  init_definition_paths();
26754
-
26755
- // src/definition-hydration.ts
26756
- init_state_backend();
26757
- import { createHash as createHash8 } from "crypto";
26758
- import * as fs50 from "fs";
26759
- import * as path51 from "path";
26760
- var SLUG_RE2 = /^[a-z0-9][a-z0-9_-]{0,127}$/;
26761
- function assertSafeDefinitionPath(filePath) {
26762
- const segments = filePath.split("/");
26763
- if (!filePath || filePath.startsWith("/") || filePath.includes("\\") || filePath.includes("\0") || segments.some((segment) => !segment || segment === "." || segment === "..")) {
26764
- throw new Error(`unsafe definition path: ${filePath}`);
26765
- }
26766
- }
26767
- function normalizeDefinitionBundle(bundle) {
26768
- if (bundle.schemaVersion !== 1) throw new Error("unsupported definition bundle schema");
26769
- const files = Object.fromEntries(
26770
- Object.entries(bundle.files).sort(([left], [right]) => left.localeCompare(right)).map(([filePath, content]) => {
26771
- assertSafeDefinitionPath(filePath);
26772
- return [filePath, content.replace(/\r\n?/g, "\n")];
26773
- })
26774
- );
26775
- return { schemaVersion: 1, files };
26776
- }
26777
- function definitionVersion(bundle) {
26778
- return `sha256:${createHash8("sha256").update(JSON.stringify(normalizeDefinitionBundle(bundle))).digest("hex")}`;
26779
- }
26780
- function verifyDefinition(definition) {
26781
- if (!SLUG_RE2.test(definition.slug)) throw new Error(`invalid definition slug: ${definition.slug}`);
26782
- const bundle = normalizeDefinitionBundle(definition.bundle);
26783
- if (definitionVersion(bundle) !== definition.version) {
26784
- throw new Error(`definition version mismatch for ${definition.slug}: ${definition.version}`);
26785
- }
26786
- return bundle;
26787
- }
26788
- function writeBundle(root, bundle) {
26789
- for (const [filePath, contents] of Object.entries(bundle.files)) {
26790
- const target = path51.join(root, filePath);
26791
- fs50.mkdirSync(path51.dirname(target), { recursive: true });
26792
- fs50.writeFileSync(target, contents, "utf8");
26793
- }
26794
- }
26795
- function writeDefinition(root, kind, definition) {
26796
- const bundle = verifyDefinition(definition);
26797
- if (kind === "agent") {
26798
- const raw = bundle.files["agent.md"];
26799
- if (typeof raw !== "string") throw new Error(`agent definition ${definition.slug} is missing agent.md`);
26800
- fs50.writeFileSync(path51.join(root, "agents", `${definition.slug}.md`), raw, "utf8");
26801
- return;
26802
- }
26803
- if (kind === "goal") {
26804
- writeBundle(path51.join(root, "goals", definition.slug), bundle);
26805
- return;
26806
- }
26807
- if (kind === "implementation") {
26808
- writeBundle(path51.join(root, "implementations", definition.slug), bundle);
26809
- return;
26810
- }
26811
- if (kind === "asset") {
26812
- writeBundle(path51.join(root, "shared"), bundle);
26813
- return;
26814
- }
26815
- writeBundle(path51.join(root, "capabilities", definition.slug), bundle);
26816
- }
26817
- async function hydrateDefinitions(options) {
26818
- const root = path51.join(options.cwd, ".kody-engine", "definitions");
26819
- const staging = `${root}.tmp-${process.pid}-${Date.now()}`;
26820
- fs50.rmSync(staging, { recursive: true, force: true });
26821
- fs50.mkdirSync(path51.join(staging, "agents"), { recursive: true });
26822
- fs50.mkdirSync(path51.join(staging, "capabilities"), { recursive: true });
26823
- fs50.mkdirSync(path51.join(staging, "goals"), { recursive: true });
26824
- fs50.mkdirSync(path51.join(staging, "implementations"), { recursive: true });
26825
- fs50.mkdirSync(path51.join(staging, "shared"), { recursive: true });
26826
- try {
26827
- const [capabilities, agents, goals, implementations, assets] = await Promise.all([
26828
- options.backend.listDefinitions(options.tenantId, "capability"),
26829
- options.backend.listDefinitions(options.tenantId, "agent"),
26830
- options.backend.listDefinitions(options.tenantId, "goal"),
26831
- options.backend.listDefinitions(options.tenantId, "implementation"),
26832
- options.backend.listDefinitions(options.tenantId, "asset")
26833
- ]);
26834
- const versions = {};
26835
- for (const definition of capabilities) {
26836
- writeDefinition(staging, "capability", definition);
26837
- versions[`capability:${definition.slug}`] = definition.version;
26838
- }
26839
- for (const definition of agents) {
26840
- writeDefinition(staging, "agent", definition);
26841
- versions[`agent:${definition.slug}`] = definition.version;
26842
- }
26843
- for (const definition of goals) {
26844
- writeDefinition(staging, "goal", definition);
26845
- versions[`goal:${definition.slug}`] = definition.version;
26846
- }
26847
- for (const definition of implementations) {
26848
- writeDefinition(staging, "implementation", definition);
26849
- versions[`implementation:${definition.slug}`] = definition.version;
26850
- }
26851
- for (const definition of assets) {
26852
- writeDefinition(staging, "asset", definition);
26853
- versions[`asset:${definition.slug}`] = definition.version;
26854
- }
26855
- const manifest = {
26856
- schemaVersion: 1,
26857
- tenantId: options.tenantId,
26858
- hydratedAt: (/* @__PURE__ */ new Date()).toISOString(),
26859
- versions: Object.fromEntries(Object.entries(versions).sort(([left], [right]) => left.localeCompare(right)))
26860
- };
26861
- fs50.writeFileSync(path51.join(staging, "manifest.json"), `${JSON.stringify(manifest, null, 2)}
26862
- `, "utf8");
26863
- fs50.rmSync(root, { recursive: true, force: true });
26864
- fs50.renameSync(staging, root);
26865
- return { root, tenantId: options.tenantId, versions: manifest.versions };
26866
- } catch (error) {
26867
- fs50.rmSync(staging, { recursive: true, force: true });
26868
- throw error;
26869
- }
26870
- }
26871
- async function hydrateDefinitionsFromEnv(cwd = process.cwd(), env = process.env) {
26872
- const tenantId2 = env.GITHUB_REPOSITORY?.trim();
26873
- if (!hasStateBackendConfig(env)) {
26874
- if (env.GITHUB_ACTIONS === "true") {
26875
- throw new Error("GitHub Actions workflow identity is required for backend definitions");
26876
- }
26877
- return null;
26878
- }
26879
- if (!tenantId2) throw new Error("GITHUB_REPOSITORY is required for backend definitions");
26880
- return hydrateDefinitions({
26881
- cwd,
26882
- tenantId: tenantId2,
26883
- backend: createStateBackendFromEnv(env)
26884
- });
26885
- }
26886
-
26887
- // src/entry.ts
26888
26916
  init_job();
26889
26917
  init_registry();
26890
26918
 
@@ -28433,9 +28461,10 @@ function parseArgs(argv) {
28433
28461
  }
28434
28462
  async function main(argv = process.argv.slice(2)) {
28435
28463
  unpackAllSecrets();
28464
+ const args = parseArgs(argv);
28436
28465
  const cwdFlag = argv.indexOf("--cwd");
28437
28466
  const definitionCwd = cwdFlag >= 0 && argv[cwdFlag + 1] ? argv[cwdFlag + 1] : process.cwd();
28438
- const shouldHydrate = !hasExplicitDefinitionsRoot(definitionCwd) && (Boolean(process.env.CONVEX_URL?.trim()) || process.env.GITHUB_ACTIONS === "true" && Boolean(process.env.GITHUB_EVENT_NAME));
28467
+ const shouldHydrate = !(args.command === "server" && args.serverName === "brain-serve") && !hasExplicitDefinitionsRoot(definitionCwd) && (Boolean(process.env.CONVEX_URL?.trim()) || process.env.GITHUB_ACTIONS === "true" && Boolean(process.env.GITHUB_EVENT_NAME));
28439
28468
  if (shouldHydrate) {
28440
28469
  try {
28441
28470
  await hydrateDefinitionsFromEnv(definitionCwd);
@@ -28446,7 +28475,6 @@ async function main(argv = process.argv.slice(2)) {
28446
28475
  return 99;
28447
28476
  }
28448
28477
  }
28449
- const args = parseArgs(argv);
28450
28478
  if (args.errors.length > 0) {
28451
28479
  for (const e of args.errors) process.stderr.write(`error: ${e}
28452
28480
  `);