@kody-ade/kody-engine 0.4.307 → 0.4.308

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 +393 -310
  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.307",
18
+ version: "0.4.308",
19
19
  description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
20
20
  license: "MIT",
21
21
  type: "module",
@@ -1610,7 +1610,7 @@ function cmsHeaders(opts) {
1610
1610
  }
1611
1611
  };
1612
1612
  }
1613
- async function callDashboardCms(opts, path50, init = {}) {
1613
+ async function callDashboardCms(opts, path51, init = {}) {
1614
1614
  const baseUrl = dashboardBaseUrl(opts);
1615
1615
  if (!baseUrl) {
1616
1616
  return {
@@ -1622,7 +1622,7 @@ async function callDashboardCms(opts, path50, init = {}) {
1622
1622
  const headerResult = cmsHeaders(opts);
1623
1623
  if (!headerResult.ok) return headerResult;
1624
1624
  try {
1625
- const res = await fetch(`${baseUrl}${path50}`, {
1625
+ const res = await fetch(`${baseUrl}${path51}`, {
1626
1626
  ...init,
1627
1627
  headers: {
1628
1628
  ...headerResult.headers,
@@ -1694,8 +1694,8 @@ function documentArg(value) {
1694
1694
  function normalizeCmsDocumentIdInput(input) {
1695
1695
  const trimmed = stripWrappingQuotes(input.trim());
1696
1696
  const withoutQuery = trimmed.split(/[?#]/, 1)[0] ?? trimmed;
1697
- const path50 = parseDocumentPath(withoutQuery);
1698
- return path50 ?? parseDocumentIdSegment(withoutQuery) ?? withoutQuery;
1697
+ const path51 = parseDocumentPath(withoutQuery);
1698
+ return path51 ?? parseDocumentIdSegment(withoutQuery) ?? withoutQuery;
1699
1699
  }
1700
1700
  function stripWrappingQuotes(value) {
1701
1701
  let current = value;
@@ -1706,9 +1706,9 @@ function stripWrappingQuotes(value) {
1706
1706
  }
1707
1707
  }
1708
1708
  function parseDocumentPath(value) {
1709
- const path50 = value.startsWith("http://") || value.startsWith("https://") ? urlPathname(value) : value;
1710
- if (!path50?.includes("/content/entries/")) return null;
1711
- const parts = path50.split("/").filter(Boolean).map(decodePathPart);
1709
+ const path51 = value.startsWith("http://") || value.startsWith("https://") ? urlPathname(value) : value;
1710
+ if (!path51?.includes("/content/entries/")) return null;
1711
+ const parts = path51.split("/").filter(Boolean).map(decodePathPart);
1712
1712
  const entriesIndex = parts.findIndex((part, index) => part === "content" && parts[index + 1] === "entries");
1713
1713
  const idPart = parts[entriesIndex + 3];
1714
1714
  if (!idPart || idPart === "new") return null;
@@ -2041,6 +2041,23 @@ function getCompanyStoreAssetRoot(kind) {
2041
2041
  if (fs5.existsSync(rootLayoutPath)) return rootLayoutPath;
2042
2042
  return path7.join(root, ".kody", folderByKind[kind]);
2043
2043
  }
2044
+ function resetCompanyStoreCacheForTests() {
2045
+ memo = null;
2046
+ }
2047
+ function applyCompanyStoreRuntimeConfig(input, env = process.env) {
2048
+ const repo = stringValue(input?.storeRepoUrl ?? input?.storeRepo);
2049
+ const ref = stringValue(input?.storeRef);
2050
+ let changed = false;
2051
+ if (repo && env[STORE_ENV] !== repo) {
2052
+ env[STORE_ENV] = repo;
2053
+ changed = true;
2054
+ }
2055
+ if (ref && env[REF_ENV] !== ref) {
2056
+ env[REF_ENV] = ref;
2057
+ changed = true;
2058
+ }
2059
+ if (changed) resetCompanyStoreCacheForTests();
2060
+ }
2044
2061
  function resolveCompanyStore() {
2045
2062
  const envStore = process.env[STORE_ENV]?.trim();
2046
2063
  if (!envStore && process.env.VITEST) return null;
@@ -2050,6 +2067,9 @@ function resolveCompanyStore() {
2050
2067
  if (!ref) return null;
2051
2068
  return { repo, ref };
2052
2069
  }
2070
+ function stringValue(value) {
2071
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
2072
+ }
2053
2073
  function fetchCompanyStore(repo, ref) {
2054
2074
  const localRoot = localStoreRoot(repo);
2055
2075
  if (localRoot) return localRoot;
@@ -6897,10 +6917,10 @@ var init_state2 = __esm({
6897
6917
  "use strict";
6898
6918
  VALID_STATES = /* @__PURE__ */ new Set(["active", "abandoned", "closed", "done"]);
6899
6919
  GoalStateError = class extends Error {
6900
- constructor(path50, message) {
6901
- super(`Invalid goal state at ${path50}:
6920
+ constructor(path51, message) {
6921
+ super(`Invalid goal state at ${path51}:
6902
6922
  ${message}`);
6903
- this.path = path50;
6923
+ this.path = path51;
6904
6924
  this.name = "GoalStateError";
6905
6925
  }
6906
6926
  path;
@@ -6913,9 +6933,9 @@ import * as fs25 from "fs";
6913
6933
  function stageGoalRunLogEvent(data, goalId, event, at = nowIso()) {
6914
6934
  const logs = goalRunLogs(data);
6915
6935
  const existing = logs[goalId];
6916
- const path50 = existing?.path ?? goalRunLogPath(goalId, data);
6936
+ const path51 = existing?.path ?? goalRunLogPath(goalId, data);
6917
6937
  logs[goalId] = {
6918
- path: path50,
6938
+ path: path51,
6919
6939
  events: [...existing?.events ?? [], buildGoalRunLogEvent(data, goalId, event, at)]
6920
6940
  };
6921
6941
  }
@@ -7002,7 +7022,7 @@ function goalRunStartedAt(data) {
7002
7022
  function goalRunId(data) {
7003
7023
  const existing = data[LOG_RUN_KEY];
7004
7024
  if (typeof existing === "string" && existing.length > 0) return existing;
7005
- const raw = stringValue(data.jobId) ?? githubRunId() ?? `local-${process.pid}-${Date.now()}`;
7025
+ const raw = stringValue2(data.jobId) ?? githubRunId() ?? `local-${process.pid}-${Date.now()}`;
7006
7026
  const safe = safePathSegment(raw);
7007
7027
  data[LOG_RUN_KEY] = safe;
7008
7028
  return safe;
@@ -7101,7 +7121,7 @@ function triggerContext() {
7101
7121
  issue: numberValue(recordValue2(event?.issue)?.number),
7102
7122
  pullRequest: numberValue(recordValue2(event?.pull_request)?.number),
7103
7123
  comment: numberValue(recordValue2(event?.comment)?.id),
7104
- schedule: stringValue(event?.schedule),
7124
+ schedule: stringValue2(event?.schedule),
7105
7125
  inputs: inputs ? pickRecord(inputs, ["issue_number", "sessionId", "message", "model", "title", "executable", "base"]) : void 0
7106
7126
  });
7107
7127
  return Object.keys(trigger).length > 0 ? trigger : void 0;
@@ -7120,16 +7140,16 @@ function triggerActorRole(eventName) {
7120
7140
  }
7121
7141
  function jobContext(data) {
7122
7142
  const job = pruneUndefined({
7123
- id: stringValue(data.jobId) ?? void 0,
7124
- key: stringValue(data.jobKey) ?? void 0,
7125
- flavor: stringValue(data.jobFlavor) ?? void 0,
7126
- action: stringValue(data.jobAction) ?? void 0,
7127
- capability: stringValue(data.jobCapability) ?? void 0,
7128
- executable: stringValue(data.jobExecutable) ?? void 0,
7129
- agent: stringValue(data.jobAgent) ?? void 0,
7130
- schedule: stringValue(data.jobSchedule) ?? void 0,
7143
+ id: stringValue2(data.jobId) ?? void 0,
7144
+ key: stringValue2(data.jobKey) ?? void 0,
7145
+ flavor: stringValue2(data.jobFlavor) ?? void 0,
7146
+ action: stringValue2(data.jobAction) ?? void 0,
7147
+ capability: stringValue2(data.jobCapability) ?? void 0,
7148
+ executable: stringValue2(data.jobExecutable) ?? void 0,
7149
+ agent: stringValue2(data.jobAgent) ?? void 0,
7150
+ schedule: stringValue2(data.jobSchedule) ?? void 0,
7131
7151
  target: data.jobTarget ?? void 0,
7132
- why: truncateString(stringValue(data.jobWhy), 1e3),
7152
+ why: truncateString(stringValue2(data.jobWhy), 1e3),
7133
7153
  saveReport: data.jobSaveReport === true ? true : void 0
7134
7154
  });
7135
7155
  return Object.keys(job).length > 0 ? job : void 0;
@@ -7139,21 +7159,21 @@ function dispatchContext(event, trigger, job) {
7139
7159
  const dispatch2 = event.dispatch ?? {};
7140
7160
  const context = pruneUndefined({
7141
7161
  triggeredBy: triggerLabel(trigger),
7142
- triggerKind: stringValue(trigger?.kind),
7162
+ triggerKind: stringValue2(trigger?.kind),
7143
7163
  dispatchMode: dispatchMode(trigger),
7144
- githubActor: stringValue(trigger?.githubActor) ?? stringValue(trigger?.actor),
7145
- githubActorRole: stringValue(trigger?.actorRole),
7164
+ githubActor: stringValue2(trigger?.githubActor) ?? stringValue2(trigger?.actor),
7165
+ githubActorRole: stringValue2(trigger?.actorRole),
7146
7166
  decidedBy: event.source,
7147
7167
  dispatchedBy: event.source,
7148
7168
  target: event.target,
7149
- action: dispatch2.action ?? stringValue(job?.action),
7150
- capability: dispatch2.capability ?? stringValue(job?.capability),
7169
+ action: dispatch2.action ?? stringValue2(job?.action),
7170
+ capability: dispatch2.capability ?? stringValue2(job?.capability),
7151
7171
  reason: event.reason
7152
7172
  });
7153
7173
  return Object.keys(context).length > 0 ? context : void 0;
7154
7174
  }
7155
7175
  function triggerLabel(trigger) {
7156
- const kind = stringValue(trigger?.kind);
7176
+ const kind = stringValue2(trigger?.kind);
7157
7177
  if (kind === "schedule") return "GitHub schedule";
7158
7178
  if (kind === "manual-workflow-dispatch") return "manual workflow dispatch";
7159
7179
  if (kind === "issue_comment") return "GitHub issue comment";
@@ -7162,7 +7182,7 @@ function triggerLabel(trigger) {
7162
7182
  return "local run";
7163
7183
  }
7164
7184
  function dispatchMode(trigger) {
7165
- const kind = stringValue(trigger?.kind);
7185
+ const kind = stringValue2(trigger?.kind);
7166
7186
  if (kind === "schedule") return "automated";
7167
7187
  if (kind === "manual-workflow-dispatch") return "manual";
7168
7188
  if (kind) return "event-driven";
@@ -7174,10 +7194,10 @@ function linkContext(stateRepo) {
7174
7194
  const repository = process.env.GITHUB_REPOSITORY?.trim();
7175
7195
  const server = process.env.GITHUB_SERVER_URL?.trim() || "https://github.com";
7176
7196
  if (runId && repository) links.workflowRun = `${server}/${repository}/actions/runs/${runId}`;
7177
- const repo = stringValue(stateRepo?.repo);
7178
- const branch = stringValue(stateRepo?.branch);
7179
- const goalStatePath2 = stringValue(stateRepo?.goalStatePath);
7180
- const logPath = stringValue(stateRepo?.logPath);
7197
+ const repo = stringValue2(stateRepo?.repo);
7198
+ const branch = stringValue2(stateRepo?.branch);
7199
+ const goalStatePath2 = stringValue2(stateRepo?.goalStatePath);
7200
+ const logPath = stringValue2(stateRepo?.logPath);
7181
7201
  if (repo && branch && goalStatePath2) links.goalState = githubBlobUrl(repo, branch, goalStatePath2);
7182
7202
  if (repo && branch && logPath) links.log = githubBlobUrl(repo, branch, logPath);
7183
7203
  return Object.keys(links).length > 0 ? links : void 0;
@@ -7257,7 +7277,7 @@ function truncateString(value, max) {
7257
7277
  if (!value) return void 0;
7258
7278
  return value.length > max ? `${value.slice(0, max)}...` : value;
7259
7279
  }
7260
- function stringValue(value) {
7280
+ function stringValue2(value) {
7261
7281
  return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
7262
7282
  }
7263
7283
  function safePathSegment(value) {
@@ -7430,6 +7450,8 @@ var init_managedTodoState = __esm({
7430
7450
  });
7431
7451
 
7432
7452
  // src/goal/stateStore.ts
7453
+ import * as fs26 from "fs";
7454
+ import * as path24 from "path";
7433
7455
  function goalStatePath(goalId) {
7434
7456
  return `todos/${goalId}.json`;
7435
7457
  }
@@ -7438,7 +7460,55 @@ function fetchGoalState(config, goalId, cwd) {
7438
7460
  const loaded = readStateText(config, cwd, filePath);
7439
7461
  if (!loaded) return null;
7440
7462
  if (!isManagedTodoRaw(loaded.content)) return null;
7441
- return parseTodoGoalState(goalId, loaded.path, loaded.content);
7463
+ return resolveStoreBackedGoalState(parseTodoGoalState(goalId, loaded.path, loaded.content));
7464
+ }
7465
+ function resolveStoreBackedGoalState(state) {
7466
+ const templateId = templateIdFromGoalState(state);
7467
+ if (!templateId) return state;
7468
+ const template = readStoreGoalTemplate(templateId);
7469
+ if (!template) return state;
7470
+ const nextExtra = { ...state.extra };
7471
+ for (const key of [
7472
+ "type",
7473
+ "destination",
7474
+ "capabilities",
7475
+ "route",
7476
+ "schedule",
7477
+ "scheduleMode",
7478
+ "loopTarget",
7479
+ "preferredRunTime",
7480
+ "saveReport"
7481
+ ]) {
7482
+ if (Object.hasOwn(template, key)) nextExtra[key] = template[key];
7483
+ else if (["schedule", "loopTarget", "preferredRunTime", "saveReport"].includes(key)) delete nextExtra[key];
7484
+ }
7485
+ nextExtra.facts = {
7486
+ ...recordField2(template.facts) ?? {},
7487
+ ...recordField2(state.extra.facts) ?? {}
7488
+ };
7489
+ return { ...state, extra: nextExtra };
7490
+ }
7491
+ function templateIdFromGoalState(state) {
7492
+ for (const key of ["sourceTemplate", "templateId", "template"]) {
7493
+ const value = state.extra[key];
7494
+ if (typeof value === "string" && value.trim()) return value.trim();
7495
+ }
7496
+ return "";
7497
+ }
7498
+ function readStoreGoalTemplate(templateId) {
7499
+ const root = getCompanyStoreAssetRoot("goals");
7500
+ if (!root) return null;
7501
+ const file = path24.join(root, "templates", templateId, "state.json");
7502
+ if (!fs26.existsSync(file)) return null;
7503
+ try {
7504
+ const parsed = JSON.parse(fs26.readFileSync(file, "utf8"));
7505
+ return recordField2(parsed);
7506
+ } catch {
7507
+ return null;
7508
+ }
7509
+ }
7510
+ function recordField2(value) {
7511
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
7442
7512
  }
7443
7513
  function putGoalState(config, goalId, state, message = `chore(goals): update ${goalId}`, cwd) {
7444
7514
  const previous = readStateText(config, cwd, goalStatePath(goalId));
@@ -7463,12 +7533,13 @@ var init_stateStore = __esm({
7463
7533
  "use strict";
7464
7534
  init_stateRepo();
7465
7535
  init_managedTodoState();
7536
+ init_companyStore();
7466
7537
  }
7467
7538
  });
7468
7539
 
7469
7540
  // src/goal/targetLoopResolution.ts
7470
- import * as fs26 from "fs";
7471
- import * as path24 from "path";
7541
+ import * as fs27 from "fs";
7542
+ import * as path25 from "path";
7472
7543
  function resolveActiveGoalLoopTarget(config, cwd, loopGoalId, loopGoal) {
7473
7544
  const targetId = loopGoal.loopTarget?.id.trim() ?? "";
7474
7545
  assertSafeGoalId(targetId, "loop target");
@@ -7554,16 +7625,16 @@ function goalInstanceTime(state) {
7554
7625
  return Number.isNaN(parsed) ? 0 : parsed;
7555
7626
  }
7556
7627
  function loadGoalTemplate(cwd, targetId) {
7557
- const local = path24.join(cwd, ".kody", "goals", "templates", targetId, "state.json");
7628
+ const local = path25.join(cwd, ".kody", "goals", "templates", targetId, "state.json");
7558
7629
  const localTemplate = readJsonObject(local);
7559
7630
  if (localTemplate) return localTemplate;
7560
7631
  const storeGoalRoot = getCompanyStoreAssetRoot("goals");
7561
7632
  if (!storeGoalRoot) return null;
7562
- return readJsonObject(path24.join(storeGoalRoot, "templates", targetId, "state.json"));
7633
+ return readJsonObject(path25.join(storeGoalRoot, "templates", targetId, "state.json"));
7563
7634
  }
7564
7635
  function readJsonObject(filePath) {
7565
- if (!fs26.existsSync(filePath)) return null;
7566
- const parsed = JSON.parse(fs26.readFileSync(filePath, "utf8"));
7636
+ if (!fs27.existsSync(filePath)) return null;
7637
+ const parsed = JSON.parse(fs27.readFileSync(filePath, "utf8"));
7567
7638
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
7568
7639
  throw new Error(`goal template ${filePath} must be a JSON object`);
7569
7640
  }
@@ -7959,8 +8030,8 @@ var init_contentsApiBackend = __esm({
7959
8030
  });
7960
8031
 
7961
8032
  // src/scripts/jobState/localFileBackend.ts
7962
- import * as fs27 from "fs";
7963
- import * as path25 from "path";
8033
+ import * as fs28 from "fs";
8034
+ import * as path26 from "path";
7964
8035
  function sanitizeKey(s) {
7965
8036
  return s.replace(/[^A-Za-z0-9._-]/g, "-");
7966
8037
  }
@@ -8016,7 +8087,7 @@ var init_localFileBackend = __esm({
8016
8087
  if (!opts.owner || !opts.repo) throw new Error("LocalFileBackend: owner and repo are required");
8017
8088
  this.cwd = opts.cwd;
8018
8089
  this.jobsDir = opts.jobsDir;
8019
- this.absDir = path25.join(opts.cwd, opts.jobsDir);
8090
+ this.absDir = path26.join(opts.cwd, opts.jobsDir);
8020
8091
  this.owner = opts.owner;
8021
8092
  this.repo = opts.repo;
8022
8093
  this.cache = opts.cache ?? defaultCacheAdapter();
@@ -8031,7 +8102,7 @@ var init_localFileBackend = __esm({
8031
8102
  `);
8032
8103
  return;
8033
8104
  }
8034
- fs27.mkdirSync(this.absDir, { recursive: true });
8105
+ fs28.mkdirSync(this.absDir, { recursive: true });
8035
8106
  const prefix = this.cacheKeyPrefix();
8036
8107
  const probeKey = `${prefix}probe-${Date.now()}`;
8037
8108
  try {
@@ -8060,7 +8131,7 @@ var init_localFileBackend = __esm({
8060
8131
  `);
8061
8132
  return;
8062
8133
  }
8063
- if (!fs27.existsSync(this.absDir)) {
8134
+ if (!fs28.existsSync(this.absDir)) {
8064
8135
  return;
8065
8136
  }
8066
8137
  const key = `${this.cacheKeyPrefix()}${process.env.GITHUB_RUN_ID ?? "norunid"}-${Date.now()}`;
@@ -8076,11 +8147,11 @@ var init_localFileBackend = __esm({
8076
8147
  }
8077
8148
  load(slug2) {
8078
8149
  const relPath = stateFilePath(this.jobsDir, slug2);
8079
- const absPath = path25.join(this.cwd, relPath);
8080
- if (!fs27.existsSync(absPath)) {
8150
+ const absPath = path26.join(this.cwd, relPath);
8151
+ if (!fs28.existsSync(absPath)) {
8081
8152
  return { path: relPath, handle: null, state: initialStateEnvelope("seed"), created: true };
8082
8153
  }
8083
- const raw = fs27.readFileSync(absPath, "utf-8");
8154
+ const raw = fs28.readFileSync(absPath, "utf-8");
8084
8155
  let parsed;
8085
8156
  try {
8086
8157
  parsed = JSON.parse(raw);
@@ -8097,13 +8168,13 @@ var init_localFileBackend = __esm({
8097
8168
  if (!loaded.created && isStateUnchanged(loaded.state, next)) {
8098
8169
  return false;
8099
8170
  }
8100
- const absPath = path25.join(this.cwd, loaded.path);
8101
- fs27.mkdirSync(path25.dirname(absPath), { recursive: true });
8171
+ const absPath = path26.join(this.cwd, loaded.path);
8172
+ fs28.mkdirSync(path26.dirname(absPath), { recursive: true });
8102
8173
  const body = `${JSON.stringify(next, null, 2)}
8103
8174
  `;
8104
8175
  const tmpPath = `${absPath}.${process.pid}.tmp`;
8105
- fs27.writeFileSync(tmpPath, body, "utf-8");
8106
- fs27.renameSync(tmpPath, absPath);
8176
+ fs28.writeFileSync(tmpPath, body, "utf-8");
8177
+ fs28.renameSync(tmpPath, absPath);
8107
8178
  return true;
8108
8179
  }
8109
8180
  cacheKeyPrefix() {
@@ -8143,7 +8214,7 @@ var init_jobState = __esm({
8143
8214
  });
8144
8215
 
8145
8216
  // src/scripts/goalCapabilityScheduling.ts
8146
- import * as path26 from "path";
8217
+ import * as path27 from "path";
8147
8218
  function isCapabilityCadenceGoal(goal, extra) {
8148
8219
  return extra.scheduleMode === "agentLoop" || extra.scheduler === "agentLoop" || goal.type === "standing" && goal.capabilities.length > 0;
8149
8220
  }
@@ -8199,7 +8270,7 @@ function planTargetLoopSchedule(opts) {
8199
8270
  }
8200
8271
  async function planGoalCapabilitySchedule(opts) {
8201
8272
  const jobsDir = opts.jobsDir ?? ".kody/capabilities";
8202
- const jobsRoot = path26.join(opts.cwd, jobsDir);
8273
+ const jobsRoot = path27.join(opts.cwd, jobsDir);
8203
8274
  const now = opts.now ?? /* @__PURE__ */ new Date();
8204
8275
  const at = now.toISOString();
8205
8276
  const backend = resolveBackend({ config: opts.config, cwd: opts.cwd, jobsDir });
@@ -9010,13 +9081,13 @@ function companyIntentPath(id) {
9010
9081
  assertIntentId(id);
9011
9082
  return `intents/${id}/intent.json`;
9012
9083
  }
9013
- function normalizeCompanyIntent(path50, raw) {
9084
+ function normalizeCompanyIntent(path51, raw) {
9014
9085
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
9015
- throw new Error(`${path50}: intent must be JSON object`);
9086
+ throw new Error(`${path51}: intent must be JSON object`);
9016
9087
  }
9017
9088
  const input = raw;
9018
9089
  const id = stringField3(input.id);
9019
- if (!id || !isCompanyIntentId(id)) throw new Error(`${path50}: invalid intent id`);
9090
+ if (!id || !isCompanyIntentId(id)) throw new Error(`${path51}: invalid intent id`);
9020
9091
  const createdAt = stringField3(input.createdAt) || nowIso();
9021
9092
  const updatedAt = stringField3(input.updatedAt) || createdAt;
9022
9093
  const description = stringField3(input.description);
@@ -9033,21 +9104,21 @@ function normalizeCompanyIntent(path50, raw) {
9033
9104
  "balanced"
9034
9105
  ),
9035
9106
  scope: {
9036
- repos: stringArray4(recordField2(input.scope)?.repos),
9037
- areas: stringArray4(recordField2(input.scope)?.areas)
9107
+ repos: stringArray4(recordField3(input.scope)?.repos),
9108
+ areas: stringArray4(recordField3(input.scope)?.areas)
9038
9109
  },
9039
9110
  principles: stringArray4(input.principles),
9040
9111
  metrics: stringArray4(input.metrics),
9041
9112
  policy: {
9042
- release: normalizeReleasePolicy(recordField2(recordField2(input.policy)?.release)),
9043
- automation: normalizeAutomationPolicy(recordField2(recordField2(input.policy)?.automation))
9113
+ release: normalizeReleasePolicy(recordField3(recordField3(input.policy)?.release)),
9114
+ automation: normalizeAutomationPolicy(recordField3(recordField3(input.policy)?.automation))
9044
9115
  },
9045
9116
  portfolio: {
9046
- goals: stringArray4(recordField2(input.portfolio)?.goals).filter(isCompanyIntentId),
9047
- loops: stringArray4(recordField2(input.portfolio)?.loops).filter(isCompanyIntentId),
9048
- capabilities: stringArray4(recordField2(input.portfolio)?.capabilities).filter(isCompanyIntentId)
9117
+ goals: stringArray4(recordField3(input.portfolio)?.goals).filter(isCompanyIntentId),
9118
+ loops: stringArray4(recordField3(input.portfolio)?.loops).filter(isCompanyIntentId),
9119
+ capabilities: stringArray4(recordField3(input.portfolio)?.capabilities).filter(isCompanyIntentId)
9049
9120
  },
9050
- manager: normalizeManager(recordField2(input.manager)),
9121
+ manager: normalizeManager(recordField3(input.manager)),
9051
9122
  createdAt,
9052
9123
  updatedAt
9053
9124
  };
@@ -9057,8 +9128,8 @@ function listCompanyIntents(config, cwd) {
9057
9128
  const records = [];
9058
9129
  for (const entry of entries) {
9059
9130
  if (entry.type !== "dir" || !entry.name || !isCompanyIntentId(entry.name)) continue;
9060
- const path50 = companyIntentPath(entry.name);
9061
- const file = readStateText(config, cwd, path50);
9131
+ const path51 = companyIntentPath(entry.name);
9132
+ const file = readStateText(config, cwd, path51);
9062
9133
  if (!file) continue;
9063
9134
  records.push({
9064
9135
  id: entry.name,
@@ -9069,8 +9140,8 @@ function listCompanyIntents(config, cwd) {
9069
9140
  return records.sort((a, b) => a.intent.priority - b.intent.priority || a.id.localeCompare(b.id));
9070
9141
  }
9071
9142
  function readCompanyIntent(config, cwd, id) {
9072
- const path50 = companyIntentPath(id);
9073
- const file = readStateText(config, cwd, path50);
9143
+ const path51 = companyIntentPath(id);
9144
+ const file = readStateText(config, cwd, path51);
9074
9145
  if (!file) return null;
9075
9146
  return { id, path: file.path, intent: normalizeCompanyIntent(file.path, JSON.parse(file.content)) };
9076
9147
  }
@@ -9088,7 +9159,7 @@ function listCompanyPortfolio(config, cwd) {
9088
9159
  if (!isCompanyIntentId(id)) continue;
9089
9160
  const state = fetchGoalState(config, id, cwd);
9090
9161
  if (!state) continue;
9091
- const destination = recordField2(state.extra.destination);
9162
+ const destination = recordField3(state.extra.destination);
9092
9163
  goals.push({
9093
9164
  id,
9094
9165
  state: state.state,
@@ -9114,7 +9185,7 @@ function stringField3(value) {
9114
9185
  function numberField(value, fallback) {
9115
9186
  return typeof value === "number" && Number.isFinite(value) ? value : fallback;
9116
9187
  }
9117
- function recordField2(value) {
9188
+ function recordField3(value) {
9118
9189
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
9119
9190
  }
9120
9191
  function stringArray4(value) {
@@ -9502,7 +9573,7 @@ function capabilityEvidenceOutput(evidence) {
9502
9573
  function goalReportBody(goalId, state, snapshot, latestEvent, evidenceItems) {
9503
9574
  const outputs = evidenceItems.map(capabilityEvidenceOutput);
9504
9575
  const latestOutput = outputs.at(-1);
9505
- const facts = recordField3(snapshot, "facts") ?? recordField3(state.extra, "facts") ?? {};
9576
+ const facts = recordField4(snapshot, "facts") ?? recordField4(state.extra, "facts") ?? {};
9506
9577
  const blockers = uniqueStrings2([
9507
9578
  ...stringArrayField(snapshot, "blockers"),
9508
9579
  ...stringArrayField(latestEvent, "blockers"),
@@ -9554,7 +9625,7 @@ function capabilityEvidenceMarkdown(outputs) {
9554
9625
  function decisionReason(state, latestEvent, latestOutput, missingEvidence, blockers) {
9555
9626
  if (state.state === "done") return "destination evidence satisfied";
9556
9627
  if (blockers.length > 0) return blockers[0] ?? "blocked";
9557
- const eventReason = stringField4(latestEvent, "reason") ?? stringField4(recordField3(latestEvent, "decision"), "reason");
9628
+ const eventReason = stringField4(latestEvent, "reason") ?? stringField4(recordField4(latestEvent, "decision"), "reason");
9558
9629
  if (eventReason) return eventReason;
9559
9630
  const summary = stringField4(latestOutput, "summary");
9560
9631
  if (summary) return summary;
@@ -9567,18 +9638,18 @@ function evidenceOutputMarkdown(index, output) {
9567
9638
  `- Status: ${stringField4(output, "status") ?? "unknown"}`,
9568
9639
  `- Summary: ${stringField4(output, "summary") ?? "no summary"}`,
9569
9640
  `- Sources: ${listOrNone(stringArrayField(output, "sources"))}`,
9570
- `- Evidence values: ${inlineJson(recordField3(output, "evidence") ?? {})}`,
9641
+ `- Evidence values: ${inlineJson(recordField4(output, "evidence") ?? {})}`,
9571
9642
  `- Missing evidence: ${listOrNone(stringArrayField(output, "missingEvidence"))}`,
9572
9643
  `- Blockers: ${listOrNone(stringArrayField(output, "blockers"))}`,
9573
9644
  ""
9574
9645
  ];
9575
9646
  }
9576
9647
  function dispatchContextMarkdown(latestEvent) {
9577
- const context = recordField3(latestEvent, "dispatchContext");
9648
+ const context = recordField4(latestEvent, "dispatchContext");
9578
9649
  if (!context) return ["- none"];
9579
9650
  const githubActor = stringField4(context, "githubActor");
9580
9651
  const githubActorRole = stringField4(context, "githubActorRole");
9581
- const target = dispatchTargetLabel(recordField3(context, "target"));
9652
+ const target = dispatchTargetLabel(recordField4(context, "target"));
9582
9653
  return [
9583
9654
  `- Triggered by: ${stringField4(context, "triggeredBy") ?? "unknown"}`,
9584
9655
  `- Mode: ${stringField4(context, "dispatchMode") ?? "unknown"}`,
@@ -9617,7 +9688,7 @@ function stringField4(record2, key) {
9617
9688
  const value = record2?.[key];
9618
9689
  return typeof value === "string" && value.trim() ? value : void 0;
9619
9690
  }
9620
- function recordField3(record2, key) {
9691
+ function recordField4(record2, key) {
9621
9692
  const value = record2?.[key];
9622
9693
  return value && typeof value === "object" && !Array.isArray(value) ? { ...value } : void 0;
9623
9694
  }
@@ -9650,7 +9721,7 @@ ${artifact.path ?? ""}`;
9650
9721
  }
9651
9722
  function nextStepFromEvent(state, goalAfter, capabilityOutput, latestEvent) {
9652
9723
  if (state.state === "done") return "done";
9653
- const decisionKind = stringField4(recordField3(latestEvent, "decision"), "kind") ?? stringField4(latestEvent, "status");
9724
+ const decisionKind = stringField4(recordField4(latestEvent, "decision"), "kind") ?? stringField4(latestEvent, "status");
9654
9725
  if (decisionKind === "done") return "done";
9655
9726
  if (decisionKind === "dispatch") return "dispatch";
9656
9727
  if (decisionKind === "blocked" || decisionKind === "reject-evidence") return "block";
@@ -10113,8 +10184,8 @@ var init_classifyByLabel = __esm({
10113
10184
  });
10114
10185
 
10115
10186
  // src/scripts/commitAndPush.ts
10116
- import * as fs28 from "fs";
10117
- import * as path27 from "path";
10187
+ import * as fs29 from "fs";
10188
+ import * as path28 from "path";
10118
10189
  function sentinelPathForStage(cwd, profileName) {
10119
10190
  const runId = resolveRunId();
10120
10191
  return runtimeStatePath(cwd, "agent-runs", runId, `commit-${profileName}.lock`);
@@ -10135,9 +10206,9 @@ var init_commitAndPush = __esm({
10135
10206
  }
10136
10207
  const idempotencyEnabled = process.env.KODY_COMMIT_IDEMPOTENCY !== "0";
10137
10208
  const sentinel = idempotencyEnabled ? sentinelPathForStage(ctx.cwd, profile.name) : null;
10138
- if (sentinel && fs28.existsSync(sentinel)) {
10209
+ if (sentinel && fs29.existsSync(sentinel)) {
10139
10210
  try {
10140
- const replay = JSON.parse(fs28.readFileSync(sentinel, "utf-8"));
10211
+ const replay = JSON.parse(fs29.readFileSync(sentinel, "utf-8"));
10141
10212
  ctx.data.commitResult = replay.commitResult ?? { committed: false, pushed: false };
10142
10213
  if (Array.isArray(replay.changedFiles)) ctx.data.changedFiles = replay.changedFiles;
10143
10214
  if (typeof replay.hasCommitsAhead === "boolean") ctx.data.hasCommitsAhead = replay.hasCommitsAhead;
@@ -10190,8 +10261,8 @@ var init_commitAndPush = __esm({
10190
10261
  const result = ctx.data.commitResult;
10191
10262
  if (sentinel && result?.committed) {
10192
10263
  try {
10193
- fs28.mkdirSync(path27.dirname(sentinel), { recursive: true });
10194
- fs28.writeFileSync(
10264
+ fs29.mkdirSync(path28.dirname(sentinel), { recursive: true });
10265
+ fs29.writeFileSync(
10195
10266
  sentinel,
10196
10267
  JSON.stringify(
10197
10268
  {
@@ -10282,8 +10353,8 @@ var init_commitGoalState = __esm({
10282
10353
  });
10283
10354
 
10284
10355
  // src/scripts/composePrompt.ts
10285
- import * as fs29 from "fs";
10286
- import * as path28 from "path";
10356
+ import * as fs30 from "fs";
10357
+ import * as path29 from "path";
10287
10358
  function fenceUntrusted(value) {
10288
10359
  if (value.trim().length === 0) return value;
10289
10360
  const safe = value.replace(/-{3,}\s*END UNTRUSTED INPUT\s*-{3,}/gi, "[END UNTRUSTED INPUT]");
@@ -10406,10 +10477,10 @@ var init_composePrompt = __esm({
10406
10477
  const explicit = ctx.data.promptTemplate;
10407
10478
  const mode = ctx.args.mode;
10408
10479
  const candidates = [
10409
- explicit ? path28.join(profile.dir, explicit) : null,
10410
- mode ? path28.join(profile.dir, "prompts", `${mode}.md`) : null,
10411
- path28.join(profile.dir, "prompt.md"),
10412
- path28.join(profile.dir, "capability.md")
10480
+ explicit ? path29.join(profile.dir, explicit) : null,
10481
+ mode ? path29.join(profile.dir, "prompts", `${mode}.md`) : null,
10482
+ path29.join(profile.dir, "prompt.md"),
10483
+ path29.join(profile.dir, "capability.md")
10413
10484
  ].filter(Boolean);
10414
10485
  let templatePath = "";
10415
10486
  let template = "";
@@ -10422,7 +10493,7 @@ var init_composePrompt = __esm({
10422
10493
  break;
10423
10494
  }
10424
10495
  try {
10425
- template = fs29.readFileSync(c, "utf-8");
10496
+ template = fs30.readFileSync(c, "utf-8");
10426
10497
  templatePath = c;
10427
10498
  break;
10428
10499
  } catch (err) {
@@ -10433,7 +10504,7 @@ var init_composePrompt = __esm({
10433
10504
  if (!templatePath) {
10434
10505
  let dirState;
10435
10506
  try {
10436
- dirState = `dir contents: [${fs29.readdirSync(profile.dir).join(", ")}]`;
10507
+ dirState = `dir contents: [${fs30.readdirSync(profile.dir).join(", ")}]`;
10437
10508
  } catch (err) {
10438
10509
  dirState = `readdir(${profile.dir}) failed: ${err?.code ?? String(err)}`;
10439
10510
  }
@@ -11118,19 +11189,19 @@ var init_deriveQaScopeFromIssue = __esm({
11118
11189
 
11119
11190
  // src/scripts/diagMcp.ts
11120
11191
  import { execFileSync as execFileSync10 } from "child_process";
11121
- import * as fs30 from "fs";
11192
+ import * as fs31 from "fs";
11122
11193
  import * as os6 from "os";
11123
- import * as path29 from "path";
11194
+ import * as path30 from "path";
11124
11195
  var diagMcp;
11125
11196
  var init_diagMcp = __esm({
11126
11197
  "src/scripts/diagMcp.ts"() {
11127
11198
  "use strict";
11128
11199
  diagMcp = async (_ctx) => {
11129
11200
  const home = os6.homedir();
11130
- const cacheDir = path29.join(home, ".cache", "ms-playwright");
11201
+ const cacheDir = path30.join(home, ".cache", "ms-playwright");
11131
11202
  let entries = [];
11132
11203
  try {
11133
- entries = fs30.readdirSync(cacheDir);
11204
+ entries = fs31.readdirSync(cacheDir);
11134
11205
  } catch {
11135
11206
  }
11136
11207
  const hasChromium = entries.some((e) => e.startsWith("chromium"));
@@ -11158,13 +11229,13 @@ var init_diagMcp = __esm({
11158
11229
  });
11159
11230
 
11160
11231
  // src/scripts/frameworkDetectors.ts
11161
- import * as fs31 from "fs";
11162
- import * as path30 from "path";
11232
+ import * as fs32 from "fs";
11233
+ import * as path31 from "path";
11163
11234
  function detectFrameworks(cwd) {
11164
11235
  const out = [];
11165
11236
  let deps = {};
11166
11237
  try {
11167
- const pkg = JSON.parse(fs31.readFileSync(path30.join(cwd, "package.json"), "utf-8"));
11238
+ const pkg = JSON.parse(fs32.readFileSync(path31.join(cwd, "package.json"), "utf-8"));
11168
11239
  deps = { ...pkg.dependencies, ...pkg.devDependencies };
11169
11240
  } catch {
11170
11241
  return out;
@@ -11201,25 +11272,25 @@ function detectFrameworks(cwd) {
11201
11272
  }
11202
11273
  function findFile(cwd, candidates) {
11203
11274
  for (const c of candidates) {
11204
- if (fs31.existsSync(path30.join(cwd, c))) return c;
11275
+ if (fs32.existsSync(path31.join(cwd, c))) return c;
11205
11276
  }
11206
11277
  return null;
11207
11278
  }
11208
11279
  function discoverPayloadCollections(cwd) {
11209
11280
  const out = [];
11210
11281
  for (const dir of COLLECTION_DIRS) {
11211
- const full = path30.join(cwd, dir);
11212
- if (!fs31.existsSync(full)) continue;
11282
+ const full = path31.join(cwd, dir);
11283
+ if (!fs32.existsSync(full)) continue;
11213
11284
  let files;
11214
11285
  try {
11215
- files = fs31.readdirSync(full).filter((f) => f.endsWith(".ts") || f.endsWith(".tsx"));
11286
+ files = fs32.readdirSync(full).filter((f) => f.endsWith(".ts") || f.endsWith(".tsx"));
11216
11287
  } catch {
11217
11288
  continue;
11218
11289
  }
11219
11290
  for (const file of files) {
11220
11291
  try {
11221
- const filePath = path30.join(full, file);
11222
- const content = fs31.readFileSync(filePath, "utf-8").slice(0, 1e4);
11292
+ const filePath = path31.join(full, file);
11293
+ const content = fs32.readFileSync(filePath, "utf-8").slice(0, 1e4);
11223
11294
  const slugMatch = content.match(/slug:\s*['"]([a-z0-9-]+)['"]/);
11224
11295
  if (!slugMatch) continue;
11225
11296
  const slug2 = slugMatch[1];
@@ -11233,7 +11304,7 @@ function discoverPayloadCollections(cwd) {
11233
11304
  out.push({
11234
11305
  name,
11235
11306
  slug: slug2,
11236
- filePath: path30.relative(cwd, filePath),
11307
+ filePath: path31.relative(cwd, filePath),
11237
11308
  fields: fields.slice(0, 20),
11238
11309
  hasAdmin
11239
11310
  });
@@ -11246,28 +11317,28 @@ function discoverPayloadCollections(cwd) {
11246
11317
  function discoverAdminComponents(cwd, collections) {
11247
11318
  const out = [];
11248
11319
  for (const dir of ADMIN_COMPONENT_DIRS) {
11249
- const full = path30.join(cwd, dir);
11250
- if (!fs31.existsSync(full)) continue;
11320
+ const full = path31.join(cwd, dir);
11321
+ if (!fs32.existsSync(full)) continue;
11251
11322
  let entries;
11252
11323
  try {
11253
- entries = fs31.readdirSync(full, { withFileTypes: true });
11324
+ entries = fs32.readdirSync(full, { withFileTypes: true });
11254
11325
  } catch {
11255
11326
  continue;
11256
11327
  }
11257
11328
  for (const entry of entries) {
11258
- const entryPath = path30.join(full, entry.name);
11329
+ const entryPath = path31.join(full, entry.name);
11259
11330
  let name;
11260
11331
  let filePath;
11261
11332
  if (entry.isDirectory()) {
11262
11333
  const indexFile = ["index.tsx", "index.ts", "index.jsx", "index.js"].find(
11263
- (f) => fs31.existsSync(path30.join(entryPath, f))
11334
+ (f) => fs32.existsSync(path31.join(entryPath, f))
11264
11335
  );
11265
11336
  if (!indexFile) continue;
11266
11337
  name = entry.name;
11267
- filePath = path30.relative(cwd, path30.join(entryPath, indexFile));
11338
+ filePath = path31.relative(cwd, path31.join(entryPath, indexFile));
11268
11339
  } else if (/\.(tsx?|jsx?)$/.test(entry.name)) {
11269
11340
  name = entry.name.replace(/\.(tsx?|jsx?)$/, "");
11270
- filePath = path30.relative(cwd, entryPath);
11341
+ filePath = path31.relative(cwd, entryPath);
11271
11342
  } else {
11272
11343
  continue;
11273
11344
  }
@@ -11275,7 +11346,7 @@ function discoverAdminComponents(cwd, collections) {
11275
11346
  if (collections) {
11276
11347
  for (const col of collections) {
11277
11348
  try {
11278
- const colContent = fs31.readFileSync(path30.join(cwd, col.filePath), "utf-8");
11349
+ const colContent = fs32.readFileSync(path31.join(cwd, col.filePath), "utf-8");
11279
11350
  if (colContent.includes(name)) {
11280
11351
  usedInCollection = col.slug;
11281
11352
  break;
@@ -11293,8 +11364,8 @@ function scanApiRoutes(cwd) {
11293
11364
  const out = [];
11294
11365
  const appDirs = ["src/app", "app"];
11295
11366
  for (const appDir of appDirs) {
11296
- const apiDir = path30.join(cwd, appDir, "api");
11297
- if (!fs31.existsSync(apiDir)) continue;
11367
+ const apiDir = path31.join(cwd, appDir, "api");
11368
+ if (!fs32.existsSync(apiDir)) continue;
11298
11369
  walkApiRoutes(apiDir, "/api", cwd, out);
11299
11370
  break;
11300
11371
  }
@@ -11303,14 +11374,14 @@ function scanApiRoutes(cwd) {
11303
11374
  function walkApiRoutes(dir, prefix, cwd, out) {
11304
11375
  let entries;
11305
11376
  try {
11306
- entries = fs31.readdirSync(dir, { withFileTypes: true });
11377
+ entries = fs32.readdirSync(dir, { withFileTypes: true });
11307
11378
  } catch {
11308
11379
  return;
11309
11380
  }
11310
11381
  const routeFile = entries.find((e) => e.isFile() && /^route\.(ts|js|tsx|jsx)$/.test(e.name));
11311
11382
  if (routeFile) {
11312
11383
  try {
11313
- const content = fs31.readFileSync(path30.join(dir, routeFile.name), "utf-8").slice(0, 5e3);
11384
+ const content = fs32.readFileSync(path31.join(dir, routeFile.name), "utf-8").slice(0, 5e3);
11314
11385
  const methods = HTTP_METHODS.filter(
11315
11386
  (m) => new RegExp(`export\\s+(?:async\\s+)?function\\s+${m}\\b`).test(content)
11316
11387
  );
@@ -11318,7 +11389,7 @@ function walkApiRoutes(dir, prefix, cwd, out) {
11318
11389
  out.push({
11319
11390
  path: prefix,
11320
11391
  methods,
11321
- filePath: path30.relative(cwd, path30.join(dir, routeFile.name))
11392
+ filePath: path31.relative(cwd, path31.join(dir, routeFile.name))
11322
11393
  });
11323
11394
  }
11324
11395
  } catch {
@@ -11329,7 +11400,7 @@ function walkApiRoutes(dir, prefix, cwd, out) {
11329
11400
  if (entry.name === "node_modules" || entry.name === ".next") continue;
11330
11401
  let segment = entry.name;
11331
11402
  if (segment.startsWith("(") && segment.endsWith(")")) {
11332
- walkApiRoutes(path30.join(dir, entry.name), prefix, cwd, out);
11403
+ walkApiRoutes(path31.join(dir, entry.name), prefix, cwd, out);
11333
11404
  continue;
11334
11405
  }
11335
11406
  if (segment.startsWith("[[") && segment.endsWith("]]")) {
@@ -11337,16 +11408,16 @@ function walkApiRoutes(dir, prefix, cwd, out) {
11337
11408
  } else if (segment.startsWith("[") && segment.endsWith("]")) {
11338
11409
  segment = `:${segment.slice(1, -1)}`;
11339
11410
  }
11340
- walkApiRoutes(path30.join(dir, entry.name), `${prefix}/${segment}`, cwd, out);
11411
+ walkApiRoutes(path31.join(dir, entry.name), `${prefix}/${segment}`, cwd, out);
11341
11412
  }
11342
11413
  }
11343
11414
  function scanEnvVars(cwd) {
11344
11415
  const candidates = [".env.example", ".env.local.example", ".env.template"];
11345
11416
  for (const envFile of candidates) {
11346
- const envPath = path30.join(cwd, envFile);
11347
- if (!fs31.existsSync(envPath)) continue;
11417
+ const envPath = path31.join(cwd, envFile);
11418
+ if (!fs32.existsSync(envPath)) continue;
11348
11419
  try {
11349
- const content = fs31.readFileSync(envPath, "utf-8");
11420
+ const content = fs32.readFileSync(envPath, "utf-8");
11350
11421
  const vars = [];
11351
11422
  for (const line of content.split("\n")) {
11352
11423
  const trimmed = line.trim();
@@ -11391,8 +11462,8 @@ var init_frameworkDetectors = __esm({
11391
11462
  });
11392
11463
 
11393
11464
  // src/scripts/discoverQaContext.ts
11394
- import * as fs32 from "fs";
11395
- import * as path31 from "path";
11465
+ import * as fs33 from "fs";
11466
+ import * as path32 from "path";
11396
11467
  function runQaDiscovery(cwd) {
11397
11468
  const out = {
11398
11469
  routes: [],
@@ -11423,9 +11494,9 @@ function runQaDiscovery(cwd) {
11423
11494
  }
11424
11495
  function detectDevServer(cwd, out) {
11425
11496
  try {
11426
- const pkg = JSON.parse(fs32.readFileSync(path31.join(cwd, "package.json"), "utf-8"));
11497
+ const pkg = JSON.parse(fs33.readFileSync(path32.join(cwd, "package.json"), "utf-8"));
11427
11498
  const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
11428
- const pm = fs32.existsSync(path31.join(cwd, "pnpm-lock.yaml")) ? "pnpm" : fs32.existsSync(path31.join(cwd, "yarn.lock")) ? "yarn" : fs32.existsSync(path31.join(cwd, "bun.lockb")) ? "bun" : "npm";
11499
+ const pm = fs33.existsSync(path32.join(cwd, "pnpm-lock.yaml")) ? "pnpm" : fs33.existsSync(path32.join(cwd, "yarn.lock")) ? "yarn" : fs33.existsSync(path32.join(cwd, "bun.lockb")) ? "bun" : "npm";
11429
11500
  if (pkg.scripts?.dev) out.devCommand = `${pm} dev`;
11430
11501
  if (allDeps.next || allDeps.nuxt) out.devPort = 3e3;
11431
11502
  else if (allDeps.vite) out.devPort = 5173;
@@ -11435,8 +11506,8 @@ function detectDevServer(cwd, out) {
11435
11506
  function scanFrontendRoutes(cwd, out) {
11436
11507
  const appDirs = ["src/app", "app"];
11437
11508
  for (const appDir of appDirs) {
11438
- const full = path31.join(cwd, appDir);
11439
- if (!fs32.existsSync(full)) continue;
11509
+ const full = path32.join(cwd, appDir);
11510
+ if (!fs33.existsSync(full)) continue;
11440
11511
  walkFrontendRoutes(full, "", out);
11441
11512
  break;
11442
11513
  }
@@ -11444,7 +11515,7 @@ function scanFrontendRoutes(cwd, out) {
11444
11515
  function walkFrontendRoutes(dir, prefix, out) {
11445
11516
  let entries;
11446
11517
  try {
11447
- entries = fs32.readdirSync(dir, { withFileTypes: true });
11518
+ entries = fs33.readdirSync(dir, { withFileTypes: true });
11448
11519
  } catch {
11449
11520
  return;
11450
11521
  }
@@ -11461,7 +11532,7 @@ function walkFrontendRoutes(dir, prefix, out) {
11461
11532
  if (entry.name === "node_modules" || entry.name === ".next") continue;
11462
11533
  let segment = entry.name;
11463
11534
  if (segment.startsWith("(") && segment.endsWith(")")) {
11464
- walkFrontendRoutes(path31.join(dir, entry.name), prefix, out);
11535
+ walkFrontendRoutes(path32.join(dir, entry.name), prefix, out);
11465
11536
  continue;
11466
11537
  }
11467
11538
  if (segment.startsWith("[[") && segment.endsWith("]]")) {
@@ -11469,7 +11540,7 @@ function walkFrontendRoutes(dir, prefix, out) {
11469
11540
  } else if (segment.startsWith("[") && segment.endsWith("]")) {
11470
11541
  segment = `:${segment.slice(1, -1)}`;
11471
11542
  }
11472
- walkFrontendRoutes(path31.join(dir, entry.name), `${prefix}/${segment}`, out);
11543
+ walkFrontendRoutes(path32.join(dir, entry.name), `${prefix}/${segment}`, out);
11473
11544
  }
11474
11545
  }
11475
11546
  function detectAuthFiles(cwd, out) {
@@ -11486,23 +11557,23 @@ function detectAuthFiles(cwd, out) {
11486
11557
  "src/app/api/oauth"
11487
11558
  ];
11488
11559
  for (const c of candidates) {
11489
- if (fs32.existsSync(path31.join(cwd, c))) out.authFiles.push(c);
11560
+ if (fs33.existsSync(path32.join(cwd, c))) out.authFiles.push(c);
11490
11561
  }
11491
11562
  }
11492
11563
  function detectRoles(cwd, out) {
11493
11564
  const rolePaths = ["src/types", "src/lib", "src/utils", "src/constants", "src/access", "src/collections"];
11494
11565
  for (const rp of rolePaths) {
11495
- const dir = path31.join(cwd, rp);
11496
- if (!fs32.existsSync(dir)) continue;
11566
+ const dir = path32.join(cwd, rp);
11567
+ if (!fs33.existsSync(dir)) continue;
11497
11568
  let files;
11498
11569
  try {
11499
- files = fs32.readdirSync(dir).filter((f) => f.endsWith(".ts") || f.endsWith(".tsx"));
11570
+ files = fs33.readdirSync(dir).filter((f) => f.endsWith(".ts") || f.endsWith(".tsx"));
11500
11571
  } catch {
11501
11572
  continue;
11502
11573
  }
11503
11574
  for (const f of files) {
11504
11575
  try {
11505
- const content = fs32.readFileSync(path31.join(dir, f), "utf-8").slice(0, 5e3);
11576
+ const content = fs33.readFileSync(path32.join(dir, f), "utf-8").slice(0, 5e3);
11506
11577
  const roleMatches = content.match(/(?:role|Role|ROLE)\s*[=:]\s*['"](\w+)['"]/g);
11507
11578
  if (roleMatches) {
11508
11579
  for (const m of roleMatches) {
@@ -12742,12 +12813,12 @@ var init_fixFlow = __esm({
12742
12813
 
12743
12814
  // src/scripts/initFlow.ts
12744
12815
  import { execFileSync as execFileSync15 } from "child_process";
12745
- import * as fs33 from "fs";
12746
- import * as path32 from "path";
12816
+ import * as fs34 from "fs";
12817
+ import * as path33 from "path";
12747
12818
  function detectPackageManager(cwd) {
12748
- if (fs33.existsSync(path32.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
12749
- if (fs33.existsSync(path32.join(cwd, "yarn.lock"))) return "yarn";
12750
- if (fs33.existsSync(path32.join(cwd, "bun.lockb"))) return "bun";
12819
+ if (fs34.existsSync(path33.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
12820
+ if (fs34.existsSync(path33.join(cwd, "yarn.lock"))) return "yarn";
12821
+ if (fs34.existsSync(path33.join(cwd, "bun.lockb"))) return "bun";
12751
12822
  return "npm";
12752
12823
  }
12753
12824
  function qualityCommandsFor(pm) {
@@ -12819,22 +12890,22 @@ function performInit(cwd, force) {
12819
12890
  const pm = detectPackageManager(cwd);
12820
12891
  const ownerRepo = detectOwnerRepo(cwd);
12821
12892
  const defaultBranch = defaultBranchFromGit(cwd);
12822
- const configPath = path32.join(cwd, "kody.config.json");
12823
- if (fs33.existsSync(configPath) && !force) {
12893
+ const configPath = path33.join(cwd, "kody.config.json");
12894
+ if (fs34.existsSync(configPath) && !force) {
12824
12895
  skipped.push("kody.config.json");
12825
12896
  } else {
12826
12897
  const cfg = makeConfig(pm, ownerRepo, defaultBranch);
12827
- fs33.writeFileSync(configPath, `${JSON.stringify(cfg, null, 2)}
12898
+ fs34.writeFileSync(configPath, `${JSON.stringify(cfg, null, 2)}
12828
12899
  `);
12829
12900
  wrote.push("kody.config.json");
12830
12901
  }
12831
- const workflowDir = path32.join(cwd, ".github", "workflows");
12832
- const workflowPath = path32.join(workflowDir, "kody.yml");
12833
- if (fs33.existsSync(workflowPath) && !force) {
12902
+ const workflowDir = path33.join(cwd, ".github", "workflows");
12903
+ const workflowPath = path33.join(workflowDir, "kody.yml");
12904
+ if (fs34.existsSync(workflowPath) && !force) {
12834
12905
  skipped.push(".github/workflows/kody.yml");
12835
12906
  } else {
12836
- fs33.mkdirSync(workflowDir, { recursive: true });
12837
- fs33.writeFileSync(workflowPath, WORKFLOW_TEMPLATE);
12907
+ fs34.mkdirSync(workflowDir, { recursive: true });
12908
+ fs34.writeFileSync(workflowPath, WORKFLOW_TEMPLATE);
12838
12909
  wrote.push(".github/workflows/kody.yml");
12839
12910
  }
12840
12911
  for (const exe of listExecutables()) {
@@ -12845,12 +12916,12 @@ function performInit(cwd, force) {
12845
12916
  continue;
12846
12917
  }
12847
12918
  if (profile.kind !== "scheduled" || !profile.schedule) continue;
12848
- const target = path32.join(workflowDir, `kody-${exe.name}.yml`);
12849
- if (fs33.existsSync(target) && !force) {
12919
+ const target = path33.join(workflowDir, `kody-${exe.name}.yml`);
12920
+ if (fs34.existsSync(target) && !force) {
12850
12921
  skipped.push(`.github/workflows/kody-${exe.name}.yml`);
12851
12922
  continue;
12852
12923
  }
12853
- fs33.writeFileSync(target, renderScheduledWorkflow(exe.name, profile.schedule));
12924
+ fs34.writeFileSync(target, renderScheduledWorkflow(exe.name, profile.schedule));
12854
12925
  wrote.push(`.github/workflows/kody-${exe.name}.yml`);
12855
12926
  }
12856
12927
  let labels;
@@ -12998,7 +13069,7 @@ Nothing to do. All files already present. (Use --force to overwrite.)
12998
13069
  });
12999
13070
 
13000
13071
  // src/scripts/loadAgentAdhoc.ts
13001
- import * as fs34 from "fs";
13072
+ import * as fs35 from "fs";
13002
13073
  function resolveMessage(messageArg) {
13003
13074
  const fromComment = readCommentBody();
13004
13075
  if (fromComment) return stripDirective(fromComment);
@@ -13006,9 +13077,9 @@ function resolveMessage(messageArg) {
13006
13077
  }
13007
13078
  function readCommentBody() {
13008
13079
  const eventPath = process.env.GITHUB_EVENT_PATH;
13009
- if (!eventPath || !fs34.existsSync(eventPath)) return "";
13080
+ if (!eventPath || !fs35.existsSync(eventPath)) return "";
13010
13081
  try {
13011
- const event = JSON.parse(fs34.readFileSync(eventPath, "utf-8"));
13082
+ const event = JSON.parse(fs35.readFileSync(eventPath, "utf-8"));
13012
13083
  return String(event.comment?.body ?? "");
13013
13084
  } catch {
13014
13085
  return "";
@@ -13061,10 +13132,10 @@ var init_loadAgentAdhoc = __esm({
13061
13132
  throw new Error("loadAgentAdhoc: ctx.args.agent must be a non-empty slug");
13062
13133
  }
13063
13134
  const agentPath = resolveAgentFile(ctx.cwd, agentSlug, agentsDir);
13064
- if (!fs34.existsSync(agentPath)) {
13135
+ if (!fs35.existsSync(agentPath)) {
13065
13136
  throw new Error(`loadAgentAdhoc: agent identity not found: ${agentPath}`);
13066
13137
  }
13067
- const { title, body } = parseAgentFile(fs34.readFileSync(agentPath, "utf-8"), agentSlug);
13138
+ const { title, body } = parseAgentFile(fs35.readFileSync(agentPath, "utf-8"), agentSlug);
13068
13139
  const message = resolveMessage(ctx.args.message);
13069
13140
  if (!message) {
13070
13141
  throw new Error(
@@ -13308,8 +13379,8 @@ var init_loadIssueStateComment = __esm({
13308
13379
  });
13309
13380
 
13310
13381
  // src/scripts/loadJobFromFile.ts
13311
- import * as fs35 from "fs";
13312
- import * as path33 from "path";
13382
+ import * as fs36 from "fs";
13383
+ import * as path34 from "path";
13313
13384
  function parseJobFile(raw, slug2) {
13314
13385
  let stripped = raw;
13315
13386
  if (stripped.startsWith("---\n")) {
@@ -13347,9 +13418,9 @@ var init_loadJobFromFile = __esm({
13347
13418
  if (!slug2) {
13348
13419
  throw new Error(`loadJobFromFile: ctx.args.${slugArg} must be a non-empty slug`);
13349
13420
  }
13350
- const capability = resolveCapabilityFolder(slug2, path33.join(ctx.cwd, jobsDir));
13421
+ const capability = resolveCapabilityFolder(slug2, path34.join(ctx.cwd, jobsDir));
13351
13422
  if (!capability) {
13352
- throw new Error(`loadJobFromFile: capability folder not found or incomplete: ${path33.join(ctx.cwd, jobsDir, slug2)}`);
13423
+ throw new Error(`loadJobFromFile: capability folder not found or incomplete: ${path34.join(ctx.cwd, jobsDir, slug2)}`);
13353
13424
  }
13354
13425
  const { title, body, config } = capability;
13355
13426
  const mentions = (config.mentions ?? []).map((login) => `@${login}`).join(" ");
@@ -13358,12 +13429,12 @@ var init_loadJobFromFile = __esm({
13358
13429
  let agentIdentity = "";
13359
13430
  if (agentSlug) {
13360
13431
  const agentPath = resolveAgentFile(ctx.cwd, agentSlug, agentsDir);
13361
- if (!fs35.existsSync(agentPath)) {
13432
+ if (!fs36.existsSync(agentPath)) {
13362
13433
  throw new Error(
13363
13434
  `loadJobFromFile: capability '${slug2}' declares agent '${agentSlug}' but ${agentPath} does not exist`
13364
13435
  );
13365
13436
  }
13366
- const agentRaw = fs35.readFileSync(agentPath, "utf-8");
13437
+ const agentRaw = fs36.readFileSync(agentPath, "utf-8");
13367
13438
  const parsed = parseJobFile(agentRaw, agentSlug);
13368
13439
  agentTitle = parsed.title;
13369
13440
  agentIdentity = parsed.body;
@@ -13443,13 +13514,13 @@ ${truncate(issue.body, FINDING_BODY_MAX_BYTES)}`;
13443
13514
  });
13444
13515
 
13445
13516
  // src/scripts/kodyVariables.ts
13446
- import * as fs36 from "fs";
13447
- import * as path34 from "path";
13517
+ import * as fs37 from "fs";
13518
+ import * as path35 from "path";
13448
13519
  function readKodyVariables(cwd) {
13449
- const full = path34.join(cwd, KODY_VARIABLES_REL_PATH);
13520
+ const full = path35.join(cwd, KODY_VARIABLES_REL_PATH);
13450
13521
  let raw;
13451
13522
  try {
13452
- raw = fs36.readFileSync(full, "utf-8");
13523
+ raw = fs37.readFileSync(full, "utf-8");
13453
13524
  } catch {
13454
13525
  return {};
13455
13526
  }
@@ -13517,8 +13588,8 @@ var init_keys = __esm({
13517
13588
  });
13518
13589
 
13519
13590
  // src/stateRepoGithub.ts
13520
- import * as fs37 from "fs";
13521
- import * as path35 from "path";
13591
+ import * as fs38 from "fs";
13592
+ import * as path36 from "path";
13522
13593
  function recordValue3(value) {
13523
13594
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
13524
13595
  }
@@ -13658,15 +13729,15 @@ function mergeJsonl(localText, remoteText) {
13658
13729
  async function syncJsonlFileFromGithubState(opts) {
13659
13730
  const remote = await readGithubStateTextWithConfig(opts);
13660
13731
  if (!remote) return;
13661
- const local = fs37.existsSync(opts.localPath) ? fs37.readFileSync(opts.localPath, "utf-8") : "";
13732
+ const local = fs38.existsSync(opts.localPath) ? fs38.readFileSync(opts.localPath, "utf-8") : "";
13662
13733
  const next = mergeJsonl(local, remote.content);
13663
13734
  if (next === local) return;
13664
- fs37.mkdirSync(path35.dirname(opts.localPath), { recursive: true });
13665
- fs37.writeFileSync(opts.localPath, next);
13735
+ fs38.mkdirSync(path36.dirname(opts.localPath), { recursive: true });
13736
+ fs38.writeFileSync(opts.localPath, next);
13666
13737
  }
13667
13738
  async function persistJsonlFileToGithubState(opts) {
13668
- if (!fs37.existsSync(opts.localPath)) return;
13669
- const localText = fs37.readFileSync(opts.localPath, "utf-8");
13739
+ if (!fs38.existsSync(opts.localPath)) return;
13740
+ const localText = fs38.readFileSync(opts.localPath, "utf-8");
13670
13741
  for (let attempt = 1; attempt <= 3; attempt += 1) {
13671
13742
  const remote = await readGithubStateTextWithConfig(opts);
13672
13743
  const body = mergeJsonl(localText, remote?.content ?? "");
@@ -13805,8 +13876,8 @@ var init_runtimeSecrets = __esm({
13805
13876
  });
13806
13877
 
13807
13878
  // src/scripts/loadQaContext.ts
13808
- import * as fs38 from "fs";
13809
- import * as path36 from "path";
13879
+ import * as fs39 from "fs";
13880
+ import * as path37 from "path";
13810
13881
  function parseSlugList(value) {
13811
13882
  const inner = value.startsWith("[") && value.endsWith("]") ? value.slice(1, -1) : value;
13812
13883
  return inner.split(",").map(
@@ -13835,18 +13906,18 @@ function readProfileAgents(raw) {
13835
13906
  return { agent: agent ?? legacy ?? ["kody"], body };
13836
13907
  }
13837
13908
  function readProfile(cwd) {
13838
- const dir = path36.join(cwd, CONTEXT_DIR_REL_PATH);
13839
- if (!fs38.existsSync(dir)) return "";
13909
+ const dir = path37.join(cwd, CONTEXT_DIR_REL_PATH);
13910
+ if (!fs39.existsSync(dir)) return "";
13840
13911
  let entries;
13841
13912
  try {
13842
- entries = fs38.readdirSync(dir).filter((f) => f.endsWith(".md")).sort();
13913
+ entries = fs39.readdirSync(dir).filter((f) => f.endsWith(".md")).sort();
13843
13914
  } catch {
13844
13915
  return "";
13845
13916
  }
13846
13917
  const blocks = [];
13847
13918
  for (const file of entries) {
13848
13919
  try {
13849
- const raw = fs38.readFileSync(path36.join(dir, file), "utf-8");
13920
+ const raw = fs39.readFileSync(path37.join(dir, file), "utf-8");
13850
13921
  const { agent, body } = readProfileAgents(raw);
13851
13922
  if (!agent.includes(QA_AGENT) && !agent.includes(ALL_AGENTS)) continue;
13852
13923
  blocks.push(`## ${file}
@@ -13895,8 +13966,8 @@ var init_loadQaContext = __esm({
13895
13966
  });
13896
13967
 
13897
13968
  // src/taskContext.ts
13898
- import * as fs39 from "fs";
13899
- import * as path37 from "path";
13969
+ import * as fs40 from "fs";
13970
+ import * as path38 from "path";
13900
13971
  function buildTaskContext(args) {
13901
13972
  return {
13902
13973
  schemaVersion: TASK_CONTEXT_SCHEMA_VERSION,
@@ -13912,9 +13983,9 @@ function buildTaskContext(args) {
13912
13983
  function persistTaskContext(cwd, ctx) {
13913
13984
  try {
13914
13985
  const dir = runtimeStatePath(cwd, "agent-runs", ctx.runId);
13915
- fs39.mkdirSync(dir, { recursive: true });
13916
- const file = path37.join(dir, "task-context.json");
13917
- fs39.writeFileSync(file, `${JSON.stringify(ctx, null, 2)}
13986
+ fs40.mkdirSync(dir, { recursive: true });
13987
+ const file = path38.join(dir, "task-context.json");
13988
+ fs40.writeFileSync(file, `${JSON.stringify(ctx, null, 2)}
13918
13989
  `);
13919
13990
  return file;
13920
13991
  } catch (err) {
@@ -16394,12 +16465,12 @@ fi
16394
16465
 
16395
16466
  // src/scripts/runPreviewBuild.ts
16396
16467
  import { copyFile, writeFile } from "fs/promises";
16397
- import * as path38 from "path";
16468
+ import * as path39 from "path";
16398
16469
  import { fileURLToPath } from "url";
16399
16470
  function bundledDockerfilePath(mode) {
16400
- const here = path38.dirname(fileURLToPath(import.meta.url));
16471
+ const here = path39.dirname(fileURLToPath(import.meta.url));
16401
16472
  const file = mode === "dev" ? "default-Dockerfile.preview.dev" : "default-Dockerfile.preview.prod";
16402
- return path38.join(here, "preview-build-templates", file);
16473
+ return path39.join(here, "preview-build-templates", file);
16403
16474
  }
16404
16475
  function required(name) {
16405
16476
  const v = (process.env[name] ?? "").trim();
@@ -16650,10 +16721,10 @@ var init_runPreviewBuild = __esm({
16650
16721
  console.log(`[preview-build] vault: ${Object.keys(buildEnv).length} secrets, mode=${buildMode}`);
16651
16722
  if (Object.keys(buildEnv).length > 0) {
16652
16723
  const lines = Object.entries(buildEnv).map(([k, v]) => `${k}=${JSON.stringify(v)}`);
16653
- await writeFile(path38.join(ctx.cwd, ".env.production.local"), `${lines.join("\n")}
16724
+ await writeFile(path39.join(ctx.cwd, ".env.production.local"), `${lines.join("\n")}
16654
16725
  `, "utf8");
16655
16726
  }
16656
- const consumerDockerfile = path38.join(ctx.cwd, "Dockerfile.preview");
16727
+ const consumerDockerfile = path39.join(ctx.cwd, "Dockerfile.preview");
16657
16728
  const { stat } = await import("fs/promises");
16658
16729
  let hasConsumerDockerfile = false;
16659
16730
  try {
@@ -16837,8 +16908,8 @@ var init_tickShellRunner = __esm({
16837
16908
  });
16838
16909
 
16839
16910
  // src/scripts/runScheduledExecutableTick.ts
16840
- import * as fs40 from "fs";
16841
- import * as path39 from "path";
16911
+ import * as fs41 from "fs";
16912
+ import * as path40 from "path";
16842
16913
  var runScheduledExecutableTick;
16843
16914
  var init_runScheduledExecutableTick = __esm({
16844
16915
  "src/scripts/runScheduledExecutableTick.ts"() {
@@ -16858,14 +16929,14 @@ var init_runScheduledExecutableTick = __esm({
16858
16929
  ctx.output.reason = `runScheduledExecutableTick: args.slug or ctx.args.${slugArg} must be non-empty capability slug`;
16859
16930
  return;
16860
16931
  }
16861
- const capability = resolveCapabilityFolder(slug2, path39.join(ctx.cwd, jobsDir));
16932
+ const capability = resolveCapabilityFolder(slug2, path40.join(ctx.cwd, jobsDir));
16862
16933
  if (!capability) {
16863
16934
  ctx.output.exitCode = 99;
16864
16935
  ctx.output.reason = `runScheduledExecutableTick: capability folder not found or incomplete: ${slug2} (searched ${jobsDir} and company store)`;
16865
16936
  return;
16866
16937
  }
16867
- const shellPath = path39.join(profile.dir, shell);
16868
- if (!fs40.existsSync(shellPath)) {
16938
+ const shellPath = path40.join(profile.dir, shell);
16939
+ if (!fs41.existsSync(shellPath)) {
16869
16940
  ctx.output.exitCode = 99;
16870
16941
  ctx.output.reason = `runScheduledExecutableTick: shell not found: ${shell} (looked in ${profile.dir})`;
16871
16942
  return;
@@ -16896,8 +16967,8 @@ var init_runScheduledExecutableTick = __esm({
16896
16967
  });
16897
16968
 
16898
16969
  // src/scripts/runTickScript.ts
16899
- import * as fs41 from "fs";
16900
- import * as path40 from "path";
16970
+ import * as fs42 from "fs";
16971
+ import * as path41 from "path";
16901
16972
  var runTickScript;
16902
16973
  var init_runTickScript = __esm({
16903
16974
  "src/scripts/runTickScript.ts"() {
@@ -16916,10 +16987,10 @@ var init_runTickScript = __esm({
16916
16987
  ctx.output.reason = `runTickScript: ctx.args.${slugArg} must be a non-empty slug`;
16917
16988
  return;
16918
16989
  }
16919
- const capability = readCapabilityFolder(path40.join(ctx.cwd, jobsDir), slug2);
16990
+ const capability = readCapabilityFolder(path41.join(ctx.cwd, jobsDir), slug2);
16920
16991
  if (!capability) {
16921
16992
  ctx.output.exitCode = 99;
16922
- ctx.output.reason = `runTickScript: capability folder not found or incomplete: ${path40.join(ctx.cwd, jobsDir, slug2)}`;
16993
+ ctx.output.reason = `runTickScript: capability folder not found or incomplete: ${path41.join(ctx.cwd, jobsDir, slug2)}`;
16923
16994
  return;
16924
16995
  }
16925
16996
  const tickScript = capability.config.tickScript;
@@ -16928,8 +16999,8 @@ var init_runTickScript = __esm({
16928
16999
  ctx.output.reason = `runTickScript: capability ${slug2} has no \`tickScript\` in profile.json \u2014 route via capability-tick instead`;
16929
17000
  return;
16930
17001
  }
16931
- const scriptPath = path40.isAbsolute(tickScript) ? tickScript : path40.join(ctx.cwd, tickScript);
16932
- if (!fs41.existsSync(scriptPath)) {
17002
+ const scriptPath = path41.isAbsolute(tickScript) ? tickScript : path41.join(ctx.cwd, tickScript);
17003
+ if (!fs42.existsSync(scriptPath)) {
16933
17004
  ctx.output.exitCode = 99;
16934
17005
  ctx.output.reason = `runTickScript: tickScript not found: ${scriptPath}`;
16935
17006
  return;
@@ -17752,7 +17823,7 @@ var init_warmupMcp = __esm({
17752
17823
  });
17753
17824
 
17754
17825
  // src/scripts/writeAgentRunSummary.ts
17755
- import * as fs42 from "fs";
17826
+ import * as fs43 from "fs";
17756
17827
  var writeAgentRunSummary;
17757
17828
  var init_writeAgentRunSummary = __esm({
17758
17829
  "src/scripts/writeAgentRunSummary.ts"() {
@@ -17778,7 +17849,7 @@ var init_writeAgentRunSummary = __esm({
17778
17849
  if (reason) lines.push(`- **Reason:** ${reason}`);
17779
17850
  lines.push("");
17780
17851
  try {
17781
- fs42.appendFileSync(summaryPath, `${lines.join("\n")}
17852
+ fs43.appendFileSync(summaryPath, `${lines.join("\n")}
17782
17853
  `);
17783
17854
  } catch {
17784
17855
  }
@@ -18100,53 +18171,53 @@ var init_scripts = __esm({
18100
18171
  // src/stateWorkspace.ts
18101
18172
  import { execFileSync as execFileSync24 } from "child_process";
18102
18173
  import * as crypto3 from "crypto";
18103
- import * as fs43 from "fs";
18174
+ import * as fs44 from "fs";
18104
18175
  import * as os7 from "os";
18105
- import * as path41 from "path";
18176
+ import * as path42 from "path";
18106
18177
  function writeLocalFile(cwd, relativePath, content) {
18107
- const fullPath = path41.join(cwd, relativePath);
18108
- fs43.mkdirSync(path41.dirname(fullPath), { recursive: true });
18109
- fs43.writeFileSync(fullPath, content);
18178
+ const fullPath = path42.join(cwd, relativePath);
18179
+ fs44.mkdirSync(path42.dirname(fullPath), { recursive: true });
18180
+ fs44.writeFileSync(fullPath, content);
18110
18181
  }
18111
18182
  function copyPath(source, target) {
18112
- const st = fs43.lstatSync(source);
18113
- fs43.rmSync(target, { recursive: true, force: true });
18183
+ const st = fs44.lstatSync(source);
18184
+ fs44.rmSync(target, { recursive: true, force: true });
18114
18185
  if (st.isSymbolicLink()) return;
18115
- fs43.mkdirSync(path41.dirname(target), { recursive: true });
18116
- fs43.cpSync(source, target, { recursive: true, force: true });
18186
+ fs44.mkdirSync(path42.dirname(target), { recursive: true });
18187
+ fs44.cpSync(source, target, { recursive: true, force: true });
18117
18188
  }
18118
18189
  function overlayDirectoryChildren(cwd, sourceDir, localDir) {
18119
- if (!fs43.existsSync(sourceDir)) return;
18120
- for (const entry of fs43.readdirSync(sourceDir, { withFileTypes: true })) {
18121
- const source = path41.join(sourceDir, entry.name);
18122
- const target = path41.join(cwd, localDir, entry.name);
18190
+ if (!fs44.existsSync(sourceDir)) return;
18191
+ for (const entry of fs44.readdirSync(sourceDir, { withFileTypes: true })) {
18192
+ const source = path42.join(sourceDir, entry.name);
18193
+ const target = path42.join(cwd, localDir, entry.name);
18123
18194
  copyPath(source, target);
18124
18195
  }
18125
18196
  }
18126
18197
  function hydrateStateWorkspace(config, cwd) {
18127
18198
  if (process.env.VITEST && process.env[TEST_FETCH_ENV] !== "1") return;
18128
18199
  const parsed = parseStateRepo(config);
18129
- const hydrateKey = `${path41.resolve(cwd)}|${parsed.owner}/${parsed.repo}|${parsed.basePath}|${parsed.branch}`;
18200
+ const hydrateKey = `${path42.resolve(cwd)}|${parsed.owner}/${parsed.repo}|${parsed.basePath}|${parsed.branch}`;
18130
18201
  if (hydratedWorkspaces.has(hydrateKey)) return;
18131
18202
  const snapshotRoot = fetchStateSnapshot(parsed);
18132
18203
  for (const mapping of DIR_MAPPINGS) {
18133
- overlayDirectoryChildren(cwd, path41.join(snapshotRoot, mapping.stateDir), mapping.localDir);
18204
+ overlayDirectoryChildren(cwd, path42.join(snapshotRoot, mapping.stateDir), mapping.localDir);
18134
18205
  }
18135
18206
  for (const mapping of FILE_MAPPINGS) {
18136
- const source = path41.join(snapshotRoot, mapping.statePath);
18137
- if (fs43.existsSync(source) && !fs43.lstatSync(source).isSymbolicLink() && fs43.statSync(source).isFile()) {
18138
- writeLocalFile(cwd, mapping.localPath, fs43.readFileSync(source, "utf-8"));
18207
+ const source = path42.join(snapshotRoot, mapping.statePath);
18208
+ if (fs44.existsSync(source) && !fs44.lstatSync(source).isSymbolicLink() && fs44.statSync(source).isFile()) {
18209
+ writeLocalFile(cwd, mapping.localPath, fs44.readFileSync(source, "utf-8"));
18139
18210
  }
18140
18211
  }
18141
18212
  hydratedWorkspaces.add(hydrateKey);
18142
18213
  }
18143
18214
  function fetchStateSnapshot(parsed) {
18144
- const cacheDir = path41.join(cacheRoot2(), cacheKey3(parsed));
18215
+ const cacheDir = path42.join(cacheRoot2(), cacheKey3(parsed));
18145
18216
  const url = `https://github.com/${parsed.owner}/${parsed.repo}.git`;
18146
18217
  try {
18147
- fs43.mkdirSync(path41.dirname(cacheDir), { recursive: true });
18148
- if (!fs43.existsSync(path41.join(cacheDir, ".git"))) {
18149
- fs43.rmSync(cacheDir, { recursive: true, force: true });
18218
+ fs44.mkdirSync(path42.dirname(cacheDir), { recursive: true });
18219
+ if (!fs44.existsSync(path42.join(cacheDir, ".git"))) {
18220
+ fs44.rmSync(cacheDir, { recursive: true, force: true });
18150
18221
  runGit3(["clone", "--no-checkout", "--filter=blob:none", url, cacheDir]);
18151
18222
  }
18152
18223
  runGit3(["-C", cacheDir, "remote", "set-url", "origin", url]);
@@ -18161,10 +18232,10 @@ function fetchStateSnapshot(parsed) {
18161
18232
  `stateWorkspace: failed to fetch ${parsed.owner}/${parsed.repo}:${parsed.basePath}@${parsed.branch}: ${msg}`
18162
18233
  );
18163
18234
  }
18164
- return path41.join(cacheDir, parsed.basePath);
18235
+ return path42.join(cacheDir, parsed.basePath);
18165
18236
  }
18166
18237
  function cacheRoot2() {
18167
- return process.env[CACHE_ENV2]?.trim() || path41.join(os7.homedir(), ".cache", "kody", "state-repo");
18238
+ return process.env[CACHE_ENV2]?.trim() || path42.join(os7.homedir(), ".cache", "kody", "state-repo");
18168
18239
  }
18169
18240
  function cacheKey3(parsed) {
18170
18241
  return crypto3.createHash("sha256").update(`${parsed.owner}/${parsed.repo}#${parsed.branch}#${parsed.basePath}`).digest("hex").slice(0, 24);
@@ -18204,15 +18275,15 @@ var init_stateWorkspace = __esm({
18204
18275
  "use strict";
18205
18276
  init_stateRepo();
18206
18277
  DIR_MAPPINGS = [
18207
- { stateDir: "capabilities", localDir: path41.join(".kody", "capabilities") },
18208
- { stateDir: "agents", localDir: path41.join(".kody", "agents") },
18209
- { stateDir: "context", localDir: path41.join(".kody", "context") },
18210
- { stateDir: "memory", localDir: path41.join(".kody", "memory") }
18278
+ { stateDir: "capabilities", localDir: path42.join(".kody", "capabilities") },
18279
+ { stateDir: "agents", localDir: path42.join(".kody", "agents") },
18280
+ { stateDir: "context", localDir: path42.join(".kody", "context") },
18281
+ { stateDir: "memory", localDir: path42.join(".kody", "memory") }
18211
18282
  ];
18212
18283
  FILE_MAPPINGS = [
18213
- { statePath: "instructions.md", localPath: path41.join(".kody", "instructions.md") },
18214
- { statePath: "variables.json", localPath: path41.join(".kody", "variables.json") },
18215
- { statePath: "secrets.enc", localPath: path41.join(".kody", "secrets.enc") }
18284
+ { statePath: "instructions.md", localPath: path42.join(".kody", "instructions.md") },
18285
+ { statePath: "variables.json", localPath: path42.join(".kody", "variables.json") },
18286
+ { statePath: "secrets.enc", localPath: path42.join(".kody", "secrets.enc") }
18216
18287
  ];
18217
18288
  CACHE_ENV2 = "KODY_STATE_REPO_CACHE";
18218
18289
  TEST_FETCH_ENV = "KODY_STATE_WORKSPACE_FETCH_FOR_TESTS";
@@ -18286,8 +18357,8 @@ var init_tools = __esm({
18286
18357
 
18287
18358
  // src/executor.ts
18288
18359
  import { spawn as spawn7 } from "child_process";
18289
- import * as fs44 from "fs";
18290
- import * as path42 from "path";
18360
+ import * as fs45 from "fs";
18361
+ import * as path43 from "path";
18291
18362
  function isMutatingPostflight(scriptName) {
18292
18363
  return MUTATING_POSTFLIGHTS.has(scriptName ?? "");
18293
18364
  }
@@ -18468,7 +18539,7 @@ async function runExecutable(profileName, input) {
18468
18539
  const jobWhyBlock = typeof ctx.data.jobWhy === "string" ? operatorRequestBlock(ctx.data.jobWhy) : null;
18469
18540
  const jobRefBlock = jobReferenceBlock(profileName, profile, ctx.data);
18470
18541
  const invokeAgent = async (prompt) => {
18471
- const externalPlugins = (profile.claudeCode.plugins ?? []).map((p) => path42.isAbsolute(p) ? p : path42.resolve(profile.dir, p)).filter((p) => p.length > 0);
18542
+ const externalPlugins = (profile.claudeCode.plugins ?? []).map((p) => path43.isAbsolute(p) ? p : path43.resolve(profile.dir, p)).filter((p) => p.length > 0);
18472
18543
  const syntheticPath = ctx.data.syntheticPluginPath;
18473
18544
  const pluginPaths = [...externalPlugins, ...syntheticPath ? [syntheticPath] : []];
18474
18545
  const agents = loadSubagents(profile);
@@ -18861,17 +18932,17 @@ function clearStampedLifecycleLabels(profile, ctx) {
18861
18932
  function resolveProfilePath(profileName) {
18862
18933
  const found = resolveExecutable(profileName);
18863
18934
  if (found) return found;
18864
- const here = path42.dirname(new URL(import.meta.url).pathname);
18935
+ const here = path43.dirname(new URL(import.meta.url).pathname);
18865
18936
  const candidates = [
18866
- path42.join(here, "executables", profileName, "profile.json"),
18937
+ path43.join(here, "executables", profileName, "profile.json"),
18867
18938
  // same-dir sibling (dev)
18868
- path42.join(here, "..", "executables", profileName, "profile.json"),
18939
+ path43.join(here, "..", "executables", profileName, "profile.json"),
18869
18940
  // up one (prod: dist/bin → dist/executables)
18870
- path42.join(here, "..", "src", "executables", profileName, "profile.json")
18941
+ path43.join(here, "..", "src", "executables", profileName, "profile.json")
18871
18942
  // fallback
18872
18943
  ];
18873
18944
  for (const c of candidates) {
18874
- if (fs44.existsSync(c)) return c;
18945
+ if (fs45.existsSync(c)) return c;
18875
18946
  }
18876
18947
  return candidates[0];
18877
18948
  }
@@ -18986,8 +19057,8 @@ function resolveShellTimeoutMs(entry) {
18986
19057
  }
18987
19058
  async function runShellEntry(entry, ctx, profile) {
18988
19059
  const shellName = entry.shell;
18989
- const shellPath = path42.join(profile.dir, shellName);
18990
- if (!fs44.existsSync(shellPath)) {
19060
+ const shellPath = path43.join(profile.dir, shellName);
19061
+ if (!fs45.existsSync(shellPath)) {
18991
19062
  ctx.skipAgent = true;
18992
19063
  ctx.output.exitCode = 99;
18993
19064
  ctx.output.reason = `shell script not found: ${shellName} (looked in ${profile.dir})`;
@@ -19137,8 +19208,8 @@ var init_executor = __esm({
19137
19208
  });
19138
19209
 
19139
19210
  // src/workflowDefinitions.ts
19140
- import * as fs45 from "fs";
19141
- import * as path43 from "path";
19211
+ import * as fs46 from "fs";
19212
+ import * as path44 from "path";
19142
19213
  function isWorkflowDefinitionId(value) {
19143
19214
  return WORKFLOW_ID_PATTERN.test(value);
19144
19215
  }
@@ -19152,13 +19223,11 @@ function normalizeWorkflowDefinition(value) {
19152
19223
  if (!value || typeof value !== "object" || Array.isArray(value)) return null;
19153
19224
  const raw = value;
19154
19225
  const name = typeof raw.name === "string" ? raw.name.trim() : "";
19155
- const instructions = typeof raw.instructions === "string" ? raw.instructions.trim() : "";
19156
19226
  const capabilities = normalizeWorkflowCapabilities(raw.capabilities);
19157
- if (!name || !instructions || capabilities.length === 0) return null;
19227
+ if (!name || capabilities.length === 0) return null;
19158
19228
  return {
19159
19229
  version: 1,
19160
19230
  name,
19161
- instructions,
19162
19231
  capabilities,
19163
19232
  ...typeof raw.createdAt === "string" ? { createdAt: raw.createdAt } : {},
19164
19233
  ...typeof raw.updatedAt === "string" ? { updatedAt: raw.updatedAt } : {}
@@ -19172,17 +19241,17 @@ function readWorkflowDefinition(config, cwd, id) {
19172
19241
  function workflowDefinitionToCapabilityFolder(id, workflow, source = workflowDefinitionPath(id)) {
19173
19242
  return {
19174
19243
  slug: id,
19175
- dir: path43.dirname(source),
19244
+ dir: path44.dirname(source),
19176
19245
  profilePath: source,
19177
19246
  bodyPath: source,
19178
19247
  title: workflow.name,
19179
- body: workflow.instructions,
19180
- rawBody: workflow.instructions,
19248
+ body: "",
19249
+ rawBody: "",
19181
19250
  rawProfile: { name: id, workflow },
19182
19251
  config: {
19183
19252
  action: id,
19184
19253
  workflow: workflowDefinitionToConfig(workflow),
19185
- describe: workflow.instructions
19254
+ describe: workflow.name
19186
19255
  }
19187
19256
  };
19188
19257
  }
@@ -19207,9 +19276,9 @@ function workflowDefinitionToConfig(workflow) {
19207
19276
  function readCompanyStoreWorkflowDefinition(id) {
19208
19277
  const root = getCompanyStoreAssetRoot("workflows");
19209
19278
  if (!root) return null;
19210
- const filePath = path43.join(root, id, "workflow.json");
19211
- if (!fs45.existsSync(filePath)) return null;
19212
- return parseWorkflowDefinition(fs45.readFileSync(filePath, "utf8"));
19279
+ const filePath = path44.join(root, id, "workflow.json");
19280
+ if (!fs46.existsSync(filePath)) return null;
19281
+ return parseWorkflowDefinition(fs46.readFileSync(filePath, "utf8"));
19213
19282
  }
19214
19283
  function parseWorkflowDefinition(content) {
19215
19284
  try {
@@ -19241,7 +19310,7 @@ __export(job_exports, {
19241
19310
  stableJobKey: () => stableJobKey,
19242
19311
  validateJob: () => validateJob
19243
19312
  });
19244
- import * as path44 from "path";
19313
+ import * as path45 from "path";
19245
19314
  function newJobId(flavor) {
19246
19315
  localJobSeq += 1;
19247
19316
  const runId = process.env.GITHUB_RUN_ID;
@@ -19293,7 +19362,7 @@ function parseCapabilityResultTarget(raw) {
19293
19362
  async function runJob(job, base) {
19294
19363
  const valid = validateJob(job);
19295
19364
  const action = valid.action ?? valid.capability;
19296
- const projectCapabilitiesRoot = path44.join(base.cwd, ".kody", "capabilities");
19365
+ const projectCapabilitiesRoot = path45.join(base.cwd, ".kody", "capabilities");
19297
19366
  const resolvedCapability = !valid.workflow && action ? resolveCapabilityAction(action, projectCapabilitiesRoot) : null;
19298
19367
  const capabilityIdentity = valid.capability ?? resolvedCapability?.capability;
19299
19368
  const capabilityContext = valid.workflow ? null : loadCapabilityContext(capabilityIdentity, base.cwd);
@@ -19306,7 +19375,7 @@ async function runJob(job, base) {
19306
19375
  }
19307
19376
  const workflow = capabilityContext?.config.workflow ?? workflowContext?.config.workflow;
19308
19377
  const workflowIdentity = valid.workflow ?? capabilityIdentity ?? workflowContext?.slug;
19309
- const capabilitySelectedExecutable = resolvedCapability?.executable ?? capabilityContext?.config.executable ?? capabilityContext?.config.executables?.[0] ?? (capabilityContext?.config.role ? capabilityContext.slug : void 0) ?? (capabilityContext?.config.tickScript ? "capability-tick-scripted" : void 0);
19378
+ const capabilitySelectedExecutable = resolvedCapability?.executable ?? capabilityContext?.config.implementation ?? capabilityContext?.config.executable ?? capabilityContext?.config.executables?.[0] ?? (capabilityContext?.config.role ? capabilityContext.slug : void 0) ?? (capabilityContext?.config.tickScript ? "capability-tick-scripted" : void 0);
19310
19379
  const profileName = valid.executable ?? capabilitySelectedExecutable;
19311
19380
  if (workflow && shouldRunCapabilityWorkflow(valid, workflow, workflowIdentity, capabilitySelectedExecutable, base)) {
19312
19381
  const workflowCapability = capabilityContext ?? workflowContext;
@@ -19479,7 +19548,7 @@ function shouldRunWorkflowStep(step, data) {
19479
19548
  if (!step.runWhen) return true;
19480
19549
  const context = workflowConditionContext(data);
19481
19550
  return Object.entries(step.runWhen).every(
19482
- ([path50, expected]) => valueMatches(resolveDottedPath2(context, path50), expected)
19551
+ ([path51, expected]) => valueMatches(resolveDottedPath2(context, path51), expected)
19483
19552
  );
19484
19553
  }
19485
19554
  function canContinueWorkflow(step, outcome) {
@@ -19549,7 +19618,7 @@ function composeStepWhy(parentWhy, step) {
19549
19618
  }
19550
19619
  function loadCapabilityContext(slug2, cwd) {
19551
19620
  if (!slug2) return null;
19552
- return resolveCapabilityFolder(slug2, path44.join(cwd, ".kody", "capabilities"));
19621
+ return resolveCapabilityFolder(slug2, path45.join(cwd, ".kody", "capabilities"));
19553
19622
  }
19554
19623
  function loadWorkflowContext(slug2, base) {
19555
19624
  if (!slug2 || !base.config || !isWorkflowDefinitionId(slug2)) return null;
@@ -19707,9 +19776,9 @@ function translateOpenAISseToBrain(opts) {
19707
19776
  }
19708
19777
 
19709
19778
  // src/servers/brain-serve.ts
19710
- import * as fs48 from "fs";
19779
+ import * as fs49 from "fs";
19711
19780
  import { createServer as createServer2 } from "http";
19712
- import * as path47 from "path";
19781
+ import * as path48 from "path";
19713
19782
 
19714
19783
  // src/chat/loop.ts
19715
19784
  init_agent();
@@ -20385,8 +20454,8 @@ init_config();
20385
20454
 
20386
20455
  // src/kody-cli.ts
20387
20456
  import { execFileSync as execFileSync26 } from "child_process";
20388
- import * as fs46 from "fs";
20389
- import * as path45 from "path";
20457
+ import * as fs47 from "fs";
20458
+ import * as path46 from "path";
20390
20459
 
20391
20460
  // src/app-auth.ts
20392
20461
  import { createSign } from "crypto";
@@ -20889,6 +20958,7 @@ init_gha();
20889
20958
  init_issue();
20890
20959
  init_job();
20891
20960
  init_lifecycleLabels();
20961
+ init_companyStore();
20892
20962
  init_registry();
20893
20963
 
20894
20964
  // src/run-request.ts
@@ -20959,6 +21029,9 @@ var FAILED_DISPATCH_LABEL = {
20959
21029
  color: "e11d21",
20960
21030
  description: "Kody failed or rejected the run"
20961
21031
  };
21032
+ function objectValue2(value) {
21033
+ return value && typeof value === "object" ? value : void 0;
21034
+ }
20962
21035
  var CI_HELP = `kody ci \u2014 minimal-YAML autonomous engineer (CI preflight + run)
20963
21036
 
20964
21037
  Usage:
@@ -21116,9 +21189,9 @@ async function resolveAuthToken(env = process.env) {
21116
21189
  return void 0;
21117
21190
  }
21118
21191
  function detectPackageManager2(cwd) {
21119
- if (fs46.existsSync(path45.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
21120
- if (fs46.existsSync(path45.join(cwd, "yarn.lock"))) return "yarn";
21121
- if (fs46.existsSync(path45.join(cwd, "bun.lockb"))) return "bun";
21192
+ if (fs47.existsSync(path46.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
21193
+ if (fs47.existsSync(path46.join(cwd, "yarn.lock"))) return "yarn";
21194
+ if (fs47.existsSync(path46.join(cwd, "bun.lockb"))) return "bun";
21122
21195
  return "npm";
21123
21196
  }
21124
21197
  function shouldChainScheduledWatch(match) {
@@ -21211,8 +21284,8 @@ function postFailureTail(issueNumber, cwd, reason) {
21211
21284
  const logPath = lastRunLogPath(cwd);
21212
21285
  let tail = "";
21213
21286
  try {
21214
- if (fs46.existsSync(logPath)) {
21215
- const content = fs46.readFileSync(logPath, "utf-8");
21287
+ if (fs47.existsSync(logPath)) {
21288
+ const content = fs47.readFileSync(logPath, "utf-8");
21216
21289
  tail = content.slice(-3e3);
21217
21290
  }
21218
21291
  } catch {
@@ -21241,7 +21314,7 @@ async function runCi(argv) {
21241
21314
  return 0;
21242
21315
  }
21243
21316
  const args = parseCiArgs(argv);
21244
- const cwd = args.cwd ? path45.resolve(args.cwd) : process.cwd();
21317
+ const cwd = args.cwd ? path46.resolve(args.cwd) : process.cwd();
21245
21318
  let earlyConfig;
21246
21319
  let earlyConfigError;
21247
21320
  try {
@@ -21264,6 +21337,9 @@ async function runCi(argv) {
21264
21337
  `);
21265
21338
  return 64;
21266
21339
  }
21340
+ if (parsedRunRequest && "request" in parsedRunRequest) {
21341
+ applyCompanyStoreRuntimeConfig(parsedRunRequest.request.input);
21342
+ }
21267
21343
  if (!args.issueNumber && !autoFallback && parsedRunRequest && "request" in parsedRunRequest) {
21268
21344
  const route = routeRunRequest(parsedRunRequest.request);
21269
21345
  if (route.kind === "error") {
@@ -21287,13 +21363,15 @@ async function runCi(argv) {
21287
21363
  forceRunCliArgs = { goal: envForceMessage };
21288
21364
  }
21289
21365
  }
21290
- if (!args.issueNumber && !autoFallback && !forceRunAction && !runRequestFanOut && eventName === "workflow_dispatch" && dispatchEventPath && fs46.existsSync(dispatchEventPath)) {
21366
+ if (!args.issueNumber && !autoFallback && !forceRunAction && !runRequestFanOut && eventName === "workflow_dispatch" && dispatchEventPath && fs47.existsSync(dispatchEventPath)) {
21291
21367
  try {
21292
- const evt = JSON.parse(fs46.readFileSync(dispatchEventPath, "utf-8"));
21293
- const issueInput = parseInt(String(evt?.inputs?.issue_number ?? ""), 10);
21294
- const sessionInput = String(evt?.inputs?.sessionId ?? "");
21295
- const capabilityInput = String(evt?.inputs?.capability ?? evt?.inputs?.executable ?? "").trim();
21296
- const messageInput = String(evt?.inputs?.message ?? "").trim();
21368
+ const evt = JSON.parse(fs47.readFileSync(dispatchEventPath, "utf-8"));
21369
+ const inputs = objectValue2(evt.inputs);
21370
+ applyCompanyStoreRuntimeConfig(inputs);
21371
+ const issueInput = parseInt(String(inputs?.issue_number ?? ""), 10);
21372
+ const sessionInput = String(inputs?.sessionId ?? "");
21373
+ const capabilityInput = String(inputs?.capability ?? inputs?.executable ?? "").trim();
21374
+ const messageInput = String(inputs?.message ?? "").trim();
21297
21375
  const noTarget = !sessionInput && !(Number.isFinite(issueInput) && issueInput > 0);
21298
21376
  if (noTarget && capabilityInput) {
21299
21377
  forceRunAction = capabilityInput;
@@ -21651,8 +21729,8 @@ init_repoWorkspace();
21651
21729
 
21652
21730
  // src/scripts/brainTurnLog.ts
21653
21731
  init_runtimePaths();
21654
- import * as fs47 from "fs";
21655
- import * as path46 from "path";
21732
+ import * as fs48 from "fs";
21733
+ import * as path47 from "path";
21656
21734
  import posixPath4 from "path/posix";
21657
21735
  var live = /* @__PURE__ */ new Map();
21658
21736
  function brainEventsFilePath(dir, chatId) {
@@ -21663,8 +21741,8 @@ function brainEventsStatePath(chatId) {
21663
21741
  }
21664
21742
  function lastPersistedSeq(dir, chatId) {
21665
21743
  const p = brainEventsFilePath(dir, chatId);
21666
- if (!fs47.existsSync(p)) return 0;
21667
- const lines = fs47.readFileSync(p, "utf-8").split("\n").filter(Boolean);
21744
+ if (!fs48.existsSync(p)) return 0;
21745
+ const lines = fs48.readFileSync(p, "utf-8").split("\n").filter(Boolean);
21668
21746
  if (lines.length === 0) return 0;
21669
21747
  try {
21670
21748
  return JSON.parse(lines[lines.length - 1]).seq || 0;
@@ -21674,9 +21752,9 @@ function lastPersistedSeq(dir, chatId) {
21674
21752
  }
21675
21753
  function readSince(dir, chatId, since) {
21676
21754
  const p = brainEventsFilePath(dir, chatId);
21677
- if (!fs47.existsSync(p)) return [];
21755
+ if (!fs48.existsSync(p)) return [];
21678
21756
  const out = [];
21679
- for (const line of fs47.readFileSync(p, "utf-8").split("\n")) {
21757
+ for (const line of fs48.readFileSync(p, "utf-8").split("\n")) {
21680
21758
  if (!line) continue;
21681
21759
  try {
21682
21760
  const rec = JSON.parse(line);
@@ -21702,12 +21780,12 @@ function beginTurn(dir, chatId) {
21702
21780
  };
21703
21781
  live.set(chatId, state);
21704
21782
  const p = brainEventsFilePath(dir, chatId);
21705
- fs47.mkdirSync(path46.dirname(p), { recursive: true });
21783
+ fs48.mkdirSync(path47.dirname(p), { recursive: true });
21706
21784
  return (event) => {
21707
21785
  state.seq += 1;
21708
21786
  const rec = { seq: state.seq, turn, ts: Date.now(), event };
21709
21787
  try {
21710
- fs47.appendFileSync(p, `${JSON.stringify(rec)}
21788
+ fs48.appendFileSync(p, `${JSON.stringify(rec)}
21711
21789
  `);
21712
21790
  } catch (err) {
21713
21791
  process.stderr.write(
@@ -21746,7 +21824,7 @@ function endTurnIfUnterminated(dir, chatId, errMessage) {
21746
21824
  event: { type: "error", error: errMessage || "turn ended unexpectedly", chatId }
21747
21825
  };
21748
21826
  try {
21749
- fs47.appendFileSync(brainEventsFilePath(dir, chatId), `${JSON.stringify(rec)}
21827
+ fs48.appendFileSync(brainEventsFilePath(dir, chatId), `${JSON.stringify(rec)}
21750
21828
  `);
21751
21829
  } catch {
21752
21830
  }
@@ -22070,7 +22148,7 @@ async function handleChatTurn(req, res, chatId, opts) {
22070
22148
  );
22071
22149
  }
22072
22150
  }
22073
- fs48.mkdirSync(path47.dirname(sessionFile), { recursive: true });
22151
+ fs49.mkdirSync(path48.dirname(sessionFile), { recursive: true });
22074
22152
  appendTurn(sessionFile, {
22075
22153
  role: "user",
22076
22154
  content: message,
@@ -22145,7 +22223,7 @@ async function handleChatTurn(req, res, chatId, opts) {
22145
22223
  function buildServer(opts) {
22146
22224
  const runTurn = opts.runTurn ?? runChatTurn;
22147
22225
  const cloneRepo = opts.cloneRepo ?? defaultCloneRepo;
22148
- const reposRoot = opts.reposRoot ?? path47.join(path47.dirname(path47.resolve(opts.cwd)), "repos");
22226
+ const reposRoot = opts.reposRoot ?? path48.join(path48.dirname(path48.resolve(opts.cwd)), "repos");
22149
22227
  return createServer2(async (req, res) => {
22150
22228
  if (!req.method || !req.url) {
22151
22229
  sendJson(res, 400, { error: "bad request" });
@@ -22748,8 +22826,8 @@ async function loadConfigSafe() {
22748
22826
  }
22749
22827
 
22750
22828
  // src/chat-cli.ts
22751
- import * as fs50 from "fs";
22752
- import * as path49 from "path";
22829
+ import * as fs51 from "fs";
22830
+ import * as path50 from "path";
22753
22831
 
22754
22832
  // src/chat/inbox.ts
22755
22833
  import { execFileSync as execFileSync27 } from "child_process";
@@ -22821,8 +22899,8 @@ function currentBranch(cwd) {
22821
22899
 
22822
22900
  // src/chat/state-sync.ts
22823
22901
  init_stateRepo();
22824
- import * as fs49 from "fs";
22825
- import * as path48 from "path";
22902
+ import * as fs50 from "fs";
22903
+ import * as path49 from "path";
22826
22904
  function jsonlLines2(text) {
22827
22905
  return text.split("\n").filter((line) => line.length > 0);
22828
22906
  }
@@ -22839,15 +22917,15 @@ function mergeJsonl2(localText, remoteText) {
22839
22917
  function syncJsonlFileFromState(opts) {
22840
22918
  const remote = readStateText(opts.config, opts.cwd, opts.statePath);
22841
22919
  if (!remote) return;
22842
- const local = fs49.existsSync(opts.localPath) ? fs49.readFileSync(opts.localPath, "utf-8") : "";
22920
+ const local = fs50.existsSync(opts.localPath) ? fs50.readFileSync(opts.localPath, "utf-8") : "";
22843
22921
  const next = mergeJsonl2(local, remote.content);
22844
22922
  if (next === local) return;
22845
- fs49.mkdirSync(path48.dirname(opts.localPath), { recursive: true });
22846
- fs49.writeFileSync(opts.localPath, next);
22923
+ fs50.mkdirSync(path49.dirname(opts.localPath), { recursive: true });
22924
+ fs50.writeFileSync(opts.localPath, next);
22847
22925
  }
22848
22926
  function persistJsonlFileToState(opts) {
22849
- if (!fs49.existsSync(opts.localPath)) return;
22850
- const localText = fs49.readFileSync(opts.localPath, "utf-8");
22927
+ if (!fs50.existsSync(opts.localPath)) return;
22928
+ const localText = fs50.readFileSync(opts.localPath, "utf-8");
22851
22929
  for (let attempt = 1; attempt <= 3; attempt += 1) {
22852
22930
  const remote = readStateText(opts.config, opts.cwd, opts.statePath);
22853
22931
  const body = mergeJsonl2(localText, remote?.content ?? "");
@@ -23031,6 +23109,7 @@ async function emit2(sink, type, sessionId, suffix, payload) {
23031
23109
  init_config();
23032
23110
  init_litellm();
23033
23111
  init_stateWorkspace();
23112
+ init_companyStore();
23034
23113
  var DEFAULT_MODEL2 = "claude/claude-haiku-4-5-20251001";
23035
23114
  var CHAT_HELP = `kody chat \u2014 dashboard-driven chat session
23036
23115
 
@@ -23111,8 +23190,12 @@ async function runChat(argv) {
23111
23190
  ${CHAT_HELP}`);
23112
23191
  return 64;
23113
23192
  }
23114
- const cwd = args.cwd ? path49.resolve(args.cwd) : process.cwd();
23193
+ const cwd = args.cwd ? path50.resolve(args.cwd) : process.cwd();
23115
23194
  const sessionId = args.sessionId;
23195
+ const runRequest = readRunRequestFromEnv();
23196
+ if (runRequest && "request" in runRequest) {
23197
+ applyCompanyStoreRuntimeConfig(runRequest.request.input);
23198
+ }
23116
23199
  const unpackedSecrets = unpackAllSecrets();
23117
23200
  if (unpackedSecrets > 0) {
23118
23201
  process.stdout.write(`\u2192 kody: unpacked ${unpackedSecrets} secret(s) from ALL_SECRETS
@@ -23172,7 +23255,7 @@ ${CHAT_HELP}`);
23172
23255
  const sink = buildSink(cwd, sessionId, args.dashboardUrl);
23173
23256
  const meta = readMeta(sessionFile);
23174
23257
  process.stdout.write(
23175
- `\u2192 kody:chat: session file=${sessionFile} exists=${fs50.existsSync(sessionFile)} meta=${meta ? meta.mode : "none"}
23258
+ `\u2192 kody:chat: session file=${sessionFile} exists=${fs51.existsSync(sessionFile)} meta=${meta ? meta.mode : "none"}
23176
23259
  `
23177
23260
  );
23178
23261
  try {
@@ -23302,8 +23385,8 @@ var FlyClient = class {
23302
23385
  get fetch() {
23303
23386
  return this.opts.fetchImpl ?? fetch;
23304
23387
  }
23305
- async call(path50, init = {}) {
23306
- const res = await this.fetch(`${FLY_API_BASE}${path50}`, {
23388
+ async call(path51, init = {}) {
23389
+ const res = await this.fetch(`${FLY_API_BASE}${path51}`, {
23307
23390
  method: init.method ?? "GET",
23308
23391
  headers: {
23309
23392
  Authorization: `Bearer ${this.opts.token}`,
@@ -23314,7 +23397,7 @@ var FlyClient = class {
23314
23397
  if (res.status === 404 && init.allow404) return null;
23315
23398
  if (!res.ok) {
23316
23399
  const text = await res.text().catch(() => "");
23317
- throw new Error(`Fly API ${res.status} on ${path50}: ${text.slice(0, 200) || res.statusText}`);
23400
+ throw new Error(`Fly API ${res.status} on ${path51}: ${text.slice(0, 200) || res.statusText}`);
23318
23401
  }
23319
23402
  if (res.status === 204) return null;
23320
23403
  const raw = await res.text();
@@ -24032,7 +24115,7 @@ async function poolServe() {
24032
24115
 
24033
24116
  // src/servers/runner-serve.ts
24034
24117
  import { spawn as spawn8 } from "child_process";
24035
- import * as fs51 from "fs";
24118
+ import * as fs52 from "fs";
24036
24119
  import { createServer as createServer6 } from "http";
24037
24120
  var DEFAULT_PORT2 = 8080;
24038
24121
  var DEFAULT_WORKDIR = "/workspace/repo";
@@ -24167,8 +24250,8 @@ async function defaultRunJob(job) {
24167
24250
  const workdir = process.env.RUNNER_WORKDIR ?? DEFAULT_WORKDIR;
24168
24251
  const branch = job.ref ?? "main";
24169
24252
  const authUrl = `https://x-access-token:${job.githubToken}@github.com/${job.repo}.git`;
24170
- fs51.rmSync(workdir, { recursive: true, force: true });
24171
- fs51.mkdirSync(workdir, { recursive: true });
24253
+ fs52.rmSync(workdir, { recursive: true, force: true });
24254
+ fs52.mkdirSync(workdir, { recursive: true });
24172
24255
  const allSecrets = typeof job.allSecrets === "string" ? job.allSecrets : JSON.stringify(job.allSecrets ?? {});
24173
24256
  const target = job.runRequest.target;
24174
24257
  const interactive = target.type === "chat";