@kody-ade/kody-engine 0.4.355 → 0.4.357

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.
Files changed (2) hide show
  1. package/dist/bin/kody.js +26 -28
  2. 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.355",
18
+ version: "0.4.357",
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",
@@ -2757,17 +2757,12 @@ function readDispatchTargetKind(repoSlug, issueNumber) {
2757
2757
  }
2758
2758
  }
2759
2759
  function isDispatchGated(capability, mode) {
2760
- if (mode === "auto") return false;
2761
- if (capability && GATE_EXEMPT_CAPABILITIES.has(capability)) return false;
2762
- return true;
2763
- }
2764
- function trustRefusal(capabilitySlug) {
2765
- return `Not dispatched: capability \`${capabilitySlug ?? "?"}\` is in ASK mode (not trusted for autonomy). Do NOT retry the dispatch. Instead notify the operator (use recommend_to_operator, or rely on the tracking issue that already @-mentions them), then submit_state. To let this capability act on its own, grant it Auto on the dashboard Trust page.`;
2760
+ void capability;
2761
+ void mode;
2762
+ return false;
2766
2763
  }
2767
2764
  function assertCmsWriteAllowed(opts) {
2768
- if (isDispatchGated(opts.capabilitySlug, readCapabilityTrustMode(opts.state, opts.repoSlug, opts.capabilitySlug))) {
2769
- return trustRefusal(opts.capabilitySlug);
2770
- }
2765
+ void opts;
2771
2766
  return null;
2772
2767
  }
2773
2768
  function capabilityToolDefinitions(opts) {
@@ -2796,9 +2791,6 @@ function capabilityToolDefinitions(opts) {
2796
2791
  },
2797
2792
  handler: async (args) => {
2798
2793
  const pr = Number(args.pr);
2799
- if (isDispatchGated(verb, readCapabilityTrustMode(opts.state, opts.repoSlug, opts.capabilitySlug))) {
2800
- return { content: [{ type: "text", text: trustRefusal(opts.capabilitySlug) }] };
2801
- }
2802
2794
  const result = dispatchVerb(workflowFile, opts.repoSlug, verb, pr);
2803
2795
  const text = result.ok ? `Dispatched \`${verb}\` on PR #${pr}. The repair runs in its own workflow_dispatch \u2014 wait for the next tick to see the new headSha.` : `Dispatch failed for \`${verb}\` on PR #${pr}: ${result.error}`;
2804
2796
  return { content: [{ type: "text", text }] };
@@ -2818,7 +2810,7 @@ function capabilityToolDefinitions(opts) {
2818
2810
  );
2819
2811
  const recommendTool = {
2820
2812
  name: "recommend_to_operator",
2821
- description: "Post ONE comment on a PR with the operator @-mention prepended. Use this when a capability is in ASK mode and you want the operator to confirm via the dashboard inbox. The mention handle is substituted from kody.config.json `github.operators` \u2014 do not type it yourself.",
2813
+ description: "Post ONE comment on a PR with the operator @-mention prepended. Use this when the operator should confirm or review something via the dashboard inbox. The mention handle is substituted from kody.config.json `github.operators` \u2014 do not type it yourself.",
2822
2814
  inputSchema: {
2823
2815
  pr: z3.number().int().positive().describe("PR number to comment on."),
2824
2816
  body: z3.string().min(1).describe("Comment body (markdown). Do not include the operator mention \u2014 the engine prepends it.")
@@ -2921,9 +2913,6 @@ function capabilityToolDefinitions(opts) {
2921
2913
  if (!Number.isFinite(issue) || issue <= 0) {
2922
2914
  return { content: [{ type: "text", text: "Start failed: `issue` is required and must be a positive number." }] };
2923
2915
  }
2924
- if (isDispatchGated(name, readCapabilityTrustMode(opts.state, opts.repoSlug, opts.capabilitySlug))) {
2925
- return { content: [{ type: "text", text: trustRefusal(opts.capabilitySlug) }] };
2926
- }
2927
2916
  const result = startCapability(workflowFile, name, issue, opts.repoSlug);
2928
2917
  const text = result.ok ? `Started capability \`${name}\` on #${issue} via workflow_dispatch.` : `Start failed for capability \`${name}\` on #${issue}: ${result.error}`;
2929
2918
  return { content: [{ type: "text", text }] };
@@ -2965,7 +2954,7 @@ function buildCapabilityMcpServer(opts) {
2965
2954
  });
2966
2955
  return { server };
2967
2956
  }
2968
- var FAIL_CONCLUSIONS, RUNNING_STATUSES, THREAD_BODY_MAX, CHECK_FAIL_CONCLUSIONS, DEFAULT_IGNORE_CHECKS, trackMarker, commentMarker, GATE_EXEMPT_CAPABILITIES, CAPABILITY_MCP_TOOL_NAMES;
2957
+ var FAIL_CONCLUSIONS, RUNNING_STATUSES, THREAD_BODY_MAX, CHECK_FAIL_CONCLUSIONS, DEFAULT_IGNORE_CHECKS, trackMarker, commentMarker, CAPABILITY_MCP_TOOL_NAMES;
2969
2958
  var init_capabilityMcp = __esm({
2970
2959
  "src/capabilityMcp.ts"() {
2971
2960
  "use strict";
@@ -2980,7 +2969,6 @@ var init_capabilityMcp = __esm({
2980
2969
  DEFAULT_IGNORE_CHECKS = ["run", "kody", "capability-tick", "agent-ask", "chat"];
2981
2970
  trackMarker = (key) => `<!-- kody-track:${key} -->`;
2982
2971
  commentMarker = (key) => `<!-- kody-track-comment:${key} -->`;
2983
- GATE_EXEMPT_CAPABILITIES = /* @__PURE__ */ new Set(["qa-engineer", "ui-review"]);
2984
2972
  CAPABILITY_MCP_TOOL_NAMES = [
2985
2973
  "list_prs_to_repair",
2986
2974
  "sync_pr",
@@ -9367,10 +9355,11 @@ function scalarFacts(facts) {
9367
9355
  )
9368
9356
  );
9369
9357
  }
9370
- function autonomyBlockReason(ctx, goalId, goal, goalState, dispatch2) {
9358
+ function autonomyBlockReason(ctx, goalId, goal, goalState, dispatch2, options = {}) {
9371
9359
  if (ctx.data.jobForce === true) return null;
9372
- const selfMode = firstTrustOverride(ctx, subjectCandidates(managedModelSubjectKind(goal), goalId, goalState));
9373
- if (selfMode === "ask" || selfMode !== "auto" && goal.runWithoutApproval !== true) {
9360
+ const selfKind = managedModelKind(goal);
9361
+ const selfMode = selfKind === "Goal" ? firstTrustOverride(ctx, subjectCandidates("goal", goalId, goalState)) : null;
9362
+ if (selfKind === "Goal" && (selfMode === "ask" || selfMode !== "auto" && goal.runWithoutApproval !== true)) {
9374
9363
  return `Run without approval is off for ${managedModelKind(goal)} ${goalId}`;
9375
9364
  }
9376
9365
  if (dispatch2.workflow) {
@@ -9381,11 +9370,12 @@ function autonomyBlockReason(ctx, goalId, goal, goalState, dispatch2) {
9381
9370
  }
9382
9371
  }
9383
9372
  const targetGoal = dispatch2.action === "goal-manager" && typeof dispatch2.cliArgs.goal === "string" ? dispatch2.cliArgs.goal : null;
9384
- if (targetGoal && targetGoal !== goalId) {
9373
+ if (targetGoal && targetGoal !== goalId && options.checkTargets !== false) {
9385
9374
  const target = fetchGoalState(ctx.config, targetGoal, ctx.cwd);
9386
9375
  const targetManaged = target ? managedGoalFromState(expandManagedGoalState(target)) : null;
9387
- const targetMode = targetManaged ? firstTrustOverride(ctx, subjectCandidates(managedModelSubjectKind(targetManaged), targetGoal, target)) : null;
9388
- if (targetMode === "ask" || targetMode !== "auto" && targetManaged && targetManaged.runWithoutApproval !== true) {
9376
+ const targetIsGoal = targetManaged ? managedModelKind(targetManaged) === "Goal" : false;
9377
+ const targetMode = targetManaged && targetIsGoal ? firstTrustOverride(ctx, subjectCandidates("goal", targetGoal, target)) : null;
9378
+ if (targetIsGoal && (targetMode === "ask" || targetMode !== "auto" && targetManaged && targetManaged.runWithoutApproval !== true)) {
9389
9379
  return `Run without approval is off for goal ${targetGoal}`;
9390
9380
  }
9391
9381
  }
@@ -9417,9 +9407,6 @@ function unmarkPlannedCapabilityDispatch(scheduleState, at) {
9417
9407
  function managedModelKind(goal) {
9418
9408
  return goal.loopTarget || goal.schedule ? "Loop" : "Goal";
9419
9409
  }
9420
- function managedModelSubjectKind(goal) {
9421
- return managedModelKind(goal) === "Loop" ? "loop" : "goal";
9422
- }
9423
9410
  function subjectCandidates(kind, id, state) {
9424
9411
  const ids = /* @__PURE__ */ new Set();
9425
9412
  ids.add(id);
@@ -9727,6 +9714,17 @@ var init_advanceManagedGoal = __esm({
9727
9714
  allowSameDayTargetDispatch
9728
9715
  });
9729
9716
  let targetResolution;
9717
+ const selfAutonomyBlock = decision2.kind === "dispatch" && decision2.dispatch ? autonomyBlockReason(ctx, goal.id, managed, goal.raw, decision2.dispatch, { checkTargets: false }) : null;
9718
+ if (selfAutonomyBlock) {
9719
+ restoreGoalIdFact();
9720
+ goal.raw = writeManagedGoalToState({ ...goal.raw, state: goal.state }, managed);
9721
+ const waitDecision = scheduleWaitDecision(previousScheduleState, decision2, selfAutonomyBlock);
9722
+ goal.raw.extra.scheduleState = waitDecision.scheduleState;
9723
+ ctx.data.managedGoalDecision = waitDecision;
9724
+ stageAutonomyBlocked(ctx.data, goal.id, managed, goal.state, waitDecision, previousScheduleState);
9725
+ ctx.output.reason = selfAutonomyBlock;
9726
+ return;
9727
+ }
9730
9728
  if (decision2.kind === "dispatch" && decision2.dispatch && isGoalTargetLoop(managed)) {
9731
9729
  targetResolution = resolveGoalLoopTarget(ctx.config, ctx.cwd, goal.id, managed, now);
9732
9730
  decision2 = planTargetLoopSchedule({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kody-ade/kody-engine",
3
- "version": "0.4.355",
3
+ "version": "0.4.357",
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",