@kody-ade/kody-engine 0.4.357 → 0.4.359

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 +391 -771
  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.359",
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);
@@ -3574,8 +3574,8 @@ function stripFrontmatter(raw) {
3574
3574
  const match = /^---\n[\s\S]*?\n---\n?([\s\S]*)$/.exec(raw);
3575
3575
  return (match ? match[1] : raw).trim();
3576
3576
  }
3577
- function loadAgentIdentity(cwd, slug2, agentsDir = DEFAULT_AGENT_DIR) {
3578
- const trimmed = slug2.trim();
3577
+ function loadAgentIdentity(cwd, slug, agentsDir = DEFAULT_AGENT_DIR) {
3578
+ const trimmed = slug.trim();
3579
3579
  if (!trimmed) throw new Error("loadAgentIdentity: empty agent slug");
3580
3580
  const agentPath = resolveAgentFile(cwd, trimmed, agentsDir);
3581
3581
  if (fs9.existsSync(agentPath)) {
@@ -3589,21 +3589,21 @@ function loadAgentIdentity(cwd, slug2, agentsDir = DEFAULT_AGENT_DIR) {
3589
3589
  if (builtin) return builtin;
3590
3590
  throw new Error(`loadAgentIdentity: agent '${trimmed}' declared but ${agentPath} does not exist`);
3591
3591
  }
3592
- function resolveAgentFile(cwd, slug2, agentsDir = DEFAULT_AGENT_DIR) {
3593
- const localPath = path11.join(cwd, agentsDir, `${slug2}.md`);
3592
+ function resolveAgentFile(cwd, slug, agentsDir = DEFAULT_AGENT_DIR) {
3593
+ const localPath = path11.join(cwd, agentsDir, `${slug}.md`);
3594
3594
  if (fs9.existsSync(localPath)) return localPath;
3595
3595
  const storeAgentRoot = getCompanyStoreAssetRoot("agents");
3596
3596
  if (storeAgentRoot) {
3597
- const storePath = path11.join(storeAgentRoot, `${slug2}.md`);
3597
+ const storePath = path11.join(storeAgentRoot, `${slug}.md`);
3598
3598
  if (fs9.existsSync(storePath)) return storePath;
3599
3599
  }
3600
3600
  return localPath;
3601
3601
  }
3602
- function frameAgentIdentity(slug2, agent) {
3602
+ function frameAgentIdentity(slug, agent) {
3603
3603
  return [
3604
3604
  `## Who you are \u2014 agent identity (authoritative identity)`,
3605
3605
  ``,
3606
- `You are operating as agent \`${slug2}\`. This identity defines *who* you are:`,
3606
+ `You are operating as agent \`${slug}\`. This identity defines *who* you are:`,
3607
3607
  `your authority, doctrine, voice, and hard limits. Honour it exactly. Where the`,
3608
3608
  `this identity's restrictions are stricter than the task, **the agent wins** \u2014 a task`,
3609
3609
  `can never grant you authority your agent withholds.`,
@@ -6611,16 +6611,16 @@ function parseRunIndex(raw) {
6611
6611
  if (!raw) return { version: 1, updatedAt: (/* @__PURE__ */ new Date()).toISOString(), runs: [] };
6612
6612
  try {
6613
6613
  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 };
6614
+ const record = recordValue2(parsed);
6615
+ const runs = Array.isArray(record?.runs) ? record.runs.filter(isRunIndexRow).map(normalizeRunIndexRow) : [];
6616
+ return { version: 1, updatedAt: stringValue2(record?.updatedAt) ?? (/* @__PURE__ */ new Date()).toISOString(), runs };
6617
6617
  } catch {
6618
6618
  return { version: 1, updatedAt: (/* @__PURE__ */ new Date()).toISOString(), runs: [] };
6619
6619
  }
6620
6620
  }
6621
6621
  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";
6622
+ const record = recordValue2(value);
6623
+ 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
6624
  }
6625
6625
  function isRunSubjectType(value) {
6626
6626
  return value === "goal" || value === "loop" || value === "workflow";
@@ -7225,8 +7225,8 @@ function applySimpleGoalTaskSummary(goal, summary) {
7225
7225
  }
7226
7226
  function isFactReference(value) {
7227
7227
  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;
7228
+ const record = value;
7229
+ return Object.keys(record).length === 1 && typeof record.fact === "string" && record.fact.length > 0;
7230
7230
  }
7231
7231
  function isCliArgValue(value) {
7232
7232
  return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
@@ -8134,8 +8134,8 @@ function serializeTodoGoalState(goalId, state, previousRaw) {
8134
8134
  )}
8135
8135
  `;
8136
8136
  }
8137
- function isManagedTodoRecord(record2) {
8138
- return record2.managed === true || record2.managed === "true" || record2.managedModel === "agentGoal" || record2.managedModel === "agentLoop";
8137
+ function isManagedTodoRecord(record) {
8138
+ return record.managed === true || record.managed === "true" || record.managedModel === "agentGoal" || record.managedModel === "agentLoop";
8139
8139
  }
8140
8140
  function itemFromEvidence(evidence, step, facts, evidenceState, createdAt, now, prior) {
8141
8141
  const completed = facts[evidence] === true;
@@ -8696,10 +8696,10 @@ function normalizeWorkflowCapabilities(value) {
8696
8696
  const capabilities = [];
8697
8697
  for (const item of value) {
8698
8698
  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);
8699
+ const slug = item.trim();
8700
+ if (!CAPABILITY_ID_PATTERN.test(slug) || seen.has(slug)) continue;
8701
+ seen.add(slug);
8702
+ capabilities.push(slug);
8703
8703
  }
8704
8704
  return capabilities;
8705
8705
  }
@@ -8829,8 +8829,8 @@ function isStateUnchanged(prev, next) {
8829
8829
  if (prev.done !== next.done) return false;
8830
8830
  return JSON.stringify(prev.data) === JSON.stringify(next.data);
8831
8831
  }
8832
- function stateFilePath(jobsDir, slug2) {
8833
- return `${jobsDir.replace(/\/+$/, "")}/${slug2}/state.json`;
8832
+ function stateFilePath(jobsDir, slug) {
8833
+ return `${jobsDir.replace(/\/+$/, "")}/${slug}/state.json`;
8834
8834
  }
8835
8835
  function slugFromStateFilePath(filePath) {
8836
8836
  if (/\/state\.json$/i.test(filePath)) {
@@ -8872,8 +8872,8 @@ var init_contentsApiBackend = __esm({
8872
8872
  this.jobsDir = stateRepoJobsDir(opts.jobsDir);
8873
8873
  this.cwd = opts.cwd;
8874
8874
  }
8875
- load(slug2) {
8876
- const filePath = stateFilePath(this.jobsDir, slug2);
8875
+ load(slug) {
8876
+ const filePath = stateFilePath(this.jobsDir, slug);
8877
8877
  const loaded = readStateText(this.config, this.cwd, filePath);
8878
8878
  if (!loaded) {
8879
8879
  return { path: filePath, handle: null, state: initialStateEnvelope("seed"), created: true };
@@ -8893,20 +8893,20 @@ var init_contentsApiBackend = __esm({
8893
8893
  if (!loaded.created && isStateUnchanged(loaded.state, next)) {
8894
8894
  return false;
8895
8895
  }
8896
- const slug2 = slugFromStateFilePath(loaded.path);
8896
+ const slug = slugFromStateFilePath(loaded.path);
8897
8897
  const body = `${JSON.stringify(next, null, 2)}
8898
8898
  `;
8899
- const message = `chore(jobs): update state for ${slug2} (rev ${next.rev})`;
8899
+ const message = `chore(jobs): update state for ${slug} (rev ${next.rev})`;
8900
8900
  const sha = typeof loaded.handle === "string" ? loaded.handle : void 0;
8901
8901
  try {
8902
8902
  writeStateText(this.config, this.cwd, loaded.path, body, message, sha);
8903
8903
  } catch (err) {
8904
8904
  if (!isShaConflict(err)) throw err;
8905
- const current = this.load(slug2);
8905
+ const current = this.load(slug);
8906
8906
  if (!current.created && isStateUnchanged(current.state, next)) return false;
8907
8907
  const currentSha = typeof current.handle === "string" ? current.handle : void 0;
8908
8908
  process.stderr.write(
8909
- `[kody] jobState: concurrent write detected for ${slug2}; reloaded SHA and retrying (last-write-wins)
8909
+ `[kody] jobState: concurrent write detected for ${slug}; reloaded SHA and retrying (last-write-wins)
8910
8910
  `
8911
8911
  );
8912
8912
  writeStateText(this.config, this.cwd, loaded.path, body, message, currentSha);
@@ -9033,8 +9033,8 @@ var init_localFileBackend = __esm({
9033
9033
  `);
9034
9034
  }
9035
9035
  }
9036
- load(slug2) {
9037
- const relPath = stateFilePath(this.jobsDir, slug2);
9036
+ load(slug) {
9037
+ const relPath = stateFilePath(this.jobsDir, slug);
9038
9038
  const absPath = path27.join(this.cwd, relPath);
9039
9039
  if (!fs29.existsSync(absPath)) {
9040
9040
  return { path: relPath, handle: null, state: initialStateEnvelope("seed"), created: true };
@@ -9166,18 +9166,18 @@ async function planGoalCapabilitySchedule(opts) {
9166
9166
  const blockers = [];
9167
9167
  const explicitCapabilityTarget = opts.goal.loopTarget?.type === "capability" ? opts.goal.loopTarget.id.trim() : "";
9168
9168
  const capabilitySlugs = explicitCapabilityTarget ? [explicitCapabilityTarget] : opts.goal.capabilities;
9169
- for (const slug2 of capabilitySlugs) {
9170
- const capability2 = resolveCapabilityFolder(slug2, jobsRoot);
9169
+ for (const slug of capabilitySlugs) {
9170
+ const capability2 = resolveCapabilityFolder(slug, jobsRoot);
9171
9171
  const status = await describeCapabilitySchedule(
9172
9172
  capability2,
9173
- slug2,
9173
+ slug,
9174
9174
  backend,
9175
- opts.previousScheduleState?.capabilities[slug2]
9175
+ opts.previousScheduleState?.capabilities[slug]
9176
9176
  );
9177
- statuses[slug2] = status;
9178
- if (status.state === "blocked") blockers.push(`${slug2}: ${status.reason}`);
9177
+ statuses[slug] = status;
9178
+ if (status.state === "blocked") blockers.push(`${slug}: ${status.reason}`);
9179
9179
  }
9180
- const due = capabilitySlugs.map((slug2) => statuses[slug2]).filter((status) => status?.state === "due").sort(compareOldestLastFired)[0];
9180
+ const due = capabilitySlugs.map((slug) => statuses[slug]).filter((status) => status?.state === "due").sort(compareOldestLastFired)[0];
9181
9181
  if (!due) {
9182
9182
  const reason = blockers.length > 0 ? "no runnable capability; blocked capabilities need attention" : "no runnable capability";
9183
9183
  const kind = blockers.length > 0 ? "blocked" : "idle";
@@ -9226,18 +9226,18 @@ async function planGoalCapabilitySchedule(opts) {
9226
9226
  }
9227
9227
  };
9228
9228
  }
9229
- async function describeCapabilitySchedule(capability, slug2, backend, previous) {
9230
- if (!capability) return { slug: slug2, state: "blocked", reason: "capability folder missing" };
9229
+ async function describeCapabilitySchedule(capability, slug, backend, previous) {
9230
+ if (!capability) return { slug, state: "blocked", reason: "capability folder missing" };
9231
9231
  const { config } = capability;
9232
9232
  if (config.disabled === true) {
9233
- return { slug: slug2, title: capability.title, state: "disabled", reason: "disabled" };
9233
+ return { slug, title: capability.title, state: "disabled", reason: "disabled" };
9234
9234
  }
9235
9235
  if (!config.agent || config.agent.trim().length === 0) {
9236
- return { slug: slug2, title: capability.title, state: "blocked", reason: "no agent assigned" };
9236
+ return { slug, title: capability.title, state: "blocked", reason: "no agent assigned" };
9237
9237
  }
9238
9238
  if (config.implementations && config.implementations.length > 1) {
9239
9239
  return {
9240
- slug: slug2,
9240
+ slug,
9241
9241
  title: capability.title,
9242
9242
  state: "blocked",
9243
9243
  reason: "multi-implementation capability needs task-jobs route"
@@ -9246,20 +9246,20 @@ async function describeCapabilitySchedule(capability, slug2, backend, previous)
9246
9246
  let lastFiredAt = validIso(previous?.lastFiredAt) ? previous?.lastFiredAt : void 0;
9247
9247
  try {
9248
9248
  if (!lastFiredAt) {
9249
- const loaded = await backend.load(slug2);
9249
+ const loaded = await backend.load(slug);
9250
9250
  const raw = loaded.state.data?.lastFiredAt;
9251
9251
  if (typeof raw === "string" && validIso(raw)) lastFiredAt = raw;
9252
9252
  }
9253
9253
  } catch {
9254
9254
  return {
9255
- slug: slug2,
9255
+ slug,
9256
9256
  title: capability.title,
9257
9257
  state: "due",
9258
9258
  reason: "state unreadable; ready for loop tick"
9259
9259
  };
9260
9260
  }
9261
9261
  return {
9262
- slug: slug2,
9262
+ slug,
9263
9263
  title: capability.title,
9264
9264
  state: "due",
9265
9265
  reason: "ready for loop tick",
@@ -9396,11 +9396,11 @@ function scheduleWaitDecision(previousScheduleState, plannedDecision, reason) {
9396
9396
  }
9397
9397
  function unmarkPlannedCapabilityDispatch(scheduleState, at) {
9398
9398
  return Object.fromEntries(
9399
- Object.entries(scheduleState.capabilities).map(([slug2, status]) => {
9400
- if (status.lastFiredAt !== at) return [slug2, status];
9399
+ Object.entries(scheduleState.capabilities).map(([slug, status]) => {
9400
+ if (status.lastFiredAt !== at) return [slug, status];
9401
9401
  const rest = { ...status };
9402
9402
  delete rest.lastFiredAt;
9403
- return [slug2, rest];
9403
+ return [slug, rest];
9404
9404
  })
9405
9405
  );
9406
9406
  }
@@ -9575,8 +9575,8 @@ function routeNeedsIssueFact(goal) {
9575
9575
  return goal.route.some(
9576
9576
  (step) => Object.values(step.args ?? {}).some((value) => {
9577
9577
  if (!value || typeof value !== "object" || Array.isArray(value)) return false;
9578
- const record2 = value;
9579
- return Object.keys(record2).length === 1 && record2.fact === "issue";
9578
+ const record = value;
9579
+ return Object.keys(record).length === 1 && record.fact === "issue";
9580
9580
  })
9581
9581
  );
9582
9582
  }
@@ -9585,8 +9585,8 @@ function workflowNeedsIssueFact(goal) {
9585
9585
  }
9586
9586
  function isIssueFactReference(value) {
9587
9587
  if (!value || typeof value !== "object" || Array.isArray(value)) return false;
9588
- const record2 = value;
9589
- return Object.keys(record2).length === 1 && record2.fact === "issue";
9588
+ const record = value;
9589
+ return Object.keys(record).length === 1 && record.fact === "issue";
9590
9590
  }
9591
9591
  function normalizeIssueNumber(value) {
9592
9592
  if (typeof value === "number" && Number.isInteger(value) && value > 0) return value;
@@ -9927,9 +9927,9 @@ function resolveTrigger(force) {
9927
9927
  if (force || event === "issue_comment" || event === "workflow_dispatch") return "manual";
9928
9928
  return "event";
9929
9929
  }
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}`);
9930
+ function appendLine(ctx, record) {
9931
+ const filePath = `activity/${record.ts.slice(0, 10)}.jsonl`;
9932
+ appendStateLine(ctx.config, ctx.cwd, filePath, JSON.stringify(record), `chore(activity): ${record.action}`);
9933
9933
  }
9934
9934
  var appendCompanyActivity;
9935
9935
  var init_appendCompanyActivity = __esm({
@@ -9945,7 +9945,7 @@ var init_appendCompanyActivity = __esm({
9945
9945
  const agent = ctx.data.agentSlug || null;
9946
9946
  const agentTitle = ctx.data.agentTitle || null;
9947
9947
  const force = ctx.args?.force === true;
9948
- const record2 = {
9948
+ const record = {
9949
9949
  ts: (/* @__PURE__ */ new Date()).toISOString(),
9950
9950
  action: `Ran capability: ${capabilityTitle ?? capability}`,
9951
9951
  capability,
@@ -9959,7 +9959,7 @@ var init_appendCompanyActivity = __esm({
9959
9959
  durationMs: agentResult?.durationMs ?? null,
9960
9960
  runUrl: getRunUrl() || null
9961
9961
  };
9962
- appendLine(ctx, record2);
9962
+ appendLine(ctx, record);
9963
9963
  } catch (err) {
9964
9964
  process.stderr.write(
9965
9965
  `[activity] company-activity append failed: ${err instanceof Error ? err.message : String(err)}
@@ -9970,494 +9970,6 @@ var init_appendCompanyActivity = __esm({
9970
9970
  }
9971
9971
  });
9972
9972
 
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
9973
  // src/capabilityEvidence.ts
10462
9974
  function capabilityReportToEvidence(report) {
10463
9975
  if (report.target.type !== "goal") return null;
@@ -10628,7 +10140,7 @@ function retryAfterSecondsFor(route, evidence) {
10628
10140
  const step = route.find(
10629
10141
  (item) => !!item && typeof item === "object" && !Array.isArray(item) && item.evidence === evidence
10630
10142
  );
10631
- const policy = step && recordField4(step.onFailure);
10143
+ const policy = step && recordField3(step.onFailure);
10632
10144
  const retryAfter = typeof policy?.retryAfterSeconds === "number" ? policy.retryAfterSeconds : void 0;
10633
10145
  return retryAfter !== void 0 && retryAfter >= 0 ? Math.floor(retryAfter) : void 0;
10634
10146
  }
@@ -10677,7 +10189,7 @@ function parseStringArray3(raw) {
10677
10189
  }
10678
10190
  return out;
10679
10191
  }
10680
- function recordField4(value) {
10192
+ function recordField3(value) {
10681
10193
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
10682
10194
  }
10683
10195
  var CONTROL_FACT_KEYS3;
@@ -10734,7 +10246,7 @@ function capabilityEvidenceOutput(evidence) {
10734
10246
  function goalReportBody(goalId, state, snapshot, latestEvent, evidenceItems) {
10735
10247
  const outputs = evidenceItems.map(capabilityEvidenceOutput);
10736
10248
  const latestOutput = outputs.at(-1);
10737
- const facts = recordField5(snapshot, "facts") ?? recordField5(state.extra, "facts") ?? {};
10249
+ const facts = recordField4(snapshot, "facts") ?? recordField4(state.extra, "facts") ?? {};
10738
10250
  const blockers = uniqueStrings2([
10739
10251
  ...stringArrayField(snapshot, "blockers"),
10740
10252
  ...stringArrayField(latestEvent, "blockers"),
@@ -10753,12 +10265,12 @@ function goalReportBody(goalId, state, snapshot, latestEvent, evidenceItems) {
10753
10265
  "",
10754
10266
  "## Status",
10755
10267
  `- State: ${state.state}`,
10756
- `- Stage: ${stringField5(snapshot, "stage") ?? stringField5(state.extra, "stage") ?? "unknown"}`,
10268
+ `- Stage: ${stringField4(snapshot, "stage") ?? stringField4(state.extra, "stage") ?? "unknown"}`,
10757
10269
  `- Next step: ${nextStepFromEvent(state, snapshot, latestOutput, latestEvent)}`,
10758
10270
  `- Updated: ${state.updatedAt ?? state.createdAt ?? state.startedAt ?? "unknown"}`,
10759
10271
  "",
10760
10272
  "## Decision",
10761
- `- Event: ${stringField5(latestEvent, "event") ?? "unknown"}`,
10273
+ `- Event: ${stringField4(latestEvent, "event") ?? "unknown"}`,
10762
10274
  `- Reason: ${decisionReason(state, latestEvent, latestOutput, missingEvidence, blockers)}`,
10763
10275
  `- Required evidence: ${listOrNone(stringArrayField(snapshot, "requiredEvidence"))}`,
10764
10276
  `- Satisfied evidence: ${listOrNone(stringArrayField(snapshot, "satisfiedEvidence"))}`,
@@ -10786,9 +10298,9 @@ function capabilityEvidenceMarkdown(outputs) {
10786
10298
  function decisionReason(state, latestEvent, latestOutput, missingEvidence, blockers) {
10787
10299
  if (state.state === "done") return "destination evidence satisfied";
10788
10300
  if (blockers.length > 0) return blockers[0] ?? "blocked";
10789
- const eventReason = stringField5(latestEvent, "reason") ?? stringField5(recordField5(latestEvent, "decision"), "reason");
10301
+ const eventReason = stringField4(latestEvent, "reason") ?? stringField4(recordField4(latestEvent, "decision"), "reason");
10790
10302
  if (eventReason) return eventReason;
10791
- const summary = stringField5(latestOutput, "summary");
10303
+ const summary = stringField4(latestOutput, "summary");
10792
10304
  if (summary) return summary;
10793
10305
  if (missingEvidence.length > 0) return `waiting for ${missingEvidence[0]}`;
10794
10306
  return "waiting for more evidence";
@@ -10796,33 +10308,33 @@ function decisionReason(state, latestEvent, latestOutput, missingEvidence, block
10796
10308
  function evidenceOutputMarkdown(index, output) {
10797
10309
  return [
10798
10310
  `### Output ${index}`,
10799
- `- Status: ${stringField5(output, "status") ?? "unknown"}`,
10800
- `- Summary: ${stringField5(output, "summary") ?? "no summary"}`,
10311
+ `- Status: ${stringField4(output, "status") ?? "unknown"}`,
10312
+ `- Summary: ${stringField4(output, "summary") ?? "no summary"}`,
10801
10313
  `- Sources: ${listOrNone(stringArrayField(output, "sources"))}`,
10802
- `- Evidence values: ${inlineJson(recordField5(output, "evidence") ?? {})}`,
10314
+ `- Evidence values: ${inlineJson(recordField4(output, "evidence") ?? {})}`,
10803
10315
  `- Missing evidence: ${listOrNone(stringArrayField(output, "missingEvidence"))}`,
10804
10316
  `- Blockers: ${listOrNone(stringArrayField(output, "blockers"))}`,
10805
10317
  ""
10806
10318
  ];
10807
10319
  }
10808
10320
  function dispatchContextMarkdown(latestEvent) {
10809
- const context = recordField5(latestEvent, "dispatchContext");
10321
+ const context = recordField4(latestEvent, "dispatchContext");
10810
10322
  if (!context) return ["- none"];
10811
- const githubActor = stringField5(context, "githubActor");
10812
- const githubActorRole = stringField5(context, "githubActorRole");
10813
- const target = dispatchTargetLabel(recordField5(context, "target"));
10323
+ const githubActor = stringField4(context, "githubActor");
10324
+ const githubActorRole = stringField4(context, "githubActorRole");
10325
+ const target = dispatchTargetLabel(recordField4(context, "target"));
10814
10326
  return [
10815
- `- Triggered by: ${stringField5(context, "triggeredBy") ?? "unknown"}`,
10816
- `- Mode: ${stringField5(context, "dispatchMode") ?? "unknown"}`,
10327
+ `- Triggered by: ${stringField4(context, "triggeredBy") ?? "unknown"}`,
10328
+ `- Mode: ${stringField4(context, "dispatchMode") ?? "unknown"}`,
10817
10329
  `- GitHub actor: ${githubActor ? `${githubActor}${githubActorRole ? ` (${githubActorRole})` : ""}` : "none"}`,
10818
- `- Decided by: ${stringField5(context, "decidedBy") ?? "unknown"}`,
10819
- `- Dispatched by: ${stringField5(context, "dispatchedBy") ?? "unknown"}`,
10330
+ `- Decided by: ${stringField4(context, "decidedBy") ?? "unknown"}`,
10331
+ `- Dispatched by: ${stringField4(context, "dispatchedBy") ?? "unknown"}`,
10820
10332
  `- Target: ${target ?? "none"}`
10821
10333
  ];
10822
10334
  }
10823
10335
  function dispatchTargetLabel(target) {
10824
- const type = stringField5(target, "type");
10825
- const id = stringField5(target, "id");
10336
+ const type = stringField4(target, "type");
10337
+ const id = stringField4(target, "id");
10826
10338
  if (type && id) return `${type} ${id}`;
10827
10339
  return id ?? type;
10828
10340
  }
@@ -10845,27 +10357,27 @@ function listOrNone(values) {
10845
10357
  function uniqueStrings2(values) {
10846
10358
  return [...new Set(values)].sort();
10847
10359
  }
10848
- function stringField5(record2, key) {
10849
- const value = record2?.[key];
10360
+ function stringField4(record, key) {
10361
+ const value = record?.[key];
10850
10362
  return typeof value === "string" && value.trim() ? value : void 0;
10851
10363
  }
10852
- function recordField5(record2, key) {
10853
- const value = record2?.[key];
10364
+ function recordField4(record, key) {
10365
+ const value = record?.[key];
10854
10366
  return value && typeof value === "object" && !Array.isArray(value) ? { ...value } : void 0;
10855
10367
  }
10856
- function stringArrayField(record2, key) {
10857
- const value = record2?.[key];
10368
+ function stringArrayField(record, key) {
10369
+ const value = record?.[key];
10858
10370
  return Array.isArray(value) && value.every((item) => typeof item === "string") ? value : [];
10859
10371
  }
10860
- function artifactArrayField(record2, key) {
10861
- const value = record2?.[key];
10372
+ function artifactArrayField(record, key) {
10373
+ const value = record?.[key];
10862
10374
  if (!Array.isArray(value)) return [];
10863
10375
  return value.filter(isArtifact);
10864
10376
  }
10865
10377
  function isArtifact(value) {
10866
10378
  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");
10379
+ const record = value;
10380
+ return typeof record.label === "string" && (record.url === void 0 || typeof record.url === "string") && (record.path === void 0 || typeof record.path === "string");
10869
10381
  }
10870
10382
  function uniqueArtifacts2(artifacts) {
10871
10383
  const seen = /* @__PURE__ */ new Set();
@@ -10882,7 +10394,7 @@ ${artifact.path ?? ""}`;
10882
10394
  }
10883
10395
  function nextStepFromEvent(state, goalAfter, capabilityOutput, latestEvent) {
10884
10396
  if (state.state === "done") return "done";
10885
- const decisionKind = stringField5(recordField5(latestEvent, "decision"), "kind") ?? stringField5(latestEvent, "status");
10397
+ const decisionKind = stringField4(recordField4(latestEvent, "decision"), "kind") ?? stringField4(latestEvent, "status");
10886
10398
  if (decisionKind === "done") return "done";
10887
10399
  if (decisionKind === "dispatch") return "dispatch";
10888
10400
  if (decisionKind === "blocked" || decisionKind === "reject-evidence") return "block";
@@ -11136,8 +10648,8 @@ function nextStepFromEvidence2(goalAfter, capabilityOutput) {
11136
10648
  if (missingEvidence.length > 0 && status !== "noop") return "dispatch";
11137
10649
  return "wait";
11138
10650
  }
11139
- function stringArrayField2(record2, key) {
11140
- const value = record2?.[key];
10651
+ function stringArrayField2(record, key) {
10652
+ const value = record?.[key];
11141
10653
  return Array.isArray(value) && value.every((item) => typeof item === "string") ? value : [];
11142
10654
  }
11143
10655
  function describeMessage(goalId, evidenceItems) {
@@ -12539,7 +12051,7 @@ function discoverPayloadCollections(cwd) {
12539
12051
  const content = fs33.readFileSync(filePath, "utf-8").slice(0, 1e4);
12540
12052
  const slugMatch = content.match(/slug:\s*['"]([a-z0-9-]+)['"]/);
12541
12053
  if (!slugMatch) continue;
12542
- const slug2 = slugMatch[1];
12054
+ const slug = slugMatch[1];
12543
12055
  const name = file.replace(/\.(ts|tsx)$/, "");
12544
12056
  const fields = [];
12545
12057
  const fieldMatches = content.matchAll(/name:\s*['"]([a-zA-Z_][a-zA-Z0-9_]*)['"]/g);
@@ -12549,7 +12061,7 @@ function discoverPayloadCollections(cwd) {
12549
12061
  const hasAdmin = /components:\s*\{/.test(content) || /Field:\s*['"]/.test(content) || /Cell:\s*['"]/.test(content) || /views:\s*\{/.test(content);
12550
12062
  out.push({
12551
12063
  name,
12552
- slug: slug2,
12064
+ slug,
12553
12065
  filePath: path32.relative(cwd, filePath),
12554
12066
  fields: fields.slice(0, 20),
12555
12067
  hasAdmin
@@ -13658,8 +13170,8 @@ function git3(args, cwd) {
13658
13170
  }).trim();
13659
13171
  }
13660
13172
  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`;
13173
+ const slug = title.toLowerCase().replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").slice(0, 50).replace(/-$/, "");
13174
+ return slug ? `${issueNumber}-${slug}` : `${issueNumber}-task`;
13663
13175
  }
13664
13176
  function getCurrentBranch(cwd) {
13665
13177
  return git3(["branch", "--show-current"], cwd);
@@ -14353,7 +13865,7 @@ function stripDirective(body) {
14353
13865
  }
14354
13866
  return lines.slice(start).join("\n").trim();
14355
13867
  }
14356
- function parseAgentFile(raw, slug2) {
13868
+ function parseAgentFile(raw, slug) {
14357
13869
  const stripped = stripLeadingFrontmatter(raw);
14358
13870
  const trimmed = stripped.trim();
14359
13871
  const firstLine2 = trimmed.split("\n", 1)[0] ?? "";
@@ -14362,14 +13874,14 @@ function parseAgentFile(raw, slug2) {
14362
13874
  const rest = trimmed.slice(firstLine2.length).replace(/^\n+/, "");
14363
13875
  return { title: h1[1].trim(), body: rest };
14364
13876
  }
14365
- return { title: humanizeSlug2(slug2), body: trimmed };
13877
+ return { title: humanizeSlug2(slug), body: trimmed };
14366
13878
  }
14367
13879
  function stripLeadingFrontmatter(raw) {
14368
13880
  const match = /^---\r?\n[\s\S]*?\r?\n---\r?\n?/.exec(raw);
14369
13881
  return match ? raw.slice(match[0].length) : raw;
14370
13882
  }
14371
- function humanizeSlug2(slug2) {
14372
- return slug2.split(/[-_]+/).filter((s) => s.length > 0).map((s) => s[0].toUpperCase() + s.slice(1)).join(" ");
13883
+ function humanizeSlug2(slug) {
13884
+ return slug.split(/[-_]+/).filter((s) => s.length > 0).map((s) => s[0].toUpperCase() + s.slice(1)).join(" ");
14373
13885
  }
14374
13886
  var loadAgentAdhoc;
14375
13887
  var init_loadAgentAdhoc = __esm({
@@ -14412,14 +13924,14 @@ var init_loadCapabilityState = __esm({
14412
13924
  CAPABILITY_TOOL_PALETTE = new Set(CAPABILITY_MCP_TOOL_NAMES);
14413
13925
  loadCapabilityState = async (ctx, profile, args) => {
14414
13926
  const jobsDir = String(args?.jobsDir ?? ".kody/capabilities");
14415
- const slug2 = profile.name;
13927
+ const slug = profile.name;
14416
13928
  const backend = resolveBackend({ config: ctx.config, cwd: ctx.cwd, jobsDir });
14417
13929
  if (backend.hydrate) await backend.hydrate();
14418
- const loaded = await backend.load(slug2);
14419
- ctx.data.jobSlug = slug2;
13930
+ const loaded = await backend.load(slug);
13931
+ ctx.data.jobSlug = slug;
14420
13932
  ctx.data.jobState = loaded;
14421
13933
  ctx.data.jobStateJson = JSON.stringify(loaded.state, null, 2);
14422
- ctx.data.capabilitySlug = slug2;
13934
+ ctx.data.capabilitySlug = slug;
14423
13935
  ctx.data.capabilityTitle = profile.describe;
14424
13936
  ctx.data.implementationSlug = profile.implementation ?? profile.name;
14425
13937
  ctx.data.agentSlug = profile.agent ?? "";
@@ -14432,7 +13944,7 @@ var init_loadCapabilityState = __esm({
14432
13944
  const unknown = declaredTools.filter((name) => !CAPABILITY_TOOL_PALETTE.has(name));
14433
13945
  if (unknown.length > 0) {
14434
13946
  throw new Error(
14435
- `loadCapabilityState: capability '${slug2}' declared capabilityTools not in the kody-capability palette: ${unknown.join(", ")}. Available: ${[...CAPABILITY_MCP_TOOL_NAMES].join(", ")}`
13947
+ `loadCapabilityState: capability '${slug}' declared capabilityTools not in the kody-capability palette: ${unknown.join(", ")}. Available: ${[...CAPABILITY_MCP_TOOL_NAMES].join(", ")}`
14436
13948
  );
14437
13949
  }
14438
13950
  const mode = profile.capabilityToolMode ?? "lock";
@@ -14452,6 +13964,141 @@ var init_loadCapabilityState = __esm({
14452
13964
  }
14453
13965
  });
14454
13966
 
13967
+ // src/companyIntent.ts
13968
+ function isCompanyIntentId(value) {
13969
+ return SLUG_RE.test(value);
13970
+ }
13971
+ function companyIntentPath(id) {
13972
+ assertIntentId(id);
13973
+ return `intents/${id}/intent.json`;
13974
+ }
13975
+ function normalizeCompanyIntent(path51, raw) {
13976
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
13977
+ throw new Error(`${path51}: intent must be JSON object`);
13978
+ }
13979
+ const input = raw;
13980
+ const id = stringField5(input.id);
13981
+ if (!id || !isCompanyIntentId(id)) throw new Error(`${path51}: invalid intent id`);
13982
+ const createdAt = stringField5(input.createdAt) || nowIso();
13983
+ const updatedAt = stringField5(input.updatedAt) || createdAt;
13984
+ const description = stringField5(input.description);
13985
+ return {
13986
+ version: 1,
13987
+ id,
13988
+ status: oneOf(input.status, ["active", "paused", "archived"], "active"),
13989
+ for: stringField5(input.for),
13990
+ ...description ? { description } : {},
13991
+ priority: numberField(input.priority, 100),
13992
+ posture: oneOf(
13993
+ input.posture,
13994
+ ["confidence", "speed", "stability-recovery", "maintenance", "balanced"],
13995
+ "balanced"
13996
+ ),
13997
+ scope: {
13998
+ repos: stringArray3(recordField5(input.scope)?.repos),
13999
+ areas: stringArray3(recordField5(input.scope)?.areas)
14000
+ },
14001
+ principles: stringArray3(input.principles),
14002
+ metrics: stringArray3(input.metrics),
14003
+ policy: {
14004
+ release: normalizeReleasePolicy(recordField5(recordField5(input.policy)?.release)),
14005
+ automation: normalizeAutomationPolicy(recordField5(recordField5(input.policy)?.automation))
14006
+ },
14007
+ portfolio: {
14008
+ goals: stringArray3(recordField5(input.portfolio)?.goals).filter(isCompanyIntentId),
14009
+ loops: stringArray3(recordField5(input.portfolio)?.loops).filter(isCompanyIntentId),
14010
+ capabilities: stringArray3(recordField5(input.portfolio)?.capabilities).filter(isCompanyIntentId)
14011
+ },
14012
+ createdAt,
14013
+ updatedAt
14014
+ };
14015
+ }
14016
+ function listCompanyIntents(config, cwd) {
14017
+ const entries = listStateDirectory(config, cwd, "intents");
14018
+ const records = [];
14019
+ for (const entry of entries) {
14020
+ if (entry.type !== "dir" || !entry.name || !isCompanyIntentId(entry.name)) continue;
14021
+ const path51 = companyIntentPath(entry.name);
14022
+ const file = readStateText(config, cwd, path51);
14023
+ if (!file) continue;
14024
+ records.push({
14025
+ id: entry.name,
14026
+ path: file.path,
14027
+ intent: normalizeCompanyIntent(file.path, JSON.parse(file.content))
14028
+ });
14029
+ }
14030
+ return records.sort((a, b) => a.intent.priority - b.intent.priority || a.id.localeCompare(b.id));
14031
+ }
14032
+ function listCompanyPortfolio(config, cwd) {
14033
+ const goals = [];
14034
+ for (const id of listGoalStateIds(config, cwd)) {
14035
+ if (!isCompanyIntentId(id)) continue;
14036
+ const state = fetchGoalState(config, id, cwd);
14037
+ if (!state) continue;
14038
+ const destination = recordField5(state.extra.destination);
14039
+ goals.push({
14040
+ id,
14041
+ state: state.state,
14042
+ type: stringField5(state.extra.type) || void 0,
14043
+ outcome: stringField5(destination?.outcome) || void 0,
14044
+ capabilities: stringArray3(state.extra.capabilities),
14045
+ isLoop: state.extra.scheduleMode === "agentLoop" || state.extra.type === "agentLoop",
14046
+ updatedAt: state.updatedAt
14047
+ });
14048
+ }
14049
+ return { goals: goals.sort((a, b) => a.id.localeCompare(b.id)) };
14050
+ }
14051
+ function assertIntentId(id) {
14052
+ if (!isCompanyIntentId(id)) throw new Error(`invalid intent/portfolio id: ${id}`);
14053
+ }
14054
+ function stringField5(value) {
14055
+ return typeof value === "string" ? value.trim() : "";
14056
+ }
14057
+ function numberField(value, fallback) {
14058
+ return typeof value === "number" && Number.isFinite(value) ? value : fallback;
14059
+ }
14060
+ function recordField5(value) {
14061
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
14062
+ }
14063
+ function stringArray3(value) {
14064
+ if (!Array.isArray(value)) return [];
14065
+ return value.filter((item) => typeof item === "string").map((item) => item.trim()).filter(Boolean);
14066
+ }
14067
+ function oneOf(value, allowed, fallback) {
14068
+ return typeof value === "string" && allowed.includes(value) ? value : fallback;
14069
+ }
14070
+ function normalizeReleasePolicy(raw) {
14071
+ if (!raw) return void 0;
14072
+ return {
14073
+ cadence: oneOf(raw.cadence, ["manual", "1d", "1w"], "manual"),
14074
+ qaDepth: oneOf(raw.qaDepth, ["light", "standard", "strict"], "standard"),
14075
+ blockerLevel: oneOf(raw.blockerLevel, ["low", "standard", "strict"], "standard"),
14076
+ approval: oneOf(
14077
+ raw.approval,
14078
+ ["none", "before-production", "before-risky-actions"],
14079
+ "before-risky-actions"
14080
+ )
14081
+ };
14082
+ }
14083
+ function normalizeAutomationPolicy(raw) {
14084
+ return {
14085
+ authority: "full-auto",
14086
+ maxConcurrentGoals: Math.max(1, Math.floor(numberField(raw?.maxConcurrentGoals, 1))),
14087
+ maxDailyActions: Math.max(1, Math.floor(numberField(raw?.maxDailyActions, 6))),
14088
+ requiresHumanFor: stringArray3(raw?.requiresHumanFor)
14089
+ };
14090
+ }
14091
+ var SLUG_RE;
14092
+ var init_companyIntent = __esm({
14093
+ "src/companyIntent.ts"() {
14094
+ "use strict";
14095
+ init_state2();
14096
+ init_stateStore();
14097
+ init_stateRepo();
14098
+ SLUG_RE = /^[a-z][a-z0-9-]{0,63}$/;
14099
+ }
14100
+ });
14101
+
14455
14102
  // src/scripts/loadCompanyIntents.ts
14456
14103
  var loadCompanyIntents;
14457
14104
  var init_loadCompanyIntents = __esm({
@@ -14460,11 +14107,11 @@ var init_loadCompanyIntents = __esm({
14460
14107
  init_companyIntent();
14461
14108
  loadCompanyIntents = async (ctx) => {
14462
14109
  const intents = listCompanyIntents(ctx.config, ctx.cwd);
14463
- const active = intents.filter((record2) => record2.intent.status === "active");
14110
+ const active = intents.filter((record) => record.intent.status === "active");
14464
14111
  ctx.data.companyIntents = intents;
14465
14112
  ctx.data.companyActiveIntents = active;
14466
14113
  ctx.data.companyIntentsJson = JSON.stringify(
14467
- active.map((record2) => record2.intent),
14114
+ active.map((record) => record.intent),
14468
14115
  null,
14469
14116
  2
14470
14117
  );
@@ -14632,7 +14279,7 @@ var init_loadIssueStateComment = __esm({
14632
14279
  // src/scripts/loadJobFromFile.ts
14633
14280
  import * as fs37 from "fs";
14634
14281
  import * as path35 from "path";
14635
- function parseJobFile(raw, slug2) {
14282
+ function parseJobFile(raw, slug) {
14636
14283
  let stripped = raw;
14637
14284
  if (stripped.startsWith("---\n")) {
14638
14285
  const end = stripped.indexOf("\n---\n", 4);
@@ -14647,10 +14294,10 @@ function parseJobFile(raw, slug2) {
14647
14294
  const rest = trimmed.slice(firstLine2.length).replace(/^\n+/, "");
14648
14295
  return { title: h1[1].trim(), body: rest };
14649
14296
  }
14650
- return { title: humanizeSlug3(slug2), body: trimmed };
14297
+ return { title: humanizeSlug3(slug), body: trimmed };
14651
14298
  }
14652
- function humanizeSlug3(slug2) {
14653
- return slug2.split(/[-_]+/).filter((s) => s.length > 0).map((s) => s[0].toUpperCase() + s.slice(1)).join(" ");
14299
+ function humanizeSlug3(slug) {
14300
+ return slug.split(/[-_]+/).filter((s) => s.length > 0).map((s) => s[0].toUpperCase() + s.slice(1)).join(" ");
14654
14301
  }
14655
14302
  var CAPABILITY_TOOL_PALETTE2, loadJobFromFile;
14656
14303
  var init_loadJobFromFile = __esm({
@@ -14665,13 +14312,13 @@ var init_loadJobFromFile = __esm({
14665
14312
  const jobsDir = String(args?.jobsDir ?? ".kody/capabilities");
14666
14313
  const agentsDir = String(args?.agentsDir ?? ".kody/agents");
14667
14314
  const slugArg = String(args?.slugArg ?? "job");
14668
- const slug2 = String(ctx.args[slugArg] ?? "").trim();
14669
- if (!slug2) {
14315
+ const slug = String(ctx.args[slugArg] ?? "").trim();
14316
+ if (!slug) {
14670
14317
  throw new Error(`loadJobFromFile: ctx.args.${slugArg} must be a non-empty slug`);
14671
14318
  }
14672
- const capability = resolveCapabilityFolder(slug2, path35.join(ctx.cwd, jobsDir));
14319
+ const capability = resolveCapabilityFolder(slug, path35.join(ctx.cwd, jobsDir));
14673
14320
  if (!capability) {
14674
- throw new Error(`loadJobFromFile: capability folder not found or incomplete: ${path35.join(ctx.cwd, jobsDir, slug2)}`);
14321
+ throw new Error(`loadJobFromFile: capability folder not found or incomplete: ${path35.join(ctx.cwd, jobsDir, slug)}`);
14675
14322
  }
14676
14323
  const { title, body, config } = capability;
14677
14324
  const mentions = (config.mentions ?? []).map((login) => `@${login}`).join(" ");
@@ -14682,7 +14329,7 @@ var init_loadJobFromFile = __esm({
14682
14329
  const agentPath = resolveAgentFile(ctx.cwd, agentSlug, agentsDir);
14683
14330
  if (!fs37.existsSync(agentPath)) {
14684
14331
  throw new Error(
14685
- `loadJobFromFile: capability '${slug2}' declares agent '${agentSlug}' but ${agentPath} does not exist`
14332
+ `loadJobFromFile: capability '${slug}' declares agent '${agentSlug}' but ${agentPath} does not exist`
14686
14333
  );
14687
14334
  }
14688
14335
  const agentRaw = fs37.readFileSync(agentPath, "utf-8");
@@ -14691,17 +14338,17 @@ var init_loadJobFromFile = __esm({
14691
14338
  agentIdentity = parsed.body;
14692
14339
  }
14693
14340
  const backend = resolveBackend({ config: ctx.config, cwd: ctx.cwd, jobsDir });
14694
- const loaded = await backend.load(slug2);
14695
- ctx.data.jobSlug = slug2;
14341
+ const loaded = await backend.load(slug);
14342
+ ctx.data.jobSlug = slug;
14696
14343
  ctx.data.jobTitle = title;
14697
- ctx.data.jobIntent = body.replace(/\{\{\s*mentions\s*\}\}/g, mentions).replace(/\{\{\s*capability\s*\}\}/g, slug2);
14344
+ ctx.data.jobIntent = body.replace(/\{\{\s*mentions\s*\}\}/g, mentions).replace(/\{\{\s*capability\s*\}\}/g, slug);
14698
14345
  ctx.data.jobState = loaded;
14699
14346
  ctx.data.jobStateJson = JSON.stringify(loaded.state, null, 2);
14700
14347
  ctx.data.agentSlug = agentSlug;
14701
14348
  ctx.data.agentTitle = agentTitle;
14702
14349
  ctx.data.agentIdentity = agentIdentity;
14703
14350
  ctx.data.mentions = mentions;
14704
- ctx.data.capabilitySlug = slug2;
14351
+ ctx.data.capabilitySlug = slug;
14705
14352
  ctx.data.capabilityTitle = title;
14706
14353
  ctx.data.agentSlug = agentSlug;
14707
14354
  ctx.data.agentTitle = agentTitle;
@@ -14712,7 +14359,7 @@ var init_loadJobFromFile = __esm({
14712
14359
  const unknown = declaredTools.filter((name) => !CAPABILITY_TOOL_PALETTE2.has(name));
14713
14360
  if (unknown.length > 0) {
14714
14361
  throw new Error(
14715
- `loadJobFromFile: capability '${slug2}' declared tools not in the kody-capability palette: ${unknown.join(", ")}. Available: ${[...CAPABILITY_MCP_TOOL_NAMES].join(", ")}`
14362
+ `loadJobFromFile: capability '${slug}' declared tools not in the kody-capability palette: ${unknown.join(", ")}. Available: ${[...CAPABILITY_MCP_TOOL_NAMES].join(", ")}`
14716
14363
  );
14717
14364
  }
14718
14365
  const mcpToolNames = declaredTools.map((name) => `mcp__kody-capability__${name}`);
@@ -15666,8 +15313,8 @@ function parseAgentFactoryBundle(raw) {
15666
15313
  };
15667
15314
  }
15668
15315
  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}` : "";
15316
+ const slug = title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 48).replace(/-+$/g, "");
15317
+ const suffix = slug ? `-${slug}` : "";
15671
15318
  return `${sourceLabel}/issue-${issueNumber}-${now.toString(36)}${suffix}`;
15672
15319
  }
15673
15320
  function normalizeBundleFiles(ctx, bundle) {
@@ -15996,41 +15643,8 @@ QA_REPORT_POSTED=${created.url} (verdict: ${verdict})
15996
15643
  }
15997
15644
  });
15998
15645
 
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
15646
  // src/scripts/parseAgentResult.ts
16033
- function makeAction3(type, payload) {
15647
+ function makeAction2(type, payload) {
16034
15648
  return { type, payload, timestamp: (/* @__PURE__ */ new Date()).toISOString() };
16035
15649
  }
16036
15650
  var parseAgentResult2;
@@ -16041,7 +15655,7 @@ var init_parseAgentResult = __esm({
16041
15655
  parseAgentResult2 = async (ctx, profile, agentResult) => {
16042
15656
  if (!agentResult) {
16043
15657
  ctx.data.agentDone = false;
16044
- ctx.data.action = makeAction3("AGENT_NOT_RUN", { reason: "no agent result" });
15658
+ ctx.data.action = makeAction2("AGENT_NOT_RUN", { reason: "no agent result" });
16045
15659
  return;
16046
15660
  }
16047
15661
  const parsed = parseAgentResult(agentResult.finalText);
@@ -16058,13 +15672,13 @@ var init_parseAgentResult = __esm({
16058
15672
  ctx.data.agentError = agentResult.error;
16059
15673
  const modeSeg = (ctx.args.mode ?? profile.name).replace(/-/g, "_").toUpperCase();
16060
15674
  if (parsed.done) {
16061
- ctx.data.action = makeAction3(`${modeSeg}_COMPLETED`, {
15675
+ ctx.data.action = makeAction2(`${modeSeg}_COMPLETED`, {
16062
15676
  commitMessage: parsed.commitMessage
16063
15677
  });
16064
15678
  } else {
16065
15679
  const isGenericNoOutput = parsed.failureReason === "agent produced no final message";
16066
15680
  const reason = isGenericNoOutput && agentResult.error ? `agent SDK error: ${agentResult.error}` : parsed.failureReason || agentResult.error || "unknown failure";
16067
- ctx.data.action = makeAction3(`${modeSeg}_FAILED`, { reason });
15681
+ ctx.data.action = makeAction2(`${modeSeg}_FAILED`, { reason });
16068
15682
  }
16069
15683
  };
16070
15684
  }
@@ -16835,7 +16449,7 @@ function tryAuditComment(issueNumber, body, cwd) {
16835
16449
  } catch {
16836
16450
  }
16837
16451
  }
16838
- function makeAction4(type, payload) {
16452
+ function makeAction3(type, payload) {
16839
16453
  return { type, payload, timestamp: (/* @__PURE__ */ new Date()).toISOString() };
16840
16454
  }
16841
16455
  function failedAction4(reason) {
@@ -16872,7 +16486,7 @@ var init_recordClassification = __esm({
16872
16486
  ctx.output.reason = "classify: no decision";
16873
16487
  return;
16874
16488
  }
16875
- ctx.data.action = makeAction4(`CLASSIFIED_AS_${classification.toUpperCase()}`, {
16489
+ ctx.data.action = makeAction3(`CLASSIFIED_AS_${classification.toUpperCase()}`, {
16876
16490
  classification,
16877
16491
  reason: reason ?? "",
16878
16492
  source: ctx.data.classificationSource ?? "agent"
@@ -18204,16 +17818,16 @@ var init_runScheduledImplementationTick = __esm({
18204
17818
  const slugArg = String(args?.slugArg ?? "capability");
18205
17819
  const fenceLabel = String(args?.fenceLabel ?? "kody-job-next-state");
18206
17820
  const shell = String(args?.shell ?? "tick.sh");
18207
- const slug2 = String(args?.slug ?? ctx.args[slugArg] ?? ctx.args.capability ?? "").trim();
18208
- if (!slug2) {
17821
+ const slug = String(args?.slug ?? ctx.args[slugArg] ?? ctx.args.capability ?? "").trim();
17822
+ if (!slug) {
18209
17823
  ctx.output.exitCode = 99;
18210
17824
  ctx.output.reason = `runScheduledImplementationTick: args.slug or ctx.args.${slugArg} must be non-empty capability slug`;
18211
17825
  return;
18212
17826
  }
18213
- const capability = resolveCapabilityFolder(slug2, path41.join(ctx.cwd, jobsDir));
17827
+ const capability = resolveCapabilityFolder(slug, path41.join(ctx.cwd, jobsDir));
18214
17828
  if (!capability) {
18215
17829
  ctx.output.exitCode = 99;
18216
- ctx.output.reason = `runScheduledImplementationTick: capability folder not found or incomplete: ${slug2} (searched ${jobsDir} and company store)`;
17830
+ ctx.output.reason = `runScheduledImplementationTick: capability folder not found or incomplete: ${slug} (searched ${jobsDir} and company store)`;
18217
17831
  return;
18218
17832
  }
18219
17833
  const shellPath = path41.join(profile.dir, shell);
@@ -18225,14 +17839,14 @@ var init_runScheduledImplementationTick = __esm({
18225
17839
  const backend = resolveBackend({ config: ctx.config, cwd: ctx.cwd, jobsDir });
18226
17840
  let loaded;
18227
17841
  try {
18228
- loaded = await backend.load(slug2);
17842
+ loaded = await backend.load(slug);
18229
17843
  } catch (err) {
18230
17844
  ctx.output.exitCode = 99;
18231
17845
  ctx.output.reason = `runScheduledImplementationTick: state load failed: ${err instanceof Error ? err.message : String(err)}`;
18232
17846
  return;
18233
17847
  }
18234
- ctx.data.jobSlug = slug2;
18235
- ctx.data.capabilitySlug = slug2;
17848
+ ctx.data.jobSlug = slug;
17849
+ ctx.data.capabilitySlug = slug;
18236
17850
  ctx.data.implementationSlug = profile.name;
18237
17851
  ctx.data.jobState = loaded;
18238
17852
  runTickShellAndParse({
@@ -18262,22 +17876,22 @@ var init_runTickScript = __esm({
18262
17876
  const jobsDir = String(args?.jobsDir ?? ".kody/capabilities");
18263
17877
  const slugArg = String(args?.slugArg ?? "job");
18264
17878
  const fenceLabel = String(args?.fenceLabel ?? "kody-job-next-state");
18265
- const slug2 = String(ctx.args[slugArg] ?? "").trim();
18266
- if (!slug2) {
17879
+ const slug = String(ctx.args[slugArg] ?? "").trim();
17880
+ if (!slug) {
18267
17881
  ctx.output.exitCode = 99;
18268
17882
  ctx.output.reason = `runTickScript: ctx.args.${slugArg} must be a non-empty slug`;
18269
17883
  return;
18270
17884
  }
18271
- const capability = readCapabilityFolder(path42.join(ctx.cwd, jobsDir), slug2);
17885
+ const capability = readCapabilityFolder(path42.join(ctx.cwd, jobsDir), slug);
18272
17886
  if (!capability) {
18273
17887
  ctx.output.exitCode = 99;
18274
- ctx.output.reason = `runTickScript: capability folder not found or incomplete: ${path42.join(ctx.cwd, jobsDir, slug2)}`;
17888
+ ctx.output.reason = `runTickScript: capability folder not found or incomplete: ${path42.join(ctx.cwd, jobsDir, slug)}`;
18275
17889
  return;
18276
17890
  }
18277
17891
  const tickScript = capability.config.tickScript;
18278
17892
  if (!tickScript) {
18279
17893
  ctx.output.exitCode = 99;
18280
- ctx.output.reason = `runTickScript: capability ${slug2} has no \`tickScript\` in profile.json \u2014 route via capability-tick instead`;
17894
+ ctx.output.reason = `runTickScript: capability ${slug} has no \`tickScript\` in profile.json \u2014 route via capability-tick instead`;
18281
17895
  return;
18282
17896
  }
18283
17897
  const scriptPath = path42.isAbsolute(tickScript) ? tickScript : path42.join(ctx.cwd, tickScript);
@@ -18289,13 +17903,13 @@ var init_runTickScript = __esm({
18289
17903
  const backend = resolveBackend({ config: ctx.config, cwd: ctx.cwd, jobsDir });
18290
17904
  let loaded;
18291
17905
  try {
18292
- loaded = await backend.load(slug2);
17906
+ loaded = await backend.load(slug);
18293
17907
  } catch (err) {
18294
17908
  ctx.output.exitCode = 99;
18295
17909
  ctx.output.reason = `runTickScript: state load failed: ${err instanceof Error ? err.message : String(err)}`;
18296
17910
  return;
18297
17911
  }
18298
- ctx.data.jobSlug = slug2;
17912
+ ctx.data.jobSlug = slug;
18299
17913
  ctx.data.jobState = loaded;
18300
17914
  runTickShellAndParse({
18301
17915
  ctx,
@@ -18567,7 +18181,7 @@ function validateModelBundle(bundle, producer) {
18567
18181
  const failures = [];
18568
18182
  const expectedKind = CREATOR_KIND[producer];
18569
18183
  if (producer === FACTORY_PRODUCER) {
18570
- const contracts = stringArray5(bundle.modelCreatorContractsUsed);
18184
+ const contracts = stringArray4(bundle.modelCreatorContractsUsed);
18571
18185
  for (const contract of CREATOR_CONTRACTS) {
18572
18186
  if (!contracts.includes(contract)) failures.push(`modelCreatorContractsUsed missing ${contract}`);
18573
18187
  }
@@ -18594,36 +18208,36 @@ function validateOneModel(rawModel, files, label, strictSingleModel, failures, e
18594
18208
  if (!isModelKind(kind)) failures.push(`${label}.kind must be agent, capability, goal, agentLoop, or workflow`);
18595
18209
  if (expectedKind && kind !== expectedKind && producer)
18596
18210
  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`);
18211
+ const slug = stringField6(model.slug);
18212
+ if (!isSlug(slug)) failures.push(`${label}.slug must be a lowercase slug`);
18599
18213
  if (isModelKind(kind)) {
18600
- const docsUsed = stringArray5(model.docsUsed);
18214
+ const docsUsed = stringArray4(model.docsUsed);
18601
18215
  for (const doc of REQUIRED_DOCS[kind]) {
18602
18216
  if (!docsUsed.includes(doc)) failures.push(`${label} docsUsed missing ${doc}`);
18603
18217
  }
18604
- validateFilesForKind(kind, slug2, files, strictSingleModel, failures);
18605
- validateModelShape(kind, model, files, slug2, failures);
18218
+ validateFilesForKind(kind, slug, files, strictSingleModel, failures);
18219
+ validateModelShape(kind, model, files, slug, failures);
18606
18220
  }
18607
18221
  }
18608
- function validateFilesForKind(kind, slug2, files, strictSingleModel, failures) {
18222
+ function validateFilesForKind(kind, slug, files, strictSingleModel, failures) {
18609
18223
  const paths = files.map((file) => normalizeBundlePath(file.path));
18610
18224
  if (paths.some((filePath) => filePath === "implementations" || filePath.startsWith("implementations/"))) {
18611
18225
  failures.push("files must not use obsolete implementation storage");
18612
18226
  }
18613
18227
  if (kind === "agent") {
18614
- requirePath(paths, `agents/${slug2}.md`, "agent file", failures);
18228
+ requirePath(paths, `agents/${slug}.md`, "agent file", failures);
18615
18229
  if (strictSingleModel) rejectOtherRoots(paths, ["agents/"], "agent", failures);
18616
18230
  }
18617
18231
  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);
18232
+ requirePath(paths, `capabilities/${slug}/profile.json`, "capability profile", failures);
18233
+ requirePath(paths, `capabilities/${slug}/capability.md`, "capability body", failures);
18234
+ if (strictSingleModel) rejectOtherRoots(paths, [`capabilities/${slug}/`], "capability", failures);
18235
+ const profile = parseJsonFile(files, `capabilities/${slug}/profile.json`, failures);
18622
18236
  if (profile) {
18623
18237
  const profileSlug = stringField6(profile.slug);
18624
18238
  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) {
18239
+ if (profileSlug && profileSlug !== slug) failures.push("capability profile slug must match model.slug");
18240
+ if (!profileSlug && profileName && profileName !== slug) {
18627
18241
  failures.push("capability profile name must match model.slug when slug is absent");
18628
18242
  }
18629
18243
  if (profile.agent !== void 0)
@@ -18634,8 +18248,8 @@ function validateFilesForKind(kind, slug2, files, strictSingleModel, failures) {
18634
18248
  }
18635
18249
  }
18636
18250
  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);
18251
+ requirePath(paths, `goals/templates/${slug}/state.json`, "goal template state", failures);
18252
+ if (strictSingleModel) rejectOtherRoots(paths, [`goals/templates/${slug}/`], "goal", failures);
18639
18253
  }
18640
18254
  if (kind === "agentLoop") {
18641
18255
  if (!paths.some((filePath) => filePath.endsWith("/state.json")))
@@ -18643,8 +18257,8 @@ function validateFilesForKind(kind, slug2, files, strictSingleModel, failures) {
18643
18257
  if (strictSingleModel) rejectOtherRoots(paths, ["goals/", "loops/", "capabilities/"], "agentLoop", failures);
18644
18258
  }
18645
18259
  if (kind === "workflow") {
18646
- requirePath(paths, `capabilities/${slug2}/profile.json`, "workflow capability profile", failures);
18647
- const profile = parseJsonFile(files, `capabilities/${slug2}/profile.json`, failures);
18260
+ requirePath(paths, `capabilities/${slug}/profile.json`, "workflow capability profile", failures);
18261
+ const profile = parseJsonFile(files, `capabilities/${slug}/profile.json`, failures);
18648
18262
  if (profile) {
18649
18263
  if (profile.capabilityKind !== void 0) {
18650
18264
  failures.push("workflow profile must not declare capabilityKind");
@@ -18663,8 +18277,8 @@ function validateFactoryAssembly(models, failures) {
18663
18277
  if (!model || typeof model !== "object" || Array.isArray(model)) continue;
18664
18278
  const input = model;
18665
18279
  const kind = stringField6(input.kind);
18666
- const slug2 = stringField6(input.slug);
18667
- if (isModelKind(kind) && isSlug2(slug2)) available.set(`${kind}:${slug2}`, kind);
18280
+ const slug = stringField6(input.slug);
18281
+ if (isModelKind(kind) && isSlug(slug)) available.set(`${kind}:${slug}`, kind);
18668
18282
  }
18669
18283
  for (const model of models) {
18670
18284
  if (!model || typeof model !== "object" || Array.isArray(model)) continue;
@@ -18678,7 +18292,7 @@ function validateFactoryAssembly(models, failures) {
18678
18292
  }
18679
18293
  }
18680
18294
  if (kind === "workflow") {
18681
- for (const capability of stringArray5(input.steps)) {
18295
+ for (const capability of stringArray4(input.steps)) {
18682
18296
  if (!available.has(`capability:${capability}`)) {
18683
18297
  failures.push(`workflow ${stringField6(input.slug)} references missing capability ${capability}`);
18684
18298
  }
@@ -18708,10 +18322,10 @@ function validateFactoryAssembly(models, failures) {
18708
18322
  }
18709
18323
  }
18710
18324
  }
18711
- function validateModelShape(kind, model, files, slug2, failures) {
18325
+ function validateModelShape(kind, model, files, slug, failures) {
18712
18326
  if (kind === "agent") {
18713
- const agentFile = textFile(files, `agents/${slug2}.md`);
18714
- if (!stringArray5(model.owns).includes("identity") && !containsWord(agentFile, "identity")) {
18327
+ const agentFile = textFile(files, `agents/${slug}.md`);
18328
+ if (!stringArray4(model.owns).includes("identity") && !containsWord(agentFile, "identity")) {
18715
18329
  failures.push("agent owns must include identity");
18716
18330
  }
18717
18331
  requireStringArrayIncludes(model.doesNotOwn, "tasks", "agent doesNotOwn", failures);
@@ -18728,7 +18342,7 @@ function validateModelShape(kind, model, files, slug2, failures) {
18728
18342
  requireStringArrayIncludes(model.doesNotOwn, "goal progress", "capability doesNotOwn", failures);
18729
18343
  }
18730
18344
  if (kind === "goal") {
18731
- const goalState = parseJsonContent(textFile(files, `goals/templates/${slug2}/state.json`));
18345
+ const goalState = parseJsonContent(textFile(files, `goals/templates/${slug}/state.json`));
18732
18346
  if (!stringField6(model.outcome) && !stringField6(goalState?.outcome))
18733
18347
  failures.push("goal model must declare outcome");
18734
18348
  if (evidenceRefs(model).length === 0 && evidenceRefs(goalState).length === 0) {
@@ -18740,7 +18354,7 @@ function validateModelShape(kind, model, files, slug2, failures) {
18740
18354
  }
18741
18355
  if (kind === "agentLoop") {
18742
18356
  if (!stringField6(model.cadence)) failures.push("agentLoop model must declare cadence");
18743
- const loopState = parseJsonContent(firstStateFile(files, slug2));
18357
+ const loopState = parseJsonContent(firstStateFile(files, slug));
18744
18358
  const hasTarget = Boolean(wakeTarget(model)) || Boolean(stringField6(model.target)) || Boolean(wakeTarget(loopState)) || Boolean(stringField6(loopState?.target)) || Boolean(loopTargetString(loopState));
18745
18359
  if (!hasTarget) {
18746
18360
  failures.push("agentLoop model must declare wakeTarget object");
@@ -18754,7 +18368,7 @@ function validateModelShape(kind, model, files, slug2, failures) {
18754
18368
  }
18755
18369
  }
18756
18370
  function capabilityRefs(value) {
18757
- return [...stringArray5(value?.capabilities), ...stringArray5(value?.allowedCapabilities)];
18371
+ return [...stringArray4(value?.capabilities), ...stringArray4(value?.allowedCapabilities)];
18758
18372
  }
18759
18373
  function evidenceRefs(value) {
18760
18374
  if (!value) return [];
@@ -18767,8 +18381,8 @@ function wakeTarget(value) {
18767
18381
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
18768
18382
  const target = raw;
18769
18383
  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 };
18384
+ const slug = stringField6(target.slug);
18385
+ if ((type === "goal" || type === "workflow" || type === "capability") && slug) return { kind: type, slug };
18772
18386
  return null;
18773
18387
  }
18774
18388
  function loopTargetString(value) {
@@ -18779,8 +18393,8 @@ function loopTargetString(value) {
18779
18393
  function textFile(files, wantedPath) {
18780
18394
  return files.find((item) => normalizeBundlePath(item.path) === wantedPath)?.content ?? "";
18781
18395
  }
18782
- function firstStateFile(files, slug2) {
18783
- const normalizedSlug = `${slug2}/state.json`;
18396
+ function firstStateFile(files, slug) {
18397
+ const normalizedSlug = `${slug}/state.json`;
18784
18398
  return files.find((item) => normalizeBundlePath(item.path).endsWith(normalizedSlug))?.content ?? "";
18785
18399
  }
18786
18400
  function parseJsonContent(content) {
@@ -18826,7 +18440,7 @@ function normalizeBundlePath(filePath) {
18826
18440
  function stringField6(value) {
18827
18441
  return typeof value === "string" ? value.trim() : "";
18828
18442
  }
18829
- function stringArray5(value) {
18443
+ function stringArray4(value) {
18830
18444
  if (!Array.isArray(value)) return [];
18831
18445
  return value.filter((item) => typeof item === "string").map((item) => item.trim()).filter(Boolean);
18832
18446
  }
@@ -18837,9 +18451,9 @@ function arrayObjects(value) {
18837
18451
  );
18838
18452
  }
18839
18453
  function requireStringArrayIncludes(value, expected, label, failures) {
18840
- if (!stringArray5(value).includes(expected)) failures.push(`${label} must include ${expected}`);
18454
+ if (!stringArray4(value).includes(expected)) failures.push(`${label} must include ${expected}`);
18841
18455
  }
18842
- function isSlug2(value) {
18456
+ function isSlug(value) {
18843
18457
  return /^[a-z][a-z0-9-]{0,63}$/.test(value);
18844
18458
  }
18845
18459
  function isModelKind(value) {
@@ -19572,8 +19186,6 @@ var init_scripts = __esm({
19572
19186
  init_advanceFlow();
19573
19187
  init_advanceManagedGoal();
19574
19188
  init_appendCompanyActivity();
19575
- init_appendCompanyIntentDecision();
19576
- init_applyAgencyArchitectDecision();
19577
19189
  init_applyCapabilityReports();
19578
19190
  init_buildSyntheticPlugin();
19579
19191
  init_checkCoverageWithRetry();
@@ -19621,7 +19233,6 @@ var init_scripts = __esm({
19621
19233
  init_notifyTerminal();
19622
19234
  init_openAgentFactoryStatePr();
19623
19235
  init_openQaIssue();
19624
- init_parseAgencyArchitectDecision();
19625
19236
  init_parseAgentResult();
19626
19237
  init_parseIssueStateFromAgentResult();
19627
19238
  init_parseJobStateFromAgentResult();
@@ -19719,7 +19330,6 @@ var init_scripts = __esm({
19719
19330
  };
19720
19331
  postflightScripts = {
19721
19332
  parseAgentResult: parseAgentResult2,
19722
- parseAgencyArchitectDecision,
19723
19333
  parseIssueStateFromAgentResult,
19724
19334
  parseJobStateFromAgentResult,
19725
19335
  parseReproOutput,
@@ -19727,8 +19337,6 @@ var init_scripts = __esm({
19727
19337
  writeIssueStateComment,
19728
19338
  writeJobStateFile,
19729
19339
  appendCompanyActivity,
19730
- appendCompanyIntentDecision: appendCompanyIntentDecision2,
19731
- applyAgencyArchitectDecision,
19732
19340
  requireFeedbackActions,
19733
19341
  requirePlanDeviations,
19734
19342
  verify,
@@ -19890,6 +19498,7 @@ var init_stateWorkspace = __esm({
19890
19498
  ];
19891
19499
  FILE_MAPPINGS = [
19892
19500
  { statePath: "instructions.md", localPath: path43.join(".kody", "instructions.md") },
19501
+ { statePath: "system-prompt.md", localPath: path43.join(".kody", "system-prompt.md") },
19893
19502
  { statePath: "variables.json", localPath: path43.join(".kody", "variables.json") },
19894
19503
  { statePath: "secrets.enc", localPath: path43.join(".kody", "secrets.enc") }
19895
19504
  ];
@@ -21263,14 +20872,14 @@ function filterCliArgsForStep(action, raw) {
21263
20872
  function composeStepWhy(parentWhy, step) {
21264
20873
  return [parentWhy?.trim(), step.reason ? `Workflow step: ${step.reason}` : ""].filter((part) => Boolean(part)).join("\n\n");
21265
20874
  }
21266
- function loadCapabilityContext(slug2, cwd) {
21267
- if (!slug2) return null;
21268
- return resolveCapabilityFolder(slug2, path45.join(cwd, ".kody", "capabilities"));
20875
+ function loadCapabilityContext(slug, cwd) {
20876
+ if (!slug) return null;
20877
+ return resolveCapabilityFolder(slug, path45.join(cwd, ".kody", "capabilities"));
21269
20878
  }
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;
20879
+ function loadWorkflowContext(slug, base) {
20880
+ if (!slug || !base.config || !isWorkflowDefinitionId(slug)) return null;
20881
+ const workflow = readWorkflowDefinition(base.config, base.cwd, slug);
20882
+ return workflow ? workflowDefinitionToCapabilityFolder(slug, workflow) : null;
21274
20883
  }
21275
20884
  function mintInstantJob(dispatch2, opts) {
21276
20885
  return {
@@ -21782,7 +21391,7 @@ async function runChatTurn(opts) {
21782
21391
  return { exitCode: 64, error };
21783
21392
  }
21784
21393
  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);
21394
+ const basePrompt = opts.systemPrompt ?? readSystemPromptOverride(opts.cwd) ?? (opts.model.protocol === "openai" ? OPENAI_CHAT_SYSTEM_PROMPT : CHAT_SYSTEM_PROMPT);
21786
21395
  const agentIdentityBlock = readAgentIdentityBlock(opts.cwd, opts.agentIdentity);
21787
21396
  const catalog = buildImplementationCatalog();
21788
21397
  const taskArtifactsPaths = prepareTaskArtifactsDir(opts.cwd, opts.sessionId);
@@ -21930,10 +21539,10 @@ async function runChatTurn(opts) {
21930
21539
  return { exitCode: 0, reply };
21931
21540
  }
21932
21541
  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);
21542
+ const slug = agentIdentity?.slug?.trim();
21543
+ if (!slug) return null;
21544
+ const body = agentIdentity?.body?.trim() || loadAgentIdentity(cwd, slug);
21545
+ return frameAgentIdentity(slug, body);
21937
21546
  }
21938
21547
  async function runOpenAIChatTurn(args) {
21939
21548
  const { opts, turns, systemPrompt, sessionFile } = args;
@@ -22075,6 +21684,17 @@ _\u2026 (context truncated; use the state repo context files for the full text)_
22075
21684
  }
22076
21685
  var INSTRUCTIONS_REL = ".kody/instructions.md";
22077
21686
  var MAX_INSTRUCTIONS_BYTES = 8e3;
21687
+ var SYSTEM_PROMPT_OVERRIDE_REL = ".kody/system-prompt.md";
21688
+ function readSystemPromptOverride(cwd) {
21689
+ let raw;
21690
+ try {
21691
+ raw = fs14.readFileSync(path16.join(cwd, SYSTEM_PROMPT_OVERRIDE_REL), "utf-8");
21692
+ } catch {
21693
+ return null;
21694
+ }
21695
+ const trimmed = raw.trim();
21696
+ return trimmed.length > 0 ? trimmed : null;
21697
+ }
22078
21698
  function readInstructionsBlock(cwd) {
22079
21699
  const instructionsPath = path16.join(cwd, INSTRUCTIONS_REL);
22080
21700
  let raw;
@@ -23626,11 +23246,11 @@ function agentIdentityField(body) {
23626
23246
  if (typeof body !== "object" || body === null || !("agentIdentity" in body)) return void 0;
23627
23247
  const value = body.agentIdentity;
23628
23248
  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 };
23249
+ const record = value;
23250
+ const slug = typeof record.slug === "string" ? record.slug.trim() : "";
23251
+ const bodyText = typeof record.body === "string" ? record.body.trim() : "";
23252
+ if (!slug || !bodyText) return void 0;
23253
+ return { slug, body: bodyText };
23634
23254
  }
23635
23255
  function sendJson(res, status, body) {
23636
23256
  res.writeHead(status, { "content-type": "application/json" });