@kody-ade/kody-engine 0.4.410 → 0.4.412

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/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.410",
18
+ version: "0.4.412",
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",
@@ -50,6 +50,7 @@ var init_package = __esm({
50
50
  prepublishOnly: "pnpm typecheck && vitest run tests/unit tests/int --no-coverage && pnpm build && pnpm verify:package"
51
51
  },
52
52
  dependencies: {
53
+ "@kody-ade/agency-domain": "0.1.1",
53
54
  "@actions/cache": "^6.0.0",
54
55
  "@anthropic-ai/claude-agent-sdk": "0.2.119",
55
56
  "@modelcontextprotocol/sdk": "^1.29.0",
@@ -746,7 +747,7 @@ function buildVerifyEnv(source = process.env) {
746
747
  return env;
747
748
  }
748
749
  function runCommand(command, cwd) {
749
- return new Promise((resolve16) => {
750
+ return new Promise((resolve17) => {
750
751
  const start = Date.now();
751
752
  const child = spawn(command, {
752
753
  cwd,
@@ -775,11 +776,11 @@ function runCommand(command, cwd) {
775
776
  child.on("exit", (code) => {
776
777
  clearTimeout(timer);
777
778
  const tail = Buffer.concat(buffers).toString("utf-8").slice(-TAIL_CHARS);
778
- resolve16({ exitCode: code ?? -1, durationMs: Date.now() - start, tail });
779
+ resolve17({ exitCode: code ?? -1, durationMs: Date.now() - start, tail });
779
780
  });
780
781
  child.on("error", (err) => {
781
782
  clearTimeout(timer);
782
- resolve16({ exitCode: -1, durationMs: Date.now() - start, tail: err.message });
783
+ resolve17({ exitCode: -1, durationMs: Date.now() - start, tail: err.message });
783
784
  });
784
785
  });
785
786
  }
@@ -1088,7 +1089,7 @@ function cmsHeaders(opts) {
1088
1089
  }
1089
1090
  };
1090
1091
  }
1091
- async function callDashboardCms(opts, path51, init = {}) {
1092
+ async function callDashboardCms(opts, path52, init = {}) {
1092
1093
  const baseUrl = dashboardBaseUrl(opts);
1093
1094
  if (!baseUrl) {
1094
1095
  return {
@@ -1100,7 +1101,7 @@ async function callDashboardCms(opts, path51, init = {}) {
1100
1101
  const headerResult = cmsHeaders(opts);
1101
1102
  if (!headerResult.ok) return headerResult;
1102
1103
  try {
1103
- const res = await fetch(`${baseUrl}${path51}`, {
1104
+ const res = await fetch(`${baseUrl}${path52}`, {
1104
1105
  ...init,
1105
1106
  headers: {
1106
1107
  ...headerResult.headers,
@@ -1172,8 +1173,8 @@ function documentArg(value) {
1172
1173
  function normalizeCmsDocumentIdInput(input) {
1173
1174
  const trimmed = stripWrappingQuotes(input.trim());
1174
1175
  const withoutQuery = trimmed.split(/[?#]/, 1)[0] ?? trimmed;
1175
- const path51 = parseDocumentPath(withoutQuery);
1176
- return path51 ?? parseDocumentIdSegment(withoutQuery) ?? withoutQuery;
1176
+ const path52 = parseDocumentPath(withoutQuery);
1177
+ return path52 ?? parseDocumentIdSegment(withoutQuery) ?? withoutQuery;
1177
1178
  }
1178
1179
  function stripWrappingQuotes(value) {
1179
1180
  let current = value;
@@ -1184,9 +1185,9 @@ function stripWrappingQuotes(value) {
1184
1185
  }
1185
1186
  }
1186
1187
  function parseDocumentPath(value) {
1187
- const path51 = value.startsWith("http://") || value.startsWith("https://") ? urlPathname(value) : value;
1188
- if (!path51?.includes("/content/entries/")) return null;
1189
- const parts = path51.split("/").filter(Boolean).map(decodePathPart);
1188
+ const path52 = value.startsWith("http://") || value.startsWith("https://") ? urlPathname(value) : value;
1189
+ if (!path52?.includes("/content/entries/")) return null;
1190
+ const parts = path52.split("/").filter(Boolean).map(decodePathPart);
1190
1191
  const entriesIndex = parts.findIndex((part, index) => part === "content" && parts[index + 1] === "entries");
1191
1192
  const idPart = parts[entriesIndex + 3];
1192
1193
  if (!idPart || idPart === "new") return null;
@@ -2435,6 +2436,46 @@ function createStateBackendFromEnv(env = process.env, client) {
2435
2436
  updatedAt
2436
2437
  });
2437
2438
  },
2439
+ async listAgencyDefinitions(tenantId2) {
2440
+ const result = await transport.query(anyApi.agencyModel.listDefinitions, {
2441
+ tenantId: requireTenant(tenantId2)
2442
+ });
2443
+ return Array.isArray(result) ? result : [];
2444
+ },
2445
+ async getAgencyState(tenantId2, definitionId) {
2446
+ const result = await transport.query(anyApi.agencyModel.getState, {
2447
+ tenantId: requireTenant(tenantId2),
2448
+ definitionId: requireNonEmpty(definitionId, "definitionId")
2449
+ });
2450
+ return result ?? null;
2451
+ },
2452
+ async putAgencyState(tenantId2, definitionId, kind, schemaVersion, data, updatedAt) {
2453
+ await transport.mutation(anyApi.agencyModel.putState, {
2454
+ tenantId: requireTenant(tenantId2),
2455
+ definitionId: requireNonEmpty(definitionId, "definitionId"),
2456
+ kind,
2457
+ schemaVersion,
2458
+ data,
2459
+ updatedAt
2460
+ });
2461
+ },
2462
+ async appendAgencyOutput(tenantId2, recordId, schemaVersion, data) {
2463
+ await transport.mutation(anyApi.agencyModel.appendOutput, {
2464
+ tenantId: requireTenant(tenantId2),
2465
+ envelope: {
2466
+ schemaVersion,
2467
+ recordId: requireNonEmpty(recordId, "recordId"),
2468
+ data
2469
+ }
2470
+ });
2471
+ },
2472
+ async listAgencyOutputs(tenantId2, runId) {
2473
+ const result = await transport.query(anyApi.agencyModel.listOutputs, {
2474
+ tenantId: requireTenant(tenantId2),
2475
+ ...runId ? { runId: requireNonEmpty(runId, "runId") } : {}
2476
+ });
2477
+ return Array.isArray(result) ? result : [];
2478
+ },
2438
2479
  async appendRunEvent(tenantId2, runId, goalId, event, time) {
2439
2480
  await transport.mutation(anyApi.runEvents.append, {
2440
2481
  tenantId: requireTenant(tenantId2),
@@ -3153,7 +3194,7 @@ var init_repoWorkspace = __esm({
3153
3194
  defaultCloneRepo = (repo, token, dir) => {
3154
3195
  fs7.mkdirSync(path8.dirname(dir), { recursive: true });
3155
3196
  const clone = buildCloneProcess(repo, token);
3156
- return new Promise((resolve16, reject) => {
3197
+ return new Promise((resolve17, reject) => {
3157
3198
  const child = spawn2("git", ["clone", "--depth=1", clone.url, dir], {
3158
3199
  env: clone.env,
3159
3200
  stdio: "inherit"
@@ -3173,7 +3214,7 @@ var init_repoWorkspace = __esm({
3173
3214
  }
3174
3215
  } catch {
3175
3216
  }
3176
- resolve16();
3217
+ resolve17();
3177
3218
  });
3178
3219
  child.on("error", reject);
3179
3220
  });
@@ -3484,10 +3525,10 @@ async function runAgent(opts) {
3484
3525
  let timer;
3485
3526
  let next;
3486
3527
  if (turnTimeoutMs > 0) {
3487
- const timeoutPromise = new Promise((resolve16) => {
3528
+ const timeoutPromise = new Promise((resolve17) => {
3488
3529
  timer = setTimeout(() => {
3489
3530
  timedOut = true;
3490
- resolve16({ done: true, value: void 0 });
3531
+ resolve17({ done: true, value: void 0 });
3491
3532
  }, turnTimeoutMs);
3492
3533
  });
3493
3534
  next = await Promise.race([nextPromise, timeoutPromise]);
@@ -3503,7 +3544,7 @@ async function runAgent(opts) {
3503
3544
  try {
3504
3545
  await Promise.race([
3505
3546
  iterator.return(void 0).catch(() => void 0),
3506
- new Promise((resolve16) => setTimeout(resolve16, 1e4).unref())
3547
+ new Promise((resolve17) => setTimeout(resolve17, 1e4).unref())
3507
3548
  ]);
3508
3549
  } catch {
3509
3550
  }
@@ -3769,7 +3810,7 @@ function prepareTaskArtifactsDir(cwd, taskId) {
3769
3810
  function initializeTaskArtifacts(artifacts, metadata = { taskType: "job" }) {
3770
3811
  const startedAt = (/* @__PURE__ */ new Date()).toISOString();
3771
3812
  const defaults = {
3772
- "context.json": JSON.stringify(
3813
+ "context.json": `${JSON.stringify(
3773
3814
  {
3774
3815
  taskId: artifacts.taskId,
3775
3816
  taskType: metadata.taskType,
@@ -3786,7 +3827,8 @@ function initializeTaskArtifacts(artifacts, metadata = { taskType: "job" }) {
3786
3827
  },
3787
3828
  null,
3788
3829
  2
3789
- ) + "\n",
3830
+ )}
3831
+ `,
3790
3832
  "memory-recs.json": "[]\n",
3791
3833
  "followups.json": "[]\n",
3792
3834
  "handoff-notes.md": "Baseline handoff: the agent did not provide additional notes.\n"
@@ -6669,11 +6711,11 @@ async function nextAvailableLitellmUrl(url) {
6669
6711
  throw new Error(`no free LiteLLM port found after ${startPort}`);
6670
6712
  }
6671
6713
  function canListen(port, host) {
6672
- return new Promise((resolve16) => {
6714
+ return new Promise((resolve17) => {
6673
6715
  const server = net.createServer();
6674
- server.once("error", () => resolve16(false));
6716
+ server.once("error", () => resolve17(false));
6675
6717
  server.once("listening", () => {
6676
- server.close(() => resolve16(true));
6718
+ server.close(() => resolve17(true));
6677
6719
  });
6678
6720
  server.listen(port, host);
6679
6721
  });
@@ -7834,9 +7876,9 @@ import * as fs26 from "fs";
7834
7876
  function stageGoalRunLogEvent(data, goalId, event, at = nowIso()) {
7835
7877
  const logs = goalRunLogs(data);
7836
7878
  const existing = logs[goalId];
7837
- const path51 = existing?.path ?? goalRunLogPath(goalId, data);
7879
+ const path52 = existing?.path ?? goalRunLogPath(goalId, data);
7838
7880
  logs[goalId] = {
7839
- path: path51,
7881
+ path: path52,
7840
7882
  events: [...existing?.events ?? [], buildGoalRunLogEvent(data, goalId, event, at)]
7841
7883
  };
7842
7884
  }
@@ -7961,7 +8003,7 @@ function buildGoalRunLogEvent(data, goalId, event, at) {
7961
8003
  if (context !== void 0) base.dispatchContext = context;
7962
8004
  return base;
7963
8005
  }
7964
- function enrichGoalRunLogEvent(config, data, logPath, event) {
8006
+ function enrichGoalRunLogEvent(config, data, _logPath, event) {
7965
8007
  const trigger = event.trigger ?? triggerContext();
7966
8008
  const job = event.job ?? jobContext(data);
7967
8009
  const run = event.run ?? runContext(data);
@@ -8252,7 +8294,7 @@ function backendTenant(config) {
8252
8294
  return owner && repo ? `${owner}/${repo}` : null;
8253
8295
  }
8254
8296
  function decodeGoal(doc) {
8255
- if (!doc || !doc.state || typeof doc.state !== "object" || Array.isArray(doc.state)) return null;
8297
+ if (!doc?.state || typeof doc.state !== "object" || Array.isArray(doc.state)) return null;
8256
8298
  const state = doc.state;
8257
8299
  if (typeof state.state !== "string" || !state.extra || typeof state.extra !== "object") return null;
8258
8300
  return state;
@@ -8809,11 +8851,11 @@ function validateWorkflow(value, options = {}) {
8809
8851
  function formatWorkflowValidationIssues(issues) {
8810
8852
  return issues.map((entry) => `${entry.path}: ${entry.message}`);
8811
8853
  }
8812
- function validateDataMatch(value, path51, issues, capabilityOutputs) {
8854
+ function validateDataMatch(value, path52, issues, capabilityOutputs) {
8813
8855
  if (value === void 0) return;
8814
8856
  const match = asRecord2(value);
8815
8857
  if (!match || Object.keys(match).length === 0) {
8816
- issue(issues, "invalid_condition", path51, "workflow condition must contain at least one match");
8858
+ issue(issues, "invalid_condition", path52, "workflow condition must contain at least one match");
8817
8859
  return;
8818
8860
  }
8819
8861
  for (const [field, expected] of Object.entries(match)) {
@@ -8821,7 +8863,7 @@ function validateDataMatch(value, path51, issues, capabilityOutputs) {
8821
8863
  issue(
8822
8864
  issues,
8823
8865
  "invalid_data_path",
8824
- `${path51}.${field}`,
8866
+ `${path52}.${field}`,
8825
8867
  `workflow condition must read from facts, evidence, artifacts, result, workflow, or lastOutcome`
8826
8868
  );
8827
8869
  }
@@ -8829,12 +8871,12 @@ function validateDataMatch(value, path51, issues, capabilityOutputs) {
8829
8871
  issue(
8830
8872
  issues,
8831
8873
  "undeclared_result_path",
8832
- `${path51}.${field}`,
8874
+ `${path52}.${field}`,
8833
8875
  `workflow condition reads ${field}, but the source capability does not declare it`
8834
8876
  );
8835
8877
  }
8836
8878
  if (!isComparable(expected)) {
8837
- issue(issues, "invalid_condition_value", `${path51}.${field}`, "workflow condition value must be a JSON scalar");
8879
+ issue(issues, "invalid_condition_value", `${path52}.${field}`, "workflow condition value must be a JSON scalar");
8838
8880
  }
8839
8881
  }
8840
8882
  }
@@ -8852,8 +8894,8 @@ function isComparable(value) {
8852
8894
  if (value === null || ["string", "number", "boolean"].includes(typeof value)) return true;
8853
8895
  return Array.isArray(value) && value.length > 0 && value.every((item) => isComparable(item) && !Array.isArray(item));
8854
8896
  }
8855
- function issue(issues, code, path51, message) {
8856
- issues.push({ code, path: path51, message });
8897
+ function issue(issues, code, path52, message) {
8898
+ issues.push({ code, path: path52, message });
8857
8899
  }
8858
8900
  var SAFE_NAME, SAFE_STEP_ID, SAFE_DATA_PATH, SUPPORTED_STEP_FIELDS, SUPPORTED_TRANSITION_FIELDS;
8859
8901
  var init_workflowValidation = __esm({
@@ -9111,15 +9153,15 @@ var init_backendStateBackend = __esm({
9111
9153
  this.jobsDir = opts.jobsDir.replace(/\/+$/, "");
9112
9154
  }
9113
9155
  async load(slug) {
9114
- const path51 = stateFilePath(this.jobsDir, slug);
9156
+ const path52 = stateFilePath(this.jobsDir, slug);
9115
9157
  const loaded = await createStateBackendFromEnv().get(this.tenantId, `capabilities/${slug}`, "job-state");
9116
9158
  if (!loaded) {
9117
- return { path: path51, handle: null, state: initialStateEnvelope("seed"), created: true };
9159
+ return { path: path52, handle: null, state: initialStateEnvelope("seed"), created: true };
9118
9160
  }
9119
9161
  if (!isStateEnvelope(loaded.doc)) {
9120
9162
  throw new Error(`BackendStateBackend: capabilities/${slug} is not a StateEnvelope`);
9121
9163
  }
9122
- return { path: path51, handle: loaded.updatedAt, state: loaded.doc, created: false };
9164
+ return { path: path52, handle: loaded.updatedAt, state: loaded.doc, created: false };
9123
9165
  }
9124
9166
  async save(loaded, next) {
9125
9167
  if (!loaded.created && isStateUnchanged(loaded.state, next)) return false;
@@ -13915,14 +13957,33 @@ var init_fixFlow = __esm({
13915
13957
  }
13916
13958
  });
13917
13959
 
13918
- // src/scripts/initFlow.ts
13919
- import { execFileSync as execFileSync14 } from "child_process";
13960
+ // src/workflow-template.ts
13920
13961
  import * as fs35 from "fs";
13921
13962
  import * as path33 from "path";
13963
+ import { fileURLToPath } from "url";
13964
+ function loadKodyWorkflowTemplate() {
13965
+ const here = path33.dirname(fileURLToPath(import.meta.url));
13966
+ const candidates = [path33.resolve(here, "../templates/kody.yml"), path33.resolve(here, "../../templates/kody.yml")];
13967
+ const source = candidates.find((candidate) => fs35.existsSync(candidate));
13968
+ if (!source) throw new Error(`Kody workflow template is missing: ${KODY_WORKFLOW_TEMPLATE_PATH}`);
13969
+ return fs35.readFileSync(source, "utf8");
13970
+ }
13971
+ var KODY_WORKFLOW_TEMPLATE_PATH;
13972
+ var init_workflow_template = __esm({
13973
+ "src/workflow-template.ts"() {
13974
+ "use strict";
13975
+ KODY_WORKFLOW_TEMPLATE_PATH = "templates/kody.yml";
13976
+ }
13977
+ });
13978
+
13979
+ // src/scripts/initFlow.ts
13980
+ import { execFileSync as execFileSync14 } from "child_process";
13981
+ import * as fs36 from "fs";
13982
+ import * as path34 from "path";
13922
13983
  function detectPackageManager(cwd) {
13923
- if (fs35.existsSync(path33.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
13924
- if (fs35.existsSync(path33.join(cwd, "yarn.lock"))) return "yarn";
13925
- if (fs35.existsSync(path33.join(cwd, "bun.lockb"))) return "bun";
13984
+ if (fs36.existsSync(path34.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
13985
+ if (fs36.existsSync(path34.join(cwd, "yarn.lock"))) return "yarn";
13986
+ if (fs36.existsSync(path34.join(cwd, "bun.lockb"))) return "bun";
13926
13987
  return "npm";
13927
13988
  }
13928
13989
  function qualityCommandsFor(pm) {
@@ -13994,22 +14055,22 @@ function performInit(cwd, force) {
13994
14055
  const pm = detectPackageManager(cwd);
13995
14056
  const ownerRepo = detectOwnerRepo(cwd);
13996
14057
  const defaultBranch = defaultBranchFromGit(cwd);
13997
- const configPath = path33.join(cwd, "kody.config.json");
13998
- if (fs35.existsSync(configPath) && !force) {
14058
+ const configPath = path34.join(cwd, "kody.config.json");
14059
+ if (fs36.existsSync(configPath) && !force) {
13999
14060
  skipped.push("kody.config.json");
14000
14061
  } else {
14001
14062
  const cfg = makeConfig(pm, ownerRepo, defaultBranch);
14002
- fs35.writeFileSync(configPath, `${JSON.stringify(cfg, null, 2)}
14063
+ fs36.writeFileSync(configPath, `${JSON.stringify(cfg, null, 2)}
14003
14064
  `);
14004
14065
  wrote.push("kody.config.json");
14005
14066
  }
14006
- const workflowDir = path33.join(cwd, ".github", "workflows");
14007
- const workflowPath = path33.join(workflowDir, "kody.yml");
14008
- if (fs35.existsSync(workflowPath) && !force) {
14067
+ const workflowDir = path34.join(cwd, ".github", "workflows");
14068
+ const workflowPath = path34.join(workflowDir, "kody.yml");
14069
+ if (fs36.existsSync(workflowPath) && !force) {
14009
14070
  skipped.push(".github/workflows/kody.yml");
14010
14071
  } else {
14011
- fs35.mkdirSync(workflowDir, { recursive: true });
14012
- fs35.writeFileSync(workflowPath, WORKFLOW_TEMPLATE);
14072
+ fs36.mkdirSync(workflowDir, { recursive: true });
14073
+ fs36.writeFileSync(workflowPath, loadKodyWorkflowTemplate());
14013
14074
  wrote.push(".github/workflows/kody.yml");
14014
14075
  }
14015
14076
  for (const exe of listImplementations()) {
@@ -14020,12 +14081,12 @@ function performInit(cwd, force) {
14020
14081
  continue;
14021
14082
  }
14022
14083
  if (profile.kind !== "scheduled" || !profile.schedule) continue;
14023
- const target = path33.join(workflowDir, `kody-${exe.name}.yml`);
14024
- if (fs35.existsSync(target) && !force) {
14084
+ const target = path34.join(workflowDir, `kody-${exe.name}.yml`);
14085
+ if (fs36.existsSync(target) && !force) {
14025
14086
  skipped.push(`.github/workflows/kody-${exe.name}.yml`);
14026
14087
  continue;
14027
14088
  }
14028
- fs35.writeFileSync(target, renderScheduledWorkflow(exe.name, profile.schedule));
14089
+ fs36.writeFileSync(target, renderScheduledWorkflow(exe.name, profile.schedule));
14029
14090
  wrote.push(`.github/workflows/kody-${exe.name}.yml`);
14030
14091
  }
14031
14092
  let labels;
@@ -14071,7 +14132,7 @@ jobs:
14071
14132
  run: npx -y -p @kody-ade/kody-engine@latest kody-engine implementation ${name}
14072
14133
  `;
14073
14134
  }
14074
- var WORKFLOW_TEMPLATE, initFlow;
14135
+ var initFlow;
14075
14136
  var init_initFlow = __esm({
14076
14137
  "src/scripts/initFlow.ts"() {
14077
14138
  "use strict";
@@ -14079,67 +14140,7 @@ var init_initFlow = __esm({
14079
14140
  init_lifecycleLabels();
14080
14141
  init_profile();
14081
14142
  init_registry();
14082
- WORKFLOW_TEMPLATE = `# Drop this file at .github/workflows/kody.yml in your repo.
14083
- #
14084
- # Triggers: @kody comment on an issue or PR, or manual workflow_dispatch.
14085
- # Everything else (install deps, set up LiteLLM, run the agent, open the PR)
14086
- # is handled inside the @kody-ade/kody-engine package.
14087
- #
14088
- # Required repo secrets: at least one model provider key (e.g. MINIMAX_API_KEY,
14089
- # ANTHROPIC_API_KEY). kody reads any *_API_KEY secret automatically via
14090
- # toJSON(secrets) \u2014 no need to list them here.
14091
- #
14092
- # Recommended: KODY_TOKEN secret \u2014 a PAT or GitHub App token with repo
14093
- # scope so kody's pushes trigger downstream CI and PR-body edits succeed.
14094
-
14095
- name: kody
14096
-
14097
- on:
14098
- workflow_dispatch:
14099
- inputs:
14100
- issue_number:
14101
- description: "GitHub issue number"
14102
- required: true
14103
- type: string
14104
- capability:
14105
- description: "Capability action to run (default: run)"
14106
- required: false
14107
- type: string
14108
- default: ""
14109
- issue_comment:
14110
- types: [created]
14111
-
14112
- jobs:
14113
- run:
14114
- if: >-
14115
- \${{ github.event_name == 'workflow_dispatch' ||
14116
- (github.event_name == 'issue_comment' &&
14117
- contains(github.event.comment.body, '@kody')) }}
14118
- runs-on: ubuntu-latest
14119
- timeout-minutes: 60
14120
- permissions:
14121
- issues: write
14122
- pull-requests: write
14123
- contents: write
14124
- actions: read
14125
- steps:
14126
- - uses: actions/checkout@v4
14127
- with:
14128
- fetch-depth: 0
14129
- token: \${{ secrets.KODY_TOKEN || github.token }}
14130
-
14131
- - uses: actions/setup-node@v4
14132
- with:
14133
- node-version: 22
14134
-
14135
- - uses: actions/setup-python@v5
14136
- with:
14137
- python-version: "3.12"
14138
-
14139
- - env:
14140
- ALL_SECRETS: \${{ toJSON(secrets) }}
14141
- run: npx -y -p @kody-ade/kody-engine@latest kody-engine ci
14142
- `;
14143
+ init_workflow_template();
14143
14144
  initFlow = async (ctx) => {
14144
14145
  const force = ctx.args.force === true;
14145
14146
  const cwd = ctx.cwd;
@@ -14173,7 +14174,7 @@ Nothing to do. All files already present. (Use --force to overwrite.)
14173
14174
  });
14174
14175
 
14175
14176
  // src/scripts/loadAgentAdhoc.ts
14176
- import * as fs36 from "fs";
14177
+ import * as fs37 from "fs";
14177
14178
  function resolveMessage(messageArg) {
14178
14179
  const fromComment = readCommentBody();
14179
14180
  if (fromComment) return stripDirective(fromComment);
@@ -14181,9 +14182,9 @@ function resolveMessage(messageArg) {
14181
14182
  }
14182
14183
  function readCommentBody() {
14183
14184
  const eventPath = process.env.GITHUB_EVENT_PATH;
14184
- if (!eventPath || !fs36.existsSync(eventPath)) return "";
14185
+ if (!eventPath || !fs37.existsSync(eventPath)) return "";
14185
14186
  try {
14186
- const event = JSON.parse(fs36.readFileSync(eventPath, "utf-8"));
14187
+ const event = JSON.parse(fs37.readFileSync(eventPath, "utf-8"));
14187
14188
  return String(event.comment?.body ?? "");
14188
14189
  } catch {
14189
14190
  return "";
@@ -14237,10 +14238,10 @@ var init_loadAgentAdhoc = __esm({
14237
14238
  throw new Error("loadAgentAdhoc: ctx.args.agent must be a non-empty slug");
14238
14239
  }
14239
14240
  const agentPath = resolveAgentFile(ctx.cwd, agentSlug, agentsDir);
14240
- if (!fs36.existsSync(agentPath)) {
14241
+ if (!fs37.existsSync(agentPath)) {
14241
14242
  throw new Error(`loadAgentAdhoc: agent identity not found: ${agentPath}`);
14242
14243
  }
14243
- const { title, body } = parseAgentFile(fs36.readFileSync(agentPath, "utf-8"), agentSlug);
14244
+ const { title, body } = parseAgentFile(fs37.readFileSync(agentPath, "utf-8"), agentSlug);
14244
14245
  const message = resolveMessage(ctx.args.message);
14245
14246
  if (!message) {
14246
14247
  throw new Error(
@@ -14312,13 +14313,13 @@ var init_loadCapabilityState = __esm({
14312
14313
  function isCompanyIntentId(value) {
14313
14314
  return SLUG_RE.test(value);
14314
14315
  }
14315
- function normalizeCompanyIntent(path51, raw) {
14316
+ function normalizeCompanyIntent(path52, raw) {
14316
14317
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
14317
- throw new Error(`${path51}: intent must be JSON object`);
14318
+ throw new Error(`${path52}: intent must be JSON object`);
14318
14319
  }
14319
14320
  const input = raw;
14320
14321
  const id = stringField4(input.id);
14321
- if (!id || !isCompanyIntentId(id)) throw new Error(`${path51}: invalid intent id`);
14322
+ if (!id || !isCompanyIntentId(id)) throw new Error(`${path52}: invalid intent id`);
14322
14323
  const createdAt = stringField4(input.createdAt) || nowIso();
14323
14324
  const updatedAt = stringField4(input.updatedAt) || createdAt;
14324
14325
  const description = stringField4(input.description);
@@ -14480,7 +14481,7 @@ function retryDelaysMs() {
14480
14481
  }
14481
14482
  function sleep(ms) {
14482
14483
  if (ms <= 0) return Promise.resolve();
14483
- return new Promise((resolve16) => setTimeout(resolve16, ms));
14484
+ return new Promise((resolve17) => setTimeout(resolve17, ms));
14484
14485
  }
14485
14486
  async function fetchGoalStateWithRetry(config, goalId, cwd) {
14486
14487
  let state = await fetchGoalStateAsync(config, goalId, cwd);
@@ -14609,8 +14610,8 @@ var init_loadIssueStateComment = __esm({
14609
14610
  });
14610
14611
 
14611
14612
  // src/scripts/loadJobFromFile.ts
14612
- import * as fs37 from "fs";
14613
- import * as path34 from "path";
14613
+ import * as fs38 from "fs";
14614
+ import * as path35 from "path";
14614
14615
  function parseJobFile(raw, slug) {
14615
14616
  let stripped = raw;
14616
14617
  if (stripped.startsWith("---\n")) {
@@ -14649,10 +14650,10 @@ var init_loadJobFromFile = __esm({
14649
14650
  if (!slug) {
14650
14651
  throw new Error(`loadJobFromFile: ctx.args.${slugArg} must be a non-empty slug`);
14651
14652
  }
14652
- const capability = resolveCapabilityFolder(slug, path34.resolve(ctx.cwd, jobsDir));
14653
+ const capability = resolveCapabilityFolder(slug, path35.resolve(ctx.cwd, jobsDir));
14653
14654
  if (!capability) {
14654
14655
  throw new Error(
14655
- `loadJobFromFile: capability folder not found or incomplete: ${path34.resolve(ctx.cwd, jobsDir, slug)}`
14656
+ `loadJobFromFile: capability folder not found or incomplete: ${path35.resolve(ctx.cwd, jobsDir, slug)}`
14656
14657
  );
14657
14658
  }
14658
14659
  const { title, body, config } = capability;
@@ -14662,12 +14663,12 @@ var init_loadJobFromFile = __esm({
14662
14663
  let agentIdentity = "";
14663
14664
  if (agentSlug) {
14664
14665
  const agentPath = resolveAgentFile(ctx.cwd, agentSlug, agentsDir);
14665
- if (!fs37.existsSync(agentPath)) {
14666
+ if (!fs38.existsSync(agentPath)) {
14666
14667
  throw new Error(
14667
14668
  `loadJobFromFile: capability '${slug}' declares agent '${agentSlug}' but ${agentPath} does not exist`
14668
14669
  );
14669
14670
  }
14670
- const agentRaw = fs37.readFileSync(agentPath, "utf-8");
14671
+ const agentRaw = fs38.readFileSync(agentPath, "utf-8");
14671
14672
  const parsed = parseJobFile(agentRaw, agentSlug);
14672
14673
  agentTitle = parsed.title;
14673
14674
  agentIdentity = parsed.body;
@@ -14747,13 +14748,13 @@ ${truncate2(issue2.body, FINDING_BODY_MAX_BYTES)}`;
14747
14748
  });
14748
14749
 
14749
14750
  // src/scripts/kodyVariables.ts
14750
- import * as fs38 from "fs";
14751
- import * as path35 from "path";
14751
+ import * as fs39 from "fs";
14752
+ import * as path36 from "path";
14752
14753
  function readKodyVariables(cwd) {
14753
- const full = path35.join(cwd, KODY_VARIABLES_REL_PATH);
14754
+ const full = path36.join(cwd, KODY_VARIABLES_REL_PATH);
14754
14755
  let raw;
14755
14756
  try {
14756
- raw = fs38.readFileSync(full, "utf-8");
14757
+ raw = fs39.readFileSync(full, "utf-8");
14757
14758
  } catch {
14758
14759
  return {};
14759
14760
  }
@@ -14929,8 +14930,8 @@ var init_runtimeSecrets = __esm({
14929
14930
  });
14930
14931
 
14931
14932
  // src/scripts/loadQaContext.ts
14932
- import * as fs39 from "fs";
14933
- import * as path36 from "path";
14933
+ import * as fs40 from "fs";
14934
+ import * as path37 from "path";
14934
14935
  function parseSlugList(value) {
14935
14936
  const inner = value.startsWith("[") && value.endsWith("]") ? value.slice(1, -1) : value;
14936
14937
  return inner.split(",").map(
@@ -14959,18 +14960,18 @@ function readProfileAgents(raw) {
14959
14960
  return { agent: agent ?? legacy ?? ["kody"], body };
14960
14961
  }
14961
14962
  function readProfile(cwd) {
14962
- const dir = path36.join(cwd, CONTEXT_DIR_REL_PATH);
14963
- if (!fs39.existsSync(dir)) return "";
14963
+ const dir = path37.join(cwd, CONTEXT_DIR_REL_PATH);
14964
+ if (!fs40.existsSync(dir)) return "";
14964
14965
  let entries;
14965
14966
  try {
14966
- entries = fs39.readdirSync(dir).filter((f) => f.endsWith(".md")).sort();
14967
+ entries = fs40.readdirSync(dir).filter((f) => f.endsWith(".md")).sort();
14967
14968
  } catch {
14968
14969
  return "";
14969
14970
  }
14970
14971
  const blocks = [];
14971
14972
  for (const file of entries) {
14972
14973
  try {
14973
- const raw = fs39.readFileSync(path36.join(dir, file), "utf-8");
14974
+ const raw = fs40.readFileSync(path37.join(dir, file), "utf-8");
14974
14975
  const { agent, body } = readProfileAgents(raw);
14975
14976
  if (!agent.includes(QA_AGENT) && !agent.includes(ALL_AGENTS)) continue;
14976
14977
  blocks.push(`## ${file}
@@ -15019,8 +15020,8 @@ var init_loadQaContext = __esm({
15019
15020
  });
15020
15021
 
15021
15022
  // src/taskContext.ts
15022
- import * as fs40 from "fs";
15023
- import * as path37 from "path";
15023
+ import * as fs41 from "fs";
15024
+ import * as path38 from "path";
15024
15025
  function buildTaskContext(args) {
15025
15026
  return {
15026
15027
  schemaVersion: TASK_CONTEXT_SCHEMA_VERSION,
@@ -15036,9 +15037,9 @@ function buildTaskContext(args) {
15036
15037
  function persistTaskContext(cwd, ctx) {
15037
15038
  try {
15038
15039
  const dir = runtimeStatePath(cwd, "agent-runs", ctx.runId);
15039
- fs40.mkdirSync(dir, { recursive: true });
15040
- const file = path37.join(dir, "task-context.json");
15041
- fs40.writeFileSync(file, `${JSON.stringify(ctx, null, 2)}
15040
+ fs41.mkdirSync(dir, { recursive: true });
15041
+ const file = path38.join(dir, "task-context.json");
15042
+ fs41.writeFileSync(file, `${JSON.stringify(ctx, null, 2)}
15042
15043
  `);
15043
15044
  return file;
15044
15045
  } catch (err) {
@@ -15465,19 +15466,19 @@ function parseAgencyModelProposal(raw) {
15465
15466
  function normalizeBundleFiles(bundle) {
15466
15467
  const seen = /* @__PURE__ */ new Set();
15467
15468
  return bundle.files.map((file, index) => {
15468
- const path51 = file.path.replace(/^\/+/, "");
15469
- const parts = path51.split("/");
15470
- if (!path51 || file.path.startsWith("/") || file.path.includes("\\") || parts.some((part) => !part || part === "." || part === "..")) {
15469
+ const path52 = file.path.replace(/^\/+/, "");
15470
+ const parts = path52.split("/");
15471
+ if (!path52 || file.path.startsWith("/") || file.path.includes("\\") || parts.some((part) => !part || part === "." || part === "..")) {
15471
15472
  throw new Error(`openAgencyModelReviewPr: files[${index}].path is unsafe`);
15472
15473
  }
15473
15474
  if (!/^(agents\/[^/]+\.md|capabilities\/[^/]+\/.+|goals\/(?:templates\/)?[^/]+\/.+|workflows\/[^/]+\.json)$/.test(
15474
- path51
15475
+ path52
15475
15476
  )) {
15476
15477
  throw new Error(`openAgencyModelReviewPr: files[${index}].path is not a supported definition path`);
15477
15478
  }
15478
- if (seen.has(path51)) throw new Error(`openAgencyModelReviewPr: duplicate generated file path: ${path51}`);
15479
- seen.add(path51);
15480
- return { path: path51, content: file.content.replace(/\r\n?/g, "\n") };
15479
+ if (seen.has(path52)) throw new Error(`openAgencyModelReviewPr: duplicate generated file path: ${path52}`);
15480
+ seen.add(path52);
15481
+ return { path: path52, content: file.content.replace(/\r\n?/g, "\n") };
15481
15482
  });
15482
15483
  }
15483
15484
  function buildProposalId(issueNumber, bundle, sourceLabel) {
@@ -16421,9 +16422,9 @@ var init_postResearchComment = __esm({
16421
16422
  });
16422
16423
 
16423
16424
  // src/scripts/prepareBrowserAuth.ts
16424
- import * as fs41 from "fs";
16425
+ import * as fs42 from "fs";
16425
16426
  import * as os6 from "os";
16426
- import * as path38 from "path";
16427
+ import * as path39 from "path";
16427
16428
  function appendAuthMessage(ctx, message) {
16428
16429
  const current = typeof ctx.data.qaAuthBlock === "string" ? ctx.data.qaAuthBlock.trim() : "";
16429
16430
  ctx.data.qaAuthBlock = current ? `${current}
@@ -16462,9 +16463,9 @@ async function githubJson(url, token) {
16462
16463
  return await response.json();
16463
16464
  }
16464
16465
  function writeKodyStorageState(input) {
16465
- const directory = fs41.mkdtempSync(path38.join(os6.tmpdir(), "kody-browser-auth-"));
16466
- fs41.chmodSync(directory, 448);
16467
- const file = path38.join(directory, "storage-state.json");
16466
+ const directory = fs42.mkdtempSync(path39.join(os6.tmpdir(), "kody-browser-auth-"));
16467
+ fs42.chmodSync(directory, 448);
16468
+ const file = path39.join(directory, "storage-state.json");
16468
16469
  const now = Date.now();
16469
16470
  const repoEntry = {
16470
16471
  repoUrl: input.repoUrl,
@@ -16494,7 +16495,7 @@ function writeKodyStorageState(input) {
16494
16495
  }
16495
16496
  ]
16496
16497
  };
16497
- fs41.writeFileSync(file, JSON.stringify(storageState), { mode: 384 });
16498
+ fs42.writeFileSync(file, JSON.stringify(storageState), { mode: 384 });
16498
16499
  return { directory, file };
16499
16500
  }
16500
16501
  function configurePlaywright(profile, storageStatePath) {
@@ -16576,7 +16577,7 @@ async function prepareMethod(ctx, profile, method) {
16576
16577
  configurePlaywright(profile, state.file);
16577
16578
  const authDirectory = state.directory;
16578
16579
  registerRuntimeCleanup(ctx, () => {
16579
- fs41.rmSync(authDirectory, { recursive: true, force: true });
16580
+ fs42.rmSync(authDirectory, { recursive: true, force: true });
16580
16581
  });
16581
16582
  appendAuthMessage(
16582
16583
  ctx,
@@ -16584,7 +16585,7 @@ async function prepareMethod(ctx, profile, method) {
16584
16585
  );
16585
16586
  return true;
16586
16587
  } catch (error) {
16587
- if (state) fs41.rmSync(state.directory, { recursive: true, force: true });
16588
+ if (state) fs42.rmSync(state.directory, { recursive: true, force: true });
16588
16589
  const reason = error instanceof Error ? error.message : String(error);
16589
16590
  appendAuthMessage(
16590
16591
  ctx,
@@ -16697,9 +16698,9 @@ function latestResult(raw, agentResult) {
16697
16698
  function recordField4(value) {
16698
16699
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
16699
16700
  }
16700
- function resolveDotted(root, path51) {
16701
- if (!path51) return void 0;
16702
- return path51.split(".").reduce((value, key) => recordField4(value)?.[key], root);
16701
+ function resolveDotted(root, path52) {
16702
+ if (!path52) return void 0;
16703
+ return path52.split(".").reduce((value, key) => recordField4(value)?.[key], root);
16703
16704
  }
16704
16705
  function stringValue4(value) {
16705
16706
  return typeof value === "string" && value.trim() ? value.trim() : null;
@@ -17599,7 +17600,7 @@ var init_previewBuildHelpers = __esm({
17599
17600
  // src/scripts/previewBuildRun.ts
17600
17601
  import { spawn as spawn5 } from "child_process";
17601
17602
  async function runCmd(cmd, args, opts = {}) {
17602
- await new Promise((resolve16, reject) => {
17603
+ await new Promise((resolve17, reject) => {
17603
17604
  const child = spawn5(cmd, args, {
17604
17605
  cwd: opts.cwd,
17605
17606
  env: { ...process.env, ...opts.env ?? {} },
@@ -17611,7 +17612,7 @@ async function runCmd(cmd, args, opts = {}) {
17611
17612
  }
17612
17613
  child.on("error", reject);
17613
17614
  child.on("close", (code) => {
17614
- if (code === 0) resolve16();
17615
+ if (code === 0) resolve17();
17615
17616
  else reject(new Error(`${cmd} ${args.join(" ")} exited ${code}`));
17616
17617
  });
17617
17618
  });
@@ -17683,12 +17684,12 @@ fi
17683
17684
 
17684
17685
  // src/scripts/runPreviewBuild.ts
17685
17686
  import { copyFile, writeFile } from "fs/promises";
17686
- import * as path39 from "path";
17687
- import { fileURLToPath } from "url";
17687
+ import * as path40 from "path";
17688
+ import { fileURLToPath as fileURLToPath2 } from "url";
17688
17689
  function bundledDockerfilePath(mode) {
17689
- const here = path39.dirname(fileURLToPath(import.meta.url));
17690
+ const here = path40.dirname(fileURLToPath2(import.meta.url));
17690
17691
  const file = mode === "dev" ? "default-Dockerfile.preview.dev" : "default-Dockerfile.preview.prod";
17691
- return path39.join(here, "preview-build-templates", file);
17692
+ return path40.join(here, "preview-build-templates", file);
17692
17693
  }
17693
17694
  function required(name) {
17694
17695
  const v = (process.env[name] ?? "").trim();
@@ -17923,10 +17924,10 @@ var init_runPreviewBuild = __esm({
17923
17924
  console.log(`[preview-build] vault: ${Object.keys(buildEnv).length} secrets, mode=${buildMode}`);
17924
17925
  if (Object.keys(buildEnv).length > 0) {
17925
17926
  const lines = Object.entries(buildEnv).map(([k, v]) => `${k}=${JSON.stringify(v)}`);
17926
- await writeFile(path39.join(ctx.cwd, ".env.production.local"), `${lines.join("\n")}
17927
+ await writeFile(path40.join(ctx.cwd, ".env.production.local"), `${lines.join("\n")}
17927
17928
  `, "utf8");
17928
17929
  }
17929
- const consumerDockerfile = path39.join(ctx.cwd, "Dockerfile.preview");
17930
+ const consumerDockerfile = path40.join(ctx.cwd, "Dockerfile.preview");
17930
17931
  const { stat } = await import("fs/promises");
17931
17932
  let hasConsumerDockerfile = false;
17932
17933
  try {
@@ -18110,8 +18111,8 @@ var init_tickShellRunner = __esm({
18110
18111
  });
18111
18112
 
18112
18113
  // src/scripts/runScheduledImplementationTick.ts
18113
- import * as fs42 from "fs";
18114
- import * as path40 from "path";
18114
+ import * as fs43 from "fs";
18115
+ import * as path41 from "path";
18115
18116
  var runScheduledImplementationTick;
18116
18117
  var init_runScheduledImplementationTick = __esm({
18117
18118
  "src/scripts/runScheduledImplementationTick.ts"() {
@@ -18132,14 +18133,14 @@ var init_runScheduledImplementationTick = __esm({
18132
18133
  ctx.output.reason = `runScheduledImplementationTick: args.slug or ctx.args.${slugArg} must be non-empty capability slug`;
18133
18134
  return;
18134
18135
  }
18135
- const capability = resolveCapabilityFolder(slug, path40.resolve(ctx.cwd, jobsDir));
18136
+ const capability = resolveCapabilityFolder(slug, path41.resolve(ctx.cwd, jobsDir));
18136
18137
  if (!capability) {
18137
18138
  ctx.output.exitCode = 99;
18138
18139
  ctx.output.reason = `runScheduledImplementationTick: capability folder not found or incomplete: ${slug} (searched ${jobsDir} and company store)`;
18139
18140
  return;
18140
18141
  }
18141
- const shellPath = path40.join(profile.dir, shell);
18142
- if (!fs42.existsSync(shellPath)) {
18142
+ const shellPath = path41.join(profile.dir, shell);
18143
+ if (!fs43.existsSync(shellPath)) {
18143
18144
  ctx.output.exitCode = 99;
18144
18145
  ctx.output.reason = `runScheduledImplementationTick: shell not found: ${shell} (looked in ${profile.dir})`;
18145
18146
  return;
@@ -18170,8 +18171,8 @@ var init_runScheduledImplementationTick = __esm({
18170
18171
  });
18171
18172
 
18172
18173
  // src/scripts/runTickScript.ts
18173
- import * as fs43 from "fs";
18174
- import * as path41 from "path";
18174
+ import * as fs44 from "fs";
18175
+ import * as path42 from "path";
18175
18176
  var runTickScript;
18176
18177
  var init_runTickScript = __esm({
18177
18178
  "src/scripts/runTickScript.ts"() {
@@ -18191,10 +18192,10 @@ var init_runTickScript = __esm({
18191
18192
  ctx.output.reason = `runTickScript: ctx.args.${slugArg} must be a non-empty slug`;
18192
18193
  return;
18193
18194
  }
18194
- const capability = readCapabilityFolder(path41.resolve(ctx.cwd, jobsDir), slug);
18195
+ const capability = readCapabilityFolder(path42.resolve(ctx.cwd, jobsDir), slug);
18195
18196
  if (!capability) {
18196
18197
  ctx.output.exitCode = 99;
18197
- ctx.output.reason = `runTickScript: capability folder not found or incomplete: ${path41.resolve(ctx.cwd, jobsDir, slug)}`;
18198
+ ctx.output.reason = `runTickScript: capability folder not found or incomplete: ${path42.resolve(ctx.cwd, jobsDir, slug)}`;
18198
18199
  return;
18199
18200
  }
18200
18201
  const tickScript = capability.config.tickScript;
@@ -18203,8 +18204,8 @@ var init_runTickScript = __esm({
18203
18204
  ctx.output.reason = `runTickScript: capability ${slug} has no \`tickScript\` in profile.json \u2014 route via capability-tick instead`;
18204
18205
  return;
18205
18206
  }
18206
- const scriptPath = path41.isAbsolute(tickScript) ? tickScript : path41.join(ctx.cwd, tickScript);
18207
- if (!fs43.existsSync(scriptPath)) {
18207
+ const scriptPath = path42.isAbsolute(tickScript) ? tickScript : path42.join(ctx.cwd, tickScript);
18208
+ if (!fs44.existsSync(scriptPath)) {
18208
18209
  ctx.output.exitCode = 99;
18209
18210
  ctx.output.reason = `runTickScript: tickScript not found: ${scriptPath}`;
18210
18211
  return;
@@ -18486,7 +18487,7 @@ var init_syncFlow = __esm({
18486
18487
  });
18487
18488
 
18488
18489
  // src/scripts/validateAgencyModelProposal.ts
18489
- import * as path42 from "path";
18490
+ import * as path43 from "path";
18490
18491
  function validateModelBundle(bundle, expectedKind, options = {}) {
18491
18492
  const failures = [];
18492
18493
  validateOneModel(bundle.model, bundle.files, "model", true, failures, expectedKind, options);
@@ -18812,7 +18813,7 @@ var init_validateAgencyModelProposal = __esm({
18812
18813
  const bundle = parseAgencyModelProposal(raw);
18813
18814
  const expectedKind = readExpectedModelKind(args);
18814
18815
  const failures = validateModelBundle(bundle, expectedKind, {
18815
- capabilityRoot: path42.join(ctx.cwd, ".kody", "capabilities")
18816
+ capabilityRoot: path43.join(ctx.cwd, ".kody", "capabilities")
18816
18817
  });
18817
18818
  if (failures.length > 0) {
18818
18819
  throw new Error(`validateAgencyModelProposal: ${failures.join("; ")}`);
@@ -18875,7 +18876,7 @@ function stripAnsi2(s) {
18875
18876
  return s.replace(ANSI_RE2, "");
18876
18877
  }
18877
18878
  function runCommand2(command, cwd) {
18878
- return new Promise((resolve16) => {
18879
+ return new Promise((resolve17) => {
18879
18880
  const child = spawn6(command, {
18880
18881
  cwd,
18881
18882
  shell: true,
@@ -18902,11 +18903,11 @@ function runCommand2(command, cwd) {
18902
18903
  }, TEST_TIMEOUT_MS);
18903
18904
  child.on("exit", (code) => {
18904
18905
  clearTimeout(timer);
18905
- resolve16({ exitCode: code ?? -1, output: Buffer.concat(buffers).toString("utf-8") });
18906
+ resolve17({ exitCode: code ?? -1, output: Buffer.concat(buffers).toString("utf-8") });
18906
18907
  });
18907
18908
  child.on("error", (err) => {
18908
18909
  clearTimeout(timer);
18909
- resolve16({ exitCode: -1, output: err.message });
18910
+ resolve17({ exitCode: -1, output: err.message });
18910
18911
  });
18911
18912
  });
18912
18913
  }
@@ -19312,21 +19313,21 @@ function lineStream(stream) {
19312
19313
  tryDeliver();
19313
19314
  });
19314
19315
  return {
19315
- next: (timeoutMs) => new Promise((resolve16) => {
19316
+ next: (timeoutMs) => new Promise((resolve17) => {
19316
19317
  if (queue.length > 0) {
19317
- resolve16(queue.shift());
19318
+ resolve17(queue.shift());
19318
19319
  return;
19319
19320
  }
19320
19321
  if (ended) {
19321
- resolve16(null);
19322
+ resolve17(null);
19322
19323
  return;
19323
19324
  }
19324
- waiter = resolve16;
19325
+ waiter = resolve17;
19325
19326
  const t = setTimeout(
19326
19327
  () => {
19327
- if (waiter === resolve16) {
19328
+ if (waiter === resolve17) {
19328
19329
  waiter = null;
19329
- resolve16(null);
19330
+ resolve17(null);
19330
19331
  }
19331
19332
  },
19332
19333
  Math.max(0, timeoutMs)
@@ -19363,7 +19364,7 @@ var init_warmupMcp = __esm({
19363
19364
  });
19364
19365
 
19365
19366
  // src/scripts/writeAgentRunSummary.ts
19366
- import * as fs44 from "fs";
19367
+ import * as fs45 from "fs";
19367
19368
  var writeAgentRunSummary;
19368
19369
  var init_writeAgentRunSummary = __esm({
19369
19370
  "src/scripts/writeAgentRunSummary.ts"() {
@@ -19389,7 +19390,7 @@ var init_writeAgentRunSummary = __esm({
19389
19390
  if (reason) lines.push(`- **Reason:** ${reason}`);
19390
19391
  lines.push("");
19391
19392
  try {
19392
- fs44.appendFileSync(summaryPath, `${lines.join("\n")}
19393
+ fs45.appendFileSync(summaryPath, `${lines.join("\n")}
19393
19394
  `);
19394
19395
  } catch {
19395
19396
  }
@@ -19715,17 +19716,17 @@ var init_scripts = __esm({
19715
19716
  });
19716
19717
 
19717
19718
  // src/stateWorkspace.ts
19718
- import * as fs45 from "fs";
19719
- import * as path43 from "path";
19719
+ import * as fs46 from "fs";
19720
+ import * as path44 from "path";
19720
19721
  function tenantId(config) {
19721
19722
  const owner = config.github?.owner?.trim() || process.env.GITHUB_REPOSITORY?.split("/")[0]?.trim();
19722
19723
  const repo = config.github?.repo?.trim() || process.env.GITHUB_REPOSITORY?.split("/")[1]?.trim();
19723
19724
  return owner && repo ? `${owner}/${repo}` : null;
19724
19725
  }
19725
19726
  function writeRuntimeFile(cwd, relativePath, content) {
19726
- const target = path43.join(cwd, RUNTIME_ROOT, relativePath);
19727
- fs45.mkdirSync(path43.dirname(target), { recursive: true });
19728
- fs45.writeFileSync(target, content, "utf8");
19727
+ const target = path44.join(cwd, RUNTIME_ROOT, relativePath);
19728
+ fs46.mkdirSync(path44.dirname(target), { recursive: true });
19729
+ fs46.writeFileSync(target, content, "utf8");
19729
19730
  }
19730
19731
  function record(value) {
19731
19732
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
@@ -19790,11 +19791,11 @@ async function hydrateStateWorkspace(config, cwd, backendOverride) {
19790
19791
  throw new Error("Kody backend access is required for runtime workspace documents");
19791
19792
  return;
19792
19793
  }
19793
- const key = `${path43.resolve(cwd)}|${tenant}`;
19794
+ const key = `${path44.resolve(cwd)}|${tenant}`;
19794
19795
  if (hydratedWorkspaces.has(key)) return;
19795
19796
  const backend = backendOverride ?? createStateBackendFromEnv();
19796
- const root = path43.join(cwd, RUNTIME_ROOT);
19797
- fs45.rmSync(root, { recursive: true, force: true });
19797
+ const root = path44.join(cwd, RUNTIME_ROOT);
19798
+ fs46.rmSync(root, { recursive: true, force: true });
19798
19799
  await Promise.all([
19799
19800
  hydratePrefix(backend, tenant, cwd, "context:"),
19800
19801
  hydratePrefix(backend, tenant, cwd, "memory:"),
@@ -19810,7 +19811,7 @@ var init_stateWorkspace = __esm({
19810
19811
  "src/stateWorkspace.ts"() {
19811
19812
  "use strict";
19812
19813
  init_state_backend();
19813
- RUNTIME_ROOT = path43.join(".kody-engine", "runtime");
19814
+ RUNTIME_ROOT = path44.join(".kody-engine", "runtime");
19814
19815
  hydratedWorkspaces = /* @__PURE__ */ new Set();
19815
19816
  }
19816
19817
  });
@@ -19881,9 +19882,9 @@ var init_tools = __esm({
19881
19882
 
19882
19883
  // src/executor.ts
19883
19884
  import { spawn as spawn8 } from "child_process";
19884
- import * as fs46 from "fs";
19885
+ import * as fs47 from "fs";
19885
19886
  import * as os7 from "os";
19886
- import * as path44 from "path";
19887
+ import * as path45 from "path";
19887
19888
  function isMutatingPostflight(scriptName) {
19888
19889
  return MUTATING_POSTFLIGHTS.has(scriptName ?? "");
19889
19890
  }
@@ -20115,7 +20116,7 @@ async function runImplementation(profileName, input) {
20115
20116
  const jobWhyBlock = typeof ctx.data.jobWhy === "string" ? operatorRequestBlock(ctx.data.jobWhy) : null;
20116
20117
  const jobRefBlock = jobReferenceBlock(profileName, profile, ctx.data);
20117
20118
  const invokeAgent = async (prompt) => {
20118
- const externalPlugins = (profile.claudeCode.plugins ?? []).map((p) => path44.isAbsolute(p) ? p : path44.resolve(profile.dir, p)).filter((p) => p.length > 0);
20119
+ const externalPlugins = (profile.claudeCode.plugins ?? []).map((p) => path45.isAbsolute(p) ? p : path45.resolve(profile.dir, p)).filter((p) => p.length > 0);
20119
20120
  const syntheticPath = ctx.data.syntheticPluginPath;
20120
20121
  const pluginPaths = [...externalPlugins, ...syntheticPath ? [syntheticPath] : []];
20121
20122
  const agents = loadSubagents(profile);
@@ -20553,17 +20554,17 @@ function clearStampedLifecycleLabels(profile, ctx) {
20553
20554
  function resolveProfilePath(profileName) {
20554
20555
  const found = resolveImplementation(profileName);
20555
20556
  if (found) return found;
20556
- const here = path44.dirname(new URL(import.meta.url).pathname);
20557
+ const here = path45.dirname(new URL(import.meta.url).pathname);
20557
20558
  const candidates = [
20558
- path44.join(here, "implementations", profileName, "profile.json"),
20559
+ path45.join(here, "implementations", profileName, "profile.json"),
20559
20560
  // same-dir sibling (dev)
20560
- path44.join(here, "..", "implementations", profileName, "profile.json"),
20561
+ path45.join(here, "..", "implementations", profileName, "profile.json"),
20561
20562
  // up one (prod: dist/bin → dist/implementations)
20562
- path44.join(here, "..", "src", "implementations", profileName, "profile.json")
20563
+ path45.join(here, "..", "src", "implementations", profileName, "profile.json")
20563
20564
  // fallback
20564
20565
  ];
20565
20566
  for (const c of candidates) {
20566
- if (fs46.existsSync(c)) return c;
20567
+ if (fs47.existsSync(c)) return c;
20567
20568
  }
20568
20569
  return candidates[0];
20569
20570
  }
@@ -20678,15 +20679,15 @@ function resolveShellTimeoutMs(entry) {
20678
20679
  }
20679
20680
  async function runShellEntry(entry, ctx, profile) {
20680
20681
  const shellName = entry.shell;
20681
- const shellPath = path44.join(profile.dir, shellName);
20682
- if (!fs46.existsSync(shellPath)) {
20682
+ const shellPath = path45.join(profile.dir, shellName);
20683
+ if (!fs47.existsSync(shellPath)) {
20683
20684
  ctx.skipAgent = true;
20684
20685
  ctx.output.exitCode = 99;
20685
20686
  ctx.output.reason = `shell script not found: ${shellName} (looked in ${profile.dir})`;
20686
20687
  return;
20687
20688
  }
20688
20689
  const positional = entry.with ? Object.values(entry.with).map((v) => String(v)) : [];
20689
- const outputFile = path44.join(
20690
+ const outputFile = path45.join(
20690
20691
  os7.tmpdir(),
20691
20692
  `kody-shell-output-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`
20692
20693
  );
@@ -20721,14 +20722,14 @@ async function runShellEntry(entry, ctx, profile) {
20721
20722
  let killTimer;
20722
20723
  let escalateTimer;
20723
20724
  const result = await new Promise(
20724
- (resolve16) => {
20725
+ (resolve17) => {
20725
20726
  let settled = false;
20726
20727
  const settle = (code, signal, spawnErr) => {
20727
20728
  if (settled) return;
20728
20729
  settled = true;
20729
20730
  if (killTimer) clearTimeout(killTimer);
20730
20731
  if (escalateTimer) clearTimeout(escalateTimer);
20731
- resolve16({ code, signal, spawnErr });
20732
+ resolve17({ code, signal, spawnErr });
20732
20733
  };
20733
20734
  child.on("error", (err) => settle(null, null, err));
20734
20735
  child.on("close", (code, signal) => settle(code, signal));
@@ -20758,9 +20759,9 @@ async function runShellEntry(entry, ctx, profile) {
20758
20759
  }
20759
20760
  let sideChannelText = "";
20760
20761
  try {
20761
- if (fs46.existsSync(outputFile)) {
20762
- sideChannelText = fs46.readFileSync(outputFile, "utf-8");
20763
- fs46.rmSync(outputFile, { force: true });
20762
+ if (fs47.existsSync(outputFile)) {
20763
+ sideChannelText = fs47.readFileSync(outputFile, "utf-8");
20764
+ fs47.rmSync(outputFile, { force: true });
20764
20765
  }
20765
20766
  } catch {
20766
20767
  }
@@ -20931,7 +20932,7 @@ __export(job_exports, {
20931
20932
  stableJobKey: () => stableJobKey,
20932
20933
  validateJob: () => validateJob
20933
20934
  });
20934
- import * as path45 from "path";
20935
+ import * as path46 from "path";
20935
20936
  function newJobId(flavor) {
20936
20937
  localJobSeq += 1;
20937
20938
  const runId = process.env.GITHUB_RUN_ID;
@@ -21394,11 +21395,11 @@ function selectWorkflowTransition(step, data, counts) {
21394
21395
  }
21395
21396
  function workflowResultConditionPaths(transitions) {
21396
21397
  return transitions.flatMap(
21397
- (transition) => Object.keys(transition.when ?? {}).filter((path51) => path51.startsWith("result."))
21398
+ (transition) => Object.keys(transition.when ?? {}).filter((path52) => path52.startsWith("result."))
21398
21399
  );
21399
21400
  }
21400
21401
  function conditionMatches(condition, context) {
21401
- return Object.entries(condition).every(([path51, expected]) => valueMatches(resolveDottedPath2(context, path51), expected));
21402
+ return Object.entries(condition).every(([path52, expected]) => valueMatches(resolveDottedPath2(context, path52), expected));
21402
21403
  }
21403
21404
  function withWorkflowBoundaryEval(capability, result) {
21404
21405
  const capabilityKind = capability.config.capabilityKind;
@@ -21556,7 +21557,7 @@ function loadCapabilityContext(slug, cwd) {
21556
21557
  return resolveCapabilityFolder(slug, hydratedCapabilitiesRoot(cwd));
21557
21558
  }
21558
21559
  function hydratedCapabilitiesRoot(cwd) {
21559
- return path45.join(cwd, ".kody-engine", "definitions", "capabilities");
21560
+ return path46.join(cwd, ".kody-engine", "definitions", "capabilities");
21560
21561
  }
21561
21562
  function loadWorkflowContext(slug, base) {
21562
21563
  if (!slug || !base.config || !isWorkflowDefinitionId(slug)) return null;
@@ -21719,7 +21720,7 @@ function translateOpenAISseToBrain(opts) {
21719
21720
 
21720
21721
  // src/servers/brain-serve.ts
21721
21722
  import { createServer as createServer2 } from "http";
21722
- import * as path48 from "path";
21723
+ import * as path49 from "path";
21723
21724
 
21724
21725
  // src/chat/loop.ts
21725
21726
  init_agent();
@@ -21873,9 +21874,9 @@ var CodexAppServerClient = class {
21873
21874
  await this.request("thread/resume", { threadId });
21874
21875
  }
21875
21876
  async runTurn(args) {
21876
- await new Promise((resolve16, reject) => {
21877
+ await new Promise((resolve17, reject) => {
21877
21878
  this.process.turnWaiters.set(args.threadId, {
21878
- resolve: resolve16,
21879
+ resolve: resolve17,
21879
21880
  reject,
21880
21881
  onNotification: args.onNotification,
21881
21882
  queue: Promise.resolve()
@@ -21892,8 +21893,8 @@ var CodexAppServerClient = class {
21892
21893
  }
21893
21894
  request(method, params) {
21894
21895
  const id = this.process.nextId++;
21895
- return new Promise((resolve16, reject) => {
21896
- this.process.pending.set(id, { resolve: resolve16, reject });
21896
+ return new Promise((resolve17, reject) => {
21897
+ this.process.pending.set(id, { resolve: resolve17, reject });
21897
21898
  this.process.child.stdin.write(`${JSON.stringify({ method, id, params })}
21898
21899
  `);
21899
21900
  });
@@ -22761,8 +22762,8 @@ init_config();
22761
22762
 
22762
22763
  // src/kody-cli.ts
22763
22764
  import { execFileSync as execFileSync24 } from "child_process";
22764
- import * as fs47 from "fs";
22765
- import * as path46 from "path";
22765
+ import * as fs48 from "fs";
22766
+ import * as path47 from "path";
22766
22767
 
22767
22768
  // src/app-auth.ts
22768
22769
  import { createSign } from "crypto";
@@ -23530,6 +23531,20 @@ function recoverCheckoutToken(env = process.env, cwd = process.cwd()) {
23530
23531
  return token;
23531
23532
  }
23532
23533
  async function resolveAuthToken(env = process.env) {
23534
+ const readySources = [
23535
+ ["GH_PAT", env.GH_PAT],
23536
+ ["KODY_TOKEN", env.KODY_TOKEN],
23537
+ ["GH_TOKEN", env.GH_TOKEN]
23538
+ ];
23539
+ const ready = readySources.find(([, value]) => !!value?.trim());
23540
+ if (ready?.[1]) {
23541
+ const token2 = ready[1].trim();
23542
+ env.GH_TOKEN = token2;
23543
+ recoverCheckoutToken(env);
23544
+ process.stdout.write(`\u2192 kody: GH_TOKEN sourced from env.${ready[0]}
23545
+ `);
23546
+ return token2;
23547
+ }
23533
23548
  const creds = readAppCreds(env);
23534
23549
  if (creds) {
23535
23550
  try {
@@ -23543,12 +23558,7 @@ async function resolveAuthToken(env = process.env) {
23543
23558
  `);
23544
23559
  }
23545
23560
  }
23546
- const sources = [
23547
- ["KODY_TOKEN", env.KODY_TOKEN],
23548
- ["GH_TOKEN", env.GH_TOKEN],
23549
- ["GITHUB_TOKEN", env.GITHUB_TOKEN],
23550
- ["GH_PAT", env.GH_PAT]
23551
- ];
23561
+ const sources = [["GITHUB_TOKEN", env.GITHUB_TOKEN]];
23552
23562
  const picked = sources.find(([, v]) => !!v);
23553
23563
  const token = picked?.[1];
23554
23564
  if (token && !env.GH_TOKEN) env.GH_TOKEN = token;
@@ -23564,9 +23574,9 @@ async function resolveAuthToken(env = process.env) {
23564
23574
  return void 0;
23565
23575
  }
23566
23576
  function detectPackageManager2(cwd) {
23567
- if (fs47.existsSync(path46.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
23568
- if (fs47.existsSync(path46.join(cwd, "yarn.lock"))) return "yarn";
23569
- if (fs47.existsSync(path46.join(cwd, "bun.lockb"))) return "bun";
23577
+ if (fs48.existsSync(path47.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
23578
+ if (fs48.existsSync(path47.join(cwd, "yarn.lock"))) return "yarn";
23579
+ if (fs48.existsSync(path47.join(cwd, "bun.lockb"))) return "bun";
23570
23580
  return "npm";
23571
23581
  }
23572
23582
  function shouldChainScheduledWatch(match) {
@@ -23659,8 +23669,8 @@ function postFailureTail(issueNumber, cwd, reason) {
23659
23669
  const logPath = lastRunLogPath(cwd);
23660
23670
  let tail = "";
23661
23671
  try {
23662
- if (fs47.existsSync(logPath)) {
23663
- const content = fs47.readFileSync(logPath, "utf-8");
23672
+ if (fs48.existsSync(logPath)) {
23673
+ const content = fs48.readFileSync(logPath, "utf-8");
23664
23674
  tail = content.slice(-3e3);
23665
23675
  }
23666
23676
  } catch {
@@ -23689,7 +23699,7 @@ async function runCi(argv) {
23689
23699
  return 0;
23690
23700
  }
23691
23701
  const args = parseCiArgs(argv);
23692
- const cwd = args.cwd ? path46.resolve(args.cwd) : process.cwd();
23702
+ const cwd = args.cwd ? path47.resolve(args.cwd) : process.cwd();
23693
23703
  try {
23694
23704
  const n = unpackAllSecrets();
23695
23705
  if (n > 0) process.stdout.write(`\u2192 kody: unpacked ${n} secret(s) from ALL_SECRETS
@@ -23748,9 +23758,9 @@ async function runCi(argv) {
23748
23758
  forceRunCliArgs = { goal: envForceMessage };
23749
23759
  }
23750
23760
  }
23751
- if (!args.issueNumber && !autoFallback && !forceRunAction && !runRequestFanOut && eventName === "workflow_dispatch" && dispatchEventPath && fs47.existsSync(dispatchEventPath)) {
23761
+ if (!args.issueNumber && !autoFallback && !forceRunAction && !runRequestFanOut && eventName === "workflow_dispatch" && dispatchEventPath && fs48.existsSync(dispatchEventPath)) {
23752
23762
  try {
23753
- const evt = JSON.parse(fs47.readFileSync(dispatchEventPath, "utf-8"));
23763
+ const evt = JSON.parse(fs48.readFileSync(dispatchEventPath, "utf-8"));
23754
23764
  const inputs = objectValue2(evt.inputs);
23755
23765
  const issueInput = parseInt(String(inputs?.issue_number ?? ""), 10);
23756
23766
  const sessionInput = String(inputs?.sessionId ?? "");
@@ -24123,8 +24133,8 @@ init_repoWorkspace();
24123
24133
 
24124
24134
  // src/scripts/brainTurnLog.ts
24125
24135
  init_runtimePaths();
24126
- import * as fs48 from "fs";
24127
- import * as path47 from "path";
24136
+ import * as fs49 from "fs";
24137
+ import * as path48 from "path";
24128
24138
  import posixPath4 from "path/posix";
24129
24139
  var live = /* @__PURE__ */ new Map();
24130
24140
  function brainEventsFilePath(dir, chatId) {
@@ -24132,8 +24142,8 @@ function brainEventsFilePath(dir, chatId) {
24132
24142
  }
24133
24143
  function lastPersistedSeq(dir, chatId) {
24134
24144
  const p = brainEventsFilePath(dir, chatId);
24135
- if (!fs48.existsSync(p)) return 0;
24136
- const lines = fs48.readFileSync(p, "utf-8").split("\n").filter(Boolean);
24145
+ if (!fs49.existsSync(p)) return 0;
24146
+ const lines = fs49.readFileSync(p, "utf-8").split("\n").filter(Boolean);
24137
24147
  if (lines.length === 0) return 0;
24138
24148
  try {
24139
24149
  return JSON.parse(lines[lines.length - 1]).seq || 0;
@@ -24143,9 +24153,9 @@ function lastPersistedSeq(dir, chatId) {
24143
24153
  }
24144
24154
  function readSince(dir, chatId, since) {
24145
24155
  const p = brainEventsFilePath(dir, chatId);
24146
- if (!fs48.existsSync(p)) return [];
24156
+ if (!fs49.existsSync(p)) return [];
24147
24157
  const out = [];
24148
- for (const line of fs48.readFileSync(p, "utf-8").split("\n")) {
24158
+ for (const line of fs49.readFileSync(p, "utf-8").split("\n")) {
24149
24159
  if (!line) continue;
24150
24160
  try {
24151
24161
  const rec = JSON.parse(line);
@@ -24171,12 +24181,12 @@ function beginTurn(dir, chatId) {
24171
24181
  };
24172
24182
  live.set(chatId, state);
24173
24183
  const p = brainEventsFilePath(dir, chatId);
24174
- fs48.mkdirSync(path47.dirname(p), { recursive: true });
24184
+ fs49.mkdirSync(path48.dirname(p), { recursive: true });
24175
24185
  return (event) => {
24176
24186
  state.seq += 1;
24177
24187
  const rec = { seq: state.seq, turn, ts: Date.now(), event };
24178
24188
  try {
24179
- fs48.appendFileSync(p, `${JSON.stringify(rec)}
24189
+ fs49.appendFileSync(p, `${JSON.stringify(rec)}
24180
24190
  `);
24181
24191
  } catch (err) {
24182
24192
  process.stderr.write(
@@ -24215,7 +24225,7 @@ function endTurnIfUnterminated(dir, chatId, errMessage) {
24215
24225
  event: { type: "error", error: errMessage || "turn ended unexpectedly", chatId }
24216
24226
  };
24217
24227
  try {
24218
- fs48.appendFileSync(brainEventsFilePath(dir, chatId), `${JSON.stringify(rec)}
24228
+ fs49.appendFileSync(brainEventsFilePath(dir, chatId), `${JSON.stringify(rec)}
24219
24229
  `);
24220
24230
  } catch {
24221
24231
  }
@@ -24309,17 +24319,17 @@ function authOk(req, expected) {
24309
24319
  return false;
24310
24320
  }
24311
24321
  function readJsonBody(req) {
24312
- return new Promise((resolve16, reject) => {
24322
+ return new Promise((resolve17, reject) => {
24313
24323
  const chunks = [];
24314
24324
  req.on("data", (c) => chunks.push(c));
24315
24325
  req.on("end", () => {
24316
24326
  const raw = Buffer.concat(chunks).toString("utf-8");
24317
24327
  if (!raw.trim()) {
24318
- resolve16({});
24328
+ resolve17({});
24319
24329
  return;
24320
24330
  }
24321
24331
  try {
24322
- resolve16(JSON.parse(raw));
24332
+ resolve17(JSON.parse(raw));
24323
24333
  } catch (err) {
24324
24334
  reject(err instanceof Error ? err : new Error(String(err)));
24325
24335
  }
@@ -24578,7 +24588,7 @@ function buildServer(opts) {
24578
24588
  const runTurn = opts.runTurn ?? runChatTurn;
24579
24589
  const createStore = opts.createStore ?? createSessionStore;
24580
24590
  const cloneRepo = opts.cloneRepo ?? defaultCloneRepo;
24581
- const reposRoot = opts.reposRoot ?? path48.join(path48.dirname(path48.resolve(opts.cwd)), "repos");
24591
+ const reposRoot = opts.reposRoot ?? path49.join(path49.dirname(path49.resolve(opts.cwd)), "repos");
24582
24592
  return createServer2(async (req, res) => {
24583
24593
  if (!req.method || !req.url) {
24584
24594
  sendJson(res, 400, { error: "bad request" });
@@ -24659,11 +24669,11 @@ async function brainServe(opts) {
24659
24669
  litellmUrl,
24660
24670
  driver
24661
24671
  });
24662
- await new Promise((resolve16) => {
24672
+ await new Promise((resolve17) => {
24663
24673
  server.listen(port, "0.0.0.0", () => {
24664
24674
  process.stdout.write(`[brain-serve] listening on 0.0.0.0:${port} (cwd=${opts.cwd})
24665
24675
  `);
24666
- resolve16();
24676
+ resolve17();
24667
24677
  });
24668
24678
  });
24669
24679
  const shutdown = (signal) => {
@@ -24918,14 +24928,14 @@ async function startBrainProxy(opts) {
24918
24928
  const { httpServer, handler } = buildBrainProxy(opts);
24919
24929
  const port = opts.port ?? 0;
24920
24930
  const host = opts.host ?? "127.0.0.1";
24921
- await new Promise((resolve16) => httpServer.listen(port, host, () => resolve16()));
24931
+ await new Promise((resolve17) => httpServer.listen(port, host, () => resolve17()));
24922
24932
  const addr = httpServer.address();
24923
24933
  return {
24924
24934
  httpServer,
24925
24935
  port: addr.port,
24926
24936
  url: `http://${host}:${addr.port}`,
24927
- stop: () => new Promise((resolve16) => {
24928
- httpServer.close(() => resolve16());
24937
+ stop: () => new Promise((resolve17) => {
24938
+ httpServer.close(() => resolve17());
24929
24939
  }),
24930
24940
  handler
24931
24941
  };
@@ -25075,23 +25085,23 @@ function buildMcpHttpServer(opts) {
25075
25085
  httpServer,
25076
25086
  routes,
25077
25087
  port,
25078
- stop: () => new Promise((resolve16) => {
25088
+ stop: () => new Promise((resolve17) => {
25079
25089
  let pending = transports.size;
25080
25090
  if (pending === 0) {
25081
- httpServer.close(() => resolve16());
25091
+ httpServer.close(() => resolve17());
25082
25092
  return;
25083
25093
  }
25084
25094
  for (const transport of transports.values()) {
25085
25095
  void transport.close().finally(() => {
25086
25096
  pending--;
25087
- if (pending === 0) httpServer.close(() => resolve16());
25097
+ if (pending === 0) httpServer.close(() => resolve17());
25088
25098
  });
25089
25099
  }
25090
25100
  })
25091
25101
  };
25092
25102
  }
25093
25103
  function listenMcpHttpServer(server, host = "127.0.0.1") {
25094
- return new Promise((resolve16, reject) => {
25104
+ return new Promise((resolve17, reject) => {
25095
25105
  server.httpServer.once("error", reject);
25096
25106
  server.httpServer.listen(server.port, host, () => {
25097
25107
  server.httpServer.off("error", reject);
@@ -25099,7 +25109,7 @@ function listenMcpHttpServer(server, host = "127.0.0.1") {
25099
25109
  if (addr && typeof addr === "object") {
25100
25110
  server.port = addr.port;
25101
25111
  }
25102
- resolve16();
25112
+ resolve17();
25103
25113
  });
25104
25114
  });
25105
25115
  }
@@ -25182,7 +25192,7 @@ async function loadConfigSafe() {
25182
25192
  }
25183
25193
 
25184
25194
  // src/chat-cli.ts
25185
- import * as path49 from "path";
25195
+ import * as path50 from "path";
25186
25196
 
25187
25197
  // src/chat/inbox.ts
25188
25198
  import { execFileSync as execFileSync25 } from "child_process";
@@ -25249,7 +25259,7 @@ async function waitForNextUserMessage(opts) {
25249
25259
  }
25250
25260
  }
25251
25261
  function sleep3(ms) {
25252
- return new Promise((resolve16) => setTimeout(resolve16, ms));
25262
+ return new Promise((resolve17) => setTimeout(resolve17, ms));
25253
25263
  }
25254
25264
  function currentBranch(cwd) {
25255
25265
  try {
@@ -25463,7 +25473,7 @@ async function runChat(argv) {
25463
25473
  ${CHAT_HELP}`);
25464
25474
  return 64;
25465
25475
  }
25466
- const cwd = args.cwd ? path49.resolve(args.cwd) : process.cwd();
25476
+ const cwd = args.cwd ? path50.resolve(args.cwd) : process.cwd();
25467
25477
  const sessionId = args.sessionId;
25468
25478
  const runRequest = readRunRequestFromEnv();
25469
25479
  if (runRequest && "request" in runRequest) {
@@ -25584,8 +25594,8 @@ init_config();
25584
25594
  // src/definition-hydration.ts
25585
25595
  init_state_backend();
25586
25596
  import { createHash as createHash5 } from "crypto";
25587
- import * as fs49 from "fs";
25588
- import * as path50 from "path";
25597
+ import * as fs50 from "fs";
25598
+ import * as path51 from "path";
25589
25599
  var SLUG_RE2 = /^[a-z0-9][a-z0-9_-]{0,63}$/;
25590
25600
  function assertSafeDefinitionPath(filePath) {
25591
25601
  const segments = filePath.split("/");
@@ -25619,32 +25629,32 @@ function writeDefinition(root, kind, definition) {
25619
25629
  if (kind === "agent") {
25620
25630
  const raw = bundle.files["agent.md"];
25621
25631
  if (typeof raw !== "string") throw new Error(`agent definition ${definition.slug} is missing agent.md`);
25622
- fs49.writeFileSync(path50.join(root, "agents", `${definition.slug}.md`), raw, "utf8");
25632
+ fs50.writeFileSync(path51.join(root, "agents", `${definition.slug}.md`), raw, "utf8");
25623
25633
  return;
25624
25634
  }
25625
25635
  if (kind === "goal") {
25626
- const goalRoot = path50.join(root, "goals", definition.slug);
25636
+ const goalRoot = path51.join(root, "goals", definition.slug);
25627
25637
  for (const [filePath, contents] of Object.entries(bundle.files)) {
25628
- const target = path50.join(goalRoot, filePath);
25629
- fs49.mkdirSync(path50.dirname(target), { recursive: true });
25630
- fs49.writeFileSync(target, contents, "utf8");
25638
+ const target = path51.join(goalRoot, filePath);
25639
+ fs50.mkdirSync(path51.dirname(target), { recursive: true });
25640
+ fs50.writeFileSync(target, contents, "utf8");
25631
25641
  }
25632
25642
  return;
25633
25643
  }
25634
- const capabilityRoot = path50.join(root, "capabilities", definition.slug);
25644
+ const capabilityRoot = path51.join(root, "capabilities", definition.slug);
25635
25645
  for (const [filePath, contents] of Object.entries(bundle.files)) {
25636
- const target = path50.join(capabilityRoot, filePath);
25637
- fs49.mkdirSync(path50.dirname(target), { recursive: true });
25638
- fs49.writeFileSync(target, contents, "utf8");
25646
+ const target = path51.join(capabilityRoot, filePath);
25647
+ fs50.mkdirSync(path51.dirname(target), { recursive: true });
25648
+ fs50.writeFileSync(target, contents, "utf8");
25639
25649
  }
25640
25650
  }
25641
25651
  async function hydrateDefinitions(options) {
25642
- const root = path50.join(options.cwd, ".kody-engine", "definitions");
25652
+ const root = path51.join(options.cwd, ".kody-engine", "definitions");
25643
25653
  const staging = `${root}.tmp-${process.pid}-${Date.now()}`;
25644
- fs49.rmSync(staging, { recursive: true, force: true });
25645
- fs49.mkdirSync(path50.join(staging, "agents"), { recursive: true });
25646
- fs49.mkdirSync(path50.join(staging, "capabilities"), { recursive: true });
25647
- fs49.mkdirSync(path50.join(staging, "goals"), { recursive: true });
25654
+ fs50.rmSync(staging, { recursive: true, force: true });
25655
+ fs50.mkdirSync(path51.join(staging, "agents"), { recursive: true });
25656
+ fs50.mkdirSync(path51.join(staging, "capabilities"), { recursive: true });
25657
+ fs50.mkdirSync(path51.join(staging, "goals"), { recursive: true });
25648
25658
  try {
25649
25659
  const [capabilities, agents, goals] = await Promise.all([
25650
25660
  options.backend.listDefinitions(options.tenantId, "capability"),
@@ -25670,13 +25680,13 @@ async function hydrateDefinitions(options) {
25670
25680
  hydratedAt: (/* @__PURE__ */ new Date()).toISOString(),
25671
25681
  versions: Object.fromEntries(Object.entries(versions).sort(([left], [right]) => left.localeCompare(right)))
25672
25682
  };
25673
- fs49.writeFileSync(path50.join(staging, "manifest.json"), `${JSON.stringify(manifest, null, 2)}
25683
+ fs50.writeFileSync(path51.join(staging, "manifest.json"), `${JSON.stringify(manifest, null, 2)}
25674
25684
  `, "utf8");
25675
- fs49.rmSync(root, { recursive: true, force: true });
25676
- fs49.renameSync(staging, root);
25685
+ fs50.rmSync(root, { recursive: true, force: true });
25686
+ fs50.renameSync(staging, root);
25677
25687
  return { root, tenantId: options.tenantId, versions: manifest.versions };
25678
25688
  } catch (error) {
25679
- fs49.rmSync(staging, { recursive: true, force: true });
25689
+ fs50.rmSync(staging, { recursive: true, force: true });
25680
25690
  throw error;
25681
25691
  }
25682
25692
  }
@@ -25769,8 +25779,8 @@ var FlyClient = class {
25769
25779
  get fetch() {
25770
25780
  return this.opts.fetchImpl ?? fetch;
25771
25781
  }
25772
- async call(path51, init = {}) {
25773
- const res = await this.fetch(`${FLY_API_BASE}${path51}`, {
25782
+ async call(path52, init = {}) {
25783
+ const res = await this.fetch(`${FLY_API_BASE}${path52}`, {
25774
25784
  method: init.method ?? "GET",
25775
25785
  headers: {
25776
25786
  Authorization: `Bearer ${this.opts.token}`,
@@ -25781,7 +25791,7 @@ var FlyClient = class {
25781
25791
  if (res.status === 404 && init.allow404) return null;
25782
25792
  if (!res.ok) {
25783
25793
  const text2 = await res.text().catch(() => "");
25784
- throw new Error(`Fly API ${res.status} on ${path51}: ${text2.slice(0, 200) || res.statusText}`);
25794
+ throw new Error(`Fly API ${res.status} on ${path52}: ${text2.slice(0, 200) || res.statusText}`);
25785
25795
  }
25786
25796
  if (res.status === 204) return null;
25787
25797
  const raw = await res.text();
@@ -26294,14 +26304,14 @@ function sendJson2(res, status, body) {
26294
26304
  res.end(JSON.stringify(body));
26295
26305
  }
26296
26306
  function readJsonBody2(req) {
26297
- return new Promise((resolve16, reject) => {
26307
+ return new Promise((resolve17, reject) => {
26298
26308
  const chunks = [];
26299
26309
  req.on("data", (c) => chunks.push(c));
26300
26310
  req.on("end", () => {
26301
26311
  const raw = Buffer.concat(chunks).toString("utf-8");
26302
- if (!raw.trim()) return resolve16({});
26312
+ if (!raw.trim()) return resolve17({});
26303
26313
  try {
26304
- resolve16(JSON.parse(raw));
26314
+ resolve17(JSON.parse(raw));
26305
26315
  } catch (err) {
26306
26316
  reject(err instanceof Error ? err : new Error(String(err)));
26307
26317
  }
@@ -26512,10 +26522,10 @@ async function poolServe() {
26512
26522
  }
26513
26523
  });
26514
26524
  const apiHost = process.env.POOL_API_HOST ?? "::";
26515
- await new Promise((resolve16) => {
26525
+ await new Promise((resolve17) => {
26516
26526
  server.listen(apiPort, apiHost, () => {
26517
26527
  log(`listening on ${apiHost}:${apiPort} (min=${min}, app=${app}, region=${region})`);
26518
- resolve16();
26528
+ resolve17();
26519
26529
  });
26520
26530
  });
26521
26531
  if (loopTickEnabled) void runLoopTick();
@@ -26534,7 +26544,7 @@ async function poolServe() {
26534
26544
 
26535
26545
  // src/servers/runner-serve.ts
26536
26546
  import { spawn as spawn9 } from "child_process";
26537
- import * as fs50 from "fs";
26547
+ import * as fs51 from "fs";
26538
26548
  import { createServer as createServer6 } from "http";
26539
26549
  var DEFAULT_PORT2 = 8080;
26540
26550
  var DEFAULT_WORKDIR = "/workspace/repo";
@@ -26555,17 +26565,17 @@ function authOk2(req, expected) {
26555
26565
  return false;
26556
26566
  }
26557
26567
  function readJsonBody3(req) {
26558
- return new Promise((resolve16, reject) => {
26568
+ return new Promise((resolve17, reject) => {
26559
26569
  const chunks = [];
26560
26570
  req.on("data", (c) => chunks.push(c));
26561
26571
  req.on("end", () => {
26562
26572
  const raw = Buffer.concat(chunks).toString("utf-8");
26563
26573
  if (!raw.trim()) {
26564
- resolve16({});
26574
+ resolve17({});
26565
26575
  return;
26566
26576
  }
26567
26577
  try {
26568
- resolve16(JSON.parse(raw));
26578
+ resolve17(JSON.parse(raw));
26569
26579
  } catch (err) {
26570
26580
  reject(err instanceof Error ? err : new Error(String(err)));
26571
26581
  }
@@ -26669,8 +26679,8 @@ async function defaultRunJob(job) {
26669
26679
  const workdir = process.env.RUNNER_WORKDIR ?? DEFAULT_WORKDIR;
26670
26680
  const branch = job.ref ?? "main";
26671
26681
  const authUrl = `https://x-access-token:${job.githubToken}@github.com/${job.repo}.git`;
26672
- fs50.rmSync(workdir, { recursive: true, force: true });
26673
- fs50.mkdirSync(workdir, { recursive: true });
26682
+ fs51.rmSync(workdir, { recursive: true, force: true });
26683
+ fs51.mkdirSync(workdir, { recursive: true });
26674
26684
  const allSecrets = typeof job.allSecrets === "string" ? job.allSecrets : JSON.stringify(job.allSecrets ?? {});
26675
26685
  const target = job.runRequest.target;
26676
26686
  const interactive = target.type === "chat";
@@ -26699,13 +26709,13 @@ async function defaultRunJob(job) {
26699
26709
  ...interactive && job.idleExitMs ? { KODY_IDLE_EXIT_MS: String(job.idleExitMs) } : {},
26700
26710
  ...interactive && job.hardCapMs ? { KODY_HARD_CAP_MS: String(job.hardCapMs) } : {}
26701
26711
  };
26702
- const run = (cmd, args, cwd) => new Promise((resolve16) => {
26712
+ const run = (cmd, args, cwd) => new Promise((resolve17) => {
26703
26713
  const child = spawn9(cmd, args, { stdio: "inherit", env: childEnv, cwd });
26704
- child.on("exit", (code) => resolve16(code ?? 0));
26714
+ child.on("exit", (code) => resolve17(code ?? 0));
26705
26715
  child.on("error", (err) => {
26706
26716
  process.stderr.write(`[runner-serve] ${cmd} failed: ${err.message}
26707
26717
  `);
26708
- resolve16(1);
26718
+ resolve17(1);
26709
26719
  });
26710
26720
  });
26711
26721
  process.stdout.write(`[runner-serve] job ${job.jobId}: cloning ${job.repo}@${branch}
@@ -26781,11 +26791,11 @@ async function runnerServe() {
26781
26791
  const port = Number(process.env.PORT ?? DEFAULT_PORT2);
26782
26792
  const server = buildServer2({ apiKey });
26783
26793
  const host = process.env.RUNNER_HOST ?? "::";
26784
- await new Promise((resolve16) => {
26794
+ await new Promise((resolve17) => {
26785
26795
  server.listen(port, host, () => {
26786
26796
  process.stdout.write(`[runner-serve] listening on ${host}:${port} (idle, awaiting job)
26787
26797
  `);
26788
- resolve16();
26798
+ resolve17();
26789
26799
  });
26790
26800
  });
26791
26801
  const shutdown = (signal) => {
@@ -26854,14 +26864,14 @@ async function serve(opts) {
26854
26864
  `);
26855
26865
  const args = ["--dangerously-skip-permissions", "--model", model.model];
26856
26866
  const child = spawn10("claude", args, { stdio: "inherit", env: editorEnv, cwd: opts.cwd });
26857
- const exitCode = await new Promise((resolve16) => {
26858
- child.on("exit", (code) => resolve16(code ?? 0));
26867
+ const exitCode = await new Promise((resolve17) => {
26868
+ child.on("exit", (code) => resolve17(code ?? 0));
26859
26869
  child.on("error", (err) => {
26860
26870
  process.stderr.write(`[kody serve] failed to launch Claude Code: ${err.message}
26861
26871
  `);
26862
26872
  process.stderr.write(` Install: https://docs.anthropic.com/claude/docs/claude-code
26863
26873
  `);
26864
- resolve16(1);
26874
+ resolve17(1);
26865
26875
  });
26866
26876
  });
26867
26877
  killProxy();
@@ -27245,7 +27255,7 @@ function parseArgs(argv) {
27245
27255
  }
27246
27256
  async function main(argv = process.argv.slice(2)) {
27247
27257
  unpackAllSecrets();
27248
- const cwdFlag = argv.findIndex((value) => value === "--cwd");
27258
+ const cwdFlag = argv.indexOf("--cwd");
27249
27259
  const definitionCwd = cwdFlag >= 0 && argv[cwdFlag + 1] ? argv[cwdFlag + 1] : process.cwd();
27250
27260
  const shouldHydrate = Boolean(process.env.CONVEX_URL?.trim()) || process.env.GITHUB_ACTIONS === "true" && Boolean(process.env.GITHUB_EVENT_NAME);
27251
27261
  if (shouldHydrate) {