@kody-ade/kody-engine 0.4.618 → 0.4.620

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 +22 -9
  2. package/package.json +2 -2
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.618",
18
+ version: "0.4.620",
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
  repository: {
@@ -2355,11 +2355,14 @@ function parseCapabilityRequirements(raw) {
2355
2355
  if (raw === void 0) return void 0;
2356
2356
  if (!isPlainObject(raw)) throw new Error("contract.json requirements must be an object");
2357
2357
  const unsupported = Object.keys(raw).filter(
2358
- (key) => key !== "browser" && key !== "qaCredentials" && key !== "githubTestToken" && key !== "qaAccountCredentials" && key !== "qaAccountModelSettings" && key !== "browserOnly"
2358
+ (key) => key !== "cms" && key !== "browser" && key !== "qaCredentials" && key !== "githubTestToken" && key !== "qaAccountCredentials" && key !== "qaAccountModelSettings" && key !== "browserOnly"
2359
2359
  );
2360
2360
  if (unsupported.length > 0) {
2361
2361
  throw new Error(`contract.json requirements contains unsupported fields: ${unsupported.join(", ")}`);
2362
2362
  }
2363
+ if (raw.cms !== void 0 && typeof raw.cms !== "boolean") {
2364
+ throw new Error("contract.json requirements.cms must be boolean");
2365
+ }
2363
2366
  if (raw.browser !== void 0 && typeof raw.browser !== "boolean") {
2364
2367
  throw new Error("contract.json requirements.browser must be boolean");
2365
2368
  }
@@ -2382,6 +2385,7 @@ function parseCapabilityRequirements(raw) {
2382
2385
  throw new Error("contract.json authentication requirements require browser");
2383
2386
  }
2384
2387
  const requirements = {
2388
+ ...raw.cms === true ? { cms: true } : {},
2385
2389
  ...raw.browser === true ? { browser: true } : {},
2386
2390
  ...raw.qaCredentials === true ? { qaCredentials: true } : {},
2387
2391
  ...raw.githubTestToken === true ? { githubTestToken: true } : {},
@@ -9035,13 +9039,13 @@ function commitAndPush(branch, agentMessage, cwd, deliveryPathAllowlist = [], de
9035
9039
  const allowedFiles = allChanged.filter(
9036
9040
  (f) => !isForbiddenPath(f, deliveryPathAllowlist) || isTrustedConfigActivationChange(f, deliveryPathAllowlist, deliveryConfigAllowlist, cwd)
9037
9041
  );
9038
- const mergeHeadExists = fs29.existsSync(path28.join(cwd ?? process.cwd(), ".git", "MERGE_HEAD"));
9039
- if (allowedFiles.length === 0 && !mergeHeadExists) {
9040
- return { committed: false, pushed: false, sha: "", message: "" };
9041
- }
9042
9042
  const forbiddenFiles = allChanged.filter(
9043
9043
  (f) => isForbiddenPath(f, deliveryPathAllowlist) && !isTrustedConfigActivationChange(f, deliveryPathAllowlist, deliveryConfigAllowlist, cwd)
9044
9044
  );
9045
+ const mergeHeadExists = fs29.existsSync(path28.join(cwd ?? process.cwd(), ".git", "MERGE_HEAD"));
9046
+ if (allowedFiles.length === 0 && !mergeHeadExists) {
9047
+ return { committed: false, pushed: false, sha: "", message: "", omittedFiles: forbiddenFiles };
9048
+ }
9045
9049
  for (const f of forbiddenFiles) {
9046
9050
  try {
9047
9051
  git(["reset", "-q", "--", f], cwd);
@@ -9068,9 +9072,9 @@ function commitAndPush(branch, agentMessage, cwd, deliveryPathAllowlist = [], de
9068
9072
  const sha = git(["rev-parse", "HEAD"], cwd).slice(0, 7);
9069
9073
  const pushResult = pushWithRetry({ cwd, branch, setUpstream: true });
9070
9074
  if (pushResult.ok) {
9071
- return { committed: true, pushed: true, sha, message };
9075
+ return { committed: true, pushed: true, sha, message, omittedFiles: forbiddenFiles };
9072
9076
  }
9073
- return { committed: true, pushed: false, sha, message, pushError: pushResult.reason };
9077
+ return { committed: true, pushed: false, sha, message, pushError: pushResult.reason, omittedFiles: forbiddenFiles };
9074
9078
  }
9075
9079
  function hasCommitsAhead(branch, defaultBranch, cwd) {
9076
9080
  try {
@@ -12714,6 +12718,7 @@ var init_commitAndPush = __esm({
12714
12718
  try {
12715
12719
  const result2 = commitAndPush(branch, message, ctx.cwd, deliveryPathAllowlist, deliveryConfigAllowlist);
12716
12720
  ctx.data.commitResult = result2;
12721
+ if (result2.omittedFiles?.length) ctx.data.deliveryOmissions = result2.omittedFiles;
12717
12722
  const postCommitFiles = result2.committed ? listFilesInCommit("HEAD", ctx.cwd) : listChangedFiles(ctx.cwd);
12718
12723
  ctx.data.changedFiles = postCommitFiles.filter((f) => !isForbiddenPath(f, deliveryPathAllowlist));
12719
12724
  if (result2.committed && !result2.pushed) {
@@ -18302,6 +18307,10 @@ function renderMessage(input) {
18302
18307
  }
18303
18308
  }
18304
18309
  function computeFailureReason2(ctx) {
18310
+ const omissions = Array.isArray(ctx.data.deliveryOmissions) ? ctx.data.deliveryOmissions.filter((file) => typeof file === "string") : [];
18311
+ if (omissions.length > 0) {
18312
+ return `delivery blocked protected files: ${omissions.join(", ")}`;
18313
+ }
18305
18314
  const misses = ctx.data.coverageMisses ?? [];
18306
18315
  if (misses.length > 0) return `missing tests: ${misses.map((m) => m.expectedTest).join(", ")}`;
18307
18316
  const agentDone = Boolean(ctx.data.agentDone);
@@ -18435,7 +18444,7 @@ var init_postIssueComment = __esm({
18435
18444
  const agentDone = Boolean(ctx.data.agentDone);
18436
18445
  const verifyOk = ctx.data.verifyOk !== false;
18437
18446
  const misses = ctx.data.coverageMisses ?? [];
18438
- if (!agentDone || misses.length > 0) exitCode = 1;
18447
+ if (isFailure || !agentDone || misses.length > 0) exitCode = 1;
18439
18448
  else if (!verifyOk) exitCode = 2;
18440
18449
  exitCode = Math.max(ctx.output.exitCode ?? 0, exitCode);
18441
18450
  if (exitCode !== 0) markRunFailed(ctx);
@@ -23042,6 +23051,10 @@ async function runImplementation(profileName, input) {
23042
23051
  // to know the palette — it just forwards the flag so agent.ts can spin
23043
23052
  // up the in-process `kody-capability` MCP server with the right context.
23044
23053
  enableCapabilityTool: Array.isArray(ctx.data.capabilityTools) && ctx.data.capabilityTools.length > 0,
23054
+ enableDashboardCmsTool: Boolean(
23055
+ ctx.data.capabilityRequirements && typeof ctx.data.capabilityRequirements === "object" && !Array.isArray(ctx.data.capabilityRequirements) && ctx.data.capabilityRequirements.cms === true
23056
+ ),
23057
+ cmsRepoSlug: config.github?.owner && config.github?.repo ? `${config.github.owner}/${config.github.repo}` : process.env.GITHUB_REPOSITORY?.trim() || void 0,
23045
23058
  capabilityOperatorMention: typeof ctx.data.capabilityOperatorMention === "string" ? ctx.data.capabilityOperatorMention : void 0,
23046
23059
  // Stamp the running capability's slug onto recommendations so the dashboard
23047
23060
  // keys trust per capability (not per agent). `jobSlug` is set by loadJobFromFile.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kody-ade/kody-engine",
3
- "version": "0.4.618",
4
- "description": "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative implementation profiles.",
3
+ "version": "0.4.620",
4
+ "description": "kody autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative implementation profiles.",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",