@kody-ade/kody-engine 0.4.353 → 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 +87 -28
- 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;
|
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",
|