@kody-ade/kody-engine-lite 0.1.135 → 0.1.136

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/cli.js +75 -13
  2. package/package.json +1 -1
package/dist/bin/cli.js CHANGED
@@ -4932,7 +4932,10 @@ function executeShipStage(ctx, _def) {
4932
4932
  const head = getCurrentBranch(ctx.projectDir);
4933
4933
  const base = getDefaultBranch(ctx.projectDir);
4934
4934
  try {
4935
- execFileSync14("git", ["add", ctx.taskDir], {
4935
+ const memoryDir = path22.join(ctx.projectDir, ".kody", "memory");
4936
+ const addPaths = [ctx.taskDir];
4937
+ if (fs24.existsSync(memoryDir)) addPaths.push(memoryDir);
4938
+ execFileSync14("git", ["add", ...addPaths], {
4936
4939
  cwd: ctx.projectDir,
4937
4940
  env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" },
4938
4941
  stdio: "pipe"
@@ -5865,6 +5868,9 @@ async function runPipelineInner(ctx) {
5865
5868
  }
5866
5869
  continue;
5867
5870
  }
5871
+ if (def.name === "ship") {
5872
+ autoLearn(ctx);
5873
+ }
5868
5874
  ciGroup(`Stage: ${def.name}`);
5869
5875
  state.stages[def.name] = { state: "running", startedAt: (/* @__PURE__ */ new Date()).toISOString(), retries: 0 };
5870
5876
  writeState(state, ctx.taskDir);
@@ -5926,7 +5932,6 @@ async function runPipelineInner(ctx) {
5926
5932
  if (ctx.input.issueNumber && !ctx.input.local) {
5927
5933
  setLifecycleLabel(ctx.input.issueNumber, "done");
5928
5934
  }
5929
- autoLearn(ctx);
5930
5935
  }
5931
5936
  await runRetrospective(ctx, state, pipelineStartTime).catch((err) => {
5932
5937
  logger.warn(` Retrospective failed: ${err instanceof Error ? err.message : String(err)}`);
@@ -6218,18 +6223,36 @@ async function runResolve(options) {
6218
6223
  logger.info(`Resolving PR #${prNumber} \u2014 merging ${defaultBranch}...`);
6219
6224
  const mergeResult = mergeDefault(projectDir);
6220
6225
  if (mergeResult === "error") {
6221
- return { outcome: "failed", error: "Failed to merge default branch" };
6226
+ const error = "Failed to merge default branch";
6227
+ if (!local) {
6228
+ try {
6229
+ postPRComment(prNumber, `\u274C **Resolve failed:** ${error}`);
6230
+ } catch {
6231
+ }
6232
+ }
6233
+ return { outcome: "failed", error };
6222
6234
  }
6223
6235
  if (mergeResult === "clean") {
6224
6236
  logger.info(" Clean merge \u2014 no conflicts");
6225
6237
  if (!local) {
6226
6238
  pushBranch(projectDir);
6239
+ try {
6240
+ postPRComment(prNumber, `\u2705 **Clean merge** \u2014 synced with \`${defaultBranch}\`, no conflicts.`);
6241
+ } catch {
6242
+ }
6227
6243
  }
6228
6244
  return { outcome: "merged" };
6229
6245
  }
6230
6246
  const conflictedFiles = getConflictedFiles(projectDir);
6231
6247
  if (conflictedFiles.length === 0) {
6232
- return { outcome: "failed", error: "Merge reported conflict but no conflicted files found" };
6248
+ const error = "Merge reported conflict but no conflicted files found";
6249
+ if (!local) {
6250
+ try {
6251
+ postPRComment(prNumber, `\u274C **Resolve failed:** ${error}`);
6252
+ } catch {
6253
+ }
6254
+ }
6255
+ return { outcome: "failed", error };
6233
6256
  }
6234
6257
  logger.info(` ${conflictedFiles.length} conflicted file(s): ${conflictedFiles.join(", ")}`);
6235
6258
  const conflictContext = getConflictContext(projectDir, conflictedFiles);
@@ -6238,7 +6261,14 @@ async function runResolve(options) {
6238
6261
  const runnerName = config.agent.defaultRunner ?? Object.keys(runners)[0] ?? "claude";
6239
6262
  const runner = runners[runnerName];
6240
6263
  if (!runner) {
6241
- return { outcome: "failed", error: `Runner "${runnerName}" not found` };
6264
+ const error = `Runner "${runnerName}" not found`;
6265
+ if (!local) {
6266
+ try {
6267
+ postPRComment(prNumber, `\u274C **Resolve failed:** ${error}`);
6268
+ } catch {
6269
+ }
6270
+ }
6271
+ return { outcome: "failed", error };
6242
6272
  }
6243
6273
  const model = resolveModel("mid");
6244
6274
  const extraEnv = {};
@@ -6251,7 +6281,14 @@ async function runResolve(options) {
6251
6281
  env: extraEnv
6252
6282
  });
6253
6283
  if (result2.outcome !== "completed") {
6254
- return { outcome: "failed", error: `Agent failed: ${result2.error}` };
6284
+ const error = `Agent failed: ${result2.error}`;
6285
+ if (!local) {
6286
+ try {
6287
+ postPRComment(prNumber, `\u274C **Resolve failed:** ${error}`);
6288
+ } catch {
6289
+ }
6290
+ }
6291
+ return { outcome: "failed", error };
6255
6292
  }
6256
6293
  logger.info(" Verifying resolution...");
6257
6294
  const verify = runQualityGates(projectDir, projectDir, { onlyFailOnFiles: conflictedFiles });
@@ -6259,8 +6296,15 @@ async function runResolve(options) {
6259
6296
  const errorSummary = verify.errors.slice(0, 5).join("\n");
6260
6297
  logger.error(` Verification failed:
6261
6298
  ${errorSummary}`);
6262
- return { outcome: "failed", error: `Conflict resolution failed verification:
6263
- ${errorSummary}` };
6299
+ const error = `Conflict resolution failed verification:
6300
+ ${errorSummary}`;
6301
+ if (!local) {
6302
+ try {
6303
+ postPRComment(prNumber, `\u274C **Resolve failed:** ${error}`);
6304
+ } catch {
6305
+ }
6306
+ }
6307
+ return { outcome: "failed", error };
6264
6308
  }
6265
6309
  logger.info(" Verification passed");
6266
6310
  commitAll(`chore: resolve merge conflicts with ${defaultBranch}`, projectDir);
@@ -7841,8 +7885,8 @@ function detectProjectKeywords(cwd) {
7841
7885
  }
7842
7886
  }
7843
7887
  function searchSkills(keywords, exclude, limit) {
7844
- const allResults = [];
7845
7888
  const seen = /* @__PURE__ */ new Set();
7889
+ const perKeyword = [];
7846
7890
  for (const keyword of keywords) {
7847
7891
  try {
7848
7892
  const output = execFileSync4("npx", ["skills", "find", keyword], {
@@ -7850,16 +7894,34 @@ function searchSkills(keywords, exclude, limit) {
7850
7894
  timeout: 15e3,
7851
7895
  stdio: ["pipe", "pipe", "pipe"]
7852
7896
  });
7897
+ const results = [];
7853
7898
  for (const skill of parseSkillsSearchOutput(output)) {
7854
- if (!seen.has(skill.ref) && !exclude.has(skill.name)) {
7855
- seen.add(skill.ref);
7856
- allResults.push(skill);
7899
+ if (!exclude.has(skill.name)) {
7900
+ results.push(skill);
7857
7901
  }
7858
7902
  }
7903
+ perKeyword.push(results);
7859
7904
  } catch {
7860
7905
  }
7861
7906
  }
7862
- return allResults.sort((a, b) => b.installs - a.installs).slice(0, limit);
7907
+ const selected = [];
7908
+ let round = 0;
7909
+ while (selected.length < limit) {
7910
+ let added = false;
7911
+ for (const results of perKeyword) {
7912
+ if (selected.length >= limit) break;
7913
+ if (round >= results.length) continue;
7914
+ const candidate = results[round];
7915
+ if (!seen.has(candidate.ref)) {
7916
+ seen.add(candidate.ref);
7917
+ selected.push(candidate);
7918
+ added = true;
7919
+ }
7920
+ }
7921
+ if (!added) break;
7922
+ round++;
7923
+ }
7924
+ return selected;
7863
7925
  }
7864
7926
  function collectSkillPaths(cwd, skillName, paths) {
7865
7927
  for (const dir of [".claude/skills", ".agents/skills"]) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kody-ade/kody-engine-lite",
3
- "version": "0.1.135",
3
+ "version": "0.1.136",
4
4
  "description": "Autonomous SDLC pipeline: Kody orchestration + Claude Code + LiteLLM",
5
5
  "license": "MIT",
6
6
  "type": "module",