@kody-ade/kody-engine 0.4.24 → 0.4.25

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 CHANGED
@@ -3,7 +3,7 @@
3
3
  // package.json
4
4
  var package_default = {
5
5
  name: "@kody-ade/kody-engine",
6
- version: "0.4.24",
6
+ version: "0.4.25",
7
7
  description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
8
8
  license: "MIT",
9
9
  type: "module",
@@ -1002,6 +1002,32 @@ function getExecutablesRoot() {
1002
1002
  function getProjectExecutablesRoot() {
1003
1003
  return path6.join(process.cwd(), ".kody", "executables");
1004
1004
  }
1005
+ function getBuiltinJobsRoot() {
1006
+ const here = path6.dirname(new URL(import.meta.url).pathname);
1007
+ const candidates = [
1008
+ path6.join(here, "jobs"),
1009
+ // dev: src/
1010
+ path6.join(here, "..", "jobs"),
1011
+ // built: dist/bin → dist/jobs
1012
+ path6.join(here, "..", "src", "jobs")
1013
+ // fallback
1014
+ ];
1015
+ for (const c of candidates) {
1016
+ if (fs6.existsSync(c) && fs6.statSync(c).isDirectory()) return c;
1017
+ }
1018
+ return candidates[0];
1019
+ }
1020
+ function listBuiltinJobs(root = getBuiltinJobsRoot()) {
1021
+ if (!fs6.existsSync(root) || !fs6.statSync(root).isDirectory()) return [];
1022
+ const out = [];
1023
+ for (const ent of fs6.readdirSync(root, { withFileTypes: true })) {
1024
+ if (!ent.isFile() || !ent.name.endsWith(".md")) continue;
1025
+ const slug = ent.name.slice(0, -3);
1026
+ out.push({ slug, filePath: path6.join(root, ent.name) });
1027
+ }
1028
+ out.sort((a, b) => a.slug.localeCompare(b.slug));
1029
+ return out;
1030
+ }
1005
1031
  function getExecutableRoots() {
1006
1032
  return [getProjectExecutablesRoot(), getExecutablesRoot()];
1007
1033
  }
@@ -2578,7 +2604,8 @@ function parseAgentResult(finalText) {
2578
2604
  feedbackActions: "",
2579
2605
  planDeviations: "",
2580
2606
  priorArt: "",
2581
- failureReason: "agent produced no final message"
2607
+ failureReason: "agent produced no final message",
2608
+ markerMissing: false
2582
2609
  };
2583
2610
  const MARKDOWN_PREFIX = "[\\s>*_#`~\\-]*";
2584
2611
  const FAILED_RE = new RegExp(`(?:^|\\n)${MARKDOWN_PREFIX}FAILED${MARKDOWN_PREFIX}\\s*:\\s*(.+?)\\s*$`, "is");
@@ -2592,7 +2619,8 @@ function parseAgentResult(finalText) {
2592
2619
  feedbackActions: "",
2593
2620
  planDeviations: "",
2594
2621
  priorArt: "",
2595
- failureReason: stripMarkdownEmphasis(failedMatch[1])
2622
+ failureReason: stripMarkdownEmphasis(failedMatch[1]),
2623
+ markerMissing: false
2596
2624
  };
2597
2625
  }
2598
2626
  const hasDoneMarker = DONE_RE.test(text);
@@ -2607,7 +2635,8 @@ function parseAgentResult(finalText) {
2607
2635
  feedbackActions: "",
2608
2636
  planDeviations: "",
2609
2637
  priorArt: "",
2610
- failureReason: `no DONE or FAILED marker in agent output \u2014 agent tail: ${tail}`
2638
+ failureReason: `no DONE or FAILED marker in agent output \u2014 agent tail: ${tail}`,
2639
+ markerMissing: true
2611
2640
  };
2612
2641
  }
2613
2642
  const commitMatch = text.match(/^[\s>*_#`~-]*COMMIT_MSG[\s>*_#`~-]*\s*:\s*(.+)$/im);
@@ -2635,7 +2664,16 @@ function parseAgentResult(finalText) {
2635
2664
  const afterMarker = text.slice(summaryStart).replace(/^[\s\S]*?PR_SUMMARY\s*:[ \t]*\n/i, "");
2636
2665
  prSummary = afterMarker.replace(/\n\s*```\s*$/g, "").replace(/```\s*$/g, "").trim();
2637
2666
  }
2638
- return { done: true, commitMessage, prSummary, feedbackActions, planDeviations, priorArt, failureReason: "" };
2667
+ return {
2668
+ done: true,
2669
+ commitMessage,
2670
+ prSummary,
2671
+ feedbackActions,
2672
+ planDeviations,
2673
+ priorArt,
2674
+ failureReason: "",
2675
+ markerMissing: false
2676
+ };
2639
2677
  }
2640
2678
  function stripMarkdownEmphasis(s) {
2641
2679
  return s.trim().replace(/^[*_`~]+|[*_`~]+$/g, "").trim();
@@ -2731,11 +2769,15 @@ var commitAndPush2 = async (ctx) => {
2731
2769
  ctx.data.commitResult = { committed: false, pushed: false };
2732
2770
  return;
2733
2771
  }
2734
- if (ctx.data.agentDone === false) {
2772
+ const markerMissing = ctx.data.agentMarkerMissing === true;
2773
+ if (ctx.data.agentDone === false && !markerMissing) {
2735
2774
  ctx.data.commitResult = { committed: false, pushed: false, skippedReason: "agentDone=false" };
2736
2775
  ctx.data.hasCommitsAhead = hasCommitsAhead(branch, ctx.config.git.defaultBranch, ctx.cwd);
2737
2776
  return;
2738
2777
  }
2778
+ if (ctx.data.agentDone === false && markerMissing) {
2779
+ ctx.data.salvagedFromMissingMarker = true;
2780
+ }
2739
2781
  const message = ctx.data.commitMessage || DEFAULT_COMMIT_MESSAGE;
2740
2782
  try {
2741
2783
  const result = commitAndPush(branch, message, ctx.cwd);
@@ -5460,6 +5502,21 @@ function performInit(cwd, force) {
5460
5502
  wrote.push(QA_GUIDE_REL_PATH);
5461
5503
  }
5462
5504
  }
5505
+ const builtinJobs = listBuiltinJobs();
5506
+ if (builtinJobs.length > 0) {
5507
+ const jobsDir = path20.join(cwd, ".kody", "jobs");
5508
+ fs22.mkdirSync(jobsDir, { recursive: true });
5509
+ for (const job of builtinJobs) {
5510
+ const rel = path20.join(".kody", "jobs", `${job.slug}.md`);
5511
+ const target = path20.join(cwd, rel);
5512
+ if (fs22.existsSync(target) && !force) {
5513
+ skipped.push(rel);
5514
+ continue;
5515
+ }
5516
+ fs22.writeFileSync(target, fs22.readFileSync(job.filePath, "utf-8"));
5517
+ wrote.push(rel);
5518
+ }
5519
+ }
5463
5520
  for (const exe of listExecutables()) {
5464
5521
  let profile;
5465
5522
  try {
@@ -6140,6 +6197,7 @@ var parseAgentResult2 = async (ctx, profile, agentResult) => {
6140
6197
  ctx.data.planDeviations = parsed.planDeviations;
6141
6198
  ctx.data.priorArt = parsed.priorArt;
6142
6199
  ctx.data.agentFailureReason = parsed.failureReason;
6200
+ ctx.data.agentMarkerMissing = parsed.markerMissing;
6143
6201
  ctx.data.agentOutcome = agentResult.outcome;
6144
6202
  ctx.data.agentError = agentResult.error;
6145
6203
  const modeSeg = (ctx.args.mode ?? profile.name).replace(/-/g, "_").toUpperCase();
@@ -6377,8 +6435,9 @@ var postIssueComment2 = async (ctx) => {
6377
6435
  const prUrl = ctx.output.prUrl;
6378
6436
  const prAction = ctx.data.prResult?.action;
6379
6437
  if (!commitResult?.committed && !hasCommits) {
6380
- const reason = "no changes to commit";
6381
- postWith(targetType, targetNumber, `\u26A0\uFE0F kody FAILED: ${reason}`, ctx.cwd);
6438
+ const specific = computeFailureReason2(ctx);
6439
+ const reason = specific.length > 0 ? specific : "no changes to commit";
6440
+ postWith(targetType, targetNumber, `\u26A0\uFE0F kody FAILED: ${truncate2(reason, 1500)}`, ctx.cwd);
6382
6441
  markRunFailed(ctx);
6383
6442
  ctx.output.exitCode = 3;
6384
6443
  ctx.output.reason = reason;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kody-ade/kody-engine",
3
- "version": "0.4.24",
3
+ "version": "0.4.25",
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",
@@ -1,30 +0,0 @@
1
- {
2
- "name": "watch-stale-prs",
3
- "role": "watch",
4
- "describe": "Scheduled: list open PRs untouched for N days and report. No agent invocation.",
5
- "kind": "scheduled",
6
- "schedule": "0 8 * * MON",
7
- "inputs": [],
8
- "claudeCode": {
9
- "model": "inherit",
10
- "permissionMode": "default",
11
- "maxTurns": null,
12
- "systemPromptAppend": null,
13
- "tools": [],
14
- "hooks": [],
15
- "skills": [],
16
- "commands": [],
17
- "subagents": [],
18
- "plugins": [],
19
- "mcpServers": []
20
- },
21
- "cliTools": [],
22
- "scripts": {
23
- "preflight": [
24
- {
25
- "script": "watchStalePrsFlow"
26
- }
27
- ],
28
- "postflight": []
29
- }
30
- }