@kody-ade/kody-engine 0.4.407 → 0.4.408

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 +56 -6
  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.407",
18
+ version: "0.4.408",
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",
@@ -11432,12 +11432,54 @@ var init_composePrompt = __esm({
11432
11432
  });
11433
11433
 
11434
11434
  // src/scripts/postReviewResult.ts
11435
+ function words(value) {
11436
+ return value.trim().split(/\s+/).filter(Boolean);
11437
+ }
11438
+ function removeForbiddenReviewSections(body) {
11439
+ const kept = [];
11440
+ let skipping = false;
11441
+ for (const line of body.split("\n")) {
11442
+ const heading = line.match(/^\s*(?:#{1,6}\s+(.+?)|\*\*(.+?)\*\*)\s*$/);
11443
+ if (heading) {
11444
+ const title = (heading[1] ?? heading[2] ?? "").replace(/[*_`]/g, "").trim();
11445
+ skipping = FORBIDDEN_REVIEW_SECTION.test(title);
11446
+ }
11447
+ if (!skipping) kept.push(line);
11448
+ }
11449
+ return kept.join("\n").replace(/\n{3,}/g, "\n\n").trim();
11450
+ }
11451
+ function prepareReviewBody(rawBody) {
11452
+ let body = rawBody.trim();
11453
+ const verdict = body.match(/(^|\n)(\s*#{1,6}\s*Verdict\s*:?\s*(?:PASS|CONCERNS|FAIL)\b)/i);
11454
+ if (verdict?.index !== void 0) {
11455
+ body = body.slice(verdict.index + verdict[1].length).trim();
11456
+ }
11457
+ body = removeForbiddenReviewSections(body);
11458
+ const bodyWords = words(body);
11459
+ if (bodyWords.length <= MAX_REVIEW_WORDS) return body;
11460
+ const noteWords = words(REVIEW_TRUNCATION_NOTE);
11461
+ const retainedWordCount = MAX_REVIEW_WORDS - noteWords.length;
11462
+ const matches = [...body.matchAll(/\S+/g)];
11463
+ const retainedEnd = matches[retainedWordCount - 1].index + matches[retainedWordCount - 1][0].length;
11464
+ return `${body.slice(0, retainedEnd).trimEnd()}
11465
+
11466
+ ${REVIEW_TRUNCATION_NOTE}`;
11467
+ }
11435
11468
  function inferVerdictFromReviewText(body) {
11436
11469
  const structuredVerdict = body.match(/"verdict"\s*:\s*"(pass|concerns|fail|partial)"/i);
11437
11470
  if (structuredVerdict) {
11438
11471
  const value = structuredVerdict[1].toUpperCase();
11439
11472
  return value === "PARTIAL" ? "CONCERNS" : value;
11440
11473
  }
11474
+ const status = body.match(
11475
+ /(^|\n)\s*(?:#{1,6}\s*)?(?:\*\*Status:\*\*|Status:)\s*(PASS|CONCERNS|FAIL|WARN|NONE|BLOCK|NEEDS_CONTEXT)\b/i
11476
+ );
11477
+ if (status) {
11478
+ const value = status[2].toUpperCase();
11479
+ if (value === "PASS" || value === "NONE") return "PASS";
11480
+ if (value === "CONCERNS" || value === "WARN") return "CONCERNS";
11481
+ return "FAIL";
11482
+ }
11441
11483
  if (/\bpartial\b/i.test(body) && /\b(finding|gap|unverified|unverifiable|blocker|issue)s?\b/i.test(body)) {
11442
11484
  return "CONCERNS";
11443
11485
  }
@@ -11480,11 +11522,14 @@ function reviewAction(verdict, payload) {
11480
11522
  function failedAction(reason) {
11481
11523
  return { type: "REVIEW_FAILED", payload: { reason }, timestamp: (/* @__PURE__ */ new Date()).toISOString() };
11482
11524
  }
11483
- var postReviewResult;
11525
+ var MAX_REVIEW_WORDS, REVIEW_TRUNCATION_NOTE, FORBIDDEN_REVIEW_SECTION, postReviewResult;
11484
11526
  var init_postReviewResult = __esm({
11485
11527
  "src/scripts/postReviewResult.ts"() {
11486
11528
  "use strict";
11487
11529
  init_issue();
11530
+ MAX_REVIEW_WORDS = 600;
11531
+ REVIEW_TRUNCATION_NOTE = "> Review truncated to the highest-priority findings.";
11532
+ FORBIDDEN_REVIEW_SECTION = /^(?:clean\b|strengths?\b|suggest(?:ion|ed)s?\b|follow[- ]?ups?\b|verification\b|notes?\b|nits?\b|non[- ]issues?\b)/i;
11488
11533
  postReviewResult = async (ctx, _profile, agentResult) => {
11489
11534
  const prNumber = ctx.data.commentTargetNumber;
11490
11535
  if (!prNumber) {
@@ -11504,7 +11549,7 @@ var init_postReviewResult = __esm({
11504
11549
  ctx.data.action = failedAction(reason);
11505
11550
  return;
11506
11551
  }
11507
- const reviewBody = agentResult.finalText.trim();
11552
+ const reviewBody = prepareReviewBody(agentResult.finalText);
11508
11553
  if (!reviewBody) {
11509
11554
  try {
11510
11555
  postPrReviewComment(prNumber, `\u26A0\uFE0F kody review FAILED: agent produced no review body`, ctx.cwd);
@@ -19833,6 +19878,9 @@ function jobReferenceBlock(profileName, profile, data) {
19833
19878
  ];
19834
19879
  return lines.join("\n");
19835
19880
  }
19881
+ function shouldPromptForTaskArtifacts(tools) {
19882
+ return tools.some((tool6) => TASK_ARTIFACT_WRITE_TOOLS.has(tool6));
19883
+ }
19836
19884
  async function runImplementation(profileName, input) {
19837
19885
  const stageStartedAt = Date.now();
19838
19886
  let finishRunIndex = null;
@@ -19983,6 +20031,7 @@ async function runImplementation(profileName, input) {
19983
20031
  })
19984
20032
  };
19985
20033
  })() : null;
20034
+ const agentTaskArtifacts = taskArtifacts && shouldPromptForTaskArtifacts(profile.claudeCode.tools) ? taskArtifacts : null;
19986
20035
  const ndjsonDir = agentRunDir(input.cwd);
19987
20036
  const agentSlug = typeof profile.agent === "string" && profile.agent.length > 0 ? profile.agent : typeof ctx.data.jobAgent === "string" && ctx.data.jobAgent.length > 0 ? ctx.data.jobAgent : null;
19988
20037
  const agentIdentityBlock = agentSlug ? frameAgentIdentity(agentSlug, loadAgentIdentity(input.cwd, agentSlug)) : null;
@@ -20015,7 +20064,7 @@ async function runImplementation(profileName, input) {
20015
20064
  verbose: input.verbose,
20016
20065
  quiet: input.quiet,
20017
20066
  ndjsonDir,
20018
- additionalDirectories: taskArtifacts ? [taskArtifacts.absDir] : void 0,
20067
+ additionalDirectories: agentTaskArtifacts ? [agentTaskArtifacts.absDir] : void 0,
20019
20068
  allowedToolsOverride: profile.claudeCode.tools,
20020
20069
  permissionModeOverride: profile.claudeCode.permissionMode,
20021
20070
  mcpServers: profile.claudeCode.mcpServers.length > 0 ? profile.claudeCode.mcpServers : void 0,
@@ -20033,7 +20082,7 @@ async function runImplementation(profileName, input) {
20033
20082
  jobRefBlock,
20034
20083
  jobWhyBlock,
20035
20084
  profile.claudeCode.systemPromptAppend,
20036
- taskArtifacts?.promptAddendum
20085
+ agentTaskArtifacts?.promptAddendum
20037
20086
  ].filter((s) => typeof s === "string" && s.length > 0).join("\n\n") || void 0,
20038
20087
  cacheable: profile.claudeCode.cacheable,
20039
20088
  enableVerifyTool: profile.claudeCode.enableVerifyTool,
@@ -20690,7 +20739,7 @@ function flattenConfig(obj, prefix = "") {
20690
20739
  }
20691
20740
  return out;
20692
20741
  }
20693
- var MUTATING_POSTFLIGHTS, SHELL_MARKER_RE, MAX_CHAIN_HOPS, DEFAULT_SHELL_TIMEOUT_MS, SIGKILL_GRACE_MS;
20742
+ var MUTATING_POSTFLIGHTS, SHELL_MARKER_RE, TASK_ARTIFACT_WRITE_TOOLS, MAX_CHAIN_HOPS, DEFAULT_SHELL_TIMEOUT_MS, SIGKILL_GRACE_MS;
20694
20743
  var init_executor = __esm({
20695
20744
  "src/executor.ts"() {
20696
20745
  "use strict";
@@ -20723,6 +20772,7 @@ var init_executor = __esm({
20723
20772
  "openAgencyModelReviewPr"
20724
20773
  ]);
20725
20774
  SHELL_MARKER_RE = /^KODY_(SKIP_AGENT|PR_URL|REASON|CAPABILITY_REPORT|CAPABILITY_RESULT)=/m;
20775
+ TASK_ARTIFACT_WRITE_TOOLS = /* @__PURE__ */ new Set(["Write", "Edit", "NotebookEdit"]);
20726
20776
  MAX_CHAIN_HOPS = 60;
20727
20777
  DEFAULT_SHELL_TIMEOUT_MS = 3e5;
20728
20778
  SIGKILL_GRACE_MS = 5e3;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kody-ade/kody-engine",
3
- "version": "0.4.407",
3
+ "version": "0.4.408",
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",