@kody-ade/kody-engine 0.4.455 → 0.4.456

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin/kody.js CHANGED
@@ -15,7 +15,7 @@ var init_package = __esm({
15
15
  "package.json"() {
16
16
  package_default = {
17
17
  name: "@kody-ade/kody-engine",
18
- version: "0.4.455",
18
+ version: "0.4.456",
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",
@@ -1770,6 +1770,7 @@ function parseWorkflowStep(value) {
1770
1770
  const evidence = stringField(raw.evidence);
1771
1771
  const reason = stringField(raw.reason);
1772
1772
  const target = stringField(raw.target);
1773
+ const delivery = stringField(raw.delivery);
1773
1774
  const targetFact = stringField(raw.targetFact ?? raw.target_fact);
1774
1775
  const hasInput = Object.hasOwn(raw, "input");
1775
1776
  const next = parseWorkflowTransitions(raw.next);
@@ -1781,6 +1782,7 @@ function parseWorkflowStep(value) {
1781
1782
  ...action && isSafeSlug(action) ? { action } : {},
1782
1783
  ...evidence ? { evidence } : {},
1783
1784
  ...target === "issue" || target === "pr" ? { target } : {},
1785
+ ...delivery === "pull-request" ? { delivery } : {},
1784
1786
  ...targetFact ? { targetFact } : {},
1785
1787
  ...reason ? { reason } : {},
1786
1788
  ...next ? { next } : {},
@@ -4212,6 +4214,24 @@ var init_agencyBoundaryEval = __esm({
4212
4214
  }
4213
4215
  });
4214
4216
 
4217
+ // src/capabilityDelivery.ts
4218
+ function capabilityDeliveryTarget(input) {
4219
+ if (!input || typeof input !== "object" || Array.isArray(input)) return null;
4220
+ const value = input;
4221
+ const issue2 = positiveInteger(value.issue);
4222
+ const pr = positiveInteger(value.pr);
4223
+ if (issue2 === null === (pr === null)) return null;
4224
+ return issue2 === null ? { kind: "pr", number: pr } : { kind: "issue", number: issue2 };
4225
+ }
4226
+ function positiveInteger(value) {
4227
+ return typeof value === "number" && Number.isInteger(value) && value > 0 ? value : null;
4228
+ }
4229
+ var init_capabilityDelivery = __esm({
4230
+ "src/capabilityDelivery.ts"() {
4231
+ "use strict";
4232
+ }
4233
+ });
4234
+
4215
4235
  // src/agency/capability-contract-validation.ts
4216
4236
  import Ajv from "ajv";
4217
4237
  function validateCapabilityContractValue(boundary, schema, value) {
@@ -4350,7 +4370,7 @@ function parseGoalEvidenceProgress(value) {
4350
4370
  ...stringField2(raw.reason) ? { reason: stringField2(raw.reason) } : {},
4351
4371
  ...stringField2(raw.nextAction) ? { nextAction: stringField2(raw.nextAction) } : {},
4352
4372
  ...stringField2(raw.nextRetryAt) ? { nextRetryAt: stringField2(raw.nextRetryAt) } : {},
4353
- ...positiveInteger(raw.issue) ? { issue: positiveInteger(raw.issue) } : {},
4373
+ ...positiveInteger2(raw.issue) ? { issue: positiveInteger2(raw.issue) } : {},
4354
4374
  ...stringField2(raw.updatedAt) ? { updatedAt: stringField2(raw.updatedAt) } : {}
4355
4375
  };
4356
4376
  }
@@ -4366,7 +4386,7 @@ function definedProgressFields(update) {
4366
4386
  function stringField2(value) {
4367
4387
  return typeof value === "string" && value.trim() ? value.trim() : void 0;
4368
4388
  }
4369
- function positiveInteger(value) {
4389
+ function positiveInteger2(value) {
4370
4390
  if (typeof value === "number" && Number.isInteger(value) && value > 0) return value;
4371
4391
  return void 0;
4372
4392
  }
@@ -8904,6 +8924,14 @@ function validateWorkflow(value, options = {}) {
8904
8924
  }
8905
8925
  }
8906
8926
  validateDataMatch(step.runWhen, `${base}.runWhen`, issues);
8927
+ if (step.delivery !== void 0 && step.delivery !== "pull-request") {
8928
+ issue(
8929
+ issues,
8930
+ "invalid_delivery",
8931
+ `${base}.delivery`,
8932
+ "workflow step delivery must be pull-request"
8933
+ );
8934
+ }
8907
8935
  if (step.input !== void 0 && !isJsonValue(step.input)) {
8908
8936
  issue(issues, "invalid_input", `${base}.input`, "workflow step input must be one JSON value");
8909
8937
  }
@@ -9118,6 +9146,7 @@ var init_workflowValidation = __esm({
9118
9146
  "action",
9119
9147
  "evidence",
9120
9148
  "target",
9149
+ "delivery",
9121
9150
  "targetFact",
9122
9151
  "reason",
9123
9152
  "next",
@@ -15504,6 +15533,7 @@ var init_loadSimpleCapability = __esm({
15504
15533
  const toolFiles = listFiles(toolRoot);
15505
15534
  const skillFiles = listFiles(skillRoot);
15506
15535
  const input = parseInput(ctx.args.input);
15536
+ const delivery = ctx.data.jobDelivery === "pull-request";
15507
15537
  ctx.data.jobCapability = slug;
15508
15538
  ctx.data.capabilityInput = input;
15509
15539
  ctx.data.capabilityEnvironment = capabilityEnvironment(input);
@@ -15516,7 +15546,21 @@ var init_loadSimpleCapability = __esm({
15516
15546
  JSON.stringify(input ?? null, null, 2),
15517
15547
  "```",
15518
15548
  "",
15519
- "Return one JSON value.",
15549
+ ...delivery ? [
15550
+ "## Delivery",
15551
+ "",
15552
+ "The wrapper owns git commits, pushes, and pull requests. Do not run git or gh write commands.",
15553
+ "Finish with exactly this structure:",
15554
+ "",
15555
+ "DONE",
15556
+ "PLAN_DEVIATIONS: none",
15557
+ "COMMIT_MSG: <conventional commit message>",
15558
+ "PR_SUMMARY:",
15559
+ "- <what changed>",
15560
+ "```json",
15561
+ '{"summary":"<result>","status":"changed"}',
15562
+ "```"
15563
+ ] : ["Return one JSON value."],
15520
15564
  ...skillFiles.length ? [
15521
15565
  "",
15522
15566
  "## Skills",
@@ -17926,6 +17970,208 @@ var init_prepareBrowserAuth = __esm({
17926
17970
  }
17927
17971
  });
17928
17972
 
17973
+ // src/scripts/runFlow.ts
17974
+ function tryPost(issueNumber, body, cwd) {
17975
+ try {
17976
+ postIssueComment(issueNumber, body, cwd);
17977
+ } catch {
17978
+ }
17979
+ }
17980
+ function resolveBaseOverride(value) {
17981
+ if (!value) return null;
17982
+ if (value.length > 200) return null;
17983
+ if (value.includes("..")) return null;
17984
+ if (!/^[a-z0-9][a-z0-9/._-]*$/.test(value)) return null;
17985
+ return value;
17986
+ }
17987
+ var runFlow;
17988
+ var init_runFlow = __esm({
17989
+ "src/scripts/runFlow.ts"() {
17990
+ "use strict";
17991
+ init_branch();
17992
+ init_gha();
17993
+ init_issue();
17994
+ runFlow = async (ctx) => {
17995
+ const issueNumber = ctx.args.issue;
17996
+ const issue2 = getIssue(issueNumber, ctx.cwd);
17997
+ const cfgCtx = ctx.config.issueContext ?? {};
17998
+ const commentsFormatted = formatIssueComments(
17999
+ issue2.comments,
18000
+ cfgCtx.commentLimit ?? DEFAULT_COMMENT_LIMIT,
18001
+ cfgCtx.commentMaxBytes ?? DEFAULT_COMMENT_MAX_BYTES
18002
+ );
18003
+ ctx.data.issue = { ...issue2, commentsFormatted };
18004
+ if (issue2.isPullRequest) {
18005
+ ctx.data.commentTargetType = "pr";
18006
+ ctx.data.commentTargetNumber = issueNumber;
18007
+ ctx.skipAgent = true;
18008
+ ctx.output.exitCode = 1;
18009
+ ctx.output.reason = `run target #${issueNumber} is a pull request; dispatch a PR action or the source issue instead`;
18010
+ return;
18011
+ }
18012
+ ctx.data.commentTargetType = "issue";
18013
+ ctx.data.commentTargetNumber = issueNumber;
18014
+ const argBase = resolveBaseOverride(ctx.args.base);
18015
+ const baseRaw = ctx.args.base;
18016
+ if (baseRaw && !argBase) {
18017
+ process.stderr.write(`[kody runFlow] ignoring --base "${baseRaw}" (must match kody-task or goal-branch pattern)
18018
+ `);
18019
+ }
18020
+ const base = argBase;
18021
+ if (base) {
18022
+ ctx.data.baseBranch = base;
18023
+ process.stderr.write(`[kody runFlow] resolved base branch: ${base} (from --base)
18024
+ `);
18025
+ }
18026
+ const branchInfo = ensureFeatureBranch(
18027
+ issueNumber,
18028
+ issue2.title,
18029
+ ctx.config.git.defaultBranch,
18030
+ ctx.cwd,
18031
+ base ?? void 0
18032
+ );
18033
+ ctx.data.branch = branchInfo.branch;
18034
+ const runUrl = getRunUrl();
18035
+ const startMsg = runUrl ? `\u2699\uFE0F kody started \u2014 branch \`${ctx.data.branch}\`, run ${runUrl}` : `\u2699\uFE0F kody started \u2014 branch \`${ctx.data.branch}\``;
18036
+ tryPost(issueNumber, startMsg, ctx.cwd);
18037
+ };
18038
+ }
18039
+ });
18040
+
18041
+ // src/scripts/syncFlow.ts
18042
+ import { execFileSync as execFileSync16 } from "child_process";
18043
+ function restoreDone(prNumber, cwd) {
18044
+ try {
18045
+ setKodyLabel(prNumber, DONE2, cwd);
18046
+ } catch {
18047
+ }
18048
+ }
18049
+ function bail2(ctx, prNumber, reason) {
18050
+ ctx.skipAgent = true;
18051
+ ctx.output.exitCode = 1;
18052
+ ctx.output.reason = reason;
18053
+ const runUrl = getRunUrl();
18054
+ const runSuffix = runUrl ? ` ([logs](${runUrl}))` : "";
18055
+ tryPostPr3(prNumber, `\u274C kody sync could not complete${runSuffix}: ${reason}`, ctx.cwd);
18056
+ }
18057
+ function revParseHead(cwd) {
18058
+ try {
18059
+ return execFileSync16("git", ["rev-parse", "HEAD"], { cwd, encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] }).toString().trim();
18060
+ } catch {
18061
+ return "";
18062
+ }
18063
+ }
18064
+ function pushBranch(branch, cwd) {
18065
+ const result = pushWithRetry({ cwd: cwd ?? process.cwd(), branch, setUpstream: true });
18066
+ if (!result.ok) {
18067
+ throw new Error(result.reason);
18068
+ }
18069
+ }
18070
+ function tryPostPr3(prNumber, body, cwd) {
18071
+ try {
18072
+ postPrReviewComment(prNumber, body, cwd);
18073
+ } catch {
18074
+ }
18075
+ }
18076
+ var DONE2, syncFlow;
18077
+ var init_syncFlow = __esm({
18078
+ "src/scripts/syncFlow.ts"() {
18079
+ "use strict";
18080
+ init_branch();
18081
+ init_gha();
18082
+ init_issue();
18083
+ init_lifecycleLabels();
18084
+ init_pushWithRetry();
18085
+ DONE2 = {
18086
+ label: "kody:done",
18087
+ color: "0e8a16",
18088
+ description: "kody: PR ready for human review/merge"
18089
+ };
18090
+ syncFlow = async (ctx, _profile, args) => {
18091
+ const announceOnSuccess = Boolean(args?.announceOnSuccess);
18092
+ const prNumber = ctx.args.pr;
18093
+ const pr = getPr(prNumber, ctx.cwd);
18094
+ if (pr.state !== "OPEN") {
18095
+ bail2(ctx, prNumber, `PR #${prNumber} is not OPEN (state: ${pr.state})`);
18096
+ return;
18097
+ }
18098
+ ctx.data.pr = pr;
18099
+ if (announceOnSuccess) {
18100
+ ctx.data.commentTargetType = "pr";
18101
+ ctx.data.commentTargetNumber = prNumber;
18102
+ }
18103
+ checkoutPrBranch(prNumber, ctx.cwd);
18104
+ ctx.data.branch = getCurrentBranch(ctx.cwd);
18105
+ const baseBranch = pr.baseRefName || ctx.config.git.defaultBranch;
18106
+ ctx.data.baseBranch = baseBranch;
18107
+ const headBefore = revParseHead(ctx.cwd);
18108
+ const mergeStatus = mergeBase(baseBranch, ctx.cwd);
18109
+ if (mergeStatus === "error") {
18110
+ bail2(ctx, prNumber, `failed to merge origin/${baseBranch} (non-conflict error); see runner log`);
18111
+ return;
18112
+ }
18113
+ if (mergeStatus === "conflict") {
18114
+ bail2(
18115
+ ctx,
18116
+ prNumber,
18117
+ `merge from origin/${baseBranch} produced conflicts \u2014 run \`@kody resolve\` to let kody resolve them`
18118
+ );
18119
+ return;
18120
+ }
18121
+ const headAfter = revParseHead(ctx.cwd);
18122
+ if (headAfter === headBefore) {
18123
+ ctx.data.syncResult = "noop";
18124
+ if (announceOnSuccess) {
18125
+ ctx.output.exitCode = 0;
18126
+ ctx.output.reason = `already up to date with origin/${baseBranch}`;
18127
+ restoreDone(prNumber, ctx.cwd);
18128
+ }
18129
+ return;
18130
+ }
18131
+ try {
18132
+ pushBranch(ctx.data.branch, ctx.cwd);
18133
+ } catch (err) {
18134
+ const msg = err instanceof Error ? err.message : String(err);
18135
+ bail2(ctx, prNumber, `merge succeeded but push failed: ${msg}`);
18136
+ return;
18137
+ }
18138
+ ctx.data.syncResult = "merged";
18139
+ if (announceOnSuccess) {
18140
+ ctx.output.exitCode = 0;
18141
+ ctx.output.reason = `merged origin/${baseBranch} into ${ctx.data.branch}`;
18142
+ restoreDone(prNumber, ctx.cwd);
18143
+ }
18144
+ };
18145
+ }
18146
+ });
18147
+
18148
+ // src/scripts/prepareCapabilityDelivery.ts
18149
+ var prepareCapabilityDelivery;
18150
+ var init_prepareCapabilityDelivery = __esm({
18151
+ "src/scripts/prepareCapabilityDelivery.ts"() {
18152
+ "use strict";
18153
+ init_capabilityDelivery();
18154
+ init_runFlow();
18155
+ init_syncFlow();
18156
+ prepareCapabilityDelivery = async (ctx, profile) => {
18157
+ const target = capabilityDeliveryTarget(ctx.data.capabilityInput);
18158
+ if (!target) {
18159
+ throw new Error(
18160
+ "pull-request delivery requires exactly one positive issue or pr input"
18161
+ );
18162
+ }
18163
+ ctx.args[target.kind] = target.number;
18164
+ if (target.kind === "issue") {
18165
+ await runFlow(ctx, profile);
18166
+ return;
18167
+ }
18168
+ ctx.data.commentTargetType = "pr";
18169
+ ctx.data.commentTargetNumber = target.number;
18170
+ await syncFlow(ctx, profile);
18171
+ };
18172
+ }
18173
+ });
18174
+
17929
18175
  // src/scripts/promoteQaGoal.ts
17930
18176
  var REPORT_JSON_OPEN2, promoteQaGoal;
17931
18177
  var init_promoteQaGoal = __esm({
@@ -18081,7 +18327,7 @@ var init_publishReport = __esm({
18081
18327
  });
18082
18328
 
18083
18329
  // src/scripts/recordClassification.ts
18084
- import { execFileSync as execFileSync16 } from "child_process";
18330
+ import { execFileSync as execFileSync17 } from "child_process";
18085
18331
  function parseClassification(prSummary) {
18086
18332
  if (!prSummary) return null;
18087
18333
  const classMatch = prSummary.match(/classification:\s*(feature|bug|spec|chore)\b/i);
@@ -18093,7 +18339,7 @@ function parseClassification(prSummary) {
18093
18339
  }
18094
18340
  function tryAuditComment(issueNumber, body, cwd) {
18095
18341
  try {
18096
- execFileSync16("gh", ["issue", "comment", String(issueNumber), "--body", body], {
18342
+ execFileSync17("gh", ["issue", "comment", String(issueNumber), "--body", body], {
18097
18343
  cwd,
18098
18344
  timeout: API_TIMEOUT_MS5,
18099
18345
  stdio: ["ignore", "pipe", "pipe"]
@@ -18313,7 +18559,7 @@ var init_resolveArtifacts = __esm({
18313
18559
  });
18314
18560
 
18315
18561
  // src/scripts/resolveFlow.ts
18316
- import { execFileSync as execFileSync17 } from "child_process";
18562
+ import { execFileSync as execFileSync18 } from "child_process";
18317
18563
  function buildPreferBlock(prefer, baseBranch) {
18318
18564
  if (prefer !== "ours" && prefer !== "theirs") return "";
18319
18565
  const keepSide = prefer === "ours" ? "HEAD (this PR branch)" : `origin/${baseBranch} (base branch)`;
@@ -18333,7 +18579,7 @@ function buildPreferBlock(prefer, baseBranch) {
18333
18579
  }
18334
18580
  function getConflictedFiles(cwd) {
18335
18581
  try {
18336
- const out = execFileSync17("git", ["diff", "--name-only", "--diff-filter=U"], {
18582
+ const out = execFileSync18("git", ["diff", "--name-only", "--diff-filter=U"], {
18337
18583
  encoding: "utf-8",
18338
18584
  cwd,
18339
18585
  env: { ...process.env, HUSKY: "0" }
@@ -18348,7 +18594,7 @@ function getConflictMarkersPreview(files, cwd, maxBytes = CONFLICT_DIFF_MAX_BYTE
18348
18594
  let total = 0;
18349
18595
  for (const f of files) {
18350
18596
  try {
18351
- const content = execFileSync17("cat", [f], { encoding: "utf-8", cwd }).toString();
18597
+ const content = execFileSync18("cat", [f], { encoding: "utf-8", cwd }).toString();
18352
18598
  const snippet = `### ${f}
18353
18599
 
18354
18600
  \`\`\`
@@ -18363,7 +18609,7 @@ ${content.slice(0, 6e3)}
18363
18609
  }
18364
18610
  return chunks.join("\n");
18365
18611
  }
18366
- function tryPostPr3(prNumber, body, cwd) {
18612
+ function tryPostPr4(prNumber, body, cwd) {
18367
18613
  try {
18368
18614
  postPrReviewComment(prNumber, body, cwd);
18369
18615
  } catch {
@@ -18372,12 +18618,12 @@ function tryPostPr3(prNumber, body, cwd) {
18372
18618
  function pushEmptyCommit(branch, cwd) {
18373
18619
  const env = { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" };
18374
18620
  try {
18375
- execFileSync17(
18621
+ execFileSync18(
18376
18622
  "git",
18377
18623
  ["commit", "--allow-empty", "-m", "chore: kody resolve refresh \u2014 empty commit to recompute mergeable status"],
18378
18624
  { cwd, env, stdio: ["ignore", "pipe", "pipe"] }
18379
18625
  );
18380
- execFileSync17("git", ["push", "-u", "origin", branch], {
18626
+ execFileSync18("git", ["push", "-u", "origin", branch], {
18381
18627
  cwd,
18382
18628
  env,
18383
18629
  stdio: ["ignore", "pipe", "pipe"]
@@ -18415,14 +18661,14 @@ var init_resolveFlow = __esm({
18415
18661
  ctx.output.exitCode = 0;
18416
18662
  ctx.output.reason = `PR #${prNumber} is mergeable (no conflicts) \u2014 nothing to resolve`;
18417
18663
  ctx.skipAgent = true;
18418
- tryPostPr3(prNumber, `\u2139\uFE0F kody resolve: ${ctx.output.reason}`, ctx.cwd);
18664
+ tryPostPr4(prNumber, `\u2139\uFE0F kody resolve: ${ctx.output.reason}`, ctx.cwd);
18419
18665
  return;
18420
18666
  }
18421
18667
  if (ghStatus.status === "BLOCKED") {
18422
18668
  ctx.output.exitCode = 0;
18423
18669
  ctx.output.reason = `PR #${prNumber} is mergeable but blocked by checks/reviews (mergeStateStatus=${ghStatus.mergeStateStatus}) \u2014 nothing for resolve to do`;
18424
18670
  ctx.skipAgent = true;
18425
- tryPostPr3(prNumber, `\u2139\uFE0F kody resolve: ${ctx.output.reason}`, ctx.cwd);
18671
+ tryPostPr4(prNumber, `\u2139\uFE0F kody resolve: ${ctx.output.reason}`, ctx.cwd);
18426
18672
  return;
18427
18673
  }
18428
18674
  checkoutPrBranch(prNumber, ctx.cwd);
@@ -18434,20 +18680,20 @@ var init_resolveFlow = __esm({
18434
18680
  ctx.output.exitCode = 0;
18435
18681
  ctx.output.reason = pushed ? `local merge clean despite GitHub reporting CONFLICTING \u2014 pushed empty commit to force re-evaluation` : `local merge clean despite GitHub reporting CONFLICTING \u2014 couldn't refresh GitHub cache (push failed)`;
18436
18682
  ctx.skipAgent = true;
18437
- tryPostPr3(prNumber, `\u2139\uFE0F kody resolve: ${ctx.output.reason}`, ctx.cwd);
18683
+ tryPostPr4(prNumber, `\u2139\uFE0F kody resolve: ${ctx.output.reason}`, ctx.cwd);
18438
18684
  return;
18439
18685
  }
18440
18686
  ctx.output.exitCode = 0;
18441
18687
  ctx.output.reason = `already up to date with origin/${baseBranch} \u2014 nothing to resolve`;
18442
18688
  ctx.skipAgent = true;
18443
- tryPostPr3(prNumber, `\u2139\uFE0F kody resolve: ${ctx.output.reason}`, ctx.cwd);
18689
+ tryPostPr4(prNumber, `\u2139\uFE0F kody resolve: ${ctx.output.reason}`, ctx.cwd);
18444
18690
  return;
18445
18691
  }
18446
18692
  if (mergeStatus === "error") {
18447
18693
  ctx.output.exitCode = 99;
18448
18694
  ctx.output.reason = `failed to merge origin/${baseBranch} (non-conflict error); see runner log`;
18449
18695
  ctx.skipAgent = true;
18450
- tryPostPr3(prNumber, `\u26A0\uFE0F kody resolve FAILED: ${ctx.output.reason}`, ctx.cwd);
18696
+ tryPostPr4(prNumber, `\u26A0\uFE0F kody resolve FAILED: ${ctx.output.reason}`, ctx.cwd);
18451
18697
  return;
18452
18698
  }
18453
18699
  const conflictedFiles = getConflictedFiles(ctx.cwd);
@@ -18462,7 +18708,7 @@ var init_resolveFlow = __esm({
18462
18708
  ctx.data.preferBlock = buildPreferBlock(ctx.args.prefer, baseBranch);
18463
18709
  const runUrl = getRunUrl();
18464
18710
  const runSuffix = runUrl ? `, run ${runUrl}` : "";
18465
- tryPostPr3(
18711
+ tryPostPr4(
18466
18712
  prNumber,
18467
18713
  `\u2699\uFE0F kody resolve started on \`${ctx.data.branch}\`${runSuffix} \u2014 ${conflictedFiles.length} conflicted file(s)`,
18468
18714
  ctx.cwd
@@ -18563,10 +18809,10 @@ var init_resolvePreviewUrl = __esm({
18563
18809
  });
18564
18810
 
18565
18811
  // src/scripts/resolveQaUrl.ts
18566
- import { execFileSync as execFileSync18 } from "child_process";
18812
+ import { execFileSync as execFileSync19 } from "child_process";
18567
18813
  function ghQuery(args, cwd) {
18568
18814
  try {
18569
- const out = execFileSync18("gh", args, {
18815
+ const out = execFileSync19("gh", args, {
18570
18816
  cwd,
18571
18817
  stdio: ["ignore", "pipe", "pipe"],
18572
18818
  encoding: "utf-8",
@@ -18643,7 +18889,7 @@ var init_resolveQaUrl = __esm({
18643
18889
  });
18644
18890
 
18645
18891
  // src/scripts/revertFlow.ts
18646
- import { execFileSync as execFileSync19 } from "child_process";
18892
+ import { execFileSync as execFileSync20 } from "child_process";
18647
18893
  function buildCommitMessage(resolved) {
18648
18894
  if (resolved.length === 1) {
18649
18895
  const { full, subject } = resolved[0];
@@ -18656,7 +18902,7 @@ function buildPrSummary(resolved) {
18656
18902
  return resolved.map((r) => `- Reverted \`${r.full.slice(0, 7)}\`${r.subject ? ` \u2014 ${r.subject}` : ""}`).join("\n");
18657
18903
  }
18658
18904
  function git4(args, cwd) {
18659
- return execFileSync19("git", args, {
18905
+ return execFileSync20("git", args, {
18660
18906
  encoding: "utf-8",
18661
18907
  timeout: 3e4,
18662
18908
  cwd,
@@ -18666,7 +18912,7 @@ function git4(args, cwd) {
18666
18912
  }
18667
18913
  function isAncestorOfHead(sha, cwd) {
18668
18914
  try {
18669
- execFileSync19("git", ["merge-base", "--is-ancestor", sha, "HEAD"], {
18915
+ execFileSync20("git", ["merge-base", "--is-ancestor", sha, "HEAD"], {
18670
18916
  cwd,
18671
18917
  env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" },
18672
18918
  stdio: ["ignore", "ignore", "ignore"]
@@ -18676,7 +18922,7 @@ function isAncestorOfHead(sha, cwd) {
18676
18922
  return false;
18677
18923
  }
18678
18924
  }
18679
- function tryPostPr4(prNumber, body, cwd) {
18925
+ function tryPostPr5(prNumber, body, cwd) {
18680
18926
  try {
18681
18927
  postPrReviewComment(prNumber, body, cwd);
18682
18928
  } catch (err) {
@@ -18712,7 +18958,7 @@ var init_revertFlow = __esm({
18712
18958
  ctx.output.exitCode = 64;
18713
18959
  ctx.output.reason = "no commit SHAs provided \u2014 usage: @kody revert <sha> [<sha> \u2026]";
18714
18960
  ctx.skipAgent = true;
18715
- tryPostPr4(prNumber, `\u26A0\uFE0F kody revert FAILED: ${ctx.output.reason}`, ctx.cwd);
18961
+ tryPostPr5(prNumber, `\u26A0\uFE0F kody revert FAILED: ${ctx.output.reason}`, ctx.cwd);
18716
18962
  return;
18717
18963
  }
18718
18964
  const requested = shasArg.split(/\s+/).filter((s) => s.length > 0);
@@ -18721,7 +18967,7 @@ var init_revertFlow = __esm({
18721
18967
  ctx.output.exitCode = 64;
18722
18968
  ctx.output.reason = `not valid SHA-shaped tokens: ${bad.join(", ")}`;
18723
18969
  ctx.skipAgent = true;
18724
- tryPostPr4(prNumber, `\u26A0\uFE0F kody revert FAILED: ${ctx.output.reason}`, ctx.cwd);
18970
+ tryPostPr5(prNumber, `\u26A0\uFE0F kody revert FAILED: ${ctx.output.reason}`, ctx.cwd);
18725
18971
  return;
18726
18972
  }
18727
18973
  const resolved = [];
@@ -18749,7 +18995,7 @@ var init_revertFlow = __esm({
18749
18995
  ctx.output.exitCode = 64;
18750
18996
  ctx.output.reason = `commit(s) not found in this PR branch: ${unreachable.join(", ")}`;
18751
18997
  ctx.skipAgent = true;
18752
- tryPostPr4(prNumber, `\u26A0\uFE0F kody revert FAILED: ${ctx.output.reason}`, ctx.cwd);
18998
+ tryPostPr5(prNumber, `\u26A0\uFE0F kody revert FAILED: ${ctx.output.reason}`, ctx.cwd);
18753
18999
  return;
18754
19000
  }
18755
19001
  ctx.args.shas = resolved.map((r) => r.full).join(" ");
@@ -18759,13 +19005,13 @@ var init_revertFlow = __esm({
18759
19005
  const runUrl = getRunUrl();
18760
19006
  const runSuffix = runUrl ? `, run ${runUrl}` : "";
18761
19007
  const shaList = resolved.map((r) => `\`${r.full.slice(0, 7)}\``).join(", ");
18762
- tryPostPr4(prNumber, `\u2699\uFE0F kody revert started on \`${ctx.data.branch}\`${runSuffix} \u2014 reverting ${shaList}`, ctx.cwd);
19008
+ tryPostPr5(prNumber, `\u2699\uFE0F kody revert started on \`${ctx.data.branch}\`${runSuffix} \u2014 reverting ${shaList}`, ctx.cwd);
18763
19009
  };
18764
19010
  }
18765
19011
  });
18766
19012
 
18767
19013
  // src/scripts/reviewFlow.ts
18768
- function tryPostPr5(prNumber, body, cwd) {
19014
+ function tryPostPr6(prNumber, body, cwd) {
18769
19015
  try {
18770
19016
  postPrReviewComment(prNumber, body, cwd);
18771
19017
  } catch {
@@ -18795,75 +19041,7 @@ var init_reviewFlow = __esm({
18795
19041
  ctx.data.prDiff = getPrDiff(prNumber, ctx.cwd);
18796
19042
  const runUrl = getRunUrl();
18797
19043
  const runSuffix = runUrl ? `, run ${runUrl}` : "";
18798
- tryPostPr5(prNumber, `\u{1F440} kody review started on PR #${prNumber}${runSuffix}`, ctx.cwd);
18799
- };
18800
- }
18801
- });
18802
-
18803
- // src/scripts/runFlow.ts
18804
- function tryPost(issueNumber, body, cwd) {
18805
- try {
18806
- postIssueComment(issueNumber, body, cwd);
18807
- } catch {
18808
- }
18809
- }
18810
- function resolveBaseOverride(value) {
18811
- if (!value) return null;
18812
- if (value.length > 200) return null;
18813
- if (value.includes("..")) return null;
18814
- if (!/^[a-z0-9][a-z0-9/._-]*$/.test(value)) return null;
18815
- return value;
18816
- }
18817
- var runFlow;
18818
- var init_runFlow = __esm({
18819
- "src/scripts/runFlow.ts"() {
18820
- "use strict";
18821
- init_branch();
18822
- init_gha();
18823
- init_issue();
18824
- runFlow = async (ctx) => {
18825
- const issueNumber = ctx.args.issue;
18826
- const issue2 = getIssue(issueNumber, ctx.cwd);
18827
- const cfgCtx = ctx.config.issueContext ?? {};
18828
- const commentsFormatted = formatIssueComments(
18829
- issue2.comments,
18830
- cfgCtx.commentLimit ?? DEFAULT_COMMENT_LIMIT,
18831
- cfgCtx.commentMaxBytes ?? DEFAULT_COMMENT_MAX_BYTES
18832
- );
18833
- ctx.data.issue = { ...issue2, commentsFormatted };
18834
- if (issue2.isPullRequest) {
18835
- ctx.data.commentTargetType = "pr";
18836
- ctx.data.commentTargetNumber = issueNumber;
18837
- ctx.skipAgent = true;
18838
- ctx.output.exitCode = 1;
18839
- ctx.output.reason = `run target #${issueNumber} is a pull request; dispatch a PR action or the source issue instead`;
18840
- return;
18841
- }
18842
- ctx.data.commentTargetType = "issue";
18843
- ctx.data.commentTargetNumber = issueNumber;
18844
- const argBase = resolveBaseOverride(ctx.args.base);
18845
- const baseRaw = ctx.args.base;
18846
- if (baseRaw && !argBase) {
18847
- process.stderr.write(`[kody runFlow] ignoring --base "${baseRaw}" (must match kody-task or goal-branch pattern)
18848
- `);
18849
- }
18850
- const base = argBase;
18851
- if (base) {
18852
- ctx.data.baseBranch = base;
18853
- process.stderr.write(`[kody runFlow] resolved base branch: ${base} (from --base)
18854
- `);
18855
- }
18856
- const branchInfo = ensureFeatureBranch(
18857
- issueNumber,
18858
- issue2.title,
18859
- ctx.config.git.defaultBranch,
18860
- ctx.cwd,
18861
- base ?? void 0
18862
- );
18863
- ctx.data.branch = branchInfo.branch;
18864
- const runUrl = getRunUrl();
18865
- const startMsg = runUrl ? `\u2699\uFE0F kody started \u2014 branch \`${ctx.data.branch}\`, run ${runUrl}` : `\u2699\uFE0F kody started \u2014 branch \`${ctx.data.branch}\``;
18866
- tryPost(issueNumber, startMsg, ctx.cwd);
19044
+ tryPostPr6(prNumber, `\u{1F440} kody review started on PR #${prNumber}${runSuffix}`, ctx.cwd);
18867
19045
  };
18868
19046
  }
18869
19047
  });
@@ -19633,7 +19811,7 @@ var init_skipAgent = __esm({
19633
19811
  });
19634
19812
 
19635
19813
  // src/scripts/stageMergeConflicts.ts
19636
- import { execFileSync as execFileSync20 } from "child_process";
19814
+ import { execFileSync as execFileSync21 } from "child_process";
19637
19815
  var stageMergeConflicts;
19638
19816
  var init_stageMergeConflicts = __esm({
19639
19817
  "src/scripts/stageMergeConflicts.ts"() {
@@ -19641,7 +19819,7 @@ var init_stageMergeConflicts = __esm({
19641
19819
  stageMergeConflicts = async (ctx) => {
19642
19820
  if (ctx.data.agentDone === false) return;
19643
19821
  try {
19644
- execFileSync20("git", ["add", "-A"], {
19822
+ execFileSync21("git", ["add", "-A"], {
19645
19823
  cwd: ctx.cwd,
19646
19824
  env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" },
19647
19825
  stdio: "pipe"
@@ -19694,113 +19872,6 @@ var init_startFlow = __esm({
19694
19872
  }
19695
19873
  });
19696
19874
 
19697
- // src/scripts/syncFlow.ts
19698
- import { execFileSync as execFileSync21 } from "child_process";
19699
- function restoreDone(prNumber, cwd) {
19700
- try {
19701
- setKodyLabel(prNumber, DONE2, cwd);
19702
- } catch {
19703
- }
19704
- }
19705
- function bail2(ctx, prNumber, reason) {
19706
- ctx.skipAgent = true;
19707
- ctx.output.exitCode = 1;
19708
- ctx.output.reason = reason;
19709
- const runUrl = getRunUrl();
19710
- const runSuffix = runUrl ? ` ([logs](${runUrl}))` : "";
19711
- tryPostPr6(prNumber, `\u274C kody sync could not complete${runSuffix}: ${reason}`, ctx.cwd);
19712
- }
19713
- function revParseHead(cwd) {
19714
- try {
19715
- return execFileSync21("git", ["rev-parse", "HEAD"], { cwd, encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] }).toString().trim();
19716
- } catch {
19717
- return "";
19718
- }
19719
- }
19720
- function pushBranch(branch, cwd) {
19721
- const result = pushWithRetry({ cwd: cwd ?? process.cwd(), branch, setUpstream: true });
19722
- if (!result.ok) {
19723
- throw new Error(result.reason);
19724
- }
19725
- }
19726
- function tryPostPr6(prNumber, body, cwd) {
19727
- try {
19728
- postPrReviewComment(prNumber, body, cwd);
19729
- } catch {
19730
- }
19731
- }
19732
- var DONE2, syncFlow;
19733
- var init_syncFlow = __esm({
19734
- "src/scripts/syncFlow.ts"() {
19735
- "use strict";
19736
- init_branch();
19737
- init_gha();
19738
- init_issue();
19739
- init_lifecycleLabels();
19740
- init_pushWithRetry();
19741
- DONE2 = {
19742
- label: "kody:done",
19743
- color: "0e8a16",
19744
- description: "kody: PR ready for human review/merge"
19745
- };
19746
- syncFlow = async (ctx, _profile, args) => {
19747
- const announceOnSuccess = Boolean(args?.announceOnSuccess);
19748
- const prNumber = ctx.args.pr;
19749
- const pr = getPr(prNumber, ctx.cwd);
19750
- if (pr.state !== "OPEN") {
19751
- bail2(ctx, prNumber, `PR #${prNumber} is not OPEN (state: ${pr.state})`);
19752
- return;
19753
- }
19754
- ctx.data.pr = pr;
19755
- if (announceOnSuccess) {
19756
- ctx.data.commentTargetType = "pr";
19757
- ctx.data.commentTargetNumber = prNumber;
19758
- }
19759
- checkoutPrBranch(prNumber, ctx.cwd);
19760
- ctx.data.branch = getCurrentBranch(ctx.cwd);
19761
- const baseBranch = pr.baseRefName || ctx.config.git.defaultBranch;
19762
- ctx.data.baseBranch = baseBranch;
19763
- const headBefore = revParseHead(ctx.cwd);
19764
- const mergeStatus = mergeBase(baseBranch, ctx.cwd);
19765
- if (mergeStatus === "error") {
19766
- bail2(ctx, prNumber, `failed to merge origin/${baseBranch} (non-conflict error); see runner log`);
19767
- return;
19768
- }
19769
- if (mergeStatus === "conflict") {
19770
- bail2(
19771
- ctx,
19772
- prNumber,
19773
- `merge from origin/${baseBranch} produced conflicts \u2014 run \`@kody resolve\` to let kody resolve them`
19774
- );
19775
- return;
19776
- }
19777
- const headAfter = revParseHead(ctx.cwd);
19778
- if (headAfter === headBefore) {
19779
- ctx.data.syncResult = "noop";
19780
- if (announceOnSuccess) {
19781
- ctx.output.exitCode = 0;
19782
- ctx.output.reason = `already up to date with origin/${baseBranch}`;
19783
- restoreDone(prNumber, ctx.cwd);
19784
- }
19785
- return;
19786
- }
19787
- try {
19788
- pushBranch(ctx.data.branch, ctx.cwd);
19789
- } catch (err) {
19790
- const msg = err instanceof Error ? err.message : String(err);
19791
- bail2(ctx, prNumber, `merge succeeded but push failed: ${msg}`);
19792
- return;
19793
- }
19794
- ctx.data.syncResult = "merged";
19795
- if (announceOnSuccess) {
19796
- ctx.output.exitCode = 0;
19797
- ctx.output.reason = `merged origin/${baseBranch} into ${ctx.data.branch}`;
19798
- restoreDone(prNumber, ctx.cwd);
19799
- }
19800
- };
19801
- }
19802
- });
19803
-
19804
19875
  // src/scripts/validateAgencyModelProposal.ts
19805
19876
  import * as path46 from "path";
19806
19877
  function validateModelBundle(bundle, expectedKind, options = {}) {
@@ -20882,6 +20953,7 @@ var init_scripts = __esm({
20882
20953
  init_postResearchComment();
20883
20954
  init_postReviewResult();
20884
20955
  init_prepareBrowserAuth();
20956
+ init_prepareCapabilityDelivery();
20885
20957
  init_promoteQaGoal();
20886
20958
  init_publishReport();
20887
20959
  init_recordClassification();
@@ -20943,6 +21015,7 @@ var init_scripts = __esm({
20943
21015
  loadPriorArt,
20944
21016
  loadQaContext,
20945
21017
  prepareBrowserAuth,
21018
+ prepareCapabilityDelivery,
20946
21019
  buildSyntheticPlugin,
20947
21020
  resolveArtifacts,
20948
21021
  discoverQaContext,
@@ -22303,6 +22376,9 @@ function validateJob(input) {
22303
22376
  if (j.cliArgs !== void 0 && (typeof j.cliArgs !== "object" || j.cliArgs === null)) {
22304
22377
  throw new InvalidJobError("job.cliArgs must be an object when present");
22305
22378
  }
22379
+ if (j.delivery !== void 0 && j.delivery !== "pull-request") {
22380
+ throw new InvalidJobError(`job.delivery must be "pull-request" (got ${String(j.delivery)})`);
22381
+ }
22306
22382
  return {
22307
22383
  action: typeof j.action === "string" ? j.action : void 0,
22308
22384
  implementation: typeof j.implementation === "string" ? j.implementation : void 0,
@@ -22312,6 +22388,7 @@ function validateJob(input) {
22312
22388
  agent: typeof j.agent === "string" ? j.agent : void 0,
22313
22389
  schedule: typeof j.schedule === "string" ? j.schedule : void 0,
22314
22390
  target: typeof j.target === "number" ? j.target : void 0,
22391
+ delivery: j.delivery === "pull-request" ? j.delivery : void 0,
22315
22392
  cliArgs: j.cliArgs ?? {},
22316
22393
  workflowFacts: j.workflowFacts && typeof j.workflowFacts === "object" && !Array.isArray(j.workflowFacts) ? j.workflowFacts : void 0,
22317
22394
  workflowState: parseWorkflowRunState(j.workflowState) ?? void 0,
@@ -22364,7 +22441,7 @@ async function runJob(job, base) {
22364
22441
  }
22365
22442
  const workflow = capabilityContext?.config.workflow ?? workflowContext?.config.workflow;
22366
22443
  const workflowIdentity = valid.workflow ?? capabilityIdentity ?? workflowContext?.slug;
22367
- const capabilitySelectedImplementation = resolvedCapability?.implementation ?? capabilityContext?.config.implementation ?? capabilityContext?.config.implementations?.[0] ?? (capabilityContext?.config.role ? capabilityContext.slug : void 0) ?? (capabilityContext?.config.tickScript ? "capability-tick-scripted" : void 0);
22444
+ const capabilitySelectedImplementation = valid.delivery === "pull-request" && resolvedCapability?.implementation === "capability-run" ? "capability-delivery" : resolvedCapability?.implementation ?? capabilityContext?.config.implementation ?? capabilityContext?.config.implementations?.[0] ?? (capabilityContext?.config.role ? capabilityContext.slug : void 0) ?? (capabilityContext?.config.tickScript ? "capability-tick-scripted" : void 0);
22368
22445
  const profileName = explicitImplementation ?? capabilitySelectedImplementation;
22369
22446
  if (workflow && shouldRunCapabilityWorkflow(valid, workflow, workflowIdentity, capabilitySelectedImplementation, base)) {
22370
22447
  const workflowCapability = capabilityContext ?? workflowContext;
@@ -22454,6 +22531,7 @@ async function runCapabilityImplementationStep(valid, profileName, capabilityIde
22454
22531
  preloadedData.jobKey = stableJobKey(valid);
22455
22532
  preloadedData.jobFlavor = valid.flavor;
22456
22533
  if (valid.target !== void 0) preloadedData.jobTarget = valid.target;
22534
+ if (valid.delivery !== void 0) preloadedData.jobDelivery = valid.delivery;
22457
22535
  if (valid.action !== void 0 && valid.action.length > 0) preloadedData.jobAction = valid.action;
22458
22536
  if (capabilityIdentity !== void 0 && capabilityIdentity.length > 0)
22459
22537
  preloadedData.jobCapability = capabilityIdentity;
@@ -22493,11 +22571,13 @@ async function runCapabilityImplementationStep(valid, profileName, capabilityIde
22493
22571
  };
22494
22572
  const shouldApplyResolvedCapabilityArgs = valid.implementation === void 0 && resolvedCapability && profileName === resolvedCapability.implementation;
22495
22573
  input.cliArgs = shouldApplyResolvedCapabilityArgs ? { ...resolvedCapability.cliArgs, ...input.cliArgs } : input.cliArgs;
22496
- if (profileName === "capability-run" && capabilityIdentity) {
22574
+ if ((profileName === "capability-run" || profileName === "capability-delivery") && capabilityIdentity) {
22497
22575
  const capabilityInput = Object.keys(valid.cliArgs).length > 0 ? genericInputFromArgs(valid.cliArgs) : void 0;
22576
+ const deliveryTarget = profileName === "capability-delivery" && capabilityInput && typeof capabilityInput === "object" ? capabilityDeliveryArgs(capabilityInput) : {};
22498
22577
  input.cliArgs = {
22499
22578
  capability: capabilityIdentity,
22500
- ...capabilityInput !== void 0 ? { input: JSON.stringify(capabilityInput) } : {}
22579
+ ...capabilityInput !== void 0 ? { input: JSON.stringify(capabilityInput) } : {},
22580
+ ...deliveryTarget
22501
22581
  };
22502
22582
  }
22503
22583
  const run = base.chain === false ? runImplementation : runImplementationChain;
@@ -22854,6 +22934,7 @@ function workflowStepToJob(step, parent, chainData, cwd) {
22854
22934
  ...parent.agent ? { agent: parent.agent } : {},
22855
22935
  ...parent.schedule ? { schedule: parent.schedule } : {},
22856
22936
  ...typeof target === "number" ? { target } : {},
22937
+ ...step.delivery ? { delivery: step.delivery } : {},
22857
22938
  cliArgs,
22858
22939
  ...step.evidence ? { evidence: step.evidence } : parent.evidence ? { evidence: parent.evidence } : {},
22859
22940
  flavor: parent.flavor,
@@ -22863,6 +22944,10 @@ function workflowStepToJob(step, parent, chainData, cwd) {
22863
22944
  ...parent.resultTarget ? { resultTarget: parent.resultTarget } : {}
22864
22945
  };
22865
22946
  }
22947
+ function capabilityDeliveryArgs(input) {
22948
+ const target = capabilityDeliveryTarget(input);
22949
+ return target ? { [target.kind]: target.number } : {};
22950
+ }
22866
22951
  function usesGenericCapabilityInput(action, cwd) {
22867
22952
  const inputs = getCapabilityActionInputs(action, hydratedCapabilitiesRoot(cwd));
22868
22953
  return Boolean(inputs?.length === 1 && inputs[0]?.name === "input" && inputs[0]?.flag === "--input");
@@ -23027,6 +23112,7 @@ var init_job = __esm({
23027
23112
  "src/job.ts"() {
23028
23113
  "use strict";
23029
23114
  init_agencyBoundaryEval();
23115
+ init_capabilityDelivery();
23030
23116
  init_capabilityFolders();
23031
23117
  init_definition_paths();
23032
23118
  init_executor();
@@ -569,6 +569,8 @@ export interface Job {
569
569
  schedule?: string
570
570
  /** The issue/PR number this job acts on, when applicable. */
571
571
  target?: number
572
+ /** Workflow-owned delivery policy applied by a generic runtime adapter. */
573
+ delivery?: "pull-request"
572
574
  /** Args passed through to the implementation (mirrors DispatchResult.cliArgs). */
573
575
  cliArgs: Record<string, unknown>
574
576
  /** Internal workflow resume context. Not passed to capability CLI args. */
@@ -0,0 +1,85 @@
1
+ {
2
+ "name": "capability-delivery",
3
+ "internal": true,
4
+ "role": "primitive",
5
+ "kind": "oneshot",
6
+ "inputs": [
7
+ {
8
+ "name": "capability",
9
+ "flag": "--capability",
10
+ "type": "string",
11
+ "required": true,
12
+ "describe": "Capability folder slug."
13
+ },
14
+ {
15
+ "name": "input",
16
+ "flag": "--input",
17
+ "type": "string",
18
+ "required": false,
19
+ "describe": "The capability's one JSON input."
20
+ },
21
+ {
22
+ "name": "issue",
23
+ "flag": "--issue",
24
+ "type": "int",
25
+ "required": false,
26
+ "describe": "Issue receiving a new pull request."
27
+ },
28
+ {
29
+ "name": "pr",
30
+ "flag": "--pr",
31
+ "type": "int",
32
+ "required": false,
33
+ "describe": "Existing pull request receiving changes."
34
+ }
35
+ ],
36
+ "claudeCode": {
37
+ "model": "inherit",
38
+ "permissionMode": "acceptEdits",
39
+ "maxTurns": 60,
40
+ "maxThinkingTokens": null,
41
+ "systemPromptAppend": null,
42
+ "enableVerifyTool": true,
43
+ "verifyAttempts": 4,
44
+ "tools": [
45
+ "Read",
46
+ "Write",
47
+ "Edit",
48
+ "Bash",
49
+ "Grep",
50
+ "Glob",
51
+ "mcp__kody-verify"
52
+ ],
53
+ "hooks": ["block-git"],
54
+ "skills": [],
55
+ "commands": [],
56
+ "subagents": [],
57
+ "plugins": [],
58
+ "mcpServers": []
59
+ },
60
+ "cliTools": [],
61
+ "lifecycle": "pr-branch",
62
+ "lifecycleConfig": {
63
+ "label": {
64
+ "name": "kody:working",
65
+ "color": "fbca04",
66
+ "description": "kody: delivering capability work"
67
+ },
68
+ "context": "task",
69
+ "sync": false,
70
+ "advance": false,
71
+ "mirrorState": false,
72
+ "finalize": false
73
+ },
74
+ "scripts": {
75
+ "preflight": [
76
+ { "script": "loadSimpleCapability" },
77
+ { "script": "prepareCapabilityDelivery" }
78
+ ],
79
+ "postflight": [
80
+ { "script": "parseSimpleCapabilityOutput" }
81
+ ]
82
+ },
83
+ "inputArtifacts": [],
84
+ "outputArtifacts": []
85
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kody-ade/kody-engine",
3
- "version": "0.4.455",
3
+ "version": "0.4.456",
4
4
  "description": "kody — autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative implementation profiles.",
5
5
  "license": "MIT",
6
6
  "type": "module",