@kody-ade/kody-engine 0.4.454 → 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.
|
|
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
|
-
...
|
|
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
|
|
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
|
}
|
|
@@ -8919,6 +8947,7 @@ function validateWorkflow(value, options = {}) {
|
|
|
8919
8947
|
issue(issues, "missing_start_step", "startAt", `workflow startAt references missing step ${startAt ?? "<none>"}`);
|
|
8920
8948
|
}
|
|
8921
8949
|
const adjacency = /* @__PURE__ */ new Map();
|
|
8950
|
+
const explicitEndSources = /* @__PURE__ */ new Set();
|
|
8922
8951
|
steps.forEach((step, index) => {
|
|
8923
8952
|
if (!step) return;
|
|
8924
8953
|
const id = text(step.id);
|
|
@@ -8987,6 +9016,7 @@ function validateWorkflow(value, options = {}) {
|
|
|
8987
9016
|
return;
|
|
8988
9017
|
}
|
|
8989
9018
|
if (target === "$end") {
|
|
9019
|
+
explicitEndSources.add(id);
|
|
8990
9020
|
return;
|
|
8991
9021
|
}
|
|
8992
9022
|
if (!seen.has(target)) {
|
|
@@ -9041,7 +9071,7 @@ function validateWorkflow(value, options = {}) {
|
|
|
9041
9071
|
ids.forEach((id, index) => {
|
|
9042
9072
|
if (!reachable.has(id)) issue(issues, "unreachable_step", `steps[${index}]`, `workflow step ${id} is unreachable`);
|
|
9043
9073
|
});
|
|
9044
|
-
if (![...reachable].some((id) => (adjacency.get(id) ?? []).length === 0)) {
|
|
9074
|
+
if (![...reachable].some((id) => (adjacency.get(id) ?? []).length === 0 || explicitEndSources.has(id))) {
|
|
9045
9075
|
issue(issues, "missing_terminal_step", "steps", "workflow has no reachable final step");
|
|
9046
9076
|
}
|
|
9047
9077
|
}
|
|
@@ -9116,6 +9146,7 @@ var init_workflowValidation = __esm({
|
|
|
9116
9146
|
"action",
|
|
9117
9147
|
"evidence",
|
|
9118
9148
|
"target",
|
|
9149
|
+
"delivery",
|
|
9119
9150
|
"targetFact",
|
|
9120
9151
|
"reason",
|
|
9121
9152
|
"next",
|
|
@@ -15502,6 +15533,7 @@ var init_loadSimpleCapability = __esm({
|
|
|
15502
15533
|
const toolFiles = listFiles(toolRoot);
|
|
15503
15534
|
const skillFiles = listFiles(skillRoot);
|
|
15504
15535
|
const input = parseInput(ctx.args.input);
|
|
15536
|
+
const delivery = ctx.data.jobDelivery === "pull-request";
|
|
15505
15537
|
ctx.data.jobCapability = slug;
|
|
15506
15538
|
ctx.data.capabilityInput = input;
|
|
15507
15539
|
ctx.data.capabilityEnvironment = capabilityEnvironment(input);
|
|
@@ -15514,7 +15546,21 @@ var init_loadSimpleCapability = __esm({
|
|
|
15514
15546
|
JSON.stringify(input ?? null, null, 2),
|
|
15515
15547
|
"```",
|
|
15516
15548
|
"",
|
|
15517
|
-
|
|
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."],
|
|
15518
15564
|
...skillFiles.length ? [
|
|
15519
15565
|
"",
|
|
15520
15566
|
"## Skills",
|
|
@@ -17924,6 +17970,208 @@ var init_prepareBrowserAuth = __esm({
|
|
|
17924
17970
|
}
|
|
17925
17971
|
});
|
|
17926
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
|
+
|
|
17927
18175
|
// src/scripts/promoteQaGoal.ts
|
|
17928
18176
|
var REPORT_JSON_OPEN2, promoteQaGoal;
|
|
17929
18177
|
var init_promoteQaGoal = __esm({
|
|
@@ -18079,7 +18327,7 @@ var init_publishReport = __esm({
|
|
|
18079
18327
|
});
|
|
18080
18328
|
|
|
18081
18329
|
// src/scripts/recordClassification.ts
|
|
18082
|
-
import { execFileSync as
|
|
18330
|
+
import { execFileSync as execFileSync17 } from "child_process";
|
|
18083
18331
|
function parseClassification(prSummary) {
|
|
18084
18332
|
if (!prSummary) return null;
|
|
18085
18333
|
const classMatch = prSummary.match(/classification:\s*(feature|bug|spec|chore)\b/i);
|
|
@@ -18091,7 +18339,7 @@ function parseClassification(prSummary) {
|
|
|
18091
18339
|
}
|
|
18092
18340
|
function tryAuditComment(issueNumber, body, cwd) {
|
|
18093
18341
|
try {
|
|
18094
|
-
|
|
18342
|
+
execFileSync17("gh", ["issue", "comment", String(issueNumber), "--body", body], {
|
|
18095
18343
|
cwd,
|
|
18096
18344
|
timeout: API_TIMEOUT_MS5,
|
|
18097
18345
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -18311,7 +18559,7 @@ var init_resolveArtifacts = __esm({
|
|
|
18311
18559
|
});
|
|
18312
18560
|
|
|
18313
18561
|
// src/scripts/resolveFlow.ts
|
|
18314
|
-
import { execFileSync as
|
|
18562
|
+
import { execFileSync as execFileSync18 } from "child_process";
|
|
18315
18563
|
function buildPreferBlock(prefer, baseBranch) {
|
|
18316
18564
|
if (prefer !== "ours" && prefer !== "theirs") return "";
|
|
18317
18565
|
const keepSide = prefer === "ours" ? "HEAD (this PR branch)" : `origin/${baseBranch} (base branch)`;
|
|
@@ -18331,7 +18579,7 @@ function buildPreferBlock(prefer, baseBranch) {
|
|
|
18331
18579
|
}
|
|
18332
18580
|
function getConflictedFiles(cwd) {
|
|
18333
18581
|
try {
|
|
18334
|
-
const out =
|
|
18582
|
+
const out = execFileSync18("git", ["diff", "--name-only", "--diff-filter=U"], {
|
|
18335
18583
|
encoding: "utf-8",
|
|
18336
18584
|
cwd,
|
|
18337
18585
|
env: { ...process.env, HUSKY: "0" }
|
|
@@ -18346,7 +18594,7 @@ function getConflictMarkersPreview(files, cwd, maxBytes = CONFLICT_DIFF_MAX_BYTE
|
|
|
18346
18594
|
let total = 0;
|
|
18347
18595
|
for (const f of files) {
|
|
18348
18596
|
try {
|
|
18349
|
-
const content =
|
|
18597
|
+
const content = execFileSync18("cat", [f], { encoding: "utf-8", cwd }).toString();
|
|
18350
18598
|
const snippet = `### ${f}
|
|
18351
18599
|
|
|
18352
18600
|
\`\`\`
|
|
@@ -18361,7 +18609,7 @@ ${content.slice(0, 6e3)}
|
|
|
18361
18609
|
}
|
|
18362
18610
|
return chunks.join("\n");
|
|
18363
18611
|
}
|
|
18364
|
-
function
|
|
18612
|
+
function tryPostPr4(prNumber, body, cwd) {
|
|
18365
18613
|
try {
|
|
18366
18614
|
postPrReviewComment(prNumber, body, cwd);
|
|
18367
18615
|
} catch {
|
|
@@ -18370,12 +18618,12 @@ function tryPostPr3(prNumber, body, cwd) {
|
|
|
18370
18618
|
function pushEmptyCommit(branch, cwd) {
|
|
18371
18619
|
const env = { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" };
|
|
18372
18620
|
try {
|
|
18373
|
-
|
|
18621
|
+
execFileSync18(
|
|
18374
18622
|
"git",
|
|
18375
18623
|
["commit", "--allow-empty", "-m", "chore: kody resolve refresh \u2014 empty commit to recompute mergeable status"],
|
|
18376
18624
|
{ cwd, env, stdio: ["ignore", "pipe", "pipe"] }
|
|
18377
18625
|
);
|
|
18378
|
-
|
|
18626
|
+
execFileSync18("git", ["push", "-u", "origin", branch], {
|
|
18379
18627
|
cwd,
|
|
18380
18628
|
env,
|
|
18381
18629
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -18413,14 +18661,14 @@ var init_resolveFlow = __esm({
|
|
|
18413
18661
|
ctx.output.exitCode = 0;
|
|
18414
18662
|
ctx.output.reason = `PR #${prNumber} is mergeable (no conflicts) \u2014 nothing to resolve`;
|
|
18415
18663
|
ctx.skipAgent = true;
|
|
18416
|
-
|
|
18664
|
+
tryPostPr4(prNumber, `\u2139\uFE0F kody resolve: ${ctx.output.reason}`, ctx.cwd);
|
|
18417
18665
|
return;
|
|
18418
18666
|
}
|
|
18419
18667
|
if (ghStatus.status === "BLOCKED") {
|
|
18420
18668
|
ctx.output.exitCode = 0;
|
|
18421
18669
|
ctx.output.reason = `PR #${prNumber} is mergeable but blocked by checks/reviews (mergeStateStatus=${ghStatus.mergeStateStatus}) \u2014 nothing for resolve to do`;
|
|
18422
18670
|
ctx.skipAgent = true;
|
|
18423
|
-
|
|
18671
|
+
tryPostPr4(prNumber, `\u2139\uFE0F kody resolve: ${ctx.output.reason}`, ctx.cwd);
|
|
18424
18672
|
return;
|
|
18425
18673
|
}
|
|
18426
18674
|
checkoutPrBranch(prNumber, ctx.cwd);
|
|
@@ -18432,20 +18680,20 @@ var init_resolveFlow = __esm({
|
|
|
18432
18680
|
ctx.output.exitCode = 0;
|
|
18433
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)`;
|
|
18434
18682
|
ctx.skipAgent = true;
|
|
18435
|
-
|
|
18683
|
+
tryPostPr4(prNumber, `\u2139\uFE0F kody resolve: ${ctx.output.reason}`, ctx.cwd);
|
|
18436
18684
|
return;
|
|
18437
18685
|
}
|
|
18438
18686
|
ctx.output.exitCode = 0;
|
|
18439
18687
|
ctx.output.reason = `already up to date with origin/${baseBranch} \u2014 nothing to resolve`;
|
|
18440
18688
|
ctx.skipAgent = true;
|
|
18441
|
-
|
|
18689
|
+
tryPostPr4(prNumber, `\u2139\uFE0F kody resolve: ${ctx.output.reason}`, ctx.cwd);
|
|
18442
18690
|
return;
|
|
18443
18691
|
}
|
|
18444
18692
|
if (mergeStatus === "error") {
|
|
18445
18693
|
ctx.output.exitCode = 99;
|
|
18446
18694
|
ctx.output.reason = `failed to merge origin/${baseBranch} (non-conflict error); see runner log`;
|
|
18447
18695
|
ctx.skipAgent = true;
|
|
18448
|
-
|
|
18696
|
+
tryPostPr4(prNumber, `\u26A0\uFE0F kody resolve FAILED: ${ctx.output.reason}`, ctx.cwd);
|
|
18449
18697
|
return;
|
|
18450
18698
|
}
|
|
18451
18699
|
const conflictedFiles = getConflictedFiles(ctx.cwd);
|
|
@@ -18460,7 +18708,7 @@ var init_resolveFlow = __esm({
|
|
|
18460
18708
|
ctx.data.preferBlock = buildPreferBlock(ctx.args.prefer, baseBranch);
|
|
18461
18709
|
const runUrl = getRunUrl();
|
|
18462
18710
|
const runSuffix = runUrl ? `, run ${runUrl}` : "";
|
|
18463
|
-
|
|
18711
|
+
tryPostPr4(
|
|
18464
18712
|
prNumber,
|
|
18465
18713
|
`\u2699\uFE0F kody resolve started on \`${ctx.data.branch}\`${runSuffix} \u2014 ${conflictedFiles.length} conflicted file(s)`,
|
|
18466
18714
|
ctx.cwd
|
|
@@ -18561,10 +18809,10 @@ var init_resolvePreviewUrl = __esm({
|
|
|
18561
18809
|
});
|
|
18562
18810
|
|
|
18563
18811
|
// src/scripts/resolveQaUrl.ts
|
|
18564
|
-
import { execFileSync as
|
|
18812
|
+
import { execFileSync as execFileSync19 } from "child_process";
|
|
18565
18813
|
function ghQuery(args, cwd) {
|
|
18566
18814
|
try {
|
|
18567
|
-
const out =
|
|
18815
|
+
const out = execFileSync19("gh", args, {
|
|
18568
18816
|
cwd,
|
|
18569
18817
|
stdio: ["ignore", "pipe", "pipe"],
|
|
18570
18818
|
encoding: "utf-8",
|
|
@@ -18641,7 +18889,7 @@ var init_resolveQaUrl = __esm({
|
|
|
18641
18889
|
});
|
|
18642
18890
|
|
|
18643
18891
|
// src/scripts/revertFlow.ts
|
|
18644
|
-
import { execFileSync as
|
|
18892
|
+
import { execFileSync as execFileSync20 } from "child_process";
|
|
18645
18893
|
function buildCommitMessage(resolved) {
|
|
18646
18894
|
if (resolved.length === 1) {
|
|
18647
18895
|
const { full, subject } = resolved[0];
|
|
@@ -18654,7 +18902,7 @@ function buildPrSummary(resolved) {
|
|
|
18654
18902
|
return resolved.map((r) => `- Reverted \`${r.full.slice(0, 7)}\`${r.subject ? ` \u2014 ${r.subject}` : ""}`).join("\n");
|
|
18655
18903
|
}
|
|
18656
18904
|
function git4(args, cwd) {
|
|
18657
|
-
return
|
|
18905
|
+
return execFileSync20("git", args, {
|
|
18658
18906
|
encoding: "utf-8",
|
|
18659
18907
|
timeout: 3e4,
|
|
18660
18908
|
cwd,
|
|
@@ -18664,7 +18912,7 @@ function git4(args, cwd) {
|
|
|
18664
18912
|
}
|
|
18665
18913
|
function isAncestorOfHead(sha, cwd) {
|
|
18666
18914
|
try {
|
|
18667
|
-
|
|
18915
|
+
execFileSync20("git", ["merge-base", "--is-ancestor", sha, "HEAD"], {
|
|
18668
18916
|
cwd,
|
|
18669
18917
|
env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" },
|
|
18670
18918
|
stdio: ["ignore", "ignore", "ignore"]
|
|
@@ -18674,7 +18922,7 @@ function isAncestorOfHead(sha, cwd) {
|
|
|
18674
18922
|
return false;
|
|
18675
18923
|
}
|
|
18676
18924
|
}
|
|
18677
|
-
function
|
|
18925
|
+
function tryPostPr5(prNumber, body, cwd) {
|
|
18678
18926
|
try {
|
|
18679
18927
|
postPrReviewComment(prNumber, body, cwd);
|
|
18680
18928
|
} catch (err) {
|
|
@@ -18710,7 +18958,7 @@ var init_revertFlow = __esm({
|
|
|
18710
18958
|
ctx.output.exitCode = 64;
|
|
18711
18959
|
ctx.output.reason = "no commit SHAs provided \u2014 usage: @kody revert <sha> [<sha> \u2026]";
|
|
18712
18960
|
ctx.skipAgent = true;
|
|
18713
|
-
|
|
18961
|
+
tryPostPr5(prNumber, `\u26A0\uFE0F kody revert FAILED: ${ctx.output.reason}`, ctx.cwd);
|
|
18714
18962
|
return;
|
|
18715
18963
|
}
|
|
18716
18964
|
const requested = shasArg.split(/\s+/).filter((s) => s.length > 0);
|
|
@@ -18719,7 +18967,7 @@ var init_revertFlow = __esm({
|
|
|
18719
18967
|
ctx.output.exitCode = 64;
|
|
18720
18968
|
ctx.output.reason = `not valid SHA-shaped tokens: ${bad.join(", ")}`;
|
|
18721
18969
|
ctx.skipAgent = true;
|
|
18722
|
-
|
|
18970
|
+
tryPostPr5(prNumber, `\u26A0\uFE0F kody revert FAILED: ${ctx.output.reason}`, ctx.cwd);
|
|
18723
18971
|
return;
|
|
18724
18972
|
}
|
|
18725
18973
|
const resolved = [];
|
|
@@ -18747,7 +18995,7 @@ var init_revertFlow = __esm({
|
|
|
18747
18995
|
ctx.output.exitCode = 64;
|
|
18748
18996
|
ctx.output.reason = `commit(s) not found in this PR branch: ${unreachable.join(", ")}`;
|
|
18749
18997
|
ctx.skipAgent = true;
|
|
18750
|
-
|
|
18998
|
+
tryPostPr5(prNumber, `\u26A0\uFE0F kody revert FAILED: ${ctx.output.reason}`, ctx.cwd);
|
|
18751
18999
|
return;
|
|
18752
19000
|
}
|
|
18753
19001
|
ctx.args.shas = resolved.map((r) => r.full).join(" ");
|
|
@@ -18757,13 +19005,13 @@ var init_revertFlow = __esm({
|
|
|
18757
19005
|
const runUrl = getRunUrl();
|
|
18758
19006
|
const runSuffix = runUrl ? `, run ${runUrl}` : "";
|
|
18759
19007
|
const shaList = resolved.map((r) => `\`${r.full.slice(0, 7)}\``).join(", ");
|
|
18760
|
-
|
|
19008
|
+
tryPostPr5(prNumber, `\u2699\uFE0F kody revert started on \`${ctx.data.branch}\`${runSuffix} \u2014 reverting ${shaList}`, ctx.cwd);
|
|
18761
19009
|
};
|
|
18762
19010
|
}
|
|
18763
19011
|
});
|
|
18764
19012
|
|
|
18765
19013
|
// src/scripts/reviewFlow.ts
|
|
18766
|
-
function
|
|
19014
|
+
function tryPostPr6(prNumber, body, cwd) {
|
|
18767
19015
|
try {
|
|
18768
19016
|
postPrReviewComment(prNumber, body, cwd);
|
|
18769
19017
|
} catch {
|
|
@@ -18793,75 +19041,7 @@ var init_reviewFlow = __esm({
|
|
|
18793
19041
|
ctx.data.prDiff = getPrDiff(prNumber, ctx.cwd);
|
|
18794
19042
|
const runUrl = getRunUrl();
|
|
18795
19043
|
const runSuffix = runUrl ? `, run ${runUrl}` : "";
|
|
18796
|
-
|
|
18797
|
-
};
|
|
18798
|
-
}
|
|
18799
|
-
});
|
|
18800
|
-
|
|
18801
|
-
// src/scripts/runFlow.ts
|
|
18802
|
-
function tryPost(issueNumber, body, cwd) {
|
|
18803
|
-
try {
|
|
18804
|
-
postIssueComment(issueNumber, body, cwd);
|
|
18805
|
-
} catch {
|
|
18806
|
-
}
|
|
18807
|
-
}
|
|
18808
|
-
function resolveBaseOverride(value) {
|
|
18809
|
-
if (!value) return null;
|
|
18810
|
-
if (value.length > 200) return null;
|
|
18811
|
-
if (value.includes("..")) return null;
|
|
18812
|
-
if (!/^[a-z0-9][a-z0-9/._-]*$/.test(value)) return null;
|
|
18813
|
-
return value;
|
|
18814
|
-
}
|
|
18815
|
-
var runFlow;
|
|
18816
|
-
var init_runFlow = __esm({
|
|
18817
|
-
"src/scripts/runFlow.ts"() {
|
|
18818
|
-
"use strict";
|
|
18819
|
-
init_branch();
|
|
18820
|
-
init_gha();
|
|
18821
|
-
init_issue();
|
|
18822
|
-
runFlow = async (ctx) => {
|
|
18823
|
-
const issueNumber = ctx.args.issue;
|
|
18824
|
-
const issue2 = getIssue(issueNumber, ctx.cwd);
|
|
18825
|
-
const cfgCtx = ctx.config.issueContext ?? {};
|
|
18826
|
-
const commentsFormatted = formatIssueComments(
|
|
18827
|
-
issue2.comments,
|
|
18828
|
-
cfgCtx.commentLimit ?? DEFAULT_COMMENT_LIMIT,
|
|
18829
|
-
cfgCtx.commentMaxBytes ?? DEFAULT_COMMENT_MAX_BYTES
|
|
18830
|
-
);
|
|
18831
|
-
ctx.data.issue = { ...issue2, commentsFormatted };
|
|
18832
|
-
if (issue2.isPullRequest) {
|
|
18833
|
-
ctx.data.commentTargetType = "pr";
|
|
18834
|
-
ctx.data.commentTargetNumber = issueNumber;
|
|
18835
|
-
ctx.skipAgent = true;
|
|
18836
|
-
ctx.output.exitCode = 1;
|
|
18837
|
-
ctx.output.reason = `run target #${issueNumber} is a pull request; dispatch a PR action or the source issue instead`;
|
|
18838
|
-
return;
|
|
18839
|
-
}
|
|
18840
|
-
ctx.data.commentTargetType = "issue";
|
|
18841
|
-
ctx.data.commentTargetNumber = issueNumber;
|
|
18842
|
-
const argBase = resolveBaseOverride(ctx.args.base);
|
|
18843
|
-
const baseRaw = ctx.args.base;
|
|
18844
|
-
if (baseRaw && !argBase) {
|
|
18845
|
-
process.stderr.write(`[kody runFlow] ignoring --base "${baseRaw}" (must match kody-task or goal-branch pattern)
|
|
18846
|
-
`);
|
|
18847
|
-
}
|
|
18848
|
-
const base = argBase;
|
|
18849
|
-
if (base) {
|
|
18850
|
-
ctx.data.baseBranch = base;
|
|
18851
|
-
process.stderr.write(`[kody runFlow] resolved base branch: ${base} (from --base)
|
|
18852
|
-
`);
|
|
18853
|
-
}
|
|
18854
|
-
const branchInfo = ensureFeatureBranch(
|
|
18855
|
-
issueNumber,
|
|
18856
|
-
issue2.title,
|
|
18857
|
-
ctx.config.git.defaultBranch,
|
|
18858
|
-
ctx.cwd,
|
|
18859
|
-
base ?? void 0
|
|
18860
|
-
);
|
|
18861
|
-
ctx.data.branch = branchInfo.branch;
|
|
18862
|
-
const runUrl = getRunUrl();
|
|
18863
|
-
const startMsg = runUrl ? `\u2699\uFE0F kody started \u2014 branch \`${ctx.data.branch}\`, run ${runUrl}` : `\u2699\uFE0F kody started \u2014 branch \`${ctx.data.branch}\``;
|
|
18864
|
-
tryPost(issueNumber, startMsg, ctx.cwd);
|
|
19044
|
+
tryPostPr6(prNumber, `\u{1F440} kody review started on PR #${prNumber}${runSuffix}`, ctx.cwd);
|
|
18865
19045
|
};
|
|
18866
19046
|
}
|
|
18867
19047
|
});
|
|
@@ -19631,7 +19811,7 @@ var init_skipAgent = __esm({
|
|
|
19631
19811
|
});
|
|
19632
19812
|
|
|
19633
19813
|
// src/scripts/stageMergeConflicts.ts
|
|
19634
|
-
import { execFileSync as
|
|
19814
|
+
import { execFileSync as execFileSync21 } from "child_process";
|
|
19635
19815
|
var stageMergeConflicts;
|
|
19636
19816
|
var init_stageMergeConflicts = __esm({
|
|
19637
19817
|
"src/scripts/stageMergeConflicts.ts"() {
|
|
@@ -19639,7 +19819,7 @@ var init_stageMergeConflicts = __esm({
|
|
|
19639
19819
|
stageMergeConflicts = async (ctx) => {
|
|
19640
19820
|
if (ctx.data.agentDone === false) return;
|
|
19641
19821
|
try {
|
|
19642
|
-
|
|
19822
|
+
execFileSync21("git", ["add", "-A"], {
|
|
19643
19823
|
cwd: ctx.cwd,
|
|
19644
19824
|
env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" },
|
|
19645
19825
|
stdio: "pipe"
|
|
@@ -19692,113 +19872,6 @@ var init_startFlow = __esm({
|
|
|
19692
19872
|
}
|
|
19693
19873
|
});
|
|
19694
19874
|
|
|
19695
|
-
// src/scripts/syncFlow.ts
|
|
19696
|
-
import { execFileSync as execFileSync21 } from "child_process";
|
|
19697
|
-
function restoreDone(prNumber, cwd) {
|
|
19698
|
-
try {
|
|
19699
|
-
setKodyLabel(prNumber, DONE2, cwd);
|
|
19700
|
-
} catch {
|
|
19701
|
-
}
|
|
19702
|
-
}
|
|
19703
|
-
function bail2(ctx, prNumber, reason) {
|
|
19704
|
-
ctx.skipAgent = true;
|
|
19705
|
-
ctx.output.exitCode = 1;
|
|
19706
|
-
ctx.output.reason = reason;
|
|
19707
|
-
const runUrl = getRunUrl();
|
|
19708
|
-
const runSuffix = runUrl ? ` ([logs](${runUrl}))` : "";
|
|
19709
|
-
tryPostPr6(prNumber, `\u274C kody sync could not complete${runSuffix}: ${reason}`, ctx.cwd);
|
|
19710
|
-
}
|
|
19711
|
-
function revParseHead(cwd) {
|
|
19712
|
-
try {
|
|
19713
|
-
return execFileSync21("git", ["rev-parse", "HEAD"], { cwd, encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] }).toString().trim();
|
|
19714
|
-
} catch {
|
|
19715
|
-
return "";
|
|
19716
|
-
}
|
|
19717
|
-
}
|
|
19718
|
-
function pushBranch(branch, cwd) {
|
|
19719
|
-
const result = pushWithRetry({ cwd: cwd ?? process.cwd(), branch, setUpstream: true });
|
|
19720
|
-
if (!result.ok) {
|
|
19721
|
-
throw new Error(result.reason);
|
|
19722
|
-
}
|
|
19723
|
-
}
|
|
19724
|
-
function tryPostPr6(prNumber, body, cwd) {
|
|
19725
|
-
try {
|
|
19726
|
-
postPrReviewComment(prNumber, body, cwd);
|
|
19727
|
-
} catch {
|
|
19728
|
-
}
|
|
19729
|
-
}
|
|
19730
|
-
var DONE2, syncFlow;
|
|
19731
|
-
var init_syncFlow = __esm({
|
|
19732
|
-
"src/scripts/syncFlow.ts"() {
|
|
19733
|
-
"use strict";
|
|
19734
|
-
init_branch();
|
|
19735
|
-
init_gha();
|
|
19736
|
-
init_issue();
|
|
19737
|
-
init_lifecycleLabels();
|
|
19738
|
-
init_pushWithRetry();
|
|
19739
|
-
DONE2 = {
|
|
19740
|
-
label: "kody:done",
|
|
19741
|
-
color: "0e8a16",
|
|
19742
|
-
description: "kody: PR ready for human review/merge"
|
|
19743
|
-
};
|
|
19744
|
-
syncFlow = async (ctx, _profile, args) => {
|
|
19745
|
-
const announceOnSuccess = Boolean(args?.announceOnSuccess);
|
|
19746
|
-
const prNumber = ctx.args.pr;
|
|
19747
|
-
const pr = getPr(prNumber, ctx.cwd);
|
|
19748
|
-
if (pr.state !== "OPEN") {
|
|
19749
|
-
bail2(ctx, prNumber, `PR #${prNumber} is not OPEN (state: ${pr.state})`);
|
|
19750
|
-
return;
|
|
19751
|
-
}
|
|
19752
|
-
ctx.data.pr = pr;
|
|
19753
|
-
if (announceOnSuccess) {
|
|
19754
|
-
ctx.data.commentTargetType = "pr";
|
|
19755
|
-
ctx.data.commentTargetNumber = prNumber;
|
|
19756
|
-
}
|
|
19757
|
-
checkoutPrBranch(prNumber, ctx.cwd);
|
|
19758
|
-
ctx.data.branch = getCurrentBranch(ctx.cwd);
|
|
19759
|
-
const baseBranch = pr.baseRefName || ctx.config.git.defaultBranch;
|
|
19760
|
-
ctx.data.baseBranch = baseBranch;
|
|
19761
|
-
const headBefore = revParseHead(ctx.cwd);
|
|
19762
|
-
const mergeStatus = mergeBase(baseBranch, ctx.cwd);
|
|
19763
|
-
if (mergeStatus === "error") {
|
|
19764
|
-
bail2(ctx, prNumber, `failed to merge origin/${baseBranch} (non-conflict error); see runner log`);
|
|
19765
|
-
return;
|
|
19766
|
-
}
|
|
19767
|
-
if (mergeStatus === "conflict") {
|
|
19768
|
-
bail2(
|
|
19769
|
-
ctx,
|
|
19770
|
-
prNumber,
|
|
19771
|
-
`merge from origin/${baseBranch} produced conflicts \u2014 run \`@kody resolve\` to let kody resolve them`
|
|
19772
|
-
);
|
|
19773
|
-
return;
|
|
19774
|
-
}
|
|
19775
|
-
const headAfter = revParseHead(ctx.cwd);
|
|
19776
|
-
if (headAfter === headBefore) {
|
|
19777
|
-
ctx.data.syncResult = "noop";
|
|
19778
|
-
if (announceOnSuccess) {
|
|
19779
|
-
ctx.output.exitCode = 0;
|
|
19780
|
-
ctx.output.reason = `already up to date with origin/${baseBranch}`;
|
|
19781
|
-
restoreDone(prNumber, ctx.cwd);
|
|
19782
|
-
}
|
|
19783
|
-
return;
|
|
19784
|
-
}
|
|
19785
|
-
try {
|
|
19786
|
-
pushBranch(ctx.data.branch, ctx.cwd);
|
|
19787
|
-
} catch (err) {
|
|
19788
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
19789
|
-
bail2(ctx, prNumber, `merge succeeded but push failed: ${msg}`);
|
|
19790
|
-
return;
|
|
19791
|
-
}
|
|
19792
|
-
ctx.data.syncResult = "merged";
|
|
19793
|
-
if (announceOnSuccess) {
|
|
19794
|
-
ctx.output.exitCode = 0;
|
|
19795
|
-
ctx.output.reason = `merged origin/${baseBranch} into ${ctx.data.branch}`;
|
|
19796
|
-
restoreDone(prNumber, ctx.cwd);
|
|
19797
|
-
}
|
|
19798
|
-
};
|
|
19799
|
-
}
|
|
19800
|
-
});
|
|
19801
|
-
|
|
19802
19875
|
// src/scripts/validateAgencyModelProposal.ts
|
|
19803
19876
|
import * as path46 from "path";
|
|
19804
19877
|
function validateModelBundle(bundle, expectedKind, options = {}) {
|
|
@@ -20880,6 +20953,7 @@ var init_scripts = __esm({
|
|
|
20880
20953
|
init_postResearchComment();
|
|
20881
20954
|
init_postReviewResult();
|
|
20882
20955
|
init_prepareBrowserAuth();
|
|
20956
|
+
init_prepareCapabilityDelivery();
|
|
20883
20957
|
init_promoteQaGoal();
|
|
20884
20958
|
init_publishReport();
|
|
20885
20959
|
init_recordClassification();
|
|
@@ -20941,6 +21015,7 @@ var init_scripts = __esm({
|
|
|
20941
21015
|
loadPriorArt,
|
|
20942
21016
|
loadQaContext,
|
|
20943
21017
|
prepareBrowserAuth,
|
|
21018
|
+
prepareCapabilityDelivery,
|
|
20944
21019
|
buildSyntheticPlugin,
|
|
20945
21020
|
resolveArtifacts,
|
|
20946
21021
|
discoverQaContext,
|
|
@@ -22301,6 +22376,9 @@ function validateJob(input) {
|
|
|
22301
22376
|
if (j.cliArgs !== void 0 && (typeof j.cliArgs !== "object" || j.cliArgs === null)) {
|
|
22302
22377
|
throw new InvalidJobError("job.cliArgs must be an object when present");
|
|
22303
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
|
+
}
|
|
22304
22382
|
return {
|
|
22305
22383
|
action: typeof j.action === "string" ? j.action : void 0,
|
|
22306
22384
|
implementation: typeof j.implementation === "string" ? j.implementation : void 0,
|
|
@@ -22310,6 +22388,7 @@ function validateJob(input) {
|
|
|
22310
22388
|
agent: typeof j.agent === "string" ? j.agent : void 0,
|
|
22311
22389
|
schedule: typeof j.schedule === "string" ? j.schedule : void 0,
|
|
22312
22390
|
target: typeof j.target === "number" ? j.target : void 0,
|
|
22391
|
+
delivery: j.delivery === "pull-request" ? j.delivery : void 0,
|
|
22313
22392
|
cliArgs: j.cliArgs ?? {},
|
|
22314
22393
|
workflowFacts: j.workflowFacts && typeof j.workflowFacts === "object" && !Array.isArray(j.workflowFacts) ? j.workflowFacts : void 0,
|
|
22315
22394
|
workflowState: parseWorkflowRunState(j.workflowState) ?? void 0,
|
|
@@ -22362,7 +22441,7 @@ async function runJob(job, base) {
|
|
|
22362
22441
|
}
|
|
22363
22442
|
const workflow = capabilityContext?.config.workflow ?? workflowContext?.config.workflow;
|
|
22364
22443
|
const workflowIdentity = valid.workflow ?? capabilityIdentity ?? workflowContext?.slug;
|
|
22365
|
-
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);
|
|
22366
22445
|
const profileName = explicitImplementation ?? capabilitySelectedImplementation;
|
|
22367
22446
|
if (workflow && shouldRunCapabilityWorkflow(valid, workflow, workflowIdentity, capabilitySelectedImplementation, base)) {
|
|
22368
22447
|
const workflowCapability = capabilityContext ?? workflowContext;
|
|
@@ -22452,6 +22531,7 @@ async function runCapabilityImplementationStep(valid, profileName, capabilityIde
|
|
|
22452
22531
|
preloadedData.jobKey = stableJobKey(valid);
|
|
22453
22532
|
preloadedData.jobFlavor = valid.flavor;
|
|
22454
22533
|
if (valid.target !== void 0) preloadedData.jobTarget = valid.target;
|
|
22534
|
+
if (valid.delivery !== void 0) preloadedData.jobDelivery = valid.delivery;
|
|
22455
22535
|
if (valid.action !== void 0 && valid.action.length > 0) preloadedData.jobAction = valid.action;
|
|
22456
22536
|
if (capabilityIdentity !== void 0 && capabilityIdentity.length > 0)
|
|
22457
22537
|
preloadedData.jobCapability = capabilityIdentity;
|
|
@@ -22491,11 +22571,13 @@ async function runCapabilityImplementationStep(valid, profileName, capabilityIde
|
|
|
22491
22571
|
};
|
|
22492
22572
|
const shouldApplyResolvedCapabilityArgs = valid.implementation === void 0 && resolvedCapability && profileName === resolvedCapability.implementation;
|
|
22493
22573
|
input.cliArgs = shouldApplyResolvedCapabilityArgs ? { ...resolvedCapability.cliArgs, ...input.cliArgs } : input.cliArgs;
|
|
22494
|
-
if (profileName === "capability-run" && capabilityIdentity) {
|
|
22574
|
+
if ((profileName === "capability-run" || profileName === "capability-delivery") && capabilityIdentity) {
|
|
22495
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) : {};
|
|
22496
22577
|
input.cliArgs = {
|
|
22497
22578
|
capability: capabilityIdentity,
|
|
22498
|
-
...capabilityInput !== void 0 ? { input: JSON.stringify(capabilityInput) } : {}
|
|
22579
|
+
...capabilityInput !== void 0 ? { input: JSON.stringify(capabilityInput) } : {},
|
|
22580
|
+
...deliveryTarget
|
|
22499
22581
|
};
|
|
22500
22582
|
}
|
|
22501
22583
|
const run = base.chain === false ? runImplementation : runImplementationChain;
|
|
@@ -22852,6 +22934,7 @@ function workflowStepToJob(step, parent, chainData, cwd) {
|
|
|
22852
22934
|
...parent.agent ? { agent: parent.agent } : {},
|
|
22853
22935
|
...parent.schedule ? { schedule: parent.schedule } : {},
|
|
22854
22936
|
...typeof target === "number" ? { target } : {},
|
|
22937
|
+
...step.delivery ? { delivery: step.delivery } : {},
|
|
22855
22938
|
cliArgs,
|
|
22856
22939
|
...step.evidence ? { evidence: step.evidence } : parent.evidence ? { evidence: parent.evidence } : {},
|
|
22857
22940
|
flavor: parent.flavor,
|
|
@@ -22861,6 +22944,10 @@ function workflowStepToJob(step, parent, chainData, cwd) {
|
|
|
22861
22944
|
...parent.resultTarget ? { resultTarget: parent.resultTarget } : {}
|
|
22862
22945
|
};
|
|
22863
22946
|
}
|
|
22947
|
+
function capabilityDeliveryArgs(input) {
|
|
22948
|
+
const target = capabilityDeliveryTarget(input);
|
|
22949
|
+
return target ? { [target.kind]: target.number } : {};
|
|
22950
|
+
}
|
|
22864
22951
|
function usesGenericCapabilityInput(action, cwd) {
|
|
22865
22952
|
const inputs = getCapabilityActionInputs(action, hydratedCapabilitiesRoot(cwd));
|
|
22866
22953
|
return Boolean(inputs?.length === 1 && inputs[0]?.name === "input" && inputs[0]?.flag === "--input");
|
|
@@ -23025,6 +23112,7 @@ var init_job = __esm({
|
|
|
23025
23112
|
"src/job.ts"() {
|
|
23026
23113
|
"use strict";
|
|
23027
23114
|
init_agencyBoundaryEval();
|
|
23115
|
+
init_capabilityDelivery();
|
|
23028
23116
|
init_capabilityFolders();
|
|
23029
23117
|
init_definition_paths();
|
|
23030
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.
|
|
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",
|