@kody-ade/kody-engine 0.4.311 → 0.4.313

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 +169 -93
  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.311",
18
+ version: "0.4.313",
19
19
  description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
20
20
  license: "MIT",
21
21
  type: "module",
@@ -501,7 +501,11 @@ function normalizeStatePath(raw, field = "statePath") {
501
501
  function normalizeStateBranch(raw, field = "state.branch") {
502
502
  const value = raw?.trim() || STATE_BRANCH;
503
503
  if (!value) throw new Error(`kody.config.json: ${field} must not be empty`);
504
- if (value.startsWith("/") || value.endsWith("/") || value.includes("\\") || value.includes("..") || value.includes("@{") || /[\x00-\x20\x7f~^:?*\[]/.test(value)) {
504
+ const hasInvalidChar = [...value].some((char) => {
505
+ const code = char.charCodeAt(0);
506
+ return code <= 32 || code === 127 || "~^:?*[".includes(char);
507
+ });
508
+ if (value.startsWith("/") || value.endsWith("/") || value.includes("\\") || value.includes("..") || value.includes("@{") || hasInvalidChar) {
505
509
  throw new Error(`kody.config.json: ${field} contains an invalid branch`);
506
510
  }
507
511
  for (const part of value.split("/")) {
@@ -1557,9 +1561,7 @@ var init_submitMcp = __esm({
1557
1561
  INPUT_SCHEMA2 = {
1558
1562
  cursor: z.string().describe('The next cursor value (e.g. "idle"). Must be a non-empty string.'),
1559
1563
  data: z.record(z.string(), z.unknown()).describe("The next `data` object. Carry forward prior data and mutate only what you acted on this tick."),
1560
- done: z.boolean().describe(
1561
- "true only if this capability is permanently finished; evergreen capabilities stay false."
1562
- )
1564
+ done: z.boolean().describe("true only if this capability is permanently finished; evergreen capabilities stay false.")
1563
1565
  };
1564
1566
  }
1565
1567
  });
@@ -1922,7 +1924,7 @@ function parseCapabilityConfig(raw) {
1922
1924
  stage: stringField(raw.stage),
1923
1925
  readsFrom: stringList(raw.readsFrom ?? raw.reads_from),
1924
1926
  writesTo: stringList(raw.writesTo ?? raw.writes_to),
1925
- workflow: parseWorkflow(raw.workflow)
1927
+ workflow: parseCapabilityWorkflow(raw.workflow)
1926
1928
  };
1927
1929
  }
1928
1930
  function parseCapabilityToolMode(raw) {
@@ -1963,7 +1965,7 @@ function stringList(value) {
1963
1965
  }
1964
1966
  return [];
1965
1967
  }
1966
- function parseWorkflow(value) {
1968
+ function parseCapabilityWorkflow(value) {
1967
1969
  const stepsRaw = Array.isArray(value) ? value : value && typeof value === "object" && Array.isArray(value.steps) ? value.steps : [];
1968
1970
  const steps = stepsRaw.map(parseWorkflowStep).filter((step) => step !== null);
1969
1971
  return steps.length > 0 ? { steps } : void 0;
@@ -6564,11 +6566,13 @@ function jobMetaFromData(data) {
6564
6566
  why: typeof data.jobWhy === "string" ? data.jobWhy : void 0
6565
6567
  };
6566
6568
  }
6567
- function applyStandaloneTerminalState(state, ctx, profile) {
6569
+ function applyStandaloneFinalState(state, ctx, profile) {
6568
6570
  if (profile.lifecycleConfig?.finalize !== true || state.flow?.issueNumber) return;
6569
- const delivered = ctx.output.exitCode === 0 && (!!state.core.prUrl || isDeliveryNotRequired(ctx.data));
6570
- state.core.phase = delivered ? "shipped" : "failed";
6571
- state.core.status = delivered ? "succeeded" : "failed";
6571
+ const hasPr = !!state.core.prUrl;
6572
+ const noDeliveryNeeded = isDeliveryNotRequired(ctx.data);
6573
+ const succeeded = ctx.output.exitCode === 0 && (hasPr || noDeliveryNeeded);
6574
+ state.core.phase = succeeded ? hasPr ? "reviewing" : "shipped" : "failed";
6575
+ state.core.status = succeeded ? "succeeded" : "failed";
6572
6576
  state.core.currentExecutable = null;
6573
6577
  }
6574
6578
  function synthesizeAction(ctx) {
@@ -6602,7 +6606,7 @@ var init_saveTaskState = __esm({
6602
6606
  });
6603
6607
  if (ctx.output.prUrl) next.core.prUrl = ctx.output.prUrl;
6604
6608
  if (typeof ctx.data.runUrl === "string") next.core.runUrl = ctx.data.runUrl;
6605
- applyStandaloneTerminalState(next, ctx, profile);
6609
+ applyStandaloneFinalState(next, ctx, profile);
6606
6610
  writeTaskState(target, number, next, ctx.cwd, ctx.config);
6607
6611
  ctx.data.taskState = next;
6608
6612
  ctx.data.taskStateRendered = renderStateComment(next);
@@ -7595,9 +7599,9 @@ function listGoalStateIds(config, cwd) {
7595
7599
  var init_stateStore = __esm({
7596
7600
  "src/goal/stateStore.ts"() {
7597
7601
  "use strict";
7602
+ init_companyStore();
7598
7603
  init_stateRepo();
7599
7604
  init_managedTodoState();
7600
- init_companyStore();
7601
7605
  }
7602
7606
  });
7603
7607
 
@@ -9215,7 +9219,13 @@ function writeCompanyIntent(config, cwd, intent, message = `chore(intents): upda
9215
9219
  }
9216
9220
  function appendCompanyIntentDecision(config, cwd, intentId, entry) {
9217
9221
  assertIntentId(intentId);
9218
- appendStateLine(config, cwd, `intents/${intentId}/decisions.jsonl`, JSON.stringify(entry), `chore(intents): log ${intentId} decision`);
9222
+ appendStateLine(
9223
+ config,
9224
+ cwd,
9225
+ `intents/${intentId}/decisions.jsonl`,
9226
+ JSON.stringify(entry),
9227
+ `chore(intents): log ${intentId} decision`
9228
+ );
9219
9229
  }
9220
9230
  function listCompanyPortfolio(config, cwd) {
9221
9231
  const goals = [];
@@ -9265,7 +9275,11 @@ function normalizeReleasePolicy(raw) {
9265
9275
  cadence: oneOf2(raw.cadence, ["manual", "1d", "1w"], "manual"),
9266
9276
  qaDepth: oneOf2(raw.qaDepth, ["light", "standard", "strict"], "standard"),
9267
9277
  blockerLevel: oneOf2(raw.blockerLevel, ["low", "standard", "strict"], "standard"),
9268
- approval: oneOf2(raw.approval, ["none", "before-production", "before-risky-actions"], "before-risky-actions")
9278
+ approval: oneOf2(
9279
+ raw.approval,
9280
+ ["none", "before-production", "before-risky-actions"],
9281
+ "before-risky-actions"
9282
+ )
9269
9283
  };
9270
9284
  }
9271
9285
  function normalizeAutomationPolicy(raw) {
@@ -9301,13 +9315,25 @@ function applyAction(config, cwd, action) {
9301
9315
  if (action.kind === "createManagedGoal") {
9302
9316
  const existing = fetchGoalState(config, action.id, cwd);
9303
9317
  if (existing) return applied(action, false, "goal already exists");
9304
- writeCompanyGoalState(config, cwd, action.id, buildManagedGoalState(action), `chore(goals): create ${action.id} from intent ${action.intentId}`);
9318
+ writeCompanyGoalState(
9319
+ config,
9320
+ cwd,
9321
+ action.id,
9322
+ buildManagedGoalState(action),
9323
+ `chore(goals): create ${action.id} from intent ${action.intentId}`
9324
+ );
9305
9325
  return applied(action, true, action.reason, action.id);
9306
9326
  }
9307
9327
  if (action.kind === "createAgentLoop") {
9308
9328
  const existing = fetchGoalState(config, action.id, cwd);
9309
9329
  if (existing) return applied(action, false, "loop already exists");
9310
- writeCompanyGoalState(config, cwd, action.id, buildAgentLoopState(action), `chore(goals): create loop ${action.id} from intent ${action.intentId}`);
9330
+ writeCompanyGoalState(
9331
+ config,
9332
+ cwd,
9333
+ action.id,
9334
+ buildAgentLoopState(action),
9335
+ `chore(goals): create loop ${action.id} from intent ${action.intentId}`
9336
+ );
9311
9337
  return applied(action, true, action.reason, action.id);
9312
9338
  }
9313
9339
  if (action.kind === "setGoalLifecycle") {
@@ -9325,7 +9351,13 @@ function applyAction(config, cwd, action) {
9325
9351
  lifecycleChangeReason: action.reason
9326
9352
  }
9327
9353
  };
9328
- writeCompanyGoalState(config, cwd, action.id, next, `chore(goals): ${action.state} ${action.id} from intent ${action.intentId}`);
9354
+ writeCompanyGoalState(
9355
+ config,
9356
+ cwd,
9357
+ action.id,
9358
+ next,
9359
+ `chore(goals): ${action.state} ${action.id} from intent ${action.intentId}`
9360
+ );
9329
9361
  return applied(action, true, action.reason, action.id);
9330
9362
  }
9331
9363
  if (action.kind === "updateIntentPortfolio") {
@@ -9386,8 +9418,8 @@ var init_applyAgencyArchitectDecision = __esm({
9386
9418
  "use strict";
9387
9419
  init_agencyArchitectDecision();
9388
9420
  init_companyIntent();
9389
- init_stateStore();
9390
9421
  init_state2();
9422
+ init_stateStore();
9391
9423
  applyAgencyArchitectDecision = async (ctx) => {
9392
9424
  const decision = ctx.data.agencyArchitectDecision;
9393
9425
  if (!decision || !Array.isArray(decision.actions)) return;
@@ -9927,6 +9959,16 @@ function completeSatisfiedManagedGoal(state) {
9927
9959
  if (decision.kind !== "done") return state;
9928
9960
  return writeManagedGoalToState({ ...state, state: "done" }, managed);
9929
9961
  }
9962
+ function shouldResumeManagedGoal(state) {
9963
+ if (state.state !== "active") return false;
9964
+ const managed = managedGoalFromState(state);
9965
+ if (!managed) return false;
9966
+ if (managed.blockers.length > 0) return false;
9967
+ const missing = managed.destination.evidence.find((evidence) => managed.facts[evidence] !== true);
9968
+ if (!missing) return false;
9969
+ const step = managed.route.find((candidate) => candidate.evidence === missing);
9970
+ return Boolean(step && managed.capabilities.includes(step.capability));
9971
+ }
9930
9972
  function snapshotFromState2(goalId, state) {
9931
9973
  const managed = managedGoalFromState(state);
9932
9974
  return managed ? goalRunLogSnapshot(goalId, state.state, managed) : null;
@@ -10074,6 +10116,13 @@ var init_applyCapabilityReports = __esm({
10074
10116
  putGoalState(ctx.config, goalId, nextForOutput, describeMessage(goalId, goalEvidence), ctx.cwd);
10075
10117
  }
10076
10118
  refreshReportOrFail(ctx, goalId, nextForOutput, goalEvidence);
10119
+ if (changed && ctx.output.exitCode === 0 && !ctx.output.nextDispatch && shouldResumeManagedGoal(nextForOutput)) {
10120
+ ctx.output.nextDispatch = {
10121
+ action: "goal-manager",
10122
+ executable: "goal-manager",
10123
+ cliArgs: { goal: goalId }
10124
+ };
10125
+ }
10077
10126
  } finally {
10078
10127
  flushLogs(ctx);
10079
10128
  }
@@ -10495,9 +10544,7 @@ function formatCapabilityReference(data, profileName) {
10495
10544
  const capabilitySchedule = pickToken(data, "capabilitySchedule", "jobSchedule");
10496
10545
  const lines = ["# Capability reference", ""];
10497
10546
  if (capabilitySlug) {
10498
- lines.push(
10499
- `- Capability: \`${capabilitySlug}\`${capabilityTitle ? ` \u2014 *${capabilityTitle}*` : ""}`
10500
- );
10547
+ lines.push(`- Capability: \`${capabilitySlug}\`${capabilityTitle ? ` \u2014 *${capabilityTitle}*` : ""}`);
10501
10548
  }
10502
10549
  if (executableSlug) {
10503
10550
  lines.push(`- Executable: \`${executableSlug}\``);
@@ -10783,7 +10830,11 @@ function parseFallbackFindingsJson(text) {
10783
10830
  try {
10784
10831
  const parsed = JSON.parse(raw);
10785
10832
  if (!parsed || !Array.isArray(parsed.findings)) {
10786
- return { markdown: removeFence(text, match).trim(), data: null, jsonError: "fallback JSON missing 'findings' array" };
10833
+ return {
10834
+ markdown: removeFence(text, match).trim(),
10835
+ data: null,
10836
+ jsonError: "fallback JSON missing 'findings' array"
10837
+ };
10787
10838
  }
10788
10839
  return {
10789
10840
  markdown: removeFence(text, match).trim(),
@@ -11789,9 +11840,7 @@ var init_dispatchCapabilityFileTicks = __esm({
11789
11840
  ctx.data.jobTickResults = [];
11790
11841
  ctx.output.exitCode = 0;
11791
11842
  ctx.output.reason = "capability scheduling is owned by goals and loops";
11792
- process.stdout.write(
11793
- "[jobs] no flat capability fan-out; goals and loops own scheduled capability decisions\n"
11794
- );
11843
+ process.stdout.write("[jobs] no flat capability fan-out; goals and loops own scheduled capability decisions\n");
11795
11844
  };
11796
11845
  }
11797
11846
  });
@@ -12433,7 +12482,7 @@ var init_failOnceTaskJob = __esm({
12433
12482
  });
12434
12483
 
12435
12484
  // src/scripts/finalizeTerminal.ts
12436
- var DONE, FAILED, finalizeTerminal;
12485
+ var DONE, REVIEWING, FAILED, finalizeTerminal;
12437
12486
  var init_finalizeTerminal = __esm({
12438
12487
  "src/scripts/finalizeTerminal.ts"() {
12439
12488
  "use strict";
@@ -12444,7 +12493,12 @@ var init_finalizeTerminal = __esm({
12444
12493
  DONE = {
12445
12494
  label: "kody:done",
12446
12495
  color: "0e8a16",
12447
- description: "kody: PR ready for human review/merge"
12496
+ description: "kody: work complete"
12497
+ };
12498
+ REVIEWING = {
12499
+ label: "kody:reviewing",
12500
+ color: "d93f0b",
12501
+ description: "kody: PR ready for human review"
12448
12502
  };
12449
12503
  FAILED = {
12450
12504
  label: "kody:failed",
@@ -12461,10 +12515,12 @@ var init_finalizeTerminal = __esm({
12461
12515
  const cachedState = ctx.data.taskState;
12462
12516
  let state = cachedState;
12463
12517
  const prUrl = cachedState?.core.prUrl ?? ctx.output.prUrl ?? ctx.data.prResult?.url;
12464
- const delivered = ctx.output.exitCode === 0 && (!!prUrl || isDeliveryNotRequired(ctx.data));
12465
- const spec = delivered ? DONE : FAILED;
12466
- const phase = delivered ? "shipped" : "failed";
12467
- const status = delivered ? "succeeded" : "failed";
12518
+ const hasPr = !!prUrl;
12519
+ const noDeliveryNeeded = isDeliveryNotRequired(ctx.data);
12520
+ const succeeded = ctx.output.exitCode === 0 && (hasPr || noDeliveryNeeded);
12521
+ const spec = succeeded ? hasPr ? REVIEWING : DONE : FAILED;
12522
+ const phase = succeeded ? hasPr ? "reviewing" : "shipped" : "failed";
12523
+ const status = succeeded ? "succeeded" : "failed";
12468
12524
  if (issueNumber) setKodyLabel(issueNumber, spec, ctx.cwd);
12469
12525
  const prNumber = prUrl ? parsePrNumber(prUrl) : null;
12470
12526
  if (prNumber && prNumber !== issueNumber) setKodyLabel(prNumber, spec, ctx.cwd);
@@ -14566,7 +14622,9 @@ function parseAgentFactoryBundle(raw) {
14566
14622
  try {
14567
14623
  parsed = JSON.parse(jsonText);
14568
14624
  } catch (err) {
14569
- throw new Error(`openAgentFactoryStatePr: PR_SUMMARY must be valid JSON: ${err instanceof Error ? err.message : String(err)}`);
14625
+ throw new Error(
14626
+ `openAgentFactoryStatePr: PR_SUMMARY must be valid JSON: ${err instanceof Error ? err.message : String(err)}`
14627
+ );
14570
14628
  }
14571
14629
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
14572
14630
  throw new Error("openAgentFactoryStatePr: PR_SUMMARY must be a JSON object");
@@ -14654,7 +14712,9 @@ function ghJson(args, cwd, input) {
14654
14712
  try {
14655
14713
  return JSON.parse(raw);
14656
14714
  } catch (err) {
14657
- throw new Error(`openAgentFactoryStatePr: gh api returned invalid JSON: ${err instanceof Error ? err.message : String(err)}`);
14715
+ throw new Error(
14716
+ `openAgentFactoryStatePr: gh api returned invalid JSON: ${err instanceof Error ? err.message : String(err)}`
14717
+ );
14658
14718
  }
14659
14719
  }
14660
14720
  function renderPullRequestBody(ctx, bundle, files) {
@@ -14707,21 +14767,26 @@ var init_openAgentFactoryStatePr = __esm({
14707
14767
  const stateRepo = parseStateRepo(ctx.config);
14708
14768
  const baseBranch = "main";
14709
14769
  const branch = buildAgentFactoryBranchName(issueNumber, bundle.title);
14710
- const baseRef = ghJson(["api", `/repos/${stateRepo.owner}/${stateRepo.repo}/git/ref/heads/${baseBranch}`], ctx.cwd);
14711
- const baseSha = requireString2(baseRef.object?.sha, `state repo ${stateRepo.owner}/${stateRepo.repo} ${baseBranch} ref sha`);
14770
+ const baseRef = ghJson(
14771
+ ["api", `/repos/${stateRepo.owner}/${stateRepo.repo}/git/ref/heads/${baseBranch}`],
14772
+ ctx.cwd
14773
+ );
14774
+ const baseSha = requireString2(
14775
+ baseRef.object?.sha,
14776
+ `state repo ${stateRepo.owner}/${stateRepo.repo} ${baseBranch} ref sha`
14777
+ );
14712
14778
  const baseCommit = ghJson(
14713
14779
  ["api", `/repos/${stateRepo.owner}/${stateRepo.repo}/git/commits/${baseSha}`],
14714
14780
  ctx.cwd
14715
14781
  );
14716
- const baseTreeSha = requireString2(baseCommit.tree?.sha, `state repo ${stateRepo.owner}/${stateRepo.repo} base tree sha`);
14717
- ghJson(
14718
- ["api", "--method", "POST", `/repos/${stateRepo.owner}/${stateRepo.repo}/git/refs`, "--input", "-"],
14719
- ctx.cwd,
14720
- {
14721
- ref: `refs/heads/${branch}`,
14722
- sha: baseSha
14723
- }
14782
+ const baseTreeSha = requireString2(
14783
+ baseCommit.tree?.sha,
14784
+ `state repo ${stateRepo.owner}/${stateRepo.repo} base tree sha`
14724
14785
  );
14786
+ ghJson(["api", "--method", "POST", `/repos/${stateRepo.owner}/${stateRepo.repo}/git/refs`, "--input", "-"], ctx.cwd, {
14787
+ ref: `refs/heads/${branch}`,
14788
+ sha: baseSha
14789
+ });
14725
14790
  const tree = ghJson(
14726
14791
  ["api", "--method", "POST", `/repos/${stateRepo.owner}/${stateRepo.repo}/git/trees`, "--input", "-"],
14727
14792
  ctx.cwd,
@@ -14747,7 +14812,14 @@ var init_openAgentFactoryStatePr = __esm({
14747
14812
  );
14748
14813
  const commitSha = requireString2(commit.sha, "created commit sha");
14749
14814
  ghJson(
14750
- ["api", "--method", "PATCH", `/repos/${stateRepo.owner}/${stateRepo.repo}/git/refs/heads/${branch}`, "--input", "-"],
14815
+ [
14816
+ "api",
14817
+ "--method",
14818
+ "PATCH",
14819
+ `/repos/${stateRepo.owner}/${stateRepo.repo}/git/refs/heads/${branch}`,
14820
+ "--input",
14821
+ "-"
14822
+ ],
14751
14823
  ctx.cwd,
14752
14824
  {
14753
14825
  sha: commitSha,
@@ -14899,10 +14971,43 @@ QA_REPORT_POSTED=${created.url} (verdict: ${verdict})
14899
14971
  }
14900
14972
  });
14901
14973
 
14902
- // src/scripts/parseAgentResult.ts
14974
+ // src/scripts/parseAgencyArchitectDecision.ts
14903
14975
  function makeAction2(type, payload) {
14904
14976
  return { type, payload, timestamp: (/* @__PURE__ */ new Date()).toISOString() };
14905
14977
  }
14978
+ var parseAgencyArchitectDecision;
14979
+ var init_parseAgencyArchitectDecision = __esm({
14980
+ "src/scripts/parseAgencyArchitectDecision.ts"() {
14981
+ "use strict";
14982
+ init_agencyArchitectDecision();
14983
+ parseAgencyArchitectDecision = async (ctx, _profile, agentResult) => {
14984
+ if (!agentResult) {
14985
+ ctx.data.agencyArchitectDecision = { summary: "", actions: [] };
14986
+ ctx.data.action = makeAction2("AGENCY_ARCHITECT_NOT_RUN", { reason: "no agent result" });
14987
+ return;
14988
+ }
14989
+ try {
14990
+ const decision = parseAgencyArchitectDecisionText(agentResult.finalText);
14991
+ ctx.data.agencyArchitectDecision = decision;
14992
+ ctx.data.action = makeAction2("AGENCY_ARCHITECT_DECIDED", {
14993
+ summary: decision.summary,
14994
+ actionCount: decision.actions.length
14995
+ });
14996
+ } catch (err) {
14997
+ const reason = err instanceof Error ? err.message : String(err);
14998
+ ctx.data.agencyArchitectDecisionError = reason;
14999
+ ctx.data.action = makeAction2("AGENCY_ARCHITECT_FAILED", { reason });
15000
+ ctx.output.exitCode = 1;
15001
+ ctx.output.reason = reason;
15002
+ }
15003
+ };
15004
+ }
15005
+ });
15006
+
15007
+ // src/scripts/parseAgentResult.ts
15008
+ function makeAction3(type, payload) {
15009
+ return { type, payload, timestamp: (/* @__PURE__ */ new Date()).toISOString() };
15010
+ }
14906
15011
  var parseAgentResult2;
14907
15012
  var init_parseAgentResult = __esm({
14908
15013
  "src/scripts/parseAgentResult.ts"() {
@@ -14911,7 +15016,7 @@ var init_parseAgentResult = __esm({
14911
15016
  parseAgentResult2 = async (ctx, profile, agentResult) => {
14912
15017
  if (!agentResult) {
14913
15018
  ctx.data.agentDone = false;
14914
- ctx.data.action = makeAction2("AGENT_NOT_RUN", { reason: "no agent result" });
15019
+ ctx.data.action = makeAction3("AGENT_NOT_RUN", { reason: "no agent result" });
14915
15020
  return;
14916
15021
  }
14917
15022
  const parsed = parseAgentResult(agentResult.finalText);
@@ -14928,46 +15033,13 @@ var init_parseAgentResult = __esm({
14928
15033
  ctx.data.agentError = agentResult.error;
14929
15034
  const modeSeg = (ctx.args.mode ?? profile.name).replace(/-/g, "_").toUpperCase();
14930
15035
  if (parsed.done) {
14931
- ctx.data.action = makeAction2(`${modeSeg}_COMPLETED`, {
15036
+ ctx.data.action = makeAction3(`${modeSeg}_COMPLETED`, {
14932
15037
  commitMessage: parsed.commitMessage
14933
15038
  });
14934
15039
  } else {
14935
15040
  const isGenericNoOutput = parsed.failureReason === "agent produced no final message";
14936
15041
  const reason = isGenericNoOutput && agentResult.error ? `agent SDK error: ${agentResult.error}` : parsed.failureReason || agentResult.error || "unknown failure";
14937
- ctx.data.action = makeAction2(`${modeSeg}_FAILED`, { reason });
14938
- }
14939
- };
14940
- }
14941
- });
14942
-
14943
- // src/scripts/parseAgencyArchitectDecision.ts
14944
- function makeAction3(type, payload) {
14945
- return { type, payload, timestamp: (/* @__PURE__ */ new Date()).toISOString() };
14946
- }
14947
- var parseAgencyArchitectDecision;
14948
- var init_parseAgencyArchitectDecision = __esm({
14949
- "src/scripts/parseAgencyArchitectDecision.ts"() {
14950
- "use strict";
14951
- init_agencyArchitectDecision();
14952
- parseAgencyArchitectDecision = async (ctx, _profile, agentResult) => {
14953
- if (!agentResult) {
14954
- ctx.data.agencyArchitectDecision = { summary: "", actions: [] };
14955
- ctx.data.action = makeAction3("AGENCY_ARCHITECT_NOT_RUN", { reason: "no agent result" });
14956
- return;
14957
- }
14958
- try {
14959
- const decision = parseAgencyArchitectDecisionText(agentResult.finalText);
14960
- ctx.data.agencyArchitectDecision = decision;
14961
- ctx.data.action = makeAction3("AGENCY_ARCHITECT_DECIDED", {
14962
- summary: decision.summary,
14963
- actionCount: decision.actions.length
14964
- });
14965
- } catch (err) {
14966
- const reason = err instanceof Error ? err.message : String(err);
14967
- ctx.data.agencyArchitectDecisionError = reason;
14968
- ctx.data.action = makeAction3("AGENCY_ARCHITECT_FAILED", { reason });
14969
- ctx.output.exitCode = 1;
14970
- ctx.output.reason = reason;
15042
+ ctx.data.action = makeAction3(`${modeSeg}_FAILED`, { reason });
14971
15043
  }
14972
15044
  };
14973
15045
  }
@@ -18154,8 +18226,8 @@ var init_scripts = __esm({
18154
18226
  init_advanceManagedGoal();
18155
18227
  init_appendCompanyActivity();
18156
18228
  init_appendCompanyIntentDecision();
18157
- init_applyCapabilityReports();
18158
18229
  init_applyAgencyArchitectDecision();
18230
+ init_applyCapabilityReports();
18159
18231
  init_buildSyntheticPlugin();
18160
18232
  init_checkCoverageWithRetry();
18161
18233
  init_classifyByLabel();
@@ -18202,8 +18274,8 @@ var init_scripts = __esm({
18202
18274
  init_notifyTerminal();
18203
18275
  init_openAgentFactoryStatePr();
18204
18276
  init_openQaIssue();
18205
- init_parseAgentResult();
18206
18277
  init_parseAgencyArchitectDecision();
18278
+ init_parseAgentResult();
18207
18279
  init_parseIssueStateFromAgentResult();
18208
18280
  init_parseJobStateFromAgentResult();
18209
18281
  init_parseReproOutput();
@@ -19409,12 +19481,15 @@ function normalizeWorkflowDefinition(value) {
19409
19481
  if (!value || typeof value !== "object" || Array.isArray(value)) return null;
19410
19482
  const raw = value;
19411
19483
  const name = typeof raw.name === "string" ? raw.name.trim() : "";
19412
- const capabilities = normalizeWorkflowCapabilities(raw.capabilities);
19484
+ const workflow = parseCapabilityWorkflow({ steps: raw.steps });
19485
+ const steps = workflow?.steps;
19486
+ const capabilities = steps ? steps.map((step) => step.capability) : normalizeWorkflowCapabilities(raw.capabilities);
19413
19487
  if (!name || capabilities.length === 0) return null;
19414
19488
  return {
19415
19489
  version: 1,
19416
19490
  name,
19417
19491
  capabilities,
19492
+ ...steps ? { steps } : {},
19418
19493
  ...typeof raw.createdAt === "string" ? { createdAt: raw.createdAt } : {},
19419
19494
  ...typeof raw.updatedAt === "string" ? { updatedAt: raw.updatedAt } : {}
19420
19495
  };
@@ -19456,7 +19531,7 @@ function normalizeWorkflowCapabilities(value) {
19456
19531
  }
19457
19532
  function workflowDefinitionToConfig(workflow) {
19458
19533
  return {
19459
- steps: workflow.capabilities.map((capability) => ({ capability }))
19534
+ steps: workflow.steps ?? workflow.capabilities.map((capability) => ({ capability }))
19460
19535
  };
19461
19536
  }
19462
19537
  function readCompanyStoreWorkflowDefinition(id) {
@@ -19477,6 +19552,7 @@ var WORKFLOW_ID_PATTERN, CAPABILITY_ID_PATTERN;
19477
19552
  var init_workflowDefinitions = __esm({
19478
19553
  "src/workflowDefinitions.ts"() {
19479
19554
  "use strict";
19555
+ init_capabilityFolders();
19480
19556
  init_companyStore();
19481
19557
  init_stateRepo();
19482
19558
  WORKFLOW_ID_PATTERN = /^[a-z0-9][a-z0-9_-]{0,79}$/;
@@ -19682,7 +19758,7 @@ async function runCapabilityWorkflow(parent, workflow, capability, base) {
19682
19758
  }
19683
19759
  });
19684
19760
  const outcome = workflowOutcome(result);
19685
- const prUrl = result.taskState?.core.prUrl ?? (typeof chainData.workflowPrUrl === "string" ? chainData.workflowPrUrl : void 0);
19761
+ const prUrl = result.prUrl ?? result.taskState?.core.prUrl ?? (typeof chainData.workflowPrUrl === "string" ? chainData.workflowPrUrl : void 0);
19686
19762
  chainData = {
19687
19763
  ...chainData,
19688
19764
  ...result.taskState ? { taskState: result.taskState } : {},
@@ -20714,6 +20790,7 @@ async function mintAppInstallationToken(creds) {
20714
20790
  }
20715
20791
 
20716
20792
  // src/kody-cli.ts
20793
+ init_companyStore();
20717
20794
  init_config();
20718
20795
 
20719
20796
  // src/dispatch.ts
@@ -21144,7 +21221,6 @@ init_gha();
21144
21221
  init_issue();
21145
21222
  init_job();
21146
21223
  init_lifecycleLabels();
21147
- init_companyStore();
21148
21224
  init_registry();
21149
21225
 
21150
21226
  // src/run-request.ts
@@ -23292,10 +23368,10 @@ async function emit2(sink, type, sessionId, suffix, payload) {
23292
23368
  }
23293
23369
 
23294
23370
  // src/chat-cli.ts
23371
+ init_companyStore();
23295
23372
  init_config();
23296
23373
  init_litellm();
23297
23374
  init_stateWorkspace();
23298
- init_companyStore();
23299
23375
  var DEFAULT_MODEL2 = "claude/claude-haiku-4-5-20251001";
23300
23376
  var CHAT_HELP = `kody chat \u2014 dashboard-driven chat session
23301
23377
 
@@ -23556,6 +23632,9 @@ async function runCapabilityFallbackTick(deps) {
23556
23632
  // src/servers/pool-serve.ts
23557
23633
  init_keys();
23558
23634
 
23635
+ // src/pool/registry.ts
23636
+ init_stateRepoVault();
23637
+
23559
23638
  // src/pool/fly.ts
23560
23639
  var FLY_API_BASE = "https://api.machines.dev/v1";
23561
23640
  var POOL_METADATA_KEY = "kody_pool";
@@ -23920,7 +23999,6 @@ function isSuspendedWithIp(m) {
23920
23999
  }
23921
24000
 
23922
24001
  // src/pool/registry.ts
23923
- init_stateRepoVault();
23924
24002
  var POOL_MIN_VAULT_KEY = "POOL_MIN";
23925
24003
  var POOL_MIN_MAX = 10;
23926
24004
  function parsePoolMin(raw, dflt) {
@@ -24229,9 +24307,7 @@ async function poolServe() {
24229
24307
  activeRepos: () => registry.activeRepos(),
24230
24308
  claim: (owner, repo, req) => registry.claim(owner, repo, req),
24231
24309
  log
24232
- }).catch(
24233
- (err) => log(`capability fallback tick failed: ${err instanceof Error ? err.message : String(err)}`)
24234
- );
24310
+ }).catch((err) => log(`capability fallback tick failed: ${err instanceof Error ? err.message : String(err)}`));
24235
24311
  }, capabilityTickMs) : null;
24236
24312
  const server = createServer5(async (req, res) => {
24237
24313
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kody-ade/kody-engine",
3
- "version": "0.4.311",
3
+ "version": "0.4.313",
4
4
  "description": "kody — autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
5
5
  "license": "MIT",
6
6
  "type": "module",