@kody-ade/kody-engine 0.4.315 → 0.4.317
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 +175 -180
- 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.
|
|
18
|
+
version: "0.4.317",
|
|
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",
|
|
@@ -1909,6 +1909,7 @@ function parseCapabilityConfig(raw) {
|
|
|
1909
1909
|
implementation: stringField(raw.implementation ?? raw.executable),
|
|
1910
1910
|
executable: stringField(raw.executable),
|
|
1911
1911
|
tickScript: stringField(raw.tickScript),
|
|
1912
|
+
capabilityKind: parseCapabilityKind(raw.capabilityKind),
|
|
1912
1913
|
disabled: typeof raw.disabled === "boolean" ? raw.disabled : void 0,
|
|
1913
1914
|
internal: typeof raw.internal === "boolean" ? raw.internal : void 0,
|
|
1914
1915
|
public: typeof raw.public === "boolean" ? raw.public : void 0,
|
|
@@ -1927,6 +1928,9 @@ function parseCapabilityConfig(raw) {
|
|
|
1927
1928
|
workflow: parseCapabilityWorkflow(raw.workflow)
|
|
1928
1929
|
};
|
|
1929
1930
|
}
|
|
1931
|
+
function parseCapabilityKind(raw) {
|
|
1932
|
+
return raw === "observe" || raw === "act" || raw === "verify" ? raw : void 0;
|
|
1933
|
+
}
|
|
1930
1934
|
function parseCapabilityToolMode(raw) {
|
|
1931
1935
|
if (raw === void 0 || raw === null || raw === "") return void 0;
|
|
1932
1936
|
if (raw === "lock" || raw === "append") return raw;
|
|
@@ -2633,82 +2637,13 @@ function readCheckRuns(repoSlug, ref, ignoreNames) {
|
|
|
2633
2637
|
const state = failing.length > 0 ? "RED" : pending.length > 0 ? "PENDING" : "GREEN";
|
|
2634
2638
|
return { sha, state, failing, pending };
|
|
2635
2639
|
}
|
|
2636
|
-
function
|
|
2637
|
-
return [
|
|
2638
|
-
...new Set(
|
|
2639
|
-
(values ?? []).map((value) => value.trim().replace(/^@/, "")).filter(Boolean)
|
|
2640
|
-
)
|
|
2641
|
-
];
|
|
2642
|
-
}
|
|
2643
|
-
function cleanLabels(values) {
|
|
2644
|
-
return [
|
|
2645
|
-
...new Set(
|
|
2646
|
-
(values ?? []).map((value) => value.trim()).filter(Boolean)
|
|
2647
|
-
)
|
|
2648
|
-
];
|
|
2649
|
-
}
|
|
2650
|
-
function ensureKodyLabel(repoSlug, label) {
|
|
2651
|
-
if (!label.toLowerCase().startsWith("kody:")) return;
|
|
2652
|
-
gh([
|
|
2653
|
-
"label",
|
|
2654
|
-
"create",
|
|
2655
|
-
label,
|
|
2656
|
-
"-R",
|
|
2657
|
-
repoSlug,
|
|
2658
|
-
"--color",
|
|
2659
|
-
"8b5cf6",
|
|
2660
|
-
"--description",
|
|
2661
|
-
"Kody-owned tracking issue",
|
|
2662
|
-
"--force"
|
|
2663
|
-
]);
|
|
2664
|
-
}
|
|
2665
|
-
function applyIssueUpdates(repoSlug, number, opts) {
|
|
2666
|
-
const labels = cleanLabels(opts?.labels);
|
|
2667
|
-
const assignees = cleanLogins(opts?.assignees);
|
|
2668
|
-
if (labels.length === 0 && assignees.length === 0) return null;
|
|
2669
|
-
const labelsApplied = [];
|
|
2670
|
-
const assigneesApplied = [];
|
|
2671
|
-
const warnings = [];
|
|
2672
|
-
for (const label of labels) {
|
|
2673
|
-
try {
|
|
2674
|
-
gh(["issue", "edit", String(number), "-R", repoSlug, "--add-label", label]);
|
|
2675
|
-
labelsApplied.push(label);
|
|
2676
|
-
} catch (firstErr) {
|
|
2677
|
-
try {
|
|
2678
|
-
ensureKodyLabel(repoSlug, label);
|
|
2679
|
-
gh(["issue", "edit", String(number), "-R", repoSlug, "--add-label", label]);
|
|
2680
|
-
labelsApplied.push(label);
|
|
2681
|
-
} catch (err) {
|
|
2682
|
-
warnings.push(
|
|
2683
|
-
`label ${label}: ${err instanceof Error ? err.message : firstErr instanceof Error ? firstErr.message : String(err)}`
|
|
2684
|
-
);
|
|
2685
|
-
}
|
|
2686
|
-
}
|
|
2687
|
-
}
|
|
2688
|
-
for (const assignee of assignees) {
|
|
2689
|
-
try {
|
|
2690
|
-
gh(["issue", "edit", String(number), "-R", repoSlug, "--add-assignee", assignee]);
|
|
2691
|
-
assigneesApplied.push(assignee);
|
|
2692
|
-
} catch (err) {
|
|
2693
|
-
warnings.push(`assignee ${assignee}: ${err instanceof Error ? err.message : String(err)}`);
|
|
2694
|
-
}
|
|
2695
|
-
}
|
|
2696
|
-
return {
|
|
2697
|
-
...labelsApplied.length > 0 ? { labelsApplied } : {},
|
|
2698
|
-
...assigneesApplied.length > 0 ? { assigneesApplied } : {},
|
|
2699
|
-
...warnings.length > 0 ? { warnings } : {}
|
|
2700
|
-
};
|
|
2701
|
-
}
|
|
2702
|
-
function ensureIssue(repoSlug, key, title, body, opts) {
|
|
2640
|
+
function ensureIssue(repoSlug, key, title, body) {
|
|
2703
2641
|
const marker = trackMarker(key);
|
|
2704
2642
|
try {
|
|
2705
2643
|
const raw = gh(["issue", "list", "-R", repoSlug, "--state", "open", "--limit", "100", "--json", "number,body"]);
|
|
2706
2644
|
const issues = JSON.parse(raw);
|
|
2707
2645
|
const existing = issues.find((i) => (i.body ?? "").includes(marker));
|
|
2708
|
-
if (existing) {
|
|
2709
|
-
const updates2 = applyIssueUpdates(repoSlug, existing.number, opts);
|
|
2710
|
-
return updates2 ? { created: false, number: existing.number, ...updates2 } : { created: false, number: existing.number };
|
|
2711
|
-
}
|
|
2646
|
+
if (existing) return { created: false, number: existing.number };
|
|
2712
2647
|
const url = gh(["issue", "create", "-R", repoSlug, "--title", title, "--body-file", "-"], {
|
|
2713
2648
|
input: `${body}
|
|
2714
2649
|
|
|
@@ -2716,9 +2651,7 @@ ${marker}`
|
|
|
2716
2651
|
});
|
|
2717
2652
|
const m = url.trim().match(/\/(\d+)\s*$/);
|
|
2718
2653
|
if (!m) return { error: `issue created but could not parse its number from: ${url}` };
|
|
2719
|
-
|
|
2720
|
-
const updates = applyIssueUpdates(repoSlug, number, opts);
|
|
2721
|
-
return updates ? { created: true, number, ...updates } : { created: true, number };
|
|
2654
|
+
return { created: true, number: Number(m[1]) };
|
|
2722
2655
|
} catch (err) {
|
|
2723
2656
|
return { error: err instanceof Error ? err.message : String(err) };
|
|
2724
2657
|
}
|
|
@@ -2912,19 +2845,13 @@ function capabilityToolDefinitions(opts) {
|
|
|
2912
2845
|
title: z3.string().min(1).describe("Issue title (used only on first creation)."),
|
|
2913
2846
|
body: z3.string().min(1).describe(
|
|
2914
2847
|
"Issue body markdown (used only on first creation). Include the operator mention verbatim if the capability body has one."
|
|
2915
|
-
)
|
|
2916
|
-
labels: z3.array(z3.string().min(1)).optional().describe(
|
|
2917
|
-
"Optional labels to apply to the tracking issue every time, including reused issues. Use for dashboard visibility, e.g. ['kody:backlog']."
|
|
2918
|
-
),
|
|
2919
|
-
assignees: z3.array(z3.string().min(1)).optional().describe("Optional GitHub logins to assign to the tracking issue every time, including reused issues.")
|
|
2848
|
+
)
|
|
2920
2849
|
},
|
|
2921
2850
|
handler: async (args) => {
|
|
2922
2851
|
const key = String(args.key ?? "");
|
|
2923
2852
|
const title = String(args.title ?? "");
|
|
2924
2853
|
const body = String(args.body ?? "");
|
|
2925
|
-
const
|
|
2926
|
-
const assignees = Array.isArray(args.assignees) ? args.assignees.map((assignee) => String(assignee)) : void 0;
|
|
2927
|
-
const result = ensureIssue(opts.repoSlug, key, title, body, { labels, assignees });
|
|
2854
|
+
const result = ensureIssue(opts.repoSlug, key, title, body);
|
|
2928
2855
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
2929
2856
|
}
|
|
2930
2857
|
};
|
|
@@ -3869,6 +3796,89 @@ var init_gha = __esm({
|
|
|
3869
3796
|
}
|
|
3870
3797
|
});
|
|
3871
3798
|
|
|
3799
|
+
// src/agencyBoundaryEval.ts
|
|
3800
|
+
function evaluateAgencyBoundaries(input) {
|
|
3801
|
+
const findings = [];
|
|
3802
|
+
const results = input.results ?? [];
|
|
3803
|
+
findings.push(evaluateObserveBoundary(input.capabilityKind, results));
|
|
3804
|
+
findings.push(evaluateVerifyBoundary(input.capabilityKind, results));
|
|
3805
|
+
findings.push(evaluateGoalOwnershipBoundary(results));
|
|
3806
|
+
return {
|
|
3807
|
+
version: 1,
|
|
3808
|
+
status: findings.some((finding) => finding.status === "fail") ? "fail" : "pass",
|
|
3809
|
+
...input.capability ? { capability: input.capability } : {},
|
|
3810
|
+
...input.capabilityKind ? { capabilityKind: input.capabilityKind } : {},
|
|
3811
|
+
findings
|
|
3812
|
+
};
|
|
3813
|
+
}
|
|
3814
|
+
function evaluateObserveBoundary(capabilityKind, results) {
|
|
3815
|
+
if (capabilityKind !== "observe") {
|
|
3816
|
+
return pass("observe-does-not-act", "capability is not observe", { capabilityKind });
|
|
3817
|
+
}
|
|
3818
|
+
const actionResults = results.filter(resultLooksLikeAction);
|
|
3819
|
+
if (actionResults.length === 0) {
|
|
3820
|
+
return pass("observe-does-not-act", "observe capability reported facts without action output", {
|
|
3821
|
+
resultCount: results.length
|
|
3822
|
+
});
|
|
3823
|
+
}
|
|
3824
|
+
return fail("observe-does-not-act", "observe capability returned action-shaped output", {
|
|
3825
|
+
resultCount: results.length,
|
|
3826
|
+
actionResults: actionResults.map(resultSummary)
|
|
3827
|
+
});
|
|
3828
|
+
}
|
|
3829
|
+
function evaluateVerifyBoundary(capabilityKind, results) {
|
|
3830
|
+
if (capabilityKind !== "verify") {
|
|
3831
|
+
return pass("verify-does-not-fix", "capability is not verify", { capabilityKind });
|
|
3832
|
+
}
|
|
3833
|
+
const actionResults = results.filter(resultLooksLikeAction);
|
|
3834
|
+
if (actionResults.length === 0) {
|
|
3835
|
+
return pass("verify-does-not-fix", "verify capability returned verdict evidence without action output", {
|
|
3836
|
+
resultCount: results.length
|
|
3837
|
+
});
|
|
3838
|
+
}
|
|
3839
|
+
return fail("verify-does-not-fix", "verify capability returned fix/change output", {
|
|
3840
|
+
resultCount: results.length,
|
|
3841
|
+
actionResults: actionResults.map(resultSummary)
|
|
3842
|
+
});
|
|
3843
|
+
}
|
|
3844
|
+
function evaluateGoalOwnershipBoundary(results) {
|
|
3845
|
+
const targetBearing = results.filter((result) => result.target?.type === "goal");
|
|
3846
|
+
if (targetBearing.length === 0) {
|
|
3847
|
+
return pass("capability-does-not-own-goal-progress", "capability output is parent-neutral", {
|
|
3848
|
+
resultCount: results.length
|
|
3849
|
+
});
|
|
3850
|
+
}
|
|
3851
|
+
return fail("capability-does-not-own-goal-progress", "capability output names a goal target", {
|
|
3852
|
+
resultCount: results.length,
|
|
3853
|
+
targetBearingResults: targetBearing.map(resultSummary)
|
|
3854
|
+
});
|
|
3855
|
+
}
|
|
3856
|
+
function resultLooksLikeAction(result) {
|
|
3857
|
+
if (result.status === "changed") return true;
|
|
3858
|
+
return Object.keys(result.facts).some((key) => ACTION_FACT_KEYS.has(key));
|
|
3859
|
+
}
|
|
3860
|
+
function resultSummary(result) {
|
|
3861
|
+
return {
|
|
3862
|
+
status: result.status,
|
|
3863
|
+
summary: result.summary,
|
|
3864
|
+
target: result.target,
|
|
3865
|
+
actionFactKeys: Object.keys(result.facts).filter((key) => ACTION_FACT_KEYS.has(key))
|
|
3866
|
+
};
|
|
3867
|
+
}
|
|
3868
|
+
function pass(rule, message, evidence) {
|
|
3869
|
+
return { rule, status: "pass", message, evidence };
|
|
3870
|
+
}
|
|
3871
|
+
function fail(rule, message, evidence) {
|
|
3872
|
+
return { rule, status: "fail", message, evidence };
|
|
3873
|
+
}
|
|
3874
|
+
var ACTION_FACT_KEYS;
|
|
3875
|
+
var init_agencyBoundaryEval = __esm({
|
|
3876
|
+
"src/agencyBoundaryEval.ts"() {
|
|
3877
|
+
"use strict";
|
|
3878
|
+
ACTION_FACT_KEYS = /* @__PURE__ */ new Set(["changedResources", "createdResources", "actionResult"]);
|
|
3879
|
+
}
|
|
3880
|
+
});
|
|
3881
|
+
|
|
3872
3882
|
// src/capabilityReport.ts
|
|
3873
3883
|
function parseCapabilityReportsFromText(text) {
|
|
3874
3884
|
const reports = [];
|
|
@@ -4388,7 +4398,7 @@ function loadProfile(profilePath) {
|
|
|
4388
4398
|
executable: execRef,
|
|
4389
4399
|
internal: typeof r.internal === "boolean" ? r.internal : base.internal,
|
|
4390
4400
|
public: typeof r.public === "boolean" ? r.public : base.public,
|
|
4391
|
-
capabilityKind:
|
|
4401
|
+
capabilityKind: parseCapabilityKind2(r.capabilityKind) ?? base.capabilityKind,
|
|
4392
4402
|
slug: typeof r.slug === "string" && r.slug.trim() ? r.slug.trim() : base.slug,
|
|
4393
4403
|
title: typeof r.title === "string" && r.title.trim() ? r.title.trim() : base.title,
|
|
4394
4404
|
skills: parseStringArray2(r.skills) ?? base.skills,
|
|
@@ -4442,7 +4452,7 @@ function loadProfile(profilePath) {
|
|
|
4442
4452
|
executable: void 0,
|
|
4443
4453
|
internal: typeof r.internal === "boolean" ? r.internal : void 0,
|
|
4444
4454
|
public: typeof r.public === "boolean" ? r.public : void 0,
|
|
4445
|
-
capabilityKind:
|
|
4455
|
+
capabilityKind: parseCapabilityKind2(r.capabilityKind),
|
|
4446
4456
|
slug: typeof r.slug === "string" && r.slug.trim() ? r.slug.trim() : void 0,
|
|
4447
4457
|
title: typeof r.title === "string" && r.title.trim() ? r.title.trim() : void 0,
|
|
4448
4458
|
skills: parseStringArray2(r.skills),
|
|
@@ -4549,7 +4559,7 @@ function parseStringArray2(raw) {
|
|
|
4549
4559
|
const values = raw.map((t) => String(t).trim()).filter(Boolean);
|
|
4550
4560
|
return values.length > 0 ? values : void 0;
|
|
4551
4561
|
}
|
|
4552
|
-
function
|
|
4562
|
+
function parseCapabilityKind2(raw) {
|
|
4553
4563
|
return raw === "observe" || raw === "act" || raw === "verify" ? raw : void 0;
|
|
4554
4564
|
}
|
|
4555
4565
|
function parseInputs(p, raw) {
|
|
@@ -9965,10 +9975,10 @@ function refreshReportOrFail(ctx, goalId, state, evidenceItems) {
|
|
|
9965
9975
|
evidenceItems
|
|
9966
9976
|
});
|
|
9967
9977
|
} catch (err) {
|
|
9968
|
-
|
|
9978
|
+
fail2(ctx, err instanceof Error ? err.message : String(err));
|
|
9969
9979
|
}
|
|
9970
9980
|
}
|
|
9971
|
-
function
|
|
9981
|
+
function fail2(ctx, reason) {
|
|
9972
9982
|
ctx.output.reason = ctx.output.reason ? `${ctx.output.reason}; ${reason}` : reason;
|
|
9973
9983
|
if (ctx.output.exitCode === 0) ctx.output.exitCode = 99;
|
|
9974
9984
|
}
|
|
@@ -12408,90 +12418,20 @@ var init_ensurePr = __esm({
|
|
|
12408
12418
|
}
|
|
12409
12419
|
});
|
|
12410
12420
|
|
|
12411
|
-
// src/
|
|
12412
|
-
function
|
|
12413
|
-
|
|
12414
|
-
const results = input.results ?? [];
|
|
12415
|
-
findings.push(evaluateObserveBoundary(input.capabilityKind, results));
|
|
12416
|
-
findings.push(evaluateVerifyBoundary(input.capabilityKind, results));
|
|
12417
|
-
findings.push(evaluateGoalOwnershipBoundary(results));
|
|
12418
|
-
return {
|
|
12419
|
-
version: 1,
|
|
12420
|
-
status: findings.some((finding) => finding.status === "fail") ? "fail" : "pass",
|
|
12421
|
-
...input.capability ? { capability: input.capability } : {},
|
|
12422
|
-
...input.capabilityKind ? { capabilityKind: input.capabilityKind } : {},
|
|
12423
|
-
findings
|
|
12424
|
-
};
|
|
12425
|
-
}
|
|
12426
|
-
function evaluateObserveBoundary(capabilityKind, results) {
|
|
12427
|
-
if (capabilityKind !== "observe") {
|
|
12428
|
-
return pass("observe-does-not-act", "capability is not observe", { capabilityKind });
|
|
12429
|
-
}
|
|
12430
|
-
const actionResults = results.filter(resultLooksLikeAction);
|
|
12431
|
-
if (actionResults.length === 0) {
|
|
12432
|
-
return pass("observe-does-not-act", "observe capability reported facts without action output", {
|
|
12433
|
-
resultCount: results.length
|
|
12434
|
-
});
|
|
12435
|
-
}
|
|
12436
|
-
return fail2("observe-does-not-act", "observe capability returned action-shaped output", {
|
|
12437
|
-
resultCount: results.length,
|
|
12438
|
-
actionResults: actionResults.map(resultSummary)
|
|
12439
|
-
});
|
|
12440
|
-
}
|
|
12441
|
-
function evaluateVerifyBoundary(capabilityKind, results) {
|
|
12442
|
-
if (capabilityKind !== "verify") {
|
|
12443
|
-
return pass("verify-does-not-fix", "capability is not verify", { capabilityKind });
|
|
12444
|
-
}
|
|
12445
|
-
const actionResults = results.filter(resultLooksLikeAction);
|
|
12446
|
-
if (actionResults.length === 0) {
|
|
12447
|
-
return pass("verify-does-not-fix", "verify capability returned verdict evidence without action output", {
|
|
12448
|
-
resultCount: results.length
|
|
12449
|
-
});
|
|
12450
|
-
}
|
|
12451
|
-
return fail2("verify-does-not-fix", "verify capability returned fix/change output", {
|
|
12452
|
-
resultCount: results.length,
|
|
12453
|
-
actionResults: actionResults.map(resultSummary)
|
|
12454
|
-
});
|
|
12455
|
-
}
|
|
12456
|
-
function evaluateGoalOwnershipBoundary(results) {
|
|
12457
|
-
const targetBearing = results.filter((result) => result.target?.type === "goal");
|
|
12458
|
-
if (targetBearing.length === 0) {
|
|
12459
|
-
return pass("capability-does-not-own-goal-progress", "capability output is parent-neutral", {
|
|
12460
|
-
resultCount: results.length
|
|
12461
|
-
});
|
|
12462
|
-
}
|
|
12463
|
-
return fail2("capability-does-not-own-goal-progress", "capability output names a goal target", {
|
|
12464
|
-
resultCount: results.length,
|
|
12465
|
-
targetBearingResults: targetBearing.map(resultSummary)
|
|
12466
|
-
});
|
|
12467
|
-
}
|
|
12468
|
-
function resultLooksLikeAction(result) {
|
|
12469
|
-
if (result.status === "changed") return true;
|
|
12470
|
-
return Object.keys(result.facts).some((key) => ACTION_FACT_KEYS.has(key));
|
|
12471
|
-
}
|
|
12472
|
-
function resultSummary(result) {
|
|
12473
|
-
return {
|
|
12474
|
-
status: result.status,
|
|
12475
|
-
summary: result.summary,
|
|
12476
|
-
target: result.target,
|
|
12477
|
-
actionFactKeys: Object.keys(result.facts).filter((key) => ACTION_FACT_KEYS.has(key))
|
|
12478
|
-
};
|
|
12421
|
+
// src/scripts/evaluateAgencyBoundaries.ts
|
|
12422
|
+
function shouldEvaluateAgencyBoundaries(data, profile) {
|
|
12423
|
+
return Boolean(agencyBoundaryCapabilityKind(data, profile));
|
|
12479
12424
|
}
|
|
12480
|
-
function
|
|
12481
|
-
|
|
12425
|
+
function agencyBoundaryCapability(data, profile) {
|
|
12426
|
+
if (typeof data.jobCapability === "string" && data.jobCapability.length > 0) return data.jobCapability;
|
|
12427
|
+
if (typeof data.capabilitySlug === "string" && data.capabilitySlug.length > 0) return data.capabilitySlug;
|
|
12428
|
+
return profile.name;
|
|
12482
12429
|
}
|
|
12483
|
-
function
|
|
12484
|
-
|
|
12430
|
+
function agencyBoundaryCapabilityKind(data, profile) {
|
|
12431
|
+
const fromJob = data.jobCapabilityKind;
|
|
12432
|
+
if (fromJob === "observe" || fromJob === "act" || fromJob === "verify") return fromJob;
|
|
12433
|
+
return profile.capabilityKind;
|
|
12485
12434
|
}
|
|
12486
|
-
var ACTION_FACT_KEYS;
|
|
12487
|
-
var init_agencyBoundaryEval = __esm({
|
|
12488
|
-
"src/agencyBoundaryEval.ts"() {
|
|
12489
|
-
"use strict";
|
|
12490
|
-
ACTION_FACT_KEYS = /* @__PURE__ */ new Set(["changedResources", "createdResources", "actionResult"]);
|
|
12491
|
-
}
|
|
12492
|
-
});
|
|
12493
|
-
|
|
12494
|
-
// src/scripts/evaluateAgencyBoundaries.ts
|
|
12495
12435
|
function collectResults2(raw, agentResult) {
|
|
12496
12436
|
const out = [];
|
|
12497
12437
|
if (Array.isArray(raw)) {
|
|
@@ -12511,9 +12451,11 @@ var init_evaluateAgencyBoundaries = __esm({
|
|
|
12511
12451
|
init_capabilityResult();
|
|
12512
12452
|
evaluateAgencyBoundariesScript = async (ctx, profile, agentResult) => {
|
|
12513
12453
|
const results = collectResults2(ctx.data.capabilityResults ?? ctx.data.dutyResults, agentResult);
|
|
12454
|
+
const capabilityKind = agencyBoundaryCapabilityKind(ctx.data, profile);
|
|
12455
|
+
const capability = agencyBoundaryCapability(ctx.data, profile);
|
|
12514
12456
|
const evalResult = evaluateAgencyBoundaries({
|
|
12515
|
-
capability
|
|
12516
|
-
capabilityKind
|
|
12457
|
+
capability,
|
|
12458
|
+
capabilityKind,
|
|
12517
12459
|
results
|
|
12518
12460
|
});
|
|
12519
12461
|
ctx.data.agencyBoundaryEval = evalResult;
|
|
@@ -19016,7 +18958,7 @@ async function runExecutable(profileName, input) {
|
|
|
19016
18958
|
}
|
|
19017
18959
|
});
|
|
19018
18960
|
}
|
|
19019
|
-
for (const entry of profile
|
|
18961
|
+
for (const entry of postflightEntriesForRun(profile, ctx)) {
|
|
19020
18962
|
const entryLabel = entry.script ?? entry.shell ?? "<unknown>";
|
|
19021
18963
|
if (shouldBlockMutatingPostflight(entry.script, ctx.output.exitCode)) {
|
|
19022
18964
|
if (entry.script === "commitAndPush" && ctx.data.commitResult === void 0) {
|
|
@@ -19144,6 +19086,30 @@ async function runExecutable(profileName, input) {
|
|
|
19144
19086
|
}
|
|
19145
19087
|
}
|
|
19146
19088
|
}
|
|
19089
|
+
function postflightEntriesForRun(profile, ctx) {
|
|
19090
|
+
const entries = profile.scripts.postflight;
|
|
19091
|
+
if (!shouldEvaluateAgencyBoundaries(ctx.data, profile)) return entries;
|
|
19092
|
+
if (entries.some((entry) => entry.script === "evaluateAgencyBoundaries")) return entries;
|
|
19093
|
+
const evalEntry = { script: "evaluateAgencyBoundaries" };
|
|
19094
|
+
const afterParser = lastIndexOfScript(entries, /* @__PURE__ */ new Set(["parseAgentResult", "parseJobStateFromAgentResult"]));
|
|
19095
|
+
if (afterParser >= 0) {
|
|
19096
|
+
return [...entries.slice(0, afterParser + 1), evalEntry, ...entries.slice(afterParser + 1)];
|
|
19097
|
+
}
|
|
19098
|
+
const beforeStateChange = entries.findIndex(
|
|
19099
|
+
(entry) => isMutatingPostflight(entry.script) || entry.script === "writeJobStateFile" || entry.script === "saveTaskState"
|
|
19100
|
+
);
|
|
19101
|
+
if (beforeStateChange >= 0) {
|
|
19102
|
+
return [...entries.slice(0, beforeStateChange), evalEntry, ...entries.slice(beforeStateChange)];
|
|
19103
|
+
}
|
|
19104
|
+
return [...entries, evalEntry];
|
|
19105
|
+
}
|
|
19106
|
+
function lastIndexOfScript(entries, names) {
|
|
19107
|
+
for (let i = entries.length - 1; i >= 0; i--) {
|
|
19108
|
+
const entry = entries[i];
|
|
19109
|
+
if (entry?.script && names.has(entry.script)) return i;
|
|
19110
|
+
}
|
|
19111
|
+
return -1;
|
|
19112
|
+
}
|
|
19147
19113
|
async function runExecutableChain(profileName, input) {
|
|
19148
19114
|
let result = await runExecutable(profileName, input);
|
|
19149
19115
|
let chainData = {
|
|
@@ -19528,6 +19494,7 @@ var init_executor = __esm({
|
|
|
19528
19494
|
init_scripts();
|
|
19529
19495
|
init_stateWorkspace();
|
|
19530
19496
|
init_subagents();
|
|
19497
|
+
init_evaluateAgencyBoundaries();
|
|
19531
19498
|
init_task_artifacts();
|
|
19532
19499
|
init_tools();
|
|
19533
19500
|
MUTATING_POSTFLIGHTS = /* @__PURE__ */ new Set([
|
|
@@ -19759,6 +19726,7 @@ async function runCapabilityImplementationStep(valid, profileName, capabilityIde
|
|
|
19759
19726
|
if (capabilityContext) {
|
|
19760
19727
|
preloadedData.capabilitySlug = capabilityContext.slug;
|
|
19761
19728
|
preloadedData.capabilityTitle = capabilityContext.title;
|
|
19729
|
+
if (capabilityContext.config.capabilityKind) preloadedData.jobCapabilityKind = capabilityContext.config.capabilityKind;
|
|
19762
19730
|
preloadedData.capabilityIntent = capabilityContext.body;
|
|
19763
19731
|
preloadedData.dutyIntent = capabilityContext.body;
|
|
19764
19732
|
preloadedData.jobIntent = capabilityContext.body;
|
|
@@ -19844,13 +19812,31 @@ async function runCapabilityWorkflow(parent, workflow, capability, base) {
|
|
|
19844
19812
|
...parsePrNumber5(prUrl) ? { workflowPrNumber: parsePrNumber5(prUrl) } : {}
|
|
19845
19813
|
};
|
|
19846
19814
|
if (result.exitCode !== 0 && !canContinueWorkflow(step, outcome)) {
|
|
19847
|
-
return {
|
|
19815
|
+
return withWorkflowBoundaryEval(capability, {
|
|
19848
19816
|
...result,
|
|
19849
19817
|
reason: result.reason ?? `workflow ${capability.slug} stopped at step ${index + 1}/${workflow.steps.length}: ${label}`
|
|
19850
|
-
};
|
|
19818
|
+
});
|
|
19851
19819
|
}
|
|
19852
19820
|
}
|
|
19853
|
-
return result;
|
|
19821
|
+
return withWorkflowBoundaryEval(capability, result);
|
|
19822
|
+
}
|
|
19823
|
+
function withWorkflowBoundaryEval(capability, result) {
|
|
19824
|
+
const capabilityKind = capability.config.capabilityKind;
|
|
19825
|
+
if (!capabilityKind) return result;
|
|
19826
|
+
const evalResult = evaluateAgencyBoundaries({
|
|
19827
|
+
capability: capability.slug,
|
|
19828
|
+
capabilityKind,
|
|
19829
|
+
results: []
|
|
19830
|
+
});
|
|
19831
|
+
process.stdout.write(`KODY_AGENCY_BOUNDARY_EVAL=${JSON.stringify(evalResult)}
|
|
19832
|
+
`);
|
|
19833
|
+
if (evalResult.status !== "fail" || result.exitCode !== 0) return result;
|
|
19834
|
+
const failed = evalResult.findings.filter((finding) => finding.status === "fail").map((finding) => finding.rule);
|
|
19835
|
+
return {
|
|
19836
|
+
...result,
|
|
19837
|
+
exitCode: 99,
|
|
19838
|
+
reason: result.reason ? `${result.reason}; agency boundary eval failed: ${failed.join(", ")}` : `agency boundary eval failed: ${failed.join(", ")}`
|
|
19839
|
+
};
|
|
19854
19840
|
}
|
|
19855
19841
|
function workflowStepToJob(step, parent, chainData) {
|
|
19856
19842
|
const action = step.action ?? step.capability;
|
|
@@ -19992,6 +19978,7 @@ var DEFAULT_INSTANT_AGENT, localJobSeq, InvalidJobError;
|
|
|
19992
19978
|
var init_job = __esm({
|
|
19993
19979
|
"src/job.ts"() {
|
|
19994
19980
|
"use strict";
|
|
19981
|
+
init_agencyBoundaryEval();
|
|
19995
19982
|
init_executor();
|
|
19996
19983
|
init_registry();
|
|
19997
19984
|
init_workflowDefinitions();
|
|
@@ -21363,6 +21350,7 @@ function readRunRequestFromEnv(env = process.env) {
|
|
|
21363
21350
|
// src/kody-cli.ts
|
|
21364
21351
|
init_runtimePaths();
|
|
21365
21352
|
init_stateWorkspace();
|
|
21353
|
+
init_workflowDefinitions();
|
|
21366
21354
|
var FAILED_DISPATCH_LABEL = {
|
|
21367
21355
|
label: "kody:failed",
|
|
21368
21356
|
color: "e11d21",
|
|
@@ -21728,7 +21716,11 @@ async function runCi(argv) {
|
|
|
21728
21716
|
const config = earlyConfig ?? loadConfig(cwd);
|
|
21729
21717
|
const manualGoalManager = forceRunAction === "goal-manager";
|
|
21730
21718
|
const capabilityRoute = manualGoalManager ? null : resolveCapabilityAction(forceRunAction);
|
|
21731
|
-
const
|
|
21719
|
+
const workflowRoute = manualGoalManager || capabilityRoute || !readWorkflowDefinition(config, cwd, forceRunAction) ? void 0 : {
|
|
21720
|
+
workflow: forceRunAction,
|
|
21721
|
+
cliArgs: {}
|
|
21722
|
+
};
|
|
21723
|
+
const scheduledWatchRoute = manualGoalManager || capabilityRoute || workflowRoute ? void 0 : dispatchScheduledWatches({ force: true }).find(
|
|
21732
21724
|
(match) => match.action === forceRunAction || match.executable === forceRunAction
|
|
21733
21725
|
);
|
|
21734
21726
|
const route = manualGoalManager ? {
|
|
@@ -21736,9 +21728,9 @@ async function runCi(argv) {
|
|
|
21736
21728
|
capability: "goal-manager",
|
|
21737
21729
|
executable: "goal-manager",
|
|
21738
21730
|
cliArgs: forceRunCliArgs
|
|
21739
|
-
} : capabilityRoute ?? scheduledWatchRoute;
|
|
21731
|
+
} : capabilityRoute ?? workflowRoute ?? scheduledWatchRoute;
|
|
21740
21732
|
if (!route) {
|
|
21741
|
-
process.stderr.write(`[kody] manual one-shot action '${forceRunAction}' has no capability action
|
|
21733
|
+
process.stderr.write(`[kody] manual one-shot action '${forceRunAction}' has no capability action or workflow
|
|
21742
21734
|
`);
|
|
21743
21735
|
return 64;
|
|
21744
21736
|
}
|
|
@@ -21746,9 +21738,11 @@ async function runCi(argv) {
|
|
|
21746
21738
|
process.stderr.write("[kody] manual goal-manager run requires message goal id\n");
|
|
21747
21739
|
return 64;
|
|
21748
21740
|
}
|
|
21749
|
-
process.stdout.write(
|
|
21741
|
+
process.stdout.write(
|
|
21742
|
+
`\u2192 kody: manual one-shot run ${route.workflow ? `workflow ${route.workflow}` : `action ${route.action} (${route.capability})`}
|
|
21750
21743
|
|
|
21751
|
-
`
|
|
21744
|
+
`
|
|
21745
|
+
);
|
|
21752
21746
|
try {
|
|
21753
21747
|
const n = unpackAllSecrets();
|
|
21754
21748
|
if (n > 0) process.stdout.write(`\u2192 kody: unpacked ${n} secret(s)
|
|
@@ -21781,6 +21775,7 @@ async function runCi(argv) {
|
|
|
21781
21775
|
{
|
|
21782
21776
|
action: route.action,
|
|
21783
21777
|
capability: route.capability,
|
|
21778
|
+
workflow: route.workflow,
|
|
21784
21779
|
executable: route.executable,
|
|
21785
21780
|
cliArgs: { ...route.cliArgs, ...forceRunCliArgs },
|
|
21786
21781
|
flavor: "instant",
|
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.317",
|
|
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",
|