@kody-ade/kody-engine 0.4.357 → 0.4.360

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 +413 -776
  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.357",
18
+ version: "0.4.360",
19
19
  description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative implementation profiles.",
20
20
  license: "MIT",
21
21
  type: "module",
@@ -289,8 +289,8 @@ function isRunningAsBot() {
289
289
  }
290
290
  function postIssueComment(issueNumber, body, cwd) {
291
291
  if (isRunningAsBot()) {
292
- const slug2 = detectBotDispatchShape(body);
293
- if (slug2) throw new BotDispatchCommentError(slug2);
292
+ const slug = detectBotDispatchShape(body);
293
+ if (slug) throw new BotDispatchCommentError(slug);
294
294
  }
295
295
  try {
296
296
  gh(["issue", "comment", String(issueNumber), "--body-file", "-"], {
@@ -401,8 +401,8 @@ function getPrLatestReviewBody(prNumber, cwd) {
401
401
  }
402
402
  function postPrReviewComment(prNumber, body, cwd) {
403
403
  if (isRunningAsBot()) {
404
- const slug2 = detectBotDispatchShape(body);
405
- if (slug2) throw new BotDispatchCommentError(slug2);
404
+ const slug = detectBotDispatchShape(body);
405
+ if (slug) throw new BotDispatchCommentError(slug);
406
406
  }
407
407
  try {
408
408
  gh(["pr", "comment", String(prNumber), "--body-file", "-"], {
@@ -426,9 +426,9 @@ var init_issue = __esm({
426
426
  DEFAULT_RATE_LIMIT_BASE_DELAY_MS = 1e3;
427
427
  DEFAULT_RATE_LIMIT_MAX_WAIT_MS = 65 * 60 * 1e3;
428
428
  BotDispatchCommentError = class extends Error {
429
- constructor(slug2) {
429
+ constructor(slug) {
430
430
  super(
431
- `bot self-dispatch via @kody comments is banned. Refusing to post "@kody ${slug2} \u2026" \u2014 use runImplementationChain (same-run) or dispatchImplementation (cross-run) instead. See docs/capability-dispatch.md for the contract.`
431
+ `bot self-dispatch via @kody comments is banned. Refusing to post "@kody ${slug} \u2026" \u2014 use runImplementationChain (same-run) or dispatchImplementation (cross-run) instead. See docs/capability-dispatch.md for the contract.`
432
432
  );
433
433
  this.name = "BotDispatchCommentError";
434
434
  }
@@ -458,8 +458,8 @@ function isAlreadyExists(err) {
458
458
  const msg = err instanceof Error ? err.message : String(err);
459
459
  return /HTTP 422/i.test(msg) || /Reference already exists/i.test(msg);
460
460
  }
461
- function parseStateRepoSlug(slug2, field = "stateRepo") {
462
- const value = slug2.trim();
461
+ function parseStateRepoSlug(slug, field = "stateRepo") {
462
+ const value = slug.trim();
463
463
  let repoPath = value;
464
464
  if (/^https?:\/\//i.test(value)) {
465
465
  let parsed;
@@ -694,16 +694,16 @@ function parseModelRuntimeConfig(modelSpec, rawConfig) {
694
694
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
695
695
  throw new Error("KODY_MODEL_CONFIG must be a JSON object");
696
696
  }
697
- const record2 = parsed;
698
- const modelName = optionalRuntimeString(record2, "modelName");
697
+ const record = parsed;
698
+ const modelName = optionalRuntimeString(record, "modelName");
699
699
  if (!modelName) {
700
700
  throw new Error("KODY_MODEL_CONFIG.modelName is required");
701
701
  }
702
- const protocol = optionalRuntimeString(record2, "protocol");
703
- const baseURL = optionalRuntimeString(record2, "baseURL");
704
- const apiKeyEnvVar = optionalRuntimeString(record2, "apiKeyEnvVar");
705
- const spec = optionalRuntimeString(record2, "spec");
706
- const provider = optionalRuntimeString(record2, "provider") ?? fallback.provider;
702
+ const protocol = optionalRuntimeString(record, "protocol");
703
+ const baseURL = optionalRuntimeString(record, "baseURL");
704
+ const apiKeyEnvVar = optionalRuntimeString(record, "apiKeyEnvVar");
705
+ const spec = optionalRuntimeString(record, "spec");
706
+ const provider = optionalRuntimeString(record, "provider") ?? fallback.provider;
707
707
  const out = {
708
708
  provider,
709
709
  model: modelName
@@ -854,11 +854,11 @@ function parseGoalActivations(raw) {
854
854
  const seen = /* @__PURE__ */ new Set();
855
855
  for (const value of raw) {
856
856
  if (typeof value === "string") {
857
- const slug2 = parseSlug(value, "company.activeGoals");
858
- if (!slug2) continue;
859
- if (!seen.has(slug2)) {
860
- seen.add(slug2);
861
- out.push(slug2);
857
+ const slug = parseSlug(value, "company.activeGoals");
858
+ if (!slug) continue;
859
+ if (!seen.has(slug)) {
860
+ seen.add(slug);
861
+ out.push(slug);
862
862
  }
863
863
  continue;
864
864
  }
@@ -908,20 +908,20 @@ function parseSlugArray(raw, field) {
908
908
  if (!Array.isArray(raw)) throw new Error(`kody.config.json: ${field} must be an array of strings`);
909
909
  const out = [];
910
910
  for (const value of raw) {
911
- const slug2 = parseSlug(value, field);
912
- if (!slug2) continue;
913
- out.push(slug2);
911
+ const slug = parseSlug(value, field);
912
+ if (!slug) continue;
913
+ out.push(slug);
914
914
  }
915
915
  return [...new Set(out)];
916
916
  }
917
917
  function parseSlug(value, field) {
918
918
  if (typeof value !== "string") throw new Error(`kody.config.json: ${field} entries must be strings`);
919
- const slug2 = value.trim();
920
- if (!slug2) return "";
921
- if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(slug2)) {
919
+ const slug = value.trim();
920
+ if (!slug) return "";
921
+ if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(slug)) {
922
922
  throw new Error(`kody.config.json: ${field} contains invalid slug "${value}"`);
923
923
  }
924
- return slug2;
924
+ return slug;
925
925
  }
926
926
  function recordValue(raw) {
927
927
  return raw && typeof raw === "object" && !Array.isArray(raw) ? raw : void 0;
@@ -1876,8 +1876,8 @@ function listCapabilityFolderSlugs(absDir) {
1876
1876
  function isCapabilityFolder(dir) {
1877
1877
  return fs4.existsSync(path6.join(dir, CAPABILITY_PROFILE_FILE)) && fs4.existsSync(path6.join(dir, CAPABILITY_BODY_FILE));
1878
1878
  }
1879
- function readCapabilityFolder(root, slug2) {
1880
- const dir = path6.join(root, slug2);
1879
+ function readCapabilityFolder(root, slug) {
1880
+ const dir = path6.join(root, slug);
1881
1881
  const profilePath = path6.join(dir, CAPABILITY_PROFILE_FILE);
1882
1882
  const bodyPath = path6.join(dir, CAPABILITY_BODY_FILE);
1883
1883
  if (!fs4.existsSync(profilePath) || !fs4.statSync(profilePath).isFile()) return null;
@@ -1885,9 +1885,9 @@ function readCapabilityFolder(root, slug2) {
1885
1885
  try {
1886
1886
  const rawProfile = JSON.parse(fs4.readFileSync(profilePath, "utf-8"));
1887
1887
  const rawBody = fs4.readFileSync(bodyPath, "utf-8");
1888
- const { title, body } = parseCapabilityBody(rawBody, slug2);
1888
+ const { title, body } = parseCapabilityBody(rawBody, slug);
1889
1889
  return {
1890
- slug: slug2,
1890
+ slug,
1891
1891
  dir,
1892
1892
  profilePath,
1893
1893
  bodyPath,
@@ -1934,11 +1934,11 @@ function parseCapabilityToolMode(raw) {
1934
1934
  if (raw === "lock" || raw === "append") return raw;
1935
1935
  return void 0;
1936
1936
  }
1937
- function parseCapabilityBody(raw, slug2) {
1937
+ function parseCapabilityBody(raw, slug) {
1938
1938
  const trimmed = raw.trim();
1939
1939
  const firstLine2 = trimmed.split("\n", 1)[0] ?? "";
1940
1940
  const h1 = /^#\s+(.+?)\s*$/.exec(firstLine2);
1941
- const title = h1 ? h1[1].trim() : humanizeSlug(slug2);
1941
+ const title = h1 ? h1[1].trim() : humanizeSlug(slug);
1942
1942
  const body = stripLeadingH1(raw);
1943
1943
  return { title, body };
1944
1944
  }
@@ -1952,8 +1952,8 @@ function stripLeadingH1(raw) {
1952
1952
  }
1953
1953
  return lines.slice(i).join("\n");
1954
1954
  }
1955
- function humanizeSlug(slug2) {
1956
- return slug2.split(/[-_]+/).filter(Boolean).map((part) => part[0].toUpperCase() + part.slice(1)).join(" ");
1955
+ function humanizeSlug(slug) {
1956
+ return slug.split(/[-_]+/).filter(Boolean).map((part) => part[0].toUpperCase() + part.slice(1)).join(" ");
1957
1957
  }
1958
1958
  function stringField(value) {
1959
1959
  return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
@@ -2280,10 +2280,10 @@ function resolveCapabilityAction(action, projectCapabilitiesRoot = getProjectCap
2280
2280
  function hasCapabilityAction(action, projectCapabilitiesRoot = getProjectCapabilitiesRoot()) {
2281
2281
  return resolveCapabilityAction(action, projectCapabilitiesRoot) !== null;
2282
2282
  }
2283
- function resolveCapabilityFolder(slug2, projectCapabilitiesRoot = getProjectCapabilitiesRoot()) {
2284
- if (!isSafeName(slug2)) return null;
2283
+ function resolveCapabilityFolder(slug, projectCapabilitiesRoot = getProjectCapabilitiesRoot()) {
2284
+ if (!isSafeName(slug)) return null;
2285
2285
  for (const root of getCapabilityRoots(projectCapabilitiesRoot)) {
2286
- const capability = readCapabilityFolder(root, slug2);
2286
+ const capability = readCapabilityFolder(root, slug);
2287
2287
  if (capability) return capability;
2288
2288
  }
2289
2289
  return null;
@@ -2339,17 +2339,17 @@ function isImplementationProfile(profilePath, requireImplementationProfile) {
2339
2339
  function listFolderCapabilityActions(root, source) {
2340
2340
  if (!fs6.existsSync(root) || !fs6.statSync(root).isDirectory()) return [];
2341
2341
  const out = [];
2342
- for (const slug2 of listCapabilityFolderSlugs(root)) {
2343
- if (!isSafeName(slug2)) continue;
2344
- const capability = readCapabilityFolder(root, slug2);
2342
+ for (const slug of listCapabilityFolderSlugs(root)) {
2343
+ if (!isSafeName(slug)) continue;
2344
+ const capability = readCapabilityFolder(root, slug);
2345
2345
  if (!capability) continue;
2346
2346
  if (capability.config.internal === true || capability.config.public === false) continue;
2347
- const action = capability.config.action ?? slug2;
2347
+ const action = capability.config.action ?? slug;
2348
2348
  const { implementation, cliArgs } = resolveCapabilityExecution(capability);
2349
2349
  if (hasUnresolvedExplicitImplementation(capability, implementation)) continue;
2350
2350
  out.push({
2351
2351
  action,
2352
- capability: slug2,
2352
+ capability: slug,
2353
2353
  implementation,
2354
2354
  cliArgs,
2355
2355
  source,
@@ -2371,15 +2371,15 @@ function hasUnresolvedExplicitImplementation(capability, implementation) {
2371
2371
  function listBuiltinCapabilityActions(root = getBuiltinCapabilitiesRoot()) {
2372
2372
  if (!fs6.existsSync(root) || !fs6.statSync(root).isDirectory()) return [];
2373
2373
  const out = [];
2374
- for (const slug2 of listCapabilityFolderSlugs(root)) {
2375
- if (!isSafeName(slug2)) continue;
2376
- const capability = readCapabilityFolder(root, slug2);
2374
+ for (const slug of listCapabilityFolderSlugs(root)) {
2375
+ if (!isSafeName(slug)) continue;
2376
+ const capability = readCapabilityFolder(root, slug);
2377
2377
  if (!capability) continue;
2378
- const action = capability.config.action ?? slug2;
2379
- const implementation = capability.config.implementation ?? slug2;
2378
+ const action = capability.config.action ?? slug;
2379
+ const implementation = capability.config.implementation ?? slug;
2380
2380
  out.push({
2381
2381
  action,
2382
- capability: slug2,
2382
+ capability: slug,
2383
2383
  implementation,
2384
2384
  cliArgs: {},
2385
2385
  source: "builtin",
@@ -2553,8 +2553,8 @@ function listRepairCandidates(repoSlug) {
2553
2553
  function dispatchVerb(workflowFile, repoSlug, capability, prNumber) {
2554
2554
  return dispatchWorkflow(workflowFile, capability, prNumber, repoSlug);
2555
2555
  }
2556
- function capabilityMarker(slug2) {
2557
- return `<!-- kody-capability: ${slug2} -->`;
2556
+ function capabilityMarker(slug) {
2557
+ return `<!-- kody-capability: ${slug} -->`;
2558
2558
  }
2559
2559
  function normalizeRecommendationIntent(body) {
2560
2560
  const marker = body.match(/<!--\s*kody-intent:\s*([\s\S]*?)-->/i);
@@ -2707,7 +2707,7 @@ ${marker}` });
2707
2707
  return { error: err instanceof Error ? err.message : String(err) };
2708
2708
  }
2709
2709
  }
2710
- function dispatchWorkflow(workflowFile, capability, issueNumber, repoSlug) {
2710
+ function dispatchWorkflow(workflowFile, capability, issueNumber, repoSlug, ref) {
2711
2711
  const expected = expectedDispatchTarget(capability);
2712
2712
  if (repoSlug && expected) {
2713
2713
  const target = readDispatchTargetKind(repoSlug, issueNumber);
@@ -2726,14 +2726,23 @@ function dispatchWorkflow(workflowFile, capability, issueNumber, repoSlug) {
2726
2726
  }
2727
2727
  }
2728
2728
  try {
2729
- gh(["workflow", "run", workflowFile, "-f", `capability=${capability}`, "-f", `issue_number=${issueNumber}`]);
2729
+ gh([
2730
+ "workflow",
2731
+ "run",
2732
+ workflowFile,
2733
+ ...ref ? ["--ref", ref] : [],
2734
+ "-f",
2735
+ `capability=${capability}`,
2736
+ "-f",
2737
+ `issue_number=${issueNumber}`
2738
+ ]);
2730
2739
  return { ok: true };
2731
2740
  } catch (err) {
2732
2741
  return { ok: false, error: err instanceof Error ? err.message : String(err) };
2733
2742
  }
2734
2743
  }
2735
- function startCapability(workflowFile, name, issue, repoSlug) {
2736
- return dispatchWorkflow(workflowFile, name, issue, repoSlug);
2744
+ function startCapability(workflowFile, name, issue, repoSlug, ref) {
2745
+ return dispatchWorkflow(workflowFile, name, issue, repoSlug, ref);
2737
2746
  }
2738
2747
  function expectedDispatchTarget(capability) {
2739
2748
  const route = resolveCapabilityAction(capability);
@@ -2913,7 +2922,13 @@ function capabilityToolDefinitions(opts) {
2913
2922
  if (!Number.isFinite(issue) || issue <= 0) {
2914
2923
  return { content: [{ type: "text", text: "Start failed: `issue` is required and must be a positive number." }] };
2915
2924
  }
2916
- const result = startCapability(workflowFile, name, issue, opts.repoSlug);
2925
+ const result = startCapability(
2926
+ workflowFile,
2927
+ name,
2928
+ issue,
2929
+ opts.repoSlug,
2930
+ opts.defaultBranch
2931
+ );
2917
2932
  const text = result.ok ? `Started capability \`${name}\` on #${issue} via workflow_dispatch.` : `Start failed for capability \`${name}\` on #${issue}: ${result.error}`;
2918
2933
  return { content: [{ type: "text", text }] };
2919
2934
  }
@@ -3265,6 +3280,7 @@ async function runAgent(opts) {
3265
3280
  repoSlug: opts.capabilityRepoSlug,
3266
3281
  state: opts.capabilityState,
3267
3282
  operatorMention: opts.capabilityOperatorMention ?? "",
3283
+ ...opts.capabilityDefaultBranch ? { defaultBranch: opts.capabilityDefaultBranch } : {},
3268
3284
  ...opts.capabilitySlug ? { capabilitySlug: opts.capabilitySlug } : {}
3269
3285
  });
3270
3286
  mcpEntries.push(["kody-capability", capabilityHandle.server]);
@@ -3574,8 +3590,8 @@ function stripFrontmatter(raw) {
3574
3590
  const match = /^---\n[\s\S]*?\n---\n?([\s\S]*)$/.exec(raw);
3575
3591
  return (match ? match[1] : raw).trim();
3576
3592
  }
3577
- function loadAgentIdentity(cwd, slug2, agentsDir = DEFAULT_AGENT_DIR) {
3578
- const trimmed = slug2.trim();
3593
+ function loadAgentIdentity(cwd, slug, agentsDir = DEFAULT_AGENT_DIR) {
3594
+ const trimmed = slug.trim();
3579
3595
  if (!trimmed) throw new Error("loadAgentIdentity: empty agent slug");
3580
3596
  const agentPath = resolveAgentFile(cwd, trimmed, agentsDir);
3581
3597
  if (fs9.existsSync(agentPath)) {
@@ -3589,21 +3605,21 @@ function loadAgentIdentity(cwd, slug2, agentsDir = DEFAULT_AGENT_DIR) {
3589
3605
  if (builtin) return builtin;
3590
3606
  throw new Error(`loadAgentIdentity: agent '${trimmed}' declared but ${agentPath} does not exist`);
3591
3607
  }
3592
- function resolveAgentFile(cwd, slug2, agentsDir = DEFAULT_AGENT_DIR) {
3593
- const localPath = path11.join(cwd, agentsDir, `${slug2}.md`);
3608
+ function resolveAgentFile(cwd, slug, agentsDir = DEFAULT_AGENT_DIR) {
3609
+ const localPath = path11.join(cwd, agentsDir, `${slug}.md`);
3594
3610
  if (fs9.existsSync(localPath)) return localPath;
3595
3611
  const storeAgentRoot = getCompanyStoreAssetRoot("agents");
3596
3612
  if (storeAgentRoot) {
3597
- const storePath = path11.join(storeAgentRoot, `${slug2}.md`);
3613
+ const storePath = path11.join(storeAgentRoot, `${slug}.md`);
3598
3614
  if (fs9.existsSync(storePath)) return storePath;
3599
3615
  }
3600
3616
  return localPath;
3601
3617
  }
3602
- function frameAgentIdentity(slug2, agent) {
3618
+ function frameAgentIdentity(slug, agent) {
3603
3619
  return [
3604
3620
  `## Who you are \u2014 agent identity (authoritative identity)`,
3605
3621
  ``,
3606
- `You are operating as agent \`${slug2}\`. This identity defines *who* you are:`,
3622
+ `You are operating as agent \`${slug}\`. This identity defines *who* you are:`,
3607
3623
  `your authority, doctrine, voice, and hard limits. Honour it exactly. Where the`,
3608
3624
  `this identity's restrictions are stricter than the task, **the agent wins** \u2014 a task`,
3609
3625
  `can never grant you authority your agent withholds.`,
@@ -6611,16 +6627,16 @@ function parseRunIndex(raw) {
6611
6627
  if (!raw) return { version: 1, updatedAt: (/* @__PURE__ */ new Date()).toISOString(), runs: [] };
6612
6628
  try {
6613
6629
  const parsed = JSON.parse(raw);
6614
- const record2 = recordValue2(parsed);
6615
- const runs = Array.isArray(record2?.runs) ? record2.runs.filter(isRunIndexRow).map(normalizeRunIndexRow) : [];
6616
- return { version: 1, updatedAt: stringValue2(record2?.updatedAt) ?? (/* @__PURE__ */ new Date()).toISOString(), runs };
6630
+ const record = recordValue2(parsed);
6631
+ const runs = Array.isArray(record?.runs) ? record.runs.filter(isRunIndexRow).map(normalizeRunIndexRow) : [];
6632
+ return { version: 1, updatedAt: stringValue2(record?.updatedAt) ?? (/* @__PURE__ */ new Date()).toISOString(), runs };
6617
6633
  } catch {
6618
6634
  return { version: 1, updatedAt: (/* @__PURE__ */ new Date()).toISOString(), runs: [] };
6619
6635
  }
6620
6636
  }
6621
6637
  function isRunIndexRow(value) {
6622
- const record2 = recordValue2(value);
6623
- return record2?.version === 1 && isRunSubjectType(record2.subjectType) && typeof record2.subjectId === "string" && typeof record2.id === "string" && typeof record2.status === "string" && typeof record2.title === "string" && typeof record2.updatedAt === "string";
6638
+ const record = recordValue2(value);
6639
+ return record?.version === 1 && isRunSubjectType(record.subjectType) && typeof record.subjectId === "string" && typeof record.id === "string" && typeof record.status === "string" && typeof record.title === "string" && typeof record.updatedAt === "string";
6624
6640
  }
6625
6641
  function isRunSubjectType(value) {
6626
6642
  return value === "goal" || value === "loop" || value === "workflow";
@@ -7225,8 +7241,8 @@ function applySimpleGoalTaskSummary(goal, summary) {
7225
7241
  }
7226
7242
  function isFactReference(value) {
7227
7243
  if (!value || typeof value !== "object" || Array.isArray(value)) return false;
7228
- const record2 = value;
7229
- return Object.keys(record2).length === 1 && typeof record2.fact === "string" && record2.fact.length > 0;
7244
+ const record = value;
7245
+ return Object.keys(record).length === 1 && typeof record.fact === "string" && record.fact.length > 0;
7230
7246
  }
7231
7247
  function isCliArgValue(value) {
7232
7248
  return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
@@ -8134,8 +8150,8 @@ function serializeTodoGoalState(goalId, state, previousRaw) {
8134
8150
  )}
8135
8151
  `;
8136
8152
  }
8137
- function isManagedTodoRecord(record2) {
8138
- return record2.managed === true || record2.managed === "true" || record2.managedModel === "agentGoal" || record2.managedModel === "agentLoop";
8153
+ function isManagedTodoRecord(record) {
8154
+ return record.managed === true || record.managed === "true" || record.managedModel === "agentGoal" || record.managedModel === "agentLoop";
8139
8155
  }
8140
8156
  function itemFromEvidence(evidence, step, facts, evidenceState, createdAt, now, prior) {
8141
8157
  const completed = facts[evidence] === true;
@@ -8696,10 +8712,10 @@ function normalizeWorkflowCapabilities(value) {
8696
8712
  const capabilities = [];
8697
8713
  for (const item of value) {
8698
8714
  if (typeof item !== "string") continue;
8699
- const slug2 = item.trim();
8700
- if (!CAPABILITY_ID_PATTERN.test(slug2) || seen.has(slug2)) continue;
8701
- seen.add(slug2);
8702
- capabilities.push(slug2);
8715
+ const slug = item.trim();
8716
+ if (!CAPABILITY_ID_PATTERN.test(slug) || seen.has(slug)) continue;
8717
+ seen.add(slug);
8718
+ capabilities.push(slug);
8703
8719
  }
8704
8720
  return capabilities;
8705
8721
  }
@@ -8829,8 +8845,8 @@ function isStateUnchanged(prev, next) {
8829
8845
  if (prev.done !== next.done) return false;
8830
8846
  return JSON.stringify(prev.data) === JSON.stringify(next.data);
8831
8847
  }
8832
- function stateFilePath(jobsDir, slug2) {
8833
- return `${jobsDir.replace(/\/+$/, "")}/${slug2}/state.json`;
8848
+ function stateFilePath(jobsDir, slug) {
8849
+ return `${jobsDir.replace(/\/+$/, "")}/${slug}/state.json`;
8834
8850
  }
8835
8851
  function slugFromStateFilePath(filePath) {
8836
8852
  if (/\/state\.json$/i.test(filePath)) {
@@ -8872,8 +8888,8 @@ var init_contentsApiBackend = __esm({
8872
8888
  this.jobsDir = stateRepoJobsDir(opts.jobsDir);
8873
8889
  this.cwd = opts.cwd;
8874
8890
  }
8875
- load(slug2) {
8876
- const filePath = stateFilePath(this.jobsDir, slug2);
8891
+ load(slug) {
8892
+ const filePath = stateFilePath(this.jobsDir, slug);
8877
8893
  const loaded = readStateText(this.config, this.cwd, filePath);
8878
8894
  if (!loaded) {
8879
8895
  return { path: filePath, handle: null, state: initialStateEnvelope("seed"), created: true };
@@ -8893,20 +8909,20 @@ var init_contentsApiBackend = __esm({
8893
8909
  if (!loaded.created && isStateUnchanged(loaded.state, next)) {
8894
8910
  return false;
8895
8911
  }
8896
- const slug2 = slugFromStateFilePath(loaded.path);
8912
+ const slug = slugFromStateFilePath(loaded.path);
8897
8913
  const body = `${JSON.stringify(next, null, 2)}
8898
8914
  `;
8899
- const message = `chore(jobs): update state for ${slug2} (rev ${next.rev})`;
8915
+ const message = `chore(jobs): update state for ${slug} (rev ${next.rev})`;
8900
8916
  const sha = typeof loaded.handle === "string" ? loaded.handle : void 0;
8901
8917
  try {
8902
8918
  writeStateText(this.config, this.cwd, loaded.path, body, message, sha);
8903
8919
  } catch (err) {
8904
8920
  if (!isShaConflict(err)) throw err;
8905
- const current = this.load(slug2);
8921
+ const current = this.load(slug);
8906
8922
  if (!current.created && isStateUnchanged(current.state, next)) return false;
8907
8923
  const currentSha = typeof current.handle === "string" ? current.handle : void 0;
8908
8924
  process.stderr.write(
8909
- `[kody] jobState: concurrent write detected for ${slug2}; reloaded SHA and retrying (last-write-wins)
8925
+ `[kody] jobState: concurrent write detected for ${slug}; reloaded SHA and retrying (last-write-wins)
8910
8926
  `
8911
8927
  );
8912
8928
  writeStateText(this.config, this.cwd, loaded.path, body, message, currentSha);
@@ -9033,8 +9049,8 @@ var init_localFileBackend = __esm({
9033
9049
  `);
9034
9050
  }
9035
9051
  }
9036
- load(slug2) {
9037
- const relPath = stateFilePath(this.jobsDir, slug2);
9052
+ load(slug) {
9053
+ const relPath = stateFilePath(this.jobsDir, slug);
9038
9054
  const absPath = path27.join(this.cwd, relPath);
9039
9055
  if (!fs29.existsSync(absPath)) {
9040
9056
  return { path: relPath, handle: null, state: initialStateEnvelope("seed"), created: true };
@@ -9166,18 +9182,18 @@ async function planGoalCapabilitySchedule(opts) {
9166
9182
  const blockers = [];
9167
9183
  const explicitCapabilityTarget = opts.goal.loopTarget?.type === "capability" ? opts.goal.loopTarget.id.trim() : "";
9168
9184
  const capabilitySlugs = explicitCapabilityTarget ? [explicitCapabilityTarget] : opts.goal.capabilities;
9169
- for (const slug2 of capabilitySlugs) {
9170
- const capability2 = resolveCapabilityFolder(slug2, jobsRoot);
9185
+ for (const slug of capabilitySlugs) {
9186
+ const capability2 = resolveCapabilityFolder(slug, jobsRoot);
9171
9187
  const status = await describeCapabilitySchedule(
9172
9188
  capability2,
9173
- slug2,
9189
+ slug,
9174
9190
  backend,
9175
- opts.previousScheduleState?.capabilities[slug2]
9191
+ opts.previousScheduleState?.capabilities[slug]
9176
9192
  );
9177
- statuses[slug2] = status;
9178
- if (status.state === "blocked") blockers.push(`${slug2}: ${status.reason}`);
9193
+ statuses[slug] = status;
9194
+ if (status.state === "blocked") blockers.push(`${slug}: ${status.reason}`);
9179
9195
  }
9180
- const due = capabilitySlugs.map((slug2) => statuses[slug2]).filter((status) => status?.state === "due").sort(compareOldestLastFired)[0];
9196
+ const due = capabilitySlugs.map((slug) => statuses[slug]).filter((status) => status?.state === "due").sort(compareOldestLastFired)[0];
9181
9197
  if (!due) {
9182
9198
  const reason = blockers.length > 0 ? "no runnable capability; blocked capabilities need attention" : "no runnable capability";
9183
9199
  const kind = blockers.length > 0 ? "blocked" : "idle";
@@ -9226,18 +9242,18 @@ async function planGoalCapabilitySchedule(opts) {
9226
9242
  }
9227
9243
  };
9228
9244
  }
9229
- async function describeCapabilitySchedule(capability, slug2, backend, previous) {
9230
- if (!capability) return { slug: slug2, state: "blocked", reason: "capability folder missing" };
9245
+ async function describeCapabilitySchedule(capability, slug, backend, previous) {
9246
+ if (!capability) return { slug, state: "blocked", reason: "capability folder missing" };
9231
9247
  const { config } = capability;
9232
9248
  if (config.disabled === true) {
9233
- return { slug: slug2, title: capability.title, state: "disabled", reason: "disabled" };
9249
+ return { slug, title: capability.title, state: "disabled", reason: "disabled" };
9234
9250
  }
9235
9251
  if (!config.agent || config.agent.trim().length === 0) {
9236
- return { slug: slug2, title: capability.title, state: "blocked", reason: "no agent assigned" };
9252
+ return { slug, title: capability.title, state: "blocked", reason: "no agent assigned" };
9237
9253
  }
9238
9254
  if (config.implementations && config.implementations.length > 1) {
9239
9255
  return {
9240
- slug: slug2,
9256
+ slug,
9241
9257
  title: capability.title,
9242
9258
  state: "blocked",
9243
9259
  reason: "multi-implementation capability needs task-jobs route"
@@ -9246,20 +9262,20 @@ async function describeCapabilitySchedule(capability, slug2, backend, previous)
9246
9262
  let lastFiredAt = validIso(previous?.lastFiredAt) ? previous?.lastFiredAt : void 0;
9247
9263
  try {
9248
9264
  if (!lastFiredAt) {
9249
- const loaded = await backend.load(slug2);
9265
+ const loaded = await backend.load(slug);
9250
9266
  const raw = loaded.state.data?.lastFiredAt;
9251
9267
  if (typeof raw === "string" && validIso(raw)) lastFiredAt = raw;
9252
9268
  }
9253
9269
  } catch {
9254
9270
  return {
9255
- slug: slug2,
9271
+ slug,
9256
9272
  title: capability.title,
9257
9273
  state: "due",
9258
9274
  reason: "state unreadable; ready for loop tick"
9259
9275
  };
9260
9276
  }
9261
9277
  return {
9262
- slug: slug2,
9278
+ slug,
9263
9279
  title: capability.title,
9264
9280
  state: "due",
9265
9281
  reason: "ready for loop tick",
@@ -9396,11 +9412,11 @@ function scheduleWaitDecision(previousScheduleState, plannedDecision, reason) {
9396
9412
  }
9397
9413
  function unmarkPlannedCapabilityDispatch(scheduleState, at) {
9398
9414
  return Object.fromEntries(
9399
- Object.entries(scheduleState.capabilities).map(([slug2, status]) => {
9400
- if (status.lastFiredAt !== at) return [slug2, status];
9415
+ Object.entries(scheduleState.capabilities).map(([slug, status]) => {
9416
+ if (status.lastFiredAt !== at) return [slug, status];
9401
9417
  const rest = { ...status };
9402
9418
  delete rest.lastFiredAt;
9403
- return [slug2, rest];
9419
+ return [slug, rest];
9404
9420
  })
9405
9421
  );
9406
9422
  }
@@ -9575,8 +9591,8 @@ function routeNeedsIssueFact(goal) {
9575
9591
  return goal.route.some(
9576
9592
  (step) => Object.values(step.args ?? {}).some((value) => {
9577
9593
  if (!value || typeof value !== "object" || Array.isArray(value)) return false;
9578
- const record2 = value;
9579
- return Object.keys(record2).length === 1 && record2.fact === "issue";
9594
+ const record = value;
9595
+ return Object.keys(record).length === 1 && record.fact === "issue";
9580
9596
  })
9581
9597
  );
9582
9598
  }
@@ -9585,8 +9601,8 @@ function workflowNeedsIssueFact(goal) {
9585
9601
  }
9586
9602
  function isIssueFactReference(value) {
9587
9603
  if (!value || typeof value !== "object" || Array.isArray(value)) return false;
9588
- const record2 = value;
9589
- return Object.keys(record2).length === 1 && record2.fact === "issue";
9604
+ const record = value;
9605
+ return Object.keys(record).length === 1 && record.fact === "issue";
9590
9606
  }
9591
9607
  function normalizeIssueNumber(value) {
9592
9608
  if (typeof value === "number" && Number.isInteger(value) && value > 0) return value;
@@ -9927,9 +9943,9 @@ function resolveTrigger(force) {
9927
9943
  if (force || event === "issue_comment" || event === "workflow_dispatch") return "manual";
9928
9944
  return "event";
9929
9945
  }
9930
- function appendLine(ctx, record2) {
9931
- const filePath = `activity/${record2.ts.slice(0, 10)}.jsonl`;
9932
- appendStateLine(ctx.config, ctx.cwd, filePath, JSON.stringify(record2), `chore(activity): ${record2.action}`);
9946
+ function appendLine(ctx, record) {
9947
+ const filePath = `activity/${record.ts.slice(0, 10)}.jsonl`;
9948
+ appendStateLine(ctx.config, ctx.cwd, filePath, JSON.stringify(record), `chore(activity): ${record.action}`);
9933
9949
  }
9934
9950
  var appendCompanyActivity;
9935
9951
  var init_appendCompanyActivity = __esm({
@@ -9945,7 +9961,7 @@ var init_appendCompanyActivity = __esm({
9945
9961
  const agent = ctx.data.agentSlug || null;
9946
9962
  const agentTitle = ctx.data.agentTitle || null;
9947
9963
  const force = ctx.args?.force === true;
9948
- const record2 = {
9964
+ const record = {
9949
9965
  ts: (/* @__PURE__ */ new Date()).toISOString(),
9950
9966
  action: `Ran capability: ${capabilityTitle ?? capability}`,
9951
9967
  capability,
@@ -9959,7 +9975,7 @@ var init_appendCompanyActivity = __esm({
9959
9975
  durationMs: agentResult?.durationMs ?? null,
9960
9976
  runUrl: getRunUrl() || null
9961
9977
  };
9962
- appendLine(ctx, record2);
9978
+ appendLine(ctx, record);
9963
9979
  } catch (err) {
9964
9980
  process.stderr.write(
9965
9981
  `[activity] company-activity append failed: ${err instanceof Error ? err.message : String(err)}
@@ -9970,494 +9986,6 @@ var init_appendCompanyActivity = __esm({
9970
9986
  }
9971
9987
  });
9972
9988
 
9973
- // src/agencyArchitectDecision.ts
9974
- function parseAgencyArchitectDecisionText(finalText) {
9975
- const raw = extractDecisionJson(finalText);
9976
- const parsed = JSON.parse(raw);
9977
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
9978
- throw new Error("agency-architect decision must be JSON object");
9979
- }
9980
- const input = parsed;
9981
- const actions = Array.isArray(input.actions) ? input.actions.map(parseAction) : [];
9982
- return {
9983
- summary: typeof input.summary === "string" ? input.summary.trim() : "",
9984
- actions
9985
- };
9986
- }
9987
- function buildManagedGoalState(action) {
9988
- const at = nowIso();
9989
- return {
9990
- state: "active",
9991
- createdAt: at,
9992
- updatedAt: at,
9993
- extra: {
9994
- type: action.goalType ?? "release",
9995
- destination: { outcome: action.outcome, evidence: action.evidence },
9996
- capabilities: action.capabilities,
9997
- route: action.route,
9998
- facts: action.facts ?? {},
9999
- blockers: [],
10000
- createdByIntent: action.intentId,
10001
- manager: "cto"
10002
- }
10003
- };
10004
- }
10005
- function buildAgentLoopState(action) {
10006
- const at = nowIso();
10007
- return {
10008
- state: "active",
10009
- createdAt: at,
10010
- updatedAt: at,
10011
- extra: {
10012
- type: "agentLoop",
10013
- scheduleMode: "agentLoop",
10014
- schedule: action.every,
10015
- destination: { outcome: action.outcome, evidence: [] },
10016
- capabilities: action.capabilities,
10017
- route: [],
10018
- facts: {},
10019
- blockers: [],
10020
- createdByIntent: action.intentId,
10021
- manager: "cto"
10022
- }
10023
- };
10024
- }
10025
- function extractDecisionJson(finalText) {
10026
- const fence = finalText.match(/```(?:kody-agency-architect-decision|json)\s*([\s\S]*?)```/i);
10027
- if (fence?.[1]) return fence[1].trim();
10028
- const line = finalText.match(/KODY_AGENCY_ARCHITECT_DECISION=(\{[\s\S]*\})/);
10029
- if (line?.[1]) return line[1].trim();
10030
- throw new Error("missing kody-agency-architect-decision JSON");
10031
- }
10032
- function parseAction(value) {
10033
- if (!value || typeof value !== "object" || Array.isArray(value)) {
10034
- throw new Error("agency-architect action must be object");
10035
- }
10036
- const input = value;
10037
- const kind = input.kind;
10038
- if (kind === "createManagedGoal") return parseCreateManagedGoal(input);
10039
- if (kind === "createAgentLoop") return parseCreateAgentLoop(input);
10040
- if (kind === "setGoalLifecycle") return parseSetGoalLifecycle(input);
10041
- if (kind === "updateIntentPortfolio") return parseUpdateIntentPortfolio(input);
10042
- if (kind === "note") return parseNote(input);
10043
- throw new Error(`unsupported agency-architect action kind: ${String(kind)}`);
10044
- }
10045
- function parseCreateManagedGoal(input) {
10046
- const route = Array.isArray(input.route) ? input.route.map(parseRouteStep) : [];
10047
- if (route.length === 0) throw new Error("createManagedGoal requires route");
10048
- const evidence = stringArray3(input.evidence);
10049
- if (evidence.length === 0) throw new Error("createManagedGoal requires evidence");
10050
- return {
10051
- kind: "createManagedGoal",
10052
- intentId: slug(input.intentId, "intentId"),
10053
- id: slug(input.id, "id"),
10054
- outcome: requiredString(input.outcome, "outcome"),
10055
- goalType: typeof input.goalType === "string" && input.goalType.trim() ? input.goalType.trim() : void 0,
10056
- evidence,
10057
- capabilities: nonEmptyStringArray(input.capabilities, "capabilities"),
10058
- route,
10059
- facts: record(input.facts) ?? {},
10060
- reason: requiredString(input.reason, "reason")
10061
- };
10062
- }
10063
- function parseCreateAgentLoop(input) {
10064
- return {
10065
- kind: "createAgentLoop",
10066
- intentId: slug(input.intentId, "intentId"),
10067
- id: slug(input.id, "id"),
10068
- outcome: requiredString(input.outcome, "outcome"),
10069
- every: oneOf(input.every, ["manual", "1h", "1d", "7d", "30d"], "1d"),
10070
- capabilities: nonEmptyStringArray(input.capabilities, "capabilities"),
10071
- reason: requiredString(input.reason, "reason")
10072
- };
10073
- }
10074
- function parseSetGoalLifecycle(input) {
10075
- return {
10076
- kind: "setGoalLifecycle",
10077
- intentId: slug(input.intentId, "intentId"),
10078
- id: slug(input.id, "id"),
10079
- state: oneOf(input.state, ["active", "closed", "abandoned"], "active"),
10080
- reason: requiredString(input.reason, "reason")
10081
- };
10082
- }
10083
- function parseUpdateIntentPortfolio(input) {
10084
- return {
10085
- kind: "updateIntentPortfolio",
10086
- intentId: slug(input.intentId, "intentId"),
10087
- goals: stringArray3(input.goals).filter(isSlug),
10088
- loops: stringArray3(input.loops).filter(isSlug),
10089
- capabilities: stringArray3(input.capabilities).filter(isSlug),
10090
- reason: requiredString(input.reason, "reason")
10091
- };
10092
- }
10093
- function parseNote(input) {
10094
- return {
10095
- kind: "note",
10096
- intentId: typeof input.intentId === "string" && isSlug(input.intentId) ? input.intentId : void 0,
10097
- message: requiredString(input.message ?? input.content, "message")
10098
- };
10099
- }
10100
- function parseRouteStep(value) {
10101
- if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("route step must be object");
10102
- const input = value;
10103
- return {
10104
- stage: requiredString(input.stage, "route.stage"),
10105
- evidence: requiredString(input.evidence, "route.evidence"),
10106
- capability: slug(input.capability, "route.capability"),
10107
- ...typeof input.implementation === "string" && input.implementation.trim() ? { implementation: input.implementation.trim() } : {},
10108
- ...record(input.args) ? { args: record(input.args) } : {}
10109
- };
10110
- }
10111
- function slug(value, field) {
10112
- const text = requiredString(value, field);
10113
- if (!isSlug(text)) throw new Error(`${field} must be lowercase slug`);
10114
- return text;
10115
- }
10116
- function isSlug(value) {
10117
- return SLUG_RE.test(value);
10118
- }
10119
- function requiredString(value, field) {
10120
- if (typeof value !== "string" || !value.trim()) throw new Error(`${field} is required`);
10121
- return value.trim();
10122
- }
10123
- function stringArray3(value) {
10124
- if (!Array.isArray(value)) return [];
10125
- return value.filter((item) => typeof item === "string").map((item) => item.trim()).filter(Boolean);
10126
- }
10127
- function nonEmptyStringArray(value, field) {
10128
- const values = stringArray3(value);
10129
- if (values.length === 0) throw new Error(`${field} must not be empty`);
10130
- return values;
10131
- }
10132
- function record(value) {
10133
- return value && typeof value === "object" && !Array.isArray(value) ? { ...value } : null;
10134
- }
10135
- function oneOf(value, allowed, fallback) {
10136
- return typeof value === "string" && allowed.includes(value) ? value : fallback;
10137
- }
10138
- var SLUG_RE;
10139
- var init_agencyArchitectDecision = __esm({
10140
- "src/agencyArchitectDecision.ts"() {
10141
- "use strict";
10142
- init_state2();
10143
- SLUG_RE = /^[a-z][a-z0-9-]{0,63}$/;
10144
- }
10145
- });
10146
-
10147
- // src/companyIntent.ts
10148
- function isCompanyIntentId(value) {
10149
- return SLUG_RE2.test(value);
10150
- }
10151
- function companyIntentPath(id) {
10152
- assertIntentId(id);
10153
- return `intents/${id}/intent.json`;
10154
- }
10155
- function normalizeCompanyIntent(path51, raw) {
10156
- if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
10157
- throw new Error(`${path51}: intent must be JSON object`);
10158
- }
10159
- const input = raw;
10160
- const id = stringField4(input.id);
10161
- if (!id || !isCompanyIntentId(id)) throw new Error(`${path51}: invalid intent id`);
10162
- const createdAt = stringField4(input.createdAt) || nowIso();
10163
- const updatedAt = stringField4(input.updatedAt) || createdAt;
10164
- const description = stringField4(input.description);
10165
- return {
10166
- version: 1,
10167
- id,
10168
- status: oneOf2(input.status, ["active", "paused", "archived"], "active"),
10169
- for: stringField4(input.for),
10170
- ...description ? { description } : {},
10171
- priority: numberField(input.priority, 100),
10172
- posture: oneOf2(
10173
- input.posture,
10174
- ["confidence", "speed", "stability-recovery", "maintenance", "balanced"],
10175
- "balanced"
10176
- ),
10177
- scope: {
10178
- repos: stringArray4(recordField3(input.scope)?.repos),
10179
- areas: stringArray4(recordField3(input.scope)?.areas)
10180
- },
10181
- principles: stringArray4(input.principles),
10182
- metrics: stringArray4(input.metrics),
10183
- policy: {
10184
- release: normalizeReleasePolicy(recordField3(recordField3(input.policy)?.release)),
10185
- automation: normalizeAutomationPolicy(recordField3(recordField3(input.policy)?.automation))
10186
- },
10187
- portfolio: {
10188
- goals: stringArray4(recordField3(input.portfolio)?.goals).filter(isCompanyIntentId),
10189
- loops: stringArray4(recordField3(input.portfolio)?.loops).filter(isCompanyIntentId),
10190
- capabilities: stringArray4(recordField3(input.portfolio)?.capabilities).filter(isCompanyIntentId)
10191
- },
10192
- manager: normalizeManager(recordField3(input.manager)),
10193
- createdAt,
10194
- updatedAt
10195
- };
10196
- }
10197
- function listCompanyIntents(config, cwd) {
10198
- const entries = listStateDirectory(config, cwd, "intents");
10199
- const records = [];
10200
- for (const entry of entries) {
10201
- if (entry.type !== "dir" || !entry.name || !isCompanyIntentId(entry.name)) continue;
10202
- const path51 = companyIntentPath(entry.name);
10203
- const file = readStateText(config, cwd, path51);
10204
- if (!file) continue;
10205
- records.push({
10206
- id: entry.name,
10207
- path: file.path,
10208
- intent: normalizeCompanyIntent(file.path, JSON.parse(file.content))
10209
- });
10210
- }
10211
- return records.sort((a, b) => a.intent.priority - b.intent.priority || a.id.localeCompare(b.id));
10212
- }
10213
- function readCompanyIntent(config, cwd, id) {
10214
- const path51 = companyIntentPath(id);
10215
- const file = readStateText(config, cwd, path51);
10216
- if (!file) return null;
10217
- return { id, path: file.path, intent: normalizeCompanyIntent(file.path, JSON.parse(file.content)) };
10218
- }
10219
- function writeCompanyIntent(config, cwd, intent, message = `chore(intents): update ${intent.id}`) {
10220
- upsertStateText(config, cwd, companyIntentPath(intent.id), `${JSON.stringify(intent, null, 2)}
10221
- `, message);
10222
- }
10223
- function appendCompanyIntentDecision(config, cwd, intentId, entry) {
10224
- assertIntentId(intentId);
10225
- appendStateLine(
10226
- config,
10227
- cwd,
10228
- `intents/${intentId}/decisions.jsonl`,
10229
- JSON.stringify(entry),
10230
- `chore(intents): log ${intentId} decision`
10231
- );
10232
- }
10233
- function listCompanyPortfolio(config, cwd) {
10234
- const goals = [];
10235
- for (const id of listGoalStateIds(config, cwd)) {
10236
- if (!isCompanyIntentId(id)) continue;
10237
- const state = fetchGoalState(config, id, cwd);
10238
- if (!state) continue;
10239
- const destination = recordField3(state.extra.destination);
10240
- goals.push({
10241
- id,
10242
- state: state.state,
10243
- type: stringField4(state.extra.type) || void 0,
10244
- outcome: stringField4(destination?.outcome) || void 0,
10245
- capabilities: stringArray4(state.extra.capabilities),
10246
- isLoop: state.extra.scheduleMode === "agentLoop" || state.extra.type === "agentLoop",
10247
- updatedAt: state.updatedAt
10248
- });
10249
- }
10250
- return { goals: goals.sort((a, b) => a.id.localeCompare(b.id)) };
10251
- }
10252
- function writeCompanyGoalState(config, cwd, id, state, message) {
10253
- assertIntentId(id);
10254
- putGoalState(config, id, state, message, cwd);
10255
- }
10256
- function assertIntentId(id) {
10257
- if (!isCompanyIntentId(id)) throw new Error(`invalid intent/portfolio id: ${id}`);
10258
- }
10259
- function stringField4(value) {
10260
- return typeof value === "string" ? value.trim() : "";
10261
- }
10262
- function numberField(value, fallback) {
10263
- return typeof value === "number" && Number.isFinite(value) ? value : fallback;
10264
- }
10265
- function recordField3(value) {
10266
- return value && typeof value === "object" && !Array.isArray(value) ? value : null;
10267
- }
10268
- function stringArray4(value) {
10269
- if (!Array.isArray(value)) return [];
10270
- return value.filter((item) => typeof item === "string").map((item) => item.trim()).filter(Boolean);
10271
- }
10272
- function oneOf2(value, allowed, fallback) {
10273
- return typeof value === "string" && allowed.includes(value) ? value : fallback;
10274
- }
10275
- function normalizeReleasePolicy(raw) {
10276
- if (!raw) return void 0;
10277
- return {
10278
- cadence: oneOf2(raw.cadence, ["manual", "1d", "1w"], "manual"),
10279
- qaDepth: oneOf2(raw.qaDepth, ["light", "standard", "strict"], "standard"),
10280
- blockerLevel: oneOf2(raw.blockerLevel, ["low", "standard", "strict"], "standard"),
10281
- approval: oneOf2(
10282
- raw.approval,
10283
- ["none", "before-production", "before-risky-actions"],
10284
- "before-risky-actions"
10285
- )
10286
- };
10287
- }
10288
- function normalizeAutomationPolicy(raw) {
10289
- return {
10290
- authority: "full-auto",
10291
- maxConcurrentGoals: Math.max(1, Math.floor(numberField(raw?.maxConcurrentGoals, 1))),
10292
- maxDailyActions: Math.max(1, Math.floor(numberField(raw?.maxDailyActions, 6))),
10293
- requiresHumanFor: stringArray4(raw?.requiresHumanFor)
10294
- };
10295
- }
10296
- function normalizeManager(raw) {
10297
- return {
10298
- agent: "cto",
10299
- loop: "agency-architect-loop",
10300
- capability: "agency-architect",
10301
- reviewEvery: oneOf2(raw?.reviewEvery, ["1d", "1w"], "1d"),
10302
- ...typeof raw?.lastReviewedAt === "string" ? { lastReviewedAt: raw.lastReviewedAt } : {}
10303
- };
10304
- }
10305
- var SLUG_RE2;
10306
- var init_companyIntent = __esm({
10307
- "src/companyIntent.ts"() {
10308
- "use strict";
10309
- init_state2();
10310
- init_stateStore();
10311
- init_stateRepo();
10312
- SLUG_RE2 = /^[a-z][a-z0-9-]{0,63}$/;
10313
- }
10314
- });
10315
-
10316
- // src/scripts/applyAgencyArchitectDecision.ts
10317
- function applyAction(config, cwd, action) {
10318
- if (action.kind === "createManagedGoal") {
10319
- const existing = fetchGoalState(config, action.id, cwd);
10320
- if (existing) return applied(action, false, "goal already exists");
10321
- writeCompanyGoalState(
10322
- config,
10323
- cwd,
10324
- action.id,
10325
- buildManagedGoalState(action),
10326
- `chore(goals): create ${action.id} from intent ${action.intentId}`
10327
- );
10328
- return applied(action, true, action.reason, action.id);
10329
- }
10330
- if (action.kind === "createAgentLoop") {
10331
- const existing = fetchGoalState(config, action.id, cwd);
10332
- if (existing) return applied(action, false, "loop already exists");
10333
- writeCompanyGoalState(
10334
- config,
10335
- cwd,
10336
- action.id,
10337
- buildAgentLoopState(action),
10338
- `chore(goals): create loop ${action.id} from intent ${action.intentId}`
10339
- );
10340
- return applied(action, true, action.reason, action.id);
10341
- }
10342
- if (action.kind === "setGoalLifecycle") {
10343
- const state = fetchGoalState(config, action.id, cwd);
10344
- if (!state) return applied(action, false, "goal/loop missing", action.id);
10345
- const before = state.state;
10346
- if (before === action.state) return applied(action, false, "state already set", action.id);
10347
- const next = {
10348
- ...state,
10349
- state: action.state,
10350
- updatedAt: nowIso(),
10351
- extra: {
10352
- ...state.extra,
10353
- lifecycleChangedByIntent: action.intentId,
10354
- lifecycleChangeReason: action.reason
10355
- }
10356
- };
10357
- writeCompanyGoalState(
10358
- config,
10359
- cwd,
10360
- action.id,
10361
- next,
10362
- `chore(goals): ${action.state} ${action.id} from intent ${action.intentId}`
10363
- );
10364
- return applied(action, true, action.reason, action.id);
10365
- }
10366
- if (action.kind === "updateIntentPortfolio") {
10367
- const record2 = readCompanyIntent(config, cwd, action.intentId);
10368
- if (!record2) return applied(action, false, "intent missing");
10369
- const intent = {
10370
- ...record2.intent,
10371
- portfolio: {
10372
- goals: mergeUnique(record2.intent.portfolio.goals, action.goals ?? []),
10373
- loops: mergeUnique(record2.intent.portfolio.loops, action.loops ?? []),
10374
- capabilities: mergeUnique(record2.intent.portfolio.capabilities, action.capabilities ?? [])
10375
- },
10376
- updatedAt: nowIso()
10377
- };
10378
- writeCompanyIntent(config, cwd, intent, `chore(intents): update ${action.intentId} portfolio`);
10379
- return applied(action, true, action.reason);
10380
- }
10381
- if (action.kind === "note") {
10382
- return {
10383
- kind: action.kind,
10384
- intentId: action.intentId,
10385
- changed: false,
10386
- reason: action.message
10387
- };
10388
- }
10389
- return { kind: "unknown", changed: false, reason: "unsupported action" };
10390
- }
10391
- function applied(action, changed, reason, resource) {
10392
- return {
10393
- kind: action.kind,
10394
- intentId: "intentId" in action ? action.intentId : void 0,
10395
- resource,
10396
- changed,
10397
- reason
10398
- };
10399
- }
10400
- function mergeUnique(left, right) {
10401
- return [.../* @__PURE__ */ new Set([...left, ...right])].sort();
10402
- }
10403
- function logAppliedAgencyArchitectActions(config, cwd, appliedActions) {
10404
- const at = nowIso();
10405
- for (const action of appliedActions) {
10406
- if (!action.intentId) continue;
10407
- appendCompanyIntentDecision(config, cwd, action.intentId, {
10408
- at,
10409
- agent: "cto",
10410
- intentId: action.intentId,
10411
- action: action.kind,
10412
- reason: action.reason,
10413
- after: { changed: action.changed },
10414
- resources: action.resource ? [action.resource] : []
10415
- });
10416
- }
10417
- }
10418
- var applyAgencyArchitectDecision;
10419
- var init_applyAgencyArchitectDecision = __esm({
10420
- "src/scripts/applyAgencyArchitectDecision.ts"() {
10421
- "use strict";
10422
- init_agencyArchitectDecision();
10423
- init_companyIntent();
10424
- init_state2();
10425
- init_stateStore();
10426
- applyAgencyArchitectDecision = async (ctx) => {
10427
- const decision = ctx.data.agencyArchitectDecision;
10428
- if (!decision || !Array.isArray(decision.actions)) return;
10429
- if (ctx.output.exitCode !== 0) return;
10430
- const applied2 = [];
10431
- for (const action of decision.actions) {
10432
- applied2.push(applyAction(ctx.config, ctx.cwd, action));
10433
- }
10434
- ctx.data.agencyArchitectApplied = applied2;
10435
- ctx.data.agencyArchitectApplySummary = `agency-architect applied ${applied2.filter((item) => item.changed).length}/${applied2.length} action(s)`;
10436
- };
10437
- }
10438
- });
10439
-
10440
- // src/scripts/appendCompanyIntentDecision.ts
10441
- var appendCompanyIntentDecision2;
10442
- var init_appendCompanyIntentDecision = __esm({
10443
- "src/scripts/appendCompanyIntentDecision.ts"() {
10444
- "use strict";
10445
- init_applyAgencyArchitectDecision();
10446
- appendCompanyIntentDecision2 = async (ctx) => {
10447
- const applied2 = ctx.data.agencyArchitectApplied;
10448
- if (!applied2 || applied2.length === 0) return;
10449
- try {
10450
- logAppliedAgencyArchitectActions(ctx.config, ctx.cwd, applied2);
10451
- } catch (err) {
10452
- process.stderr.write(
10453
- `[agency-architect] failed append intent decision log: ${err instanceof Error ? err.message : String(err)}
10454
- `
10455
- );
10456
- }
10457
- };
10458
- }
10459
- });
10460
-
10461
9989
  // src/capabilityEvidence.ts
10462
9990
  function capabilityReportToEvidence(report) {
10463
9991
  if (report.target.type !== "goal") return null;
@@ -10628,7 +10156,7 @@ function retryAfterSecondsFor(route, evidence) {
10628
10156
  const step = route.find(
10629
10157
  (item) => !!item && typeof item === "object" && !Array.isArray(item) && item.evidence === evidence
10630
10158
  );
10631
- const policy = step && recordField4(step.onFailure);
10159
+ const policy = step && recordField3(step.onFailure);
10632
10160
  const retryAfter = typeof policy?.retryAfterSeconds === "number" ? policy.retryAfterSeconds : void 0;
10633
10161
  return retryAfter !== void 0 && retryAfter >= 0 ? Math.floor(retryAfter) : void 0;
10634
10162
  }
@@ -10677,7 +10205,7 @@ function parseStringArray3(raw) {
10677
10205
  }
10678
10206
  return out;
10679
10207
  }
10680
- function recordField4(value) {
10208
+ function recordField3(value) {
10681
10209
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
10682
10210
  }
10683
10211
  var CONTROL_FACT_KEYS3;
@@ -10734,7 +10262,7 @@ function capabilityEvidenceOutput(evidence) {
10734
10262
  function goalReportBody(goalId, state, snapshot, latestEvent, evidenceItems) {
10735
10263
  const outputs = evidenceItems.map(capabilityEvidenceOutput);
10736
10264
  const latestOutput = outputs.at(-1);
10737
- const facts = recordField5(snapshot, "facts") ?? recordField5(state.extra, "facts") ?? {};
10265
+ const facts = recordField4(snapshot, "facts") ?? recordField4(state.extra, "facts") ?? {};
10738
10266
  const blockers = uniqueStrings2([
10739
10267
  ...stringArrayField(snapshot, "blockers"),
10740
10268
  ...stringArrayField(latestEvent, "blockers"),
@@ -10753,12 +10281,12 @@ function goalReportBody(goalId, state, snapshot, latestEvent, evidenceItems) {
10753
10281
  "",
10754
10282
  "## Status",
10755
10283
  `- State: ${state.state}`,
10756
- `- Stage: ${stringField5(snapshot, "stage") ?? stringField5(state.extra, "stage") ?? "unknown"}`,
10284
+ `- Stage: ${stringField4(snapshot, "stage") ?? stringField4(state.extra, "stage") ?? "unknown"}`,
10757
10285
  `- Next step: ${nextStepFromEvent(state, snapshot, latestOutput, latestEvent)}`,
10758
10286
  `- Updated: ${state.updatedAt ?? state.createdAt ?? state.startedAt ?? "unknown"}`,
10759
10287
  "",
10760
10288
  "## Decision",
10761
- `- Event: ${stringField5(latestEvent, "event") ?? "unknown"}`,
10289
+ `- Event: ${stringField4(latestEvent, "event") ?? "unknown"}`,
10762
10290
  `- Reason: ${decisionReason(state, latestEvent, latestOutput, missingEvidence, blockers)}`,
10763
10291
  `- Required evidence: ${listOrNone(stringArrayField(snapshot, "requiredEvidence"))}`,
10764
10292
  `- Satisfied evidence: ${listOrNone(stringArrayField(snapshot, "satisfiedEvidence"))}`,
@@ -10786,9 +10314,9 @@ function capabilityEvidenceMarkdown(outputs) {
10786
10314
  function decisionReason(state, latestEvent, latestOutput, missingEvidence, blockers) {
10787
10315
  if (state.state === "done") return "destination evidence satisfied";
10788
10316
  if (blockers.length > 0) return blockers[0] ?? "blocked";
10789
- const eventReason = stringField5(latestEvent, "reason") ?? stringField5(recordField5(latestEvent, "decision"), "reason");
10317
+ const eventReason = stringField4(latestEvent, "reason") ?? stringField4(recordField4(latestEvent, "decision"), "reason");
10790
10318
  if (eventReason) return eventReason;
10791
- const summary = stringField5(latestOutput, "summary");
10319
+ const summary = stringField4(latestOutput, "summary");
10792
10320
  if (summary) return summary;
10793
10321
  if (missingEvidence.length > 0) return `waiting for ${missingEvidence[0]}`;
10794
10322
  return "waiting for more evidence";
@@ -10796,33 +10324,33 @@ function decisionReason(state, latestEvent, latestOutput, missingEvidence, block
10796
10324
  function evidenceOutputMarkdown(index, output) {
10797
10325
  return [
10798
10326
  `### Output ${index}`,
10799
- `- Status: ${stringField5(output, "status") ?? "unknown"}`,
10800
- `- Summary: ${stringField5(output, "summary") ?? "no summary"}`,
10327
+ `- Status: ${stringField4(output, "status") ?? "unknown"}`,
10328
+ `- Summary: ${stringField4(output, "summary") ?? "no summary"}`,
10801
10329
  `- Sources: ${listOrNone(stringArrayField(output, "sources"))}`,
10802
- `- Evidence values: ${inlineJson(recordField5(output, "evidence") ?? {})}`,
10330
+ `- Evidence values: ${inlineJson(recordField4(output, "evidence") ?? {})}`,
10803
10331
  `- Missing evidence: ${listOrNone(stringArrayField(output, "missingEvidence"))}`,
10804
10332
  `- Blockers: ${listOrNone(stringArrayField(output, "blockers"))}`,
10805
10333
  ""
10806
10334
  ];
10807
10335
  }
10808
10336
  function dispatchContextMarkdown(latestEvent) {
10809
- const context = recordField5(latestEvent, "dispatchContext");
10337
+ const context = recordField4(latestEvent, "dispatchContext");
10810
10338
  if (!context) return ["- none"];
10811
- const githubActor = stringField5(context, "githubActor");
10812
- const githubActorRole = stringField5(context, "githubActorRole");
10813
- const target = dispatchTargetLabel(recordField5(context, "target"));
10339
+ const githubActor = stringField4(context, "githubActor");
10340
+ const githubActorRole = stringField4(context, "githubActorRole");
10341
+ const target = dispatchTargetLabel(recordField4(context, "target"));
10814
10342
  return [
10815
- `- Triggered by: ${stringField5(context, "triggeredBy") ?? "unknown"}`,
10816
- `- Mode: ${stringField5(context, "dispatchMode") ?? "unknown"}`,
10343
+ `- Triggered by: ${stringField4(context, "triggeredBy") ?? "unknown"}`,
10344
+ `- Mode: ${stringField4(context, "dispatchMode") ?? "unknown"}`,
10817
10345
  `- GitHub actor: ${githubActor ? `${githubActor}${githubActorRole ? ` (${githubActorRole})` : ""}` : "none"}`,
10818
- `- Decided by: ${stringField5(context, "decidedBy") ?? "unknown"}`,
10819
- `- Dispatched by: ${stringField5(context, "dispatchedBy") ?? "unknown"}`,
10346
+ `- Decided by: ${stringField4(context, "decidedBy") ?? "unknown"}`,
10347
+ `- Dispatched by: ${stringField4(context, "dispatchedBy") ?? "unknown"}`,
10820
10348
  `- Target: ${target ?? "none"}`
10821
10349
  ];
10822
10350
  }
10823
10351
  function dispatchTargetLabel(target) {
10824
- const type = stringField5(target, "type");
10825
- const id = stringField5(target, "id");
10352
+ const type = stringField4(target, "type");
10353
+ const id = stringField4(target, "id");
10826
10354
  if (type && id) return `${type} ${id}`;
10827
10355
  return id ?? type;
10828
10356
  }
@@ -10845,27 +10373,27 @@ function listOrNone(values) {
10845
10373
  function uniqueStrings2(values) {
10846
10374
  return [...new Set(values)].sort();
10847
10375
  }
10848
- function stringField5(record2, key) {
10849
- const value = record2?.[key];
10376
+ function stringField4(record, key) {
10377
+ const value = record?.[key];
10850
10378
  return typeof value === "string" && value.trim() ? value : void 0;
10851
10379
  }
10852
- function recordField5(record2, key) {
10853
- const value = record2?.[key];
10380
+ function recordField4(record, key) {
10381
+ const value = record?.[key];
10854
10382
  return value && typeof value === "object" && !Array.isArray(value) ? { ...value } : void 0;
10855
10383
  }
10856
- function stringArrayField(record2, key) {
10857
- const value = record2?.[key];
10384
+ function stringArrayField(record, key) {
10385
+ const value = record?.[key];
10858
10386
  return Array.isArray(value) && value.every((item) => typeof item === "string") ? value : [];
10859
10387
  }
10860
- function artifactArrayField(record2, key) {
10861
- const value = record2?.[key];
10388
+ function artifactArrayField(record, key) {
10389
+ const value = record?.[key];
10862
10390
  if (!Array.isArray(value)) return [];
10863
10391
  return value.filter(isArtifact);
10864
10392
  }
10865
10393
  function isArtifact(value) {
10866
10394
  if (!value || typeof value !== "object" || Array.isArray(value)) return false;
10867
- const record2 = value;
10868
- return typeof record2.label === "string" && (record2.url === void 0 || typeof record2.url === "string") && (record2.path === void 0 || typeof record2.path === "string");
10395
+ const record = value;
10396
+ return typeof record.label === "string" && (record.url === void 0 || typeof record.url === "string") && (record.path === void 0 || typeof record.path === "string");
10869
10397
  }
10870
10398
  function uniqueArtifacts2(artifacts) {
10871
10399
  const seen = /* @__PURE__ */ new Set();
@@ -10882,7 +10410,7 @@ ${artifact.path ?? ""}`;
10882
10410
  }
10883
10411
  function nextStepFromEvent(state, goalAfter, capabilityOutput, latestEvent) {
10884
10412
  if (state.state === "done") return "done";
10885
- const decisionKind = stringField5(recordField5(latestEvent, "decision"), "kind") ?? stringField5(latestEvent, "status");
10413
+ const decisionKind = stringField4(recordField4(latestEvent, "decision"), "kind") ?? stringField4(latestEvent, "status");
10886
10414
  if (decisionKind === "done") return "done";
10887
10415
  if (decisionKind === "dispatch") return "dispatch";
10888
10416
  if (decisionKind === "blocked" || decisionKind === "reject-evidence") return "block";
@@ -11136,8 +10664,8 @@ function nextStepFromEvidence2(goalAfter, capabilityOutput) {
11136
10664
  if (missingEvidence.length > 0 && status !== "noop") return "dispatch";
11137
10665
  return "wait";
11138
10666
  }
11139
- function stringArrayField2(record2, key) {
11140
- const value = record2?.[key];
10667
+ function stringArrayField2(record, key) {
10668
+ const value = record?.[key];
11141
10669
  return Array.isArray(value) && value.every((item) => typeof item === "string") ? value : [];
11142
10670
  }
11143
10671
  function describeMessage(goalId, evidenceItems) {
@@ -12539,7 +12067,7 @@ function discoverPayloadCollections(cwd) {
12539
12067
  const content = fs33.readFileSync(filePath, "utf-8").slice(0, 1e4);
12540
12068
  const slugMatch = content.match(/slug:\s*['"]([a-z0-9-]+)['"]/);
12541
12069
  if (!slugMatch) continue;
12542
- const slug2 = slugMatch[1];
12070
+ const slug = slugMatch[1];
12543
12071
  const name = file.replace(/\.(ts|tsx)$/, "");
12544
12072
  const fields = [];
12545
12073
  const fieldMatches = content.matchAll(/name:\s*['"]([a-zA-Z_][a-zA-Z0-9_]*)['"]/g);
@@ -12549,7 +12077,7 @@ function discoverPayloadCollections(cwd) {
12549
12077
  const hasAdmin = /components:\s*\{/.test(content) || /Field:\s*['"]/.test(content) || /Cell:\s*['"]/.test(content) || /views:\s*\{/.test(content);
12550
12078
  out.push({
12551
12079
  name,
12552
- slug: slug2,
12080
+ slug,
12553
12081
  filePath: path32.relative(cwd, filePath),
12554
12082
  fields: fields.slice(0, 20),
12555
12083
  hasAdmin
@@ -13658,8 +13186,8 @@ function git3(args, cwd) {
13658
13186
  }).trim();
13659
13187
  }
13660
13188
  function deriveBranchName(issueNumber, title) {
13661
- const slug2 = title.toLowerCase().replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").slice(0, 50).replace(/-$/, "");
13662
- return slug2 ? `${issueNumber}-${slug2}` : `${issueNumber}-task`;
13189
+ const slug = title.toLowerCase().replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").slice(0, 50).replace(/-$/, "");
13190
+ return slug ? `${issueNumber}-${slug}` : `${issueNumber}-task`;
13663
13191
  }
13664
13192
  function getCurrentBranch(cwd) {
13665
13193
  return git3(["branch", "--show-current"], cwd);
@@ -14353,7 +13881,7 @@ function stripDirective(body) {
14353
13881
  }
14354
13882
  return lines.slice(start).join("\n").trim();
14355
13883
  }
14356
- function parseAgentFile(raw, slug2) {
13884
+ function parseAgentFile(raw, slug) {
14357
13885
  const stripped = stripLeadingFrontmatter(raw);
14358
13886
  const trimmed = stripped.trim();
14359
13887
  const firstLine2 = trimmed.split("\n", 1)[0] ?? "";
@@ -14362,14 +13890,14 @@ function parseAgentFile(raw, slug2) {
14362
13890
  const rest = trimmed.slice(firstLine2.length).replace(/^\n+/, "");
14363
13891
  return { title: h1[1].trim(), body: rest };
14364
13892
  }
14365
- return { title: humanizeSlug2(slug2), body: trimmed };
13893
+ return { title: humanizeSlug2(slug), body: trimmed };
14366
13894
  }
14367
13895
  function stripLeadingFrontmatter(raw) {
14368
13896
  const match = /^---\r?\n[\s\S]*?\r?\n---\r?\n?/.exec(raw);
14369
13897
  return match ? raw.slice(match[0].length) : raw;
14370
13898
  }
14371
- function humanizeSlug2(slug2) {
14372
- return slug2.split(/[-_]+/).filter((s) => s.length > 0).map((s) => s[0].toUpperCase() + s.slice(1)).join(" ");
13899
+ function humanizeSlug2(slug) {
13900
+ return slug.split(/[-_]+/).filter((s) => s.length > 0).map((s) => s[0].toUpperCase() + s.slice(1)).join(" ");
14373
13901
  }
14374
13902
  var loadAgentAdhoc;
14375
13903
  var init_loadAgentAdhoc = __esm({
@@ -14412,14 +13940,14 @@ var init_loadCapabilityState = __esm({
14412
13940
  CAPABILITY_TOOL_PALETTE = new Set(CAPABILITY_MCP_TOOL_NAMES);
14413
13941
  loadCapabilityState = async (ctx, profile, args) => {
14414
13942
  const jobsDir = String(args?.jobsDir ?? ".kody/capabilities");
14415
- const slug2 = profile.name;
13943
+ const slug = profile.name;
14416
13944
  const backend = resolveBackend({ config: ctx.config, cwd: ctx.cwd, jobsDir });
14417
13945
  if (backend.hydrate) await backend.hydrate();
14418
- const loaded = await backend.load(slug2);
14419
- ctx.data.jobSlug = slug2;
13946
+ const loaded = await backend.load(slug);
13947
+ ctx.data.jobSlug = slug;
14420
13948
  ctx.data.jobState = loaded;
14421
13949
  ctx.data.jobStateJson = JSON.stringify(loaded.state, null, 2);
14422
- ctx.data.capabilitySlug = slug2;
13950
+ ctx.data.capabilitySlug = slug;
14423
13951
  ctx.data.capabilityTitle = profile.describe;
14424
13952
  ctx.data.implementationSlug = profile.implementation ?? profile.name;
14425
13953
  ctx.data.agentSlug = profile.agent ?? "";
@@ -14432,7 +13960,7 @@ var init_loadCapabilityState = __esm({
14432
13960
  const unknown = declaredTools.filter((name) => !CAPABILITY_TOOL_PALETTE.has(name));
14433
13961
  if (unknown.length > 0) {
14434
13962
  throw new Error(
14435
- `loadCapabilityState: capability '${slug2}' declared capabilityTools not in the kody-capability palette: ${unknown.join(", ")}. Available: ${[...CAPABILITY_MCP_TOOL_NAMES].join(", ")}`
13963
+ `loadCapabilityState: capability '${slug}' declared capabilityTools not in the kody-capability palette: ${unknown.join(", ")}. Available: ${[...CAPABILITY_MCP_TOOL_NAMES].join(", ")}`
14436
13964
  );
14437
13965
  }
14438
13966
  const mode = profile.capabilityToolMode ?? "lock";
@@ -14452,6 +13980,141 @@ var init_loadCapabilityState = __esm({
14452
13980
  }
14453
13981
  });
14454
13982
 
13983
+ // src/companyIntent.ts
13984
+ function isCompanyIntentId(value) {
13985
+ return SLUG_RE.test(value);
13986
+ }
13987
+ function companyIntentPath(id) {
13988
+ assertIntentId(id);
13989
+ return `intents/${id}/intent.json`;
13990
+ }
13991
+ function normalizeCompanyIntent(path51, raw) {
13992
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
13993
+ throw new Error(`${path51}: intent must be JSON object`);
13994
+ }
13995
+ const input = raw;
13996
+ const id = stringField5(input.id);
13997
+ if (!id || !isCompanyIntentId(id)) throw new Error(`${path51}: invalid intent id`);
13998
+ const createdAt = stringField5(input.createdAt) || nowIso();
13999
+ const updatedAt = stringField5(input.updatedAt) || createdAt;
14000
+ const description = stringField5(input.description);
14001
+ return {
14002
+ version: 1,
14003
+ id,
14004
+ status: oneOf(input.status, ["active", "paused", "archived"], "active"),
14005
+ for: stringField5(input.for),
14006
+ ...description ? { description } : {},
14007
+ priority: numberField(input.priority, 100),
14008
+ posture: oneOf(
14009
+ input.posture,
14010
+ ["confidence", "speed", "stability-recovery", "maintenance", "balanced"],
14011
+ "balanced"
14012
+ ),
14013
+ scope: {
14014
+ repos: stringArray3(recordField5(input.scope)?.repos),
14015
+ areas: stringArray3(recordField5(input.scope)?.areas)
14016
+ },
14017
+ principles: stringArray3(input.principles),
14018
+ metrics: stringArray3(input.metrics),
14019
+ policy: {
14020
+ release: normalizeReleasePolicy(recordField5(recordField5(input.policy)?.release)),
14021
+ automation: normalizeAutomationPolicy(recordField5(recordField5(input.policy)?.automation))
14022
+ },
14023
+ portfolio: {
14024
+ goals: stringArray3(recordField5(input.portfolio)?.goals).filter(isCompanyIntentId),
14025
+ loops: stringArray3(recordField5(input.portfolio)?.loops).filter(isCompanyIntentId),
14026
+ capabilities: stringArray3(recordField5(input.portfolio)?.capabilities).filter(isCompanyIntentId)
14027
+ },
14028
+ createdAt,
14029
+ updatedAt
14030
+ };
14031
+ }
14032
+ function listCompanyIntents(config, cwd) {
14033
+ const entries = listStateDirectory(config, cwd, "intents");
14034
+ const records = [];
14035
+ for (const entry of entries) {
14036
+ if (entry.type !== "dir" || !entry.name || !isCompanyIntentId(entry.name)) continue;
14037
+ const path51 = companyIntentPath(entry.name);
14038
+ const file = readStateText(config, cwd, path51);
14039
+ if (!file) continue;
14040
+ records.push({
14041
+ id: entry.name,
14042
+ path: file.path,
14043
+ intent: normalizeCompanyIntent(file.path, JSON.parse(file.content))
14044
+ });
14045
+ }
14046
+ return records.sort((a, b) => a.intent.priority - b.intent.priority || a.id.localeCompare(b.id));
14047
+ }
14048
+ function listCompanyPortfolio(config, cwd) {
14049
+ const goals = [];
14050
+ for (const id of listGoalStateIds(config, cwd)) {
14051
+ if (!isCompanyIntentId(id)) continue;
14052
+ const state = fetchGoalState(config, id, cwd);
14053
+ if (!state) continue;
14054
+ const destination = recordField5(state.extra.destination);
14055
+ goals.push({
14056
+ id,
14057
+ state: state.state,
14058
+ type: stringField5(state.extra.type) || void 0,
14059
+ outcome: stringField5(destination?.outcome) || void 0,
14060
+ capabilities: stringArray3(state.extra.capabilities),
14061
+ isLoop: state.extra.scheduleMode === "agentLoop" || state.extra.type === "agentLoop",
14062
+ updatedAt: state.updatedAt
14063
+ });
14064
+ }
14065
+ return { goals: goals.sort((a, b) => a.id.localeCompare(b.id)) };
14066
+ }
14067
+ function assertIntentId(id) {
14068
+ if (!isCompanyIntentId(id)) throw new Error(`invalid intent/portfolio id: ${id}`);
14069
+ }
14070
+ function stringField5(value) {
14071
+ return typeof value === "string" ? value.trim() : "";
14072
+ }
14073
+ function numberField(value, fallback) {
14074
+ return typeof value === "number" && Number.isFinite(value) ? value : fallback;
14075
+ }
14076
+ function recordField5(value) {
14077
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
14078
+ }
14079
+ function stringArray3(value) {
14080
+ if (!Array.isArray(value)) return [];
14081
+ return value.filter((item) => typeof item === "string").map((item) => item.trim()).filter(Boolean);
14082
+ }
14083
+ function oneOf(value, allowed, fallback) {
14084
+ return typeof value === "string" && allowed.includes(value) ? value : fallback;
14085
+ }
14086
+ function normalizeReleasePolicy(raw) {
14087
+ if (!raw) return void 0;
14088
+ return {
14089
+ cadence: oneOf(raw.cadence, ["manual", "1d", "1w"], "manual"),
14090
+ qaDepth: oneOf(raw.qaDepth, ["light", "standard", "strict"], "standard"),
14091
+ blockerLevel: oneOf(raw.blockerLevel, ["low", "standard", "strict"], "standard"),
14092
+ approval: oneOf(
14093
+ raw.approval,
14094
+ ["none", "before-production", "before-risky-actions"],
14095
+ "before-risky-actions"
14096
+ )
14097
+ };
14098
+ }
14099
+ function normalizeAutomationPolicy(raw) {
14100
+ return {
14101
+ authority: "full-auto",
14102
+ maxConcurrentGoals: Math.max(1, Math.floor(numberField(raw?.maxConcurrentGoals, 1))),
14103
+ maxDailyActions: Math.max(1, Math.floor(numberField(raw?.maxDailyActions, 6))),
14104
+ requiresHumanFor: stringArray3(raw?.requiresHumanFor)
14105
+ };
14106
+ }
14107
+ var SLUG_RE;
14108
+ var init_companyIntent = __esm({
14109
+ "src/companyIntent.ts"() {
14110
+ "use strict";
14111
+ init_state2();
14112
+ init_stateStore();
14113
+ init_stateRepo();
14114
+ SLUG_RE = /^[a-z][a-z0-9-]{0,63}$/;
14115
+ }
14116
+ });
14117
+
14455
14118
  // src/scripts/loadCompanyIntents.ts
14456
14119
  var loadCompanyIntents;
14457
14120
  var init_loadCompanyIntents = __esm({
@@ -14460,11 +14123,11 @@ var init_loadCompanyIntents = __esm({
14460
14123
  init_companyIntent();
14461
14124
  loadCompanyIntents = async (ctx) => {
14462
14125
  const intents = listCompanyIntents(ctx.config, ctx.cwd);
14463
- const active = intents.filter((record2) => record2.intent.status === "active");
14126
+ const active = intents.filter((record) => record.intent.status === "active");
14464
14127
  ctx.data.companyIntents = intents;
14465
14128
  ctx.data.companyActiveIntents = active;
14466
14129
  ctx.data.companyIntentsJson = JSON.stringify(
14467
- active.map((record2) => record2.intent),
14130
+ active.map((record) => record.intent),
14468
14131
  null,
14469
14132
  2
14470
14133
  );
@@ -14632,7 +14295,7 @@ var init_loadIssueStateComment = __esm({
14632
14295
  // src/scripts/loadJobFromFile.ts
14633
14296
  import * as fs37 from "fs";
14634
14297
  import * as path35 from "path";
14635
- function parseJobFile(raw, slug2) {
14298
+ function parseJobFile(raw, slug) {
14636
14299
  let stripped = raw;
14637
14300
  if (stripped.startsWith("---\n")) {
14638
14301
  const end = stripped.indexOf("\n---\n", 4);
@@ -14647,10 +14310,10 @@ function parseJobFile(raw, slug2) {
14647
14310
  const rest = trimmed.slice(firstLine2.length).replace(/^\n+/, "");
14648
14311
  return { title: h1[1].trim(), body: rest };
14649
14312
  }
14650
- return { title: humanizeSlug3(slug2), body: trimmed };
14313
+ return { title: humanizeSlug3(slug), body: trimmed };
14651
14314
  }
14652
- function humanizeSlug3(slug2) {
14653
- return slug2.split(/[-_]+/).filter((s) => s.length > 0).map((s) => s[0].toUpperCase() + s.slice(1)).join(" ");
14315
+ function humanizeSlug3(slug) {
14316
+ return slug.split(/[-_]+/).filter((s) => s.length > 0).map((s) => s[0].toUpperCase() + s.slice(1)).join(" ");
14654
14317
  }
14655
14318
  var CAPABILITY_TOOL_PALETTE2, loadJobFromFile;
14656
14319
  var init_loadJobFromFile = __esm({
@@ -14665,13 +14328,13 @@ var init_loadJobFromFile = __esm({
14665
14328
  const jobsDir = String(args?.jobsDir ?? ".kody/capabilities");
14666
14329
  const agentsDir = String(args?.agentsDir ?? ".kody/agents");
14667
14330
  const slugArg = String(args?.slugArg ?? "job");
14668
- const slug2 = String(ctx.args[slugArg] ?? "").trim();
14669
- if (!slug2) {
14331
+ const slug = String(ctx.args[slugArg] ?? "").trim();
14332
+ if (!slug) {
14670
14333
  throw new Error(`loadJobFromFile: ctx.args.${slugArg} must be a non-empty slug`);
14671
14334
  }
14672
- const capability = resolveCapabilityFolder(slug2, path35.join(ctx.cwd, jobsDir));
14335
+ const capability = resolveCapabilityFolder(slug, path35.join(ctx.cwd, jobsDir));
14673
14336
  if (!capability) {
14674
- throw new Error(`loadJobFromFile: capability folder not found or incomplete: ${path35.join(ctx.cwd, jobsDir, slug2)}`);
14337
+ throw new Error(`loadJobFromFile: capability folder not found or incomplete: ${path35.join(ctx.cwd, jobsDir, slug)}`);
14675
14338
  }
14676
14339
  const { title, body, config } = capability;
14677
14340
  const mentions = (config.mentions ?? []).map((login) => `@${login}`).join(" ");
@@ -14682,7 +14345,7 @@ var init_loadJobFromFile = __esm({
14682
14345
  const agentPath = resolveAgentFile(ctx.cwd, agentSlug, agentsDir);
14683
14346
  if (!fs37.existsSync(agentPath)) {
14684
14347
  throw new Error(
14685
- `loadJobFromFile: capability '${slug2}' declares agent '${agentSlug}' but ${agentPath} does not exist`
14348
+ `loadJobFromFile: capability '${slug}' declares agent '${agentSlug}' but ${agentPath} does not exist`
14686
14349
  );
14687
14350
  }
14688
14351
  const agentRaw = fs37.readFileSync(agentPath, "utf-8");
@@ -14691,17 +14354,17 @@ var init_loadJobFromFile = __esm({
14691
14354
  agentIdentity = parsed.body;
14692
14355
  }
14693
14356
  const backend = resolveBackend({ config: ctx.config, cwd: ctx.cwd, jobsDir });
14694
- const loaded = await backend.load(slug2);
14695
- ctx.data.jobSlug = slug2;
14357
+ const loaded = await backend.load(slug);
14358
+ ctx.data.jobSlug = slug;
14696
14359
  ctx.data.jobTitle = title;
14697
- ctx.data.jobIntent = body.replace(/\{\{\s*mentions\s*\}\}/g, mentions).replace(/\{\{\s*capability\s*\}\}/g, slug2);
14360
+ ctx.data.jobIntent = body.replace(/\{\{\s*mentions\s*\}\}/g, mentions).replace(/\{\{\s*capability\s*\}\}/g, slug);
14698
14361
  ctx.data.jobState = loaded;
14699
14362
  ctx.data.jobStateJson = JSON.stringify(loaded.state, null, 2);
14700
14363
  ctx.data.agentSlug = agentSlug;
14701
14364
  ctx.data.agentTitle = agentTitle;
14702
14365
  ctx.data.agentIdentity = agentIdentity;
14703
14366
  ctx.data.mentions = mentions;
14704
- ctx.data.capabilitySlug = slug2;
14367
+ ctx.data.capabilitySlug = slug;
14705
14368
  ctx.data.capabilityTitle = title;
14706
14369
  ctx.data.agentSlug = agentSlug;
14707
14370
  ctx.data.agentTitle = agentTitle;
@@ -14712,7 +14375,7 @@ var init_loadJobFromFile = __esm({
14712
14375
  const unknown = declaredTools.filter((name) => !CAPABILITY_TOOL_PALETTE2.has(name));
14713
14376
  if (unknown.length > 0) {
14714
14377
  throw new Error(
14715
- `loadJobFromFile: capability '${slug2}' declared tools not in the kody-capability palette: ${unknown.join(", ")}. Available: ${[...CAPABILITY_MCP_TOOL_NAMES].join(", ")}`
14378
+ `loadJobFromFile: capability '${slug}' declared tools not in the kody-capability palette: ${unknown.join(", ")}. Available: ${[...CAPABILITY_MCP_TOOL_NAMES].join(", ")}`
14716
14379
  );
14717
14380
  }
14718
14381
  const mcpToolNames = declaredTools.map((name) => `mcp__kody-capability__${name}`);
@@ -15666,8 +15329,8 @@ function parseAgentFactoryBundle(raw) {
15666
15329
  };
15667
15330
  }
15668
15331
  function buildStatePrBranchName(sourceLabel, issueNumber, title, now = Date.now()) {
15669
- const slug2 = title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 48).replace(/-+$/g, "");
15670
- const suffix = slug2 ? `-${slug2}` : "";
15332
+ const slug = title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 48).replace(/-+$/g, "");
15333
+ const suffix = slug ? `-${slug}` : "";
15671
15334
  return `${sourceLabel}/issue-${issueNumber}-${now.toString(36)}${suffix}`;
15672
15335
  }
15673
15336
  function normalizeBundleFiles(ctx, bundle) {
@@ -15996,41 +15659,8 @@ QA_REPORT_POSTED=${created.url} (verdict: ${verdict})
15996
15659
  }
15997
15660
  });
15998
15661
 
15999
- // src/scripts/parseAgencyArchitectDecision.ts
16000
- function makeAction2(type, payload) {
16001
- return { type, payload, timestamp: (/* @__PURE__ */ new Date()).toISOString() };
16002
- }
16003
- var parseAgencyArchitectDecision;
16004
- var init_parseAgencyArchitectDecision = __esm({
16005
- "src/scripts/parseAgencyArchitectDecision.ts"() {
16006
- "use strict";
16007
- init_agencyArchitectDecision();
16008
- parseAgencyArchitectDecision = async (ctx, _profile, agentResult) => {
16009
- if (!agentResult) {
16010
- ctx.data.agencyArchitectDecision = { summary: "", actions: [] };
16011
- ctx.data.action = makeAction2("AGENCY_ARCHITECT_NOT_RUN", { reason: "no agent result" });
16012
- return;
16013
- }
16014
- try {
16015
- const decision = parseAgencyArchitectDecisionText(agentResult.finalText);
16016
- ctx.data.agencyArchitectDecision = decision;
16017
- ctx.data.action = makeAction2("AGENCY_ARCHITECT_DECIDED", {
16018
- summary: decision.summary,
16019
- actionCount: decision.actions.length
16020
- });
16021
- } catch (err) {
16022
- const reason = err instanceof Error ? err.message : String(err);
16023
- ctx.data.agencyArchitectDecisionError = reason;
16024
- ctx.data.action = makeAction2("AGENCY_ARCHITECT_FAILED", { reason });
16025
- ctx.output.exitCode = 1;
16026
- ctx.output.reason = reason;
16027
- }
16028
- };
16029
- }
16030
- });
16031
-
16032
15662
  // src/scripts/parseAgentResult.ts
16033
- function makeAction3(type, payload) {
15663
+ function makeAction2(type, payload) {
16034
15664
  return { type, payload, timestamp: (/* @__PURE__ */ new Date()).toISOString() };
16035
15665
  }
16036
15666
  var parseAgentResult2;
@@ -16041,7 +15671,7 @@ var init_parseAgentResult = __esm({
16041
15671
  parseAgentResult2 = async (ctx, profile, agentResult) => {
16042
15672
  if (!agentResult) {
16043
15673
  ctx.data.agentDone = false;
16044
- ctx.data.action = makeAction3("AGENT_NOT_RUN", { reason: "no agent result" });
15674
+ ctx.data.action = makeAction2("AGENT_NOT_RUN", { reason: "no agent result" });
16045
15675
  return;
16046
15676
  }
16047
15677
  const parsed = parseAgentResult(agentResult.finalText);
@@ -16058,13 +15688,13 @@ var init_parseAgentResult = __esm({
16058
15688
  ctx.data.agentError = agentResult.error;
16059
15689
  const modeSeg = (ctx.args.mode ?? profile.name).replace(/-/g, "_").toUpperCase();
16060
15690
  if (parsed.done) {
16061
- ctx.data.action = makeAction3(`${modeSeg}_COMPLETED`, {
15691
+ ctx.data.action = makeAction2(`${modeSeg}_COMPLETED`, {
16062
15692
  commitMessage: parsed.commitMessage
16063
15693
  });
16064
15694
  } else {
16065
15695
  const isGenericNoOutput = parsed.failureReason === "agent produced no final message";
16066
15696
  const reason = isGenericNoOutput && agentResult.error ? `agent SDK error: ${agentResult.error}` : parsed.failureReason || agentResult.error || "unknown failure";
16067
- ctx.data.action = makeAction3(`${modeSeg}_FAILED`, { reason });
15697
+ ctx.data.action = makeAction2(`${modeSeg}_FAILED`, { reason });
16068
15698
  }
16069
15699
  };
16070
15700
  }
@@ -16835,7 +16465,7 @@ function tryAuditComment(issueNumber, body, cwd) {
16835
16465
  } catch {
16836
16466
  }
16837
16467
  }
16838
- function makeAction4(type, payload) {
16468
+ function makeAction3(type, payload) {
16839
16469
  return { type, payload, timestamp: (/* @__PURE__ */ new Date()).toISOString() };
16840
16470
  }
16841
16471
  function failedAction4(reason) {
@@ -16872,7 +16502,7 @@ var init_recordClassification = __esm({
16872
16502
  ctx.output.reason = "classify: no decision";
16873
16503
  return;
16874
16504
  }
16875
- ctx.data.action = makeAction4(`CLASSIFIED_AS_${classification.toUpperCase()}`, {
16505
+ ctx.data.action = makeAction3(`CLASSIFIED_AS_${classification.toUpperCase()}`, {
16876
16506
  classification,
16877
16507
  reason: reason ?? "",
16878
16508
  source: ctx.data.classificationSource ?? "agent"
@@ -18204,16 +17834,16 @@ var init_runScheduledImplementationTick = __esm({
18204
17834
  const slugArg = String(args?.slugArg ?? "capability");
18205
17835
  const fenceLabel = String(args?.fenceLabel ?? "kody-job-next-state");
18206
17836
  const shell = String(args?.shell ?? "tick.sh");
18207
- const slug2 = String(args?.slug ?? ctx.args[slugArg] ?? ctx.args.capability ?? "").trim();
18208
- if (!slug2) {
17837
+ const slug = String(args?.slug ?? ctx.args[slugArg] ?? ctx.args.capability ?? "").trim();
17838
+ if (!slug) {
18209
17839
  ctx.output.exitCode = 99;
18210
17840
  ctx.output.reason = `runScheduledImplementationTick: args.slug or ctx.args.${slugArg} must be non-empty capability slug`;
18211
17841
  return;
18212
17842
  }
18213
- const capability = resolveCapabilityFolder(slug2, path41.join(ctx.cwd, jobsDir));
17843
+ const capability = resolveCapabilityFolder(slug, path41.join(ctx.cwd, jobsDir));
18214
17844
  if (!capability) {
18215
17845
  ctx.output.exitCode = 99;
18216
- ctx.output.reason = `runScheduledImplementationTick: capability folder not found or incomplete: ${slug2} (searched ${jobsDir} and company store)`;
17846
+ ctx.output.reason = `runScheduledImplementationTick: capability folder not found or incomplete: ${slug} (searched ${jobsDir} and company store)`;
18217
17847
  return;
18218
17848
  }
18219
17849
  const shellPath = path41.join(profile.dir, shell);
@@ -18225,14 +17855,14 @@ var init_runScheduledImplementationTick = __esm({
18225
17855
  const backend = resolveBackend({ config: ctx.config, cwd: ctx.cwd, jobsDir });
18226
17856
  let loaded;
18227
17857
  try {
18228
- loaded = await backend.load(slug2);
17858
+ loaded = await backend.load(slug);
18229
17859
  } catch (err) {
18230
17860
  ctx.output.exitCode = 99;
18231
17861
  ctx.output.reason = `runScheduledImplementationTick: state load failed: ${err instanceof Error ? err.message : String(err)}`;
18232
17862
  return;
18233
17863
  }
18234
- ctx.data.jobSlug = slug2;
18235
- ctx.data.capabilitySlug = slug2;
17864
+ ctx.data.jobSlug = slug;
17865
+ ctx.data.capabilitySlug = slug;
18236
17866
  ctx.data.implementationSlug = profile.name;
18237
17867
  ctx.data.jobState = loaded;
18238
17868
  runTickShellAndParse({
@@ -18262,22 +17892,22 @@ var init_runTickScript = __esm({
18262
17892
  const jobsDir = String(args?.jobsDir ?? ".kody/capabilities");
18263
17893
  const slugArg = String(args?.slugArg ?? "job");
18264
17894
  const fenceLabel = String(args?.fenceLabel ?? "kody-job-next-state");
18265
- const slug2 = String(ctx.args[slugArg] ?? "").trim();
18266
- if (!slug2) {
17895
+ const slug = String(ctx.args[slugArg] ?? "").trim();
17896
+ if (!slug) {
18267
17897
  ctx.output.exitCode = 99;
18268
17898
  ctx.output.reason = `runTickScript: ctx.args.${slugArg} must be a non-empty slug`;
18269
17899
  return;
18270
17900
  }
18271
- const capability = readCapabilityFolder(path42.join(ctx.cwd, jobsDir), slug2);
17901
+ const capability = readCapabilityFolder(path42.join(ctx.cwd, jobsDir), slug);
18272
17902
  if (!capability) {
18273
17903
  ctx.output.exitCode = 99;
18274
- ctx.output.reason = `runTickScript: capability folder not found or incomplete: ${path42.join(ctx.cwd, jobsDir, slug2)}`;
17904
+ ctx.output.reason = `runTickScript: capability folder not found or incomplete: ${path42.join(ctx.cwd, jobsDir, slug)}`;
18275
17905
  return;
18276
17906
  }
18277
17907
  const tickScript = capability.config.tickScript;
18278
17908
  if (!tickScript) {
18279
17909
  ctx.output.exitCode = 99;
18280
- ctx.output.reason = `runTickScript: capability ${slug2} has no \`tickScript\` in profile.json \u2014 route via capability-tick instead`;
17910
+ ctx.output.reason = `runTickScript: capability ${slug} has no \`tickScript\` in profile.json \u2014 route via capability-tick instead`;
18281
17911
  return;
18282
17912
  }
18283
17913
  const scriptPath = path42.isAbsolute(tickScript) ? tickScript : path42.join(ctx.cwd, tickScript);
@@ -18289,13 +17919,13 @@ var init_runTickScript = __esm({
18289
17919
  const backend = resolveBackend({ config: ctx.config, cwd: ctx.cwd, jobsDir });
18290
17920
  let loaded;
18291
17921
  try {
18292
- loaded = await backend.load(slug2);
17922
+ loaded = await backend.load(slug);
18293
17923
  } catch (err) {
18294
17924
  ctx.output.exitCode = 99;
18295
17925
  ctx.output.reason = `runTickScript: state load failed: ${err instanceof Error ? err.message : String(err)}`;
18296
17926
  return;
18297
17927
  }
18298
- ctx.data.jobSlug = slug2;
17928
+ ctx.data.jobSlug = slug;
18299
17929
  ctx.data.jobState = loaded;
18300
17930
  runTickShellAndParse({
18301
17931
  ctx,
@@ -18567,7 +18197,7 @@ function validateModelBundle(bundle, producer) {
18567
18197
  const failures = [];
18568
18198
  const expectedKind = CREATOR_KIND[producer];
18569
18199
  if (producer === FACTORY_PRODUCER) {
18570
- const contracts = stringArray5(bundle.modelCreatorContractsUsed);
18200
+ const contracts = stringArray4(bundle.modelCreatorContractsUsed);
18571
18201
  for (const contract of CREATOR_CONTRACTS) {
18572
18202
  if (!contracts.includes(contract)) failures.push(`modelCreatorContractsUsed missing ${contract}`);
18573
18203
  }
@@ -18594,36 +18224,36 @@ function validateOneModel(rawModel, files, label, strictSingleModel, failures, e
18594
18224
  if (!isModelKind(kind)) failures.push(`${label}.kind must be agent, capability, goal, agentLoop, or workflow`);
18595
18225
  if (expectedKind && kind !== expectedKind && producer)
18596
18226
  failures.push(`${producer} must output model.kind ${expectedKind}`);
18597
- const slug2 = stringField6(model.slug);
18598
- if (!isSlug2(slug2)) failures.push(`${label}.slug must be a lowercase slug`);
18227
+ const slug = stringField6(model.slug);
18228
+ if (!isSlug(slug)) failures.push(`${label}.slug must be a lowercase slug`);
18599
18229
  if (isModelKind(kind)) {
18600
- const docsUsed = stringArray5(model.docsUsed);
18230
+ const docsUsed = stringArray4(model.docsUsed);
18601
18231
  for (const doc of REQUIRED_DOCS[kind]) {
18602
18232
  if (!docsUsed.includes(doc)) failures.push(`${label} docsUsed missing ${doc}`);
18603
18233
  }
18604
- validateFilesForKind(kind, slug2, files, strictSingleModel, failures);
18605
- validateModelShape(kind, model, files, slug2, failures);
18234
+ validateFilesForKind(kind, slug, files, strictSingleModel, failures);
18235
+ validateModelShape(kind, model, files, slug, failures);
18606
18236
  }
18607
18237
  }
18608
- function validateFilesForKind(kind, slug2, files, strictSingleModel, failures) {
18238
+ function validateFilesForKind(kind, slug, files, strictSingleModel, failures) {
18609
18239
  const paths = files.map((file) => normalizeBundlePath(file.path));
18610
18240
  if (paths.some((filePath) => filePath === "implementations" || filePath.startsWith("implementations/"))) {
18611
18241
  failures.push("files must not use obsolete implementation storage");
18612
18242
  }
18613
18243
  if (kind === "agent") {
18614
- requirePath(paths, `agents/${slug2}.md`, "agent file", failures);
18244
+ requirePath(paths, `agents/${slug}.md`, "agent file", failures);
18615
18245
  if (strictSingleModel) rejectOtherRoots(paths, ["agents/"], "agent", failures);
18616
18246
  }
18617
18247
  if (kind === "capability") {
18618
- requirePath(paths, `capabilities/${slug2}/profile.json`, "capability profile", failures);
18619
- requirePath(paths, `capabilities/${slug2}/capability.md`, "capability body", failures);
18620
- if (strictSingleModel) rejectOtherRoots(paths, [`capabilities/${slug2}/`], "capability", failures);
18621
- const profile = parseJsonFile(files, `capabilities/${slug2}/profile.json`, failures);
18248
+ requirePath(paths, `capabilities/${slug}/profile.json`, "capability profile", failures);
18249
+ requirePath(paths, `capabilities/${slug}/capability.md`, "capability body", failures);
18250
+ if (strictSingleModel) rejectOtherRoots(paths, [`capabilities/${slug}/`], "capability", failures);
18251
+ const profile = parseJsonFile(files, `capabilities/${slug}/profile.json`, failures);
18622
18252
  if (profile) {
18623
18253
  const profileSlug = stringField6(profile.slug);
18624
18254
  const profileName = stringField6(profile.name);
18625
- if (profileSlug && profileSlug !== slug2) failures.push("capability profile slug must match model.slug");
18626
- if (!profileSlug && profileName && profileName !== slug2) {
18255
+ if (profileSlug && profileSlug !== slug) failures.push("capability profile slug must match model.slug");
18256
+ if (!profileSlug && profileName && profileName !== slug) {
18627
18257
  failures.push("capability profile name must match model.slug when slug is absent");
18628
18258
  }
18629
18259
  if (profile.agent !== void 0)
@@ -18634,8 +18264,8 @@ function validateFilesForKind(kind, slug2, files, strictSingleModel, failures) {
18634
18264
  }
18635
18265
  }
18636
18266
  if (kind === "goal") {
18637
- requirePath(paths, `goals/templates/${slug2}/state.json`, "goal template state", failures);
18638
- if (strictSingleModel) rejectOtherRoots(paths, [`goals/templates/${slug2}/`], "goal", failures);
18267
+ requirePath(paths, `goals/templates/${slug}/state.json`, "goal template state", failures);
18268
+ if (strictSingleModel) rejectOtherRoots(paths, [`goals/templates/${slug}/`], "goal", failures);
18639
18269
  }
18640
18270
  if (kind === "agentLoop") {
18641
18271
  if (!paths.some((filePath) => filePath.endsWith("/state.json")))
@@ -18643,8 +18273,8 @@ function validateFilesForKind(kind, slug2, files, strictSingleModel, failures) {
18643
18273
  if (strictSingleModel) rejectOtherRoots(paths, ["goals/", "loops/", "capabilities/"], "agentLoop", failures);
18644
18274
  }
18645
18275
  if (kind === "workflow") {
18646
- requirePath(paths, `capabilities/${slug2}/profile.json`, "workflow capability profile", failures);
18647
- const profile = parseJsonFile(files, `capabilities/${slug2}/profile.json`, failures);
18276
+ requirePath(paths, `capabilities/${slug}/profile.json`, "workflow capability profile", failures);
18277
+ const profile = parseJsonFile(files, `capabilities/${slug}/profile.json`, failures);
18648
18278
  if (profile) {
18649
18279
  if (profile.capabilityKind !== void 0) {
18650
18280
  failures.push("workflow profile must not declare capabilityKind");
@@ -18663,8 +18293,8 @@ function validateFactoryAssembly(models, failures) {
18663
18293
  if (!model || typeof model !== "object" || Array.isArray(model)) continue;
18664
18294
  const input = model;
18665
18295
  const kind = stringField6(input.kind);
18666
- const slug2 = stringField6(input.slug);
18667
- if (isModelKind(kind) && isSlug2(slug2)) available.set(`${kind}:${slug2}`, kind);
18296
+ const slug = stringField6(input.slug);
18297
+ if (isModelKind(kind) && isSlug(slug)) available.set(`${kind}:${slug}`, kind);
18668
18298
  }
18669
18299
  for (const model of models) {
18670
18300
  if (!model || typeof model !== "object" || Array.isArray(model)) continue;
@@ -18678,7 +18308,7 @@ function validateFactoryAssembly(models, failures) {
18678
18308
  }
18679
18309
  }
18680
18310
  if (kind === "workflow") {
18681
- for (const capability of stringArray5(input.steps)) {
18311
+ for (const capability of stringArray4(input.steps)) {
18682
18312
  if (!available.has(`capability:${capability}`)) {
18683
18313
  failures.push(`workflow ${stringField6(input.slug)} references missing capability ${capability}`);
18684
18314
  }
@@ -18708,10 +18338,10 @@ function validateFactoryAssembly(models, failures) {
18708
18338
  }
18709
18339
  }
18710
18340
  }
18711
- function validateModelShape(kind, model, files, slug2, failures) {
18341
+ function validateModelShape(kind, model, files, slug, failures) {
18712
18342
  if (kind === "agent") {
18713
- const agentFile = textFile(files, `agents/${slug2}.md`);
18714
- if (!stringArray5(model.owns).includes("identity") && !containsWord(agentFile, "identity")) {
18343
+ const agentFile = textFile(files, `agents/${slug}.md`);
18344
+ if (!stringArray4(model.owns).includes("identity") && !containsWord(agentFile, "identity")) {
18715
18345
  failures.push("agent owns must include identity");
18716
18346
  }
18717
18347
  requireStringArrayIncludes(model.doesNotOwn, "tasks", "agent doesNotOwn", failures);
@@ -18728,7 +18358,7 @@ function validateModelShape(kind, model, files, slug2, failures) {
18728
18358
  requireStringArrayIncludes(model.doesNotOwn, "goal progress", "capability doesNotOwn", failures);
18729
18359
  }
18730
18360
  if (kind === "goal") {
18731
- const goalState = parseJsonContent(textFile(files, `goals/templates/${slug2}/state.json`));
18361
+ const goalState = parseJsonContent(textFile(files, `goals/templates/${slug}/state.json`));
18732
18362
  if (!stringField6(model.outcome) && !stringField6(goalState?.outcome))
18733
18363
  failures.push("goal model must declare outcome");
18734
18364
  if (evidenceRefs(model).length === 0 && evidenceRefs(goalState).length === 0) {
@@ -18740,7 +18370,7 @@ function validateModelShape(kind, model, files, slug2, failures) {
18740
18370
  }
18741
18371
  if (kind === "agentLoop") {
18742
18372
  if (!stringField6(model.cadence)) failures.push("agentLoop model must declare cadence");
18743
- const loopState = parseJsonContent(firstStateFile(files, slug2));
18373
+ const loopState = parseJsonContent(firstStateFile(files, slug));
18744
18374
  const hasTarget = Boolean(wakeTarget(model)) || Boolean(stringField6(model.target)) || Boolean(wakeTarget(loopState)) || Boolean(stringField6(loopState?.target)) || Boolean(loopTargetString(loopState));
18745
18375
  if (!hasTarget) {
18746
18376
  failures.push("agentLoop model must declare wakeTarget object");
@@ -18754,7 +18384,7 @@ function validateModelShape(kind, model, files, slug2, failures) {
18754
18384
  }
18755
18385
  }
18756
18386
  function capabilityRefs(value) {
18757
- return [...stringArray5(value?.capabilities), ...stringArray5(value?.allowedCapabilities)];
18387
+ return [...stringArray4(value?.capabilities), ...stringArray4(value?.allowedCapabilities)];
18758
18388
  }
18759
18389
  function evidenceRefs(value) {
18760
18390
  if (!value) return [];
@@ -18767,8 +18397,8 @@ function wakeTarget(value) {
18767
18397
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
18768
18398
  const target = raw;
18769
18399
  const type = stringField6(target.type);
18770
- const slug2 = stringField6(target.slug);
18771
- if ((type === "goal" || type === "workflow" || type === "capability") && slug2) return { kind: type, slug: slug2 };
18400
+ const slug = stringField6(target.slug);
18401
+ if ((type === "goal" || type === "workflow" || type === "capability") && slug) return { kind: type, slug };
18772
18402
  return null;
18773
18403
  }
18774
18404
  function loopTargetString(value) {
@@ -18779,8 +18409,8 @@ function loopTargetString(value) {
18779
18409
  function textFile(files, wantedPath) {
18780
18410
  return files.find((item) => normalizeBundlePath(item.path) === wantedPath)?.content ?? "";
18781
18411
  }
18782
- function firstStateFile(files, slug2) {
18783
- const normalizedSlug = `${slug2}/state.json`;
18412
+ function firstStateFile(files, slug) {
18413
+ const normalizedSlug = `${slug}/state.json`;
18784
18414
  return files.find((item) => normalizeBundlePath(item.path).endsWith(normalizedSlug))?.content ?? "";
18785
18415
  }
18786
18416
  function parseJsonContent(content) {
@@ -18826,7 +18456,7 @@ function normalizeBundlePath(filePath) {
18826
18456
  function stringField6(value) {
18827
18457
  return typeof value === "string" ? value.trim() : "";
18828
18458
  }
18829
- function stringArray5(value) {
18459
+ function stringArray4(value) {
18830
18460
  if (!Array.isArray(value)) return [];
18831
18461
  return value.filter((item) => typeof item === "string").map((item) => item.trim()).filter(Boolean);
18832
18462
  }
@@ -18837,9 +18467,9 @@ function arrayObjects(value) {
18837
18467
  );
18838
18468
  }
18839
18469
  function requireStringArrayIncludes(value, expected, label, failures) {
18840
- if (!stringArray5(value).includes(expected)) failures.push(`${label} must include ${expected}`);
18470
+ if (!stringArray4(value).includes(expected)) failures.push(`${label} must include ${expected}`);
18841
18471
  }
18842
- function isSlug2(value) {
18472
+ function isSlug(value) {
18843
18473
  return /^[a-z][a-z0-9-]{0,63}$/.test(value);
18844
18474
  }
18845
18475
  function isModelKind(value) {
@@ -19572,8 +19202,6 @@ var init_scripts = __esm({
19572
19202
  init_advanceFlow();
19573
19203
  init_advanceManagedGoal();
19574
19204
  init_appendCompanyActivity();
19575
- init_appendCompanyIntentDecision();
19576
- init_applyAgencyArchitectDecision();
19577
19205
  init_applyCapabilityReports();
19578
19206
  init_buildSyntheticPlugin();
19579
19207
  init_checkCoverageWithRetry();
@@ -19621,7 +19249,6 @@ var init_scripts = __esm({
19621
19249
  init_notifyTerminal();
19622
19250
  init_openAgentFactoryStatePr();
19623
19251
  init_openQaIssue();
19624
- init_parseAgencyArchitectDecision();
19625
19252
  init_parseAgentResult();
19626
19253
  init_parseIssueStateFromAgentResult();
19627
19254
  init_parseJobStateFromAgentResult();
@@ -19719,7 +19346,6 @@ var init_scripts = __esm({
19719
19346
  };
19720
19347
  postflightScripts = {
19721
19348
  parseAgentResult: parseAgentResult2,
19722
- parseAgencyArchitectDecision,
19723
19349
  parseIssueStateFromAgentResult,
19724
19350
  parseJobStateFromAgentResult,
19725
19351
  parseReproOutput,
@@ -19727,8 +19353,6 @@ var init_scripts = __esm({
19727
19353
  writeIssueStateComment,
19728
19354
  writeJobStateFile,
19729
19355
  appendCompanyActivity,
19730
- appendCompanyIntentDecision: appendCompanyIntentDecision2,
19731
- applyAgencyArchitectDecision,
19732
19356
  requireFeedbackActions,
19733
19357
  requirePlanDeviations,
19734
19358
  verify,
@@ -19890,6 +19514,7 @@ var init_stateWorkspace = __esm({
19890
19514
  ];
19891
19515
  FILE_MAPPINGS = [
19892
19516
  { statePath: "instructions.md", localPath: path43.join(".kody", "instructions.md") },
19517
+ { statePath: "system-prompt.md", localPath: path43.join(".kody", "system-prompt.md") },
19893
19518
  { statePath: "variables.json", localPath: path43.join(".kody", "variables.json") },
19894
19519
  { statePath: "secrets.enc", localPath: path43.join(".kody", "secrets.enc") }
19895
19520
  ];
@@ -20248,6 +19873,7 @@ async function runImplementation(profileName, input) {
20248
19873
  // keys trust per capability (not per agent). `jobSlug` is set by loadJobFromFile.
20249
19874
  capabilitySlug: typeof ctx.data.jobSlug === "string" ? ctx.data.jobSlug : void 0,
20250
19875
  capabilityState: config.state,
19876
+ capabilityDefaultBranch: config.git.defaultBranch,
20251
19877
  // owner/repo from kody.config.json; envelope falls back to GITHUB_REPOSITORY
20252
19878
  // for tester repos that don't set config.github (the file isn't always
20253
19879
  // checked in). Either way, capabilityMcp needs "owner/name" to hit the compare API.
@@ -21263,14 +20889,14 @@ function filterCliArgsForStep(action, raw) {
21263
20889
  function composeStepWhy(parentWhy, step) {
21264
20890
  return [parentWhy?.trim(), step.reason ? `Workflow step: ${step.reason}` : ""].filter((part) => Boolean(part)).join("\n\n");
21265
20891
  }
21266
- function loadCapabilityContext(slug2, cwd) {
21267
- if (!slug2) return null;
21268
- return resolveCapabilityFolder(slug2, path45.join(cwd, ".kody", "capabilities"));
20892
+ function loadCapabilityContext(slug, cwd) {
20893
+ if (!slug) return null;
20894
+ return resolveCapabilityFolder(slug, path45.join(cwd, ".kody", "capabilities"));
21269
20895
  }
21270
- function loadWorkflowContext(slug2, base) {
21271
- if (!slug2 || !base.config || !isWorkflowDefinitionId(slug2)) return null;
21272
- const workflow = readWorkflowDefinition(base.config, base.cwd, slug2);
21273
- return workflow ? workflowDefinitionToCapabilityFolder(slug2, workflow) : null;
20896
+ function loadWorkflowContext(slug, base) {
20897
+ if (!slug || !base.config || !isWorkflowDefinitionId(slug)) return null;
20898
+ const workflow = readWorkflowDefinition(base.config, base.cwd, slug);
20899
+ return workflow ? workflowDefinitionToCapabilityFolder(slug, workflow) : null;
21274
20900
  }
21275
20901
  function mintInstantJob(dispatch2, opts) {
21276
20902
  return {
@@ -21782,7 +21408,7 @@ async function runChatTurn(opts) {
21782
21408
  return { exitCode: 64, error };
21783
21409
  }
21784
21410
  const { turns: promptTurns, imagePaths } = prepareAttachments(turns, opts.cwd, opts.sessionId);
21785
- const basePrompt = opts.systemPrompt ?? (opts.model.protocol === "openai" ? OPENAI_CHAT_SYSTEM_PROMPT : CHAT_SYSTEM_PROMPT);
21411
+ const basePrompt = opts.systemPrompt ?? readSystemPromptOverride(opts.cwd) ?? (opts.model.protocol === "openai" ? OPENAI_CHAT_SYSTEM_PROMPT : CHAT_SYSTEM_PROMPT);
21786
21412
  const agentIdentityBlock = readAgentIdentityBlock(opts.cwd, opts.agentIdentity);
21787
21413
  const catalog = buildImplementationCatalog();
21788
21414
  const taskArtifactsPaths = prepareTaskArtifactsDir(opts.cwd, opts.sessionId);
@@ -21930,10 +21556,10 @@ async function runChatTurn(opts) {
21930
21556
  return { exitCode: 0, reply };
21931
21557
  }
21932
21558
  function readAgentIdentityBlock(cwd, agentIdentity) {
21933
- const slug2 = agentIdentity?.slug?.trim();
21934
- if (!slug2) return null;
21935
- const body = agentIdentity?.body?.trim() || loadAgentIdentity(cwd, slug2);
21936
- return frameAgentIdentity(slug2, body);
21559
+ const slug = agentIdentity?.slug?.trim();
21560
+ if (!slug) return null;
21561
+ const body = agentIdentity?.body?.trim() || loadAgentIdentity(cwd, slug);
21562
+ return frameAgentIdentity(slug, body);
21937
21563
  }
21938
21564
  async function runOpenAIChatTurn(args) {
21939
21565
  const { opts, turns, systemPrompt, sessionFile } = args;
@@ -22075,6 +21701,17 @@ _\u2026 (context truncated; use the state repo context files for the full text)_
22075
21701
  }
22076
21702
  var INSTRUCTIONS_REL = ".kody/instructions.md";
22077
21703
  var MAX_INSTRUCTIONS_BYTES = 8e3;
21704
+ var SYSTEM_PROMPT_OVERRIDE_REL = ".kody/system-prompt.md";
21705
+ function readSystemPromptOverride(cwd) {
21706
+ let raw;
21707
+ try {
21708
+ raw = fs14.readFileSync(path16.join(cwd, SYSTEM_PROMPT_OVERRIDE_REL), "utf-8");
21709
+ } catch {
21710
+ return null;
21711
+ }
21712
+ const trimmed = raw.trim();
21713
+ return trimmed.length > 0 ? trimmed : null;
21714
+ }
22078
21715
  function readInstructionsBlock(cwd) {
22079
21716
  const instructionsPath = path16.join(cwd, INSTRUCTIONS_REL);
22080
21717
  let raw;
@@ -23626,11 +23263,11 @@ function agentIdentityField(body) {
23626
23263
  if (typeof body !== "object" || body === null || !("agentIdentity" in body)) return void 0;
23627
23264
  const value = body.agentIdentity;
23628
23265
  if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
23629
- const record2 = value;
23630
- const slug2 = typeof record2.slug === "string" ? record2.slug.trim() : "";
23631
- const bodyText = typeof record2.body === "string" ? record2.body.trim() : "";
23632
- if (!slug2 || !bodyText) return void 0;
23633
- return { slug: slug2, body: bodyText };
23266
+ const record = value;
23267
+ const slug = typeof record.slug === "string" ? record.slug.trim() : "";
23268
+ const bodyText = typeof record.body === "string" ? record.body.trim() : "";
23269
+ if (!slug || !bodyText) return void 0;
23270
+ return { slug, body: bodyText };
23634
23271
  }
23635
23272
  function sendJson(res, status, body) {
23636
23273
  res.writeHead(status, { "content-type": "application/json" });