@kody-ade/kody-engine 0.4.352 → 0.4.354
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 +114 -36
- package/dist/implementations/types.ts +4 -1
- 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.354",
|
|
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",
|
|
@@ -2436,6 +2436,53 @@ var init_registry = __esm({
|
|
|
2436
2436
|
}
|
|
2437
2437
|
});
|
|
2438
2438
|
|
|
2439
|
+
// src/trustPolicy.ts
|
|
2440
|
+
function trustSubjectKey(subject) {
|
|
2441
|
+
return `${subject.kind}:${subject.id}`;
|
|
2442
|
+
}
|
|
2443
|
+
function parseTrustMode(rawJson, subject) {
|
|
2444
|
+
return parseTrustModeOverride(rawJson, subject) ?? "ask";
|
|
2445
|
+
}
|
|
2446
|
+
function parseTrustModeOverride(rawJson, subject) {
|
|
2447
|
+
const key = trustSubjectKey(subject);
|
|
2448
|
+
try {
|
|
2449
|
+
const parsed = JSON.parse(rawJson);
|
|
2450
|
+
const rawMode = subject.kind === "capability" ? parsed?.capabilities?.[subject.id]?.mode : parsed?.subjects?.[key]?.mode;
|
|
2451
|
+
if (rawMode === "auto" || rawMode === "ask") return rawMode;
|
|
2452
|
+
return null;
|
|
2453
|
+
} catch {
|
|
2454
|
+
return null;
|
|
2455
|
+
}
|
|
2456
|
+
}
|
|
2457
|
+
function readTrustMode(stateOrRepoSlug, repoSlugOrSubject, maybeSubject) {
|
|
2458
|
+
const mode = typeof stateOrRepoSlug === "string" ? readTrustModeOverride(stateOrRepoSlug, repoSlugOrSubject) : readTrustModeOverride(stateOrRepoSlug, repoSlugOrSubject, maybeSubject);
|
|
2459
|
+
return mode ?? "ask";
|
|
2460
|
+
}
|
|
2461
|
+
function readTrustModeOverride(stateOrRepoSlug, repoSlugOrSubject, maybeSubject) {
|
|
2462
|
+
const state = typeof stateOrRepoSlug === "string" ? void 0 : stateOrRepoSlug;
|
|
2463
|
+
const repoSlug = typeof stateOrRepoSlug === "string" ? stateOrRepoSlug : typeof repoSlugOrSubject === "string" ? repoSlugOrSubject : "";
|
|
2464
|
+
const subject = typeof stateOrRepoSlug === "string" ? repoSlugOrSubject : maybeSubject;
|
|
2465
|
+
if (!subject?.id) return null;
|
|
2466
|
+
try {
|
|
2467
|
+
const loaded = readStateText({ state: state ?? defaultStateForRepoSlug(repoSlug) }, void 0, TRUST_FILE_PATH);
|
|
2468
|
+
return loaded ? parseTrustModeOverride(loaded.content, subject) : null;
|
|
2469
|
+
} catch {
|
|
2470
|
+
return null;
|
|
2471
|
+
}
|
|
2472
|
+
}
|
|
2473
|
+
function defaultStateForRepoSlug(repoSlug) {
|
|
2474
|
+
const [owner, repo] = repoSlug.split("/");
|
|
2475
|
+
return { repo: `${owner}/kody-state`, path: repo ?? repoSlug };
|
|
2476
|
+
}
|
|
2477
|
+
var TRUST_FILE_PATH;
|
|
2478
|
+
var init_trustPolicy = __esm({
|
|
2479
|
+
"src/trustPolicy.ts"() {
|
|
2480
|
+
"use strict";
|
|
2481
|
+
init_stateRepo();
|
|
2482
|
+
TRUST_FILE_PATH = "state/trust.json";
|
|
2483
|
+
}
|
|
2484
|
+
});
|
|
2485
|
+
|
|
2439
2486
|
// src/capabilityMcp.ts
|
|
2440
2487
|
var capabilityMcp_exports = {};
|
|
2441
2488
|
__export(capabilityMcp_exports, {
|
|
@@ -2581,28 +2628,14 @@ function readLedger(label) {
|
|
|
2581
2628
|
}
|
|
2582
2629
|
}
|
|
2583
2630
|
function parseCapabilityTrustMode(rawJson, capabilitySlug) {
|
|
2584
|
-
|
|
2585
|
-
const parsed = JSON.parse(rawJson);
|
|
2586
|
-
return parsed?.capabilities?.[capabilitySlug]?.mode === "auto" ? "auto" : "ask";
|
|
2587
|
-
} catch {
|
|
2588
|
-
return "ask";
|
|
2589
|
-
}
|
|
2590
|
-
}
|
|
2591
|
-
function defaultStateForRepoSlug(repoSlug) {
|
|
2592
|
-
const [owner, repo] = repoSlug.split("/");
|
|
2593
|
-
return { repo: `${owner}/kody-state`, path: repo ?? repoSlug };
|
|
2631
|
+
return parseTrustMode(rawJson, { kind: "capability", id: capabilitySlug });
|
|
2594
2632
|
}
|
|
2595
2633
|
function readCapabilityTrustMode(stateOrRepoSlug, repoSlugOrCapabilitySlug, maybeCapabilitySlug) {
|
|
2596
2634
|
const state = typeof stateOrRepoSlug === "string" ? void 0 : stateOrRepoSlug;
|
|
2597
2635
|
const repoSlug = typeof stateOrRepoSlug === "string" ? stateOrRepoSlug : repoSlugOrCapabilitySlug ?? "";
|
|
2598
2636
|
const capabilitySlug = typeof stateOrRepoSlug === "string" ? repoSlugOrCapabilitySlug : maybeCapabilitySlug;
|
|
2599
2637
|
if (!capabilitySlug) return "ask";
|
|
2600
|
-
|
|
2601
|
-
const loaded = readStateText({ state: state ?? defaultStateForRepoSlug(repoSlug) }, void 0, TRUST_FILE_PATH);
|
|
2602
|
-
return loaded ? parseCapabilityTrustMode(loaded.content, capabilitySlug) : "ask";
|
|
2603
|
-
} catch {
|
|
2604
|
-
return "ask";
|
|
2605
|
-
}
|
|
2638
|
+
return readTrustMode(state, repoSlug, { kind: "capability", id: capabilitySlug });
|
|
2606
2639
|
}
|
|
2607
2640
|
function readThread(repoSlug, number, limit = 10) {
|
|
2608
2641
|
const meta = JSON.parse(gh(["api", `repos/${repoSlug}/issues/${number}`]));
|
|
@@ -2932,17 +2965,16 @@ function buildCapabilityMcpServer(opts) {
|
|
|
2932
2965
|
});
|
|
2933
2966
|
return { server };
|
|
2934
2967
|
}
|
|
2935
|
-
var FAIL_CONCLUSIONS, RUNNING_STATUSES,
|
|
2968
|
+
var FAIL_CONCLUSIONS, RUNNING_STATUSES, THREAD_BODY_MAX, CHECK_FAIL_CONCLUSIONS, DEFAULT_IGNORE_CHECKS, trackMarker, commentMarker, GATE_EXEMPT_CAPABILITIES, CAPABILITY_MCP_TOOL_NAMES;
|
|
2936
2969
|
var init_capabilityMcp = __esm({
|
|
2937
2970
|
"src/capabilityMcp.ts"() {
|
|
2938
2971
|
"use strict";
|
|
2939
2972
|
init_dashboardCmsMcp();
|
|
2940
2973
|
init_issue();
|
|
2941
2974
|
init_registry();
|
|
2942
|
-
|
|
2975
|
+
init_trustPolicy();
|
|
2943
2976
|
FAIL_CONCLUSIONS = /* @__PURE__ */ new Set(["FAILURE", "TIMED_OUT", "ACTION_REQUIRED", "STARTUP_FAILURE", "CANCELLED"]);
|
|
2944
2977
|
RUNNING_STATUSES = /* @__PURE__ */ new Set(["IN_PROGRESS", "QUEUED", "PENDING", "WAITING", "REQUESTED"]);
|
|
2945
|
-
TRUST_FILE_PATH = "state/trust.json";
|
|
2946
2978
|
THREAD_BODY_MAX = 4e3;
|
|
2947
2979
|
CHECK_FAIL_CONCLUSIONS = /* @__PURE__ */ new Set(["FAILURE", "TIMED_OUT", "STARTUP_FAILURE", "ACTION_REQUIRED"]);
|
|
2948
2980
|
DEFAULT_IGNORE_CHECKS = ["run", "kody", "capability-tick", "agent-ask", "chat"];
|
|
@@ -9335,14 +9367,16 @@ function scalarFacts(facts) {
|
|
|
9335
9367
|
)
|
|
9336
9368
|
);
|
|
9337
9369
|
}
|
|
9338
|
-
function autonomyBlockReason(ctx, goalId, goal, dispatch2) {
|
|
9370
|
+
function autonomyBlockReason(ctx, goalId, goal, goalState, dispatch2) {
|
|
9339
9371
|
if (ctx.data.jobForce === true) return null;
|
|
9340
|
-
|
|
9372
|
+
const selfMode = firstTrustOverride(ctx, subjectCandidates(managedModelSubjectKind(goal), goalId, goalState));
|
|
9373
|
+
if (selfMode === "ask" || selfMode !== "auto" && goal.runWithoutApproval !== true) {
|
|
9341
9374
|
return `Run without approval is off for ${managedModelKind(goal)} ${goalId}`;
|
|
9342
9375
|
}
|
|
9343
9376
|
if (dispatch2.workflow) {
|
|
9344
|
-
const
|
|
9345
|
-
|
|
9377
|
+
const workflowMode = firstTrustOverride(ctx, [{ kind: "workflow", id: dispatch2.workflow }]);
|
|
9378
|
+
const workflow = workflowMode === "auto" ? null : readWorkflowDefinition(ctx.config, ctx.cwd, dispatch2.workflow);
|
|
9379
|
+
if (workflowMode === "ask" || workflowMode !== "auto" && workflow && workflow.runWithoutApproval !== true) {
|
|
9346
9380
|
return `Run without approval is off for workflow ${dispatch2.workflow}`;
|
|
9347
9381
|
}
|
|
9348
9382
|
}
|
|
@@ -9350,7 +9384,8 @@ function autonomyBlockReason(ctx, goalId, goal, dispatch2) {
|
|
|
9350
9384
|
if (targetGoal && targetGoal !== goalId) {
|
|
9351
9385
|
const target = fetchGoalState(ctx.config, targetGoal, ctx.cwd);
|
|
9352
9386
|
const targetManaged = target ? managedGoalFromState(expandManagedGoalState(target)) : null;
|
|
9353
|
-
|
|
9387
|
+
const targetMode = targetManaged ? firstTrustOverride(ctx, subjectCandidates(managedModelSubjectKind(targetManaged), targetGoal, target)) : null;
|
|
9388
|
+
if (targetMode === "ask" || targetMode !== "auto" && targetManaged && targetManaged.runWithoutApproval !== true) {
|
|
9354
9389
|
return `Run without approval is off for goal ${targetGoal}`;
|
|
9355
9390
|
}
|
|
9356
9391
|
}
|
|
@@ -9359,6 +9394,29 @@ function autonomyBlockReason(ctx, goalId, goal, dispatch2) {
|
|
|
9359
9394
|
function managedModelKind(goal) {
|
|
9360
9395
|
return goal.loopTarget || goal.schedule ? "Loop" : "Goal";
|
|
9361
9396
|
}
|
|
9397
|
+
function managedModelSubjectKind(goal) {
|
|
9398
|
+
return managedModelKind(goal) === "Loop" ? "loop" : "goal";
|
|
9399
|
+
}
|
|
9400
|
+
function subjectCandidates(kind, id, state) {
|
|
9401
|
+
const ids = /* @__PURE__ */ new Set();
|
|
9402
|
+
ids.add(id);
|
|
9403
|
+
if (state?.extra) {
|
|
9404
|
+
for (const key of ["sourceTemplate", "templateId", "template"]) {
|
|
9405
|
+
const value = state.extra[key];
|
|
9406
|
+
if (typeof value === "string" && value.trim()) ids.add(value.trim());
|
|
9407
|
+
}
|
|
9408
|
+
}
|
|
9409
|
+
return [...ids].map((candidate) => ({ kind, id: candidate }));
|
|
9410
|
+
}
|
|
9411
|
+
function firstTrustOverride(ctx, subjects) {
|
|
9412
|
+
if (!ctx.config.state) return null;
|
|
9413
|
+
const repoSlug = ctx.config.github?.owner && ctx.config.github?.repo ? `${ctx.config.github.owner}/${ctx.config.github.repo}` : "";
|
|
9414
|
+
for (const subject of subjects) {
|
|
9415
|
+
const mode = readTrustModeOverride(ctx.config.state, repoSlug, subject);
|
|
9416
|
+
if (mode) return mode;
|
|
9417
|
+
}
|
|
9418
|
+
return null;
|
|
9419
|
+
}
|
|
9362
9420
|
function stageAutonomyBlocked(data, goalId, goal, goalState, reason) {
|
|
9363
9421
|
stageGoalRunLogEvent(data, goalId, {
|
|
9364
9422
|
source: "goal-manager",
|
|
@@ -9550,6 +9608,7 @@ var init_advanceManagedGoal = __esm({
|
|
|
9550
9608
|
init_targetLoopResolution();
|
|
9551
9609
|
init_typeDefinitions();
|
|
9552
9610
|
init_issue();
|
|
9611
|
+
init_trustPolicy();
|
|
9553
9612
|
init_workflowDefinitions();
|
|
9554
9613
|
init_goalCapabilityScheduling();
|
|
9555
9614
|
advanceManagedGoal = async (ctx) => {
|
|
@@ -9645,7 +9704,7 @@ var init_advanceManagedGoal = __esm({
|
|
|
9645
9704
|
goal.raw = writeManagedGoalToState({ ...goal.raw, state: goal.state }, managed);
|
|
9646
9705
|
goal.raw.extra.scheduleState = decision2.scheduleState;
|
|
9647
9706
|
ctx.data.managedGoalDecision = decision2;
|
|
9648
|
-
const autonomyBlock = decision2.kind === "dispatch" && decision2.dispatch ? autonomyBlockReason(ctx, goal.id, managed, decision2.dispatch) : null;
|
|
9707
|
+
const autonomyBlock = decision2.kind === "dispatch" && decision2.dispatch ? autonomyBlockReason(ctx, goal.id, managed, goal.raw, decision2.dispatch) : null;
|
|
9649
9708
|
if (autonomyBlock) {
|
|
9650
9709
|
stageAutonomyBlocked(ctx.data, goal.id, managed, goal.state, autonomyBlock);
|
|
9651
9710
|
ctx.output.reason = autonomyBlock;
|
|
@@ -9707,7 +9766,7 @@ var init_advanceManagedGoal = __esm({
|
|
|
9707
9766
|
goal.raw = writeManagedGoalToState({ ...goal.raw, state: goal.state }, managed);
|
|
9708
9767
|
goal.raw.extra.scheduleState = decision2.scheduleState;
|
|
9709
9768
|
ctx.data.managedGoalDecision = decision2;
|
|
9710
|
-
const autonomyBlock = decision2.kind === "dispatch" && decision2.dispatch ? autonomyBlockReason(ctx, goal.id, managed, decision2.dispatch) : null;
|
|
9769
|
+
const autonomyBlock = decision2.kind === "dispatch" && decision2.dispatch ? autonomyBlockReason(ctx, goal.id, managed, goal.raw, decision2.dispatch) : null;
|
|
9711
9770
|
if (autonomyBlock) {
|
|
9712
9771
|
stageAutonomyBlocked(ctx.data, goal.id, managed, goal.state, autonomyBlock);
|
|
9713
9772
|
ctx.output.reason = autonomyBlock;
|
|
@@ -9772,7 +9831,7 @@ var init_advanceManagedGoal = __esm({
|
|
|
9772
9831
|
...decision.implementation ? { implementation: decision.implementation } : {},
|
|
9773
9832
|
cliArgs: decision.cliArgs
|
|
9774
9833
|
};
|
|
9775
|
-
const autonomyBlock = autonomyBlockReason(ctx, goal.id, managed, planned);
|
|
9834
|
+
const autonomyBlock = autonomyBlockReason(ctx, goal.id, managed, goal.raw, planned);
|
|
9776
9835
|
if (autonomyBlock) {
|
|
9777
9836
|
stageAutonomyBlocked(ctx.data, goal.id, managed, goal.state, autonomyBlock);
|
|
9778
9837
|
ctx.output.reason = autonomyBlock;
|
|
@@ -9800,8 +9859,9 @@ var init_advanceManagedGoal = __esm({
|
|
|
9800
9859
|
workflow: decision.workflow,
|
|
9801
9860
|
cliArgs: decision.cliArgs,
|
|
9802
9861
|
workflowFacts: scalarFacts(managed.facts),
|
|
9862
|
+
evidence: decision.evidence,
|
|
9803
9863
|
...decision.saveReport === true ? { saveReport: true } : {},
|
|
9804
|
-
resultTarget: { type: "goal", id: goal.id
|
|
9864
|
+
resultTarget: { type: "goal", id: goal.id }
|
|
9805
9865
|
};
|
|
9806
9866
|
ctx.output.reason = `dispatch workflow ${decision.workflow} for ${decision.evidence}`;
|
|
9807
9867
|
return;
|
|
@@ -9809,9 +9869,10 @@ var init_advanceManagedGoal = __esm({
|
|
|
9809
9869
|
ctx.output.nextDispatch = {
|
|
9810
9870
|
capability: decision.capability,
|
|
9811
9871
|
cliArgs: decision.cliArgs,
|
|
9872
|
+
evidence: decision.evidence,
|
|
9812
9873
|
...decision.implementation ? { implementation: decision.implementation } : {},
|
|
9813
9874
|
...decision.saveReport === true ? { saveReport: true } : {},
|
|
9814
|
-
resultTarget: { type: "goal", id: goal.id
|
|
9875
|
+
resultTarget: { type: "goal", id: goal.id }
|
|
9815
9876
|
};
|
|
9816
9877
|
ctx.output.reason = `dispatch ${decision.capability} for ${decision.evidence}`;
|
|
9817
9878
|
};
|
|
@@ -10950,6 +11011,12 @@ function parseResultTarget(raw) {
|
|
|
10950
11011
|
...evidence ? { evidence } : {}
|
|
10951
11012
|
};
|
|
10952
11013
|
}
|
|
11014
|
+
function parseEvidenceContext(raw) {
|
|
11015
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
|
|
11016
|
+
const context = raw;
|
|
11017
|
+
const evidence = typeof context.evidence === "string" && context.evidence.trim().length > 0 ? context.evidence.trim() : void 0;
|
|
11018
|
+
return evidence ? { evidence } : null;
|
|
11019
|
+
}
|
|
10953
11020
|
function collectGoalCapabilityEvidence(reports, results, fallbackGoalId, explicitEvidence) {
|
|
10954
11021
|
const items = [];
|
|
10955
11022
|
for (const report of reports) {
|
|
@@ -11054,8 +11121,9 @@ var init_applyCapabilityReports = __esm({
|
|
|
11054
11121
|
const reports = collectReports(ctx.data.capabilityReports, agentResult);
|
|
11055
11122
|
const results = collectResults2(ctx.data.capabilityResults, agentResult);
|
|
11056
11123
|
const resultTarget = parseResultTarget(ctx.data.capabilityResultTarget);
|
|
11124
|
+
const evidenceContext = parseEvidenceContext(ctx.data.capabilityEvidence);
|
|
11057
11125
|
const resultGoalId = resultTarget?.id ?? (typeof ctx.args.goal === "string" && ctx.args.goal.length > 0 ? ctx.args.goal : null);
|
|
11058
|
-
const explicitEvidence = resultTarget?.evidence ?? (typeof ctx.args.evidence === "string" && ctx.args.evidence.length > 0 ? ctx.args.evidence : void 0);
|
|
11126
|
+
const explicitEvidence = evidenceContext?.evidence ?? resultTarget?.evidence ?? (typeof ctx.args.evidence === "string" && ctx.args.evidence.length > 0 ? ctx.args.evidence : void 0);
|
|
11059
11127
|
const evidenceItems = collectGoalCapabilityEvidence(reports, results, resultGoalId, explicitEvidence);
|
|
11060
11128
|
if (evidenceItems.length === 0) return;
|
|
11061
11129
|
const evidenceByGoal = groupGoalEvidence(evidenceItems);
|
|
@@ -20483,6 +20551,7 @@ function handoffToJob(handoff) {
|
|
|
20483
20551
|
implementation: handoff.implementation,
|
|
20484
20552
|
cliArgs: handoff.cliArgs,
|
|
20485
20553
|
workflowFacts: handoff.workflowFacts,
|
|
20554
|
+
evidence: handoff.evidence,
|
|
20486
20555
|
flavor: "instant",
|
|
20487
20556
|
saveReport: handoff.saveReport === true,
|
|
20488
20557
|
resultTarget: handoff.resultTarget
|
|
@@ -20828,6 +20897,7 @@ function validateJob(input) {
|
|
|
20828
20897
|
target: typeof j.target === "number" ? j.target : void 0,
|
|
20829
20898
|
cliArgs: j.cliArgs ?? {},
|
|
20830
20899
|
workflowFacts: j.workflowFacts && typeof j.workflowFacts === "object" && !Array.isArray(j.workflowFacts) ? j.workflowFacts : void 0,
|
|
20900
|
+
evidence: parseJobEvidence(j),
|
|
20831
20901
|
flavor: j.flavor,
|
|
20832
20902
|
force: j.force === true,
|
|
20833
20903
|
saveReport: j.saveReport === true,
|
|
@@ -20839,13 +20909,18 @@ function parseCapabilityResultTarget(raw) {
|
|
|
20839
20909
|
const target = raw;
|
|
20840
20910
|
if (target.type !== "goal") return void 0;
|
|
20841
20911
|
if (typeof target.id !== "string" || target.id.trim().length === 0) return void 0;
|
|
20842
|
-
const evidence = typeof target.evidence === "string" && target.evidence.trim().length > 0 ? target.evidence.trim() : void 0;
|
|
20843
20912
|
return {
|
|
20844
20913
|
type: "goal",
|
|
20845
|
-
id: target.id.trim()
|
|
20846
|
-
...evidence ? { evidence } : {}
|
|
20914
|
+
id: target.id.trim()
|
|
20847
20915
|
};
|
|
20848
20916
|
}
|
|
20917
|
+
function parseJobEvidence(job) {
|
|
20918
|
+
if (typeof job.evidence === "string" && job.evidence.trim().length > 0) return job.evidence.trim();
|
|
20919
|
+
const target = job.resultTarget;
|
|
20920
|
+
if (!target || typeof target !== "object" || Array.isArray(target)) return void 0;
|
|
20921
|
+
const evidence = target.evidence;
|
|
20922
|
+
return typeof evidence === "string" && evidence.trim().length > 0 ? evidence.trim() : void 0;
|
|
20923
|
+
}
|
|
20849
20924
|
async function runJob(job, base) {
|
|
20850
20925
|
const valid = validateJob(job);
|
|
20851
20926
|
const action = valid.action ?? valid.capability;
|
|
@@ -20905,6 +20980,7 @@ async function runCapabilityImplementationStep(valid, profileName, capabilityIde
|
|
|
20905
20980
|
if (valid.schedule !== void 0 && valid.schedule.length > 0) preloadedData.jobSchedule = valid.schedule;
|
|
20906
20981
|
if (valid.saveReport === true) preloadedData.jobSaveReport = true;
|
|
20907
20982
|
if (valid.force === true) preloadedData.jobForce = true;
|
|
20983
|
+
if (valid.evidence) preloadedData.capabilityEvidence = { evidence: valid.evidence };
|
|
20908
20984
|
if (valid.resultTarget) preloadedData.capabilityResultTarget = valid.resultTarget;
|
|
20909
20985
|
if (capabilityContext) {
|
|
20910
20986
|
preloadedData.capabilitySlug = capabilityContext.slug;
|
|
@@ -20964,7 +21040,7 @@ async function runCapabilityWorkflow(parent, workflow, capability, base) {
|
|
|
20964
21040
|
]
|
|
20965
21041
|
};
|
|
20966
21042
|
let result = { exitCode: 0 };
|
|
20967
|
-
const startIndex = workflowResumeStartIndex(workflow.steps, parent.
|
|
21043
|
+
const startIndex = workflowResumeStartIndex(workflow.steps, parent.evidence);
|
|
20968
21044
|
for (let index = startIndex; index < workflow.steps.length; index++) {
|
|
20969
21045
|
const step = workflow.steps[index];
|
|
20970
21046
|
const label = step.action ?? step.capability;
|
|
@@ -21054,9 +21130,11 @@ function workflowStepToJob(step, parent, chainData) {
|
|
|
21054
21130
|
...parent.schedule ? { schedule: parent.schedule } : {},
|
|
21055
21131
|
...typeof target === "number" ? { target } : {},
|
|
21056
21132
|
cliArgs,
|
|
21133
|
+
...step.evidence ? { evidence: step.evidence } : parent.evidence ? { evidence: parent.evidence } : {},
|
|
21057
21134
|
flavor: parent.flavor,
|
|
21058
21135
|
force: parent.force,
|
|
21059
|
-
saveReport: step.saveReport === true || parent.saveReport === true
|
|
21136
|
+
saveReport: step.saveReport === true || parent.saveReport === true,
|
|
21137
|
+
...parent.resultTarget ? { resultTarget: parent.resultTarget } : {}
|
|
21060
21138
|
};
|
|
21061
21139
|
}
|
|
21062
21140
|
function shouldRunWorkflowStep(step, data) {
|
|
@@ -401,7 +401,6 @@ export interface OutputContract {
|
|
|
401
401
|
export interface CapabilityResultTarget {
|
|
402
402
|
type: "goal"
|
|
403
403
|
id: string
|
|
404
|
-
evidence?: string
|
|
405
404
|
}
|
|
406
405
|
|
|
407
406
|
// ────────────────────────────────────────────────────────────────────────────
|
|
@@ -439,6 +438,7 @@ export interface Context {
|
|
|
439
438
|
implementation?: string
|
|
440
439
|
cliArgs: Record<string, unknown>
|
|
441
440
|
workflowFacts?: Record<string, unknown>
|
|
441
|
+
evidence?: string
|
|
442
442
|
saveReport?: boolean
|
|
443
443
|
resultTarget?: CapabilityResultTarget
|
|
444
444
|
}
|
|
@@ -452,6 +452,7 @@ export interface Context {
|
|
|
452
452
|
implementation?: string
|
|
453
453
|
cliArgs: Record<string, unknown>
|
|
454
454
|
workflowFacts?: Record<string, unknown>
|
|
455
|
+
evidence?: string
|
|
455
456
|
saveReport?: boolean
|
|
456
457
|
resultTarget?: CapabilityResultTarget
|
|
457
458
|
}
|
|
@@ -521,6 +522,8 @@ export interface Job {
|
|
|
521
522
|
cliArgs: Record<string, unknown>
|
|
522
523
|
/** Internal workflow resume context. Not passed to capability CLI args. */
|
|
523
524
|
workflowFacts?: Record<string, unknown>
|
|
525
|
+
/** Evidence this capability run is expected to report, independent of who consumes it. */
|
|
526
|
+
evidence?: string
|
|
524
527
|
/** Run once now ("instant") or on the schedule ("scheduled"). */
|
|
525
528
|
flavor: JobFlavor
|
|
526
529
|
/** Manual force-run (bypass cadence) for a scheduled job. */
|
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.354",
|
|
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",
|