@kody-ade/kody-engine-lite 0.1.22 → 0.1.24

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/cli.js CHANGED
@@ -145,7 +145,7 @@ var init_definitions = __esm({
145
145
  name: "taskify",
146
146
  type: "agent",
147
147
  modelTier: "cheap",
148
- timeout: 18e4,
148
+ timeout: 3e5,
149
149
  maxRetries: 1,
150
150
  outputFile: "task.json"
151
151
  },
@@ -743,9 +743,12 @@ var init_context = __esm({
743
743
  });
744
744
 
745
745
  // src/validators.ts
746
+ function stripFences(content) {
747
+ return content.replace(/^```json\s*\n?/m, "").replace(/\n?```\s*$/m, "");
748
+ }
746
749
  function validateTaskJson(content) {
747
750
  try {
748
- const parsed = JSON.parse(content);
751
+ const parsed = JSON.parse(stripFences(content));
749
752
  for (const field of REQUIRED_TASK_FIELDS) {
750
753
  if (!(field in parsed)) {
751
754
  return { valid: false, error: `Missing field: ${field}` };
@@ -868,7 +871,26 @@ async function executeAgentStage(ctx, def) {
868
871
  const content = fs5.readFileSync(outputPath, "utf-8");
869
872
  const validation = validateStageOutput(def.name, content);
870
873
  if (!validation.valid) {
871
- logger.warn(` validation warning: ${validation.error}`);
874
+ if (def.name === "taskify") {
875
+ logger.warn(` taskify output invalid (${validation.error}), retrying...`);
876
+ const retryPrompt = prompt + "\n\nIMPORTANT: Your previous output was not valid JSON. Output ONLY the raw JSON object. No markdown, no fences, no explanation.";
877
+ const retryResult = await runner.run(def.name, retryPrompt, model, def.timeout, ctx.taskDir, {
878
+ cwd: ctx.projectDir,
879
+ env: extraEnv
880
+ });
881
+ if (retryResult.outcome === "completed" && retryResult.output) {
882
+ const stripped = stripFences(retryResult.output);
883
+ const retryValidation = validateTaskJson(stripped);
884
+ if (retryValidation.valid) {
885
+ fs5.writeFileSync(outputPath, retryResult.output);
886
+ logger.info(` taskify retry produced valid JSON`);
887
+ } else {
888
+ logger.warn(` taskify retry still invalid: ${retryValidation.error}`);
889
+ }
890
+ }
891
+ } else {
892
+ logger.warn(` validation warning: ${validation.error}`);
893
+ }
872
894
  }
873
895
  }
874
896
  }
@@ -2096,11 +2118,26 @@ async function tryStartLitellm(url, projectDir) {
2096
2118
  cmd = "python3";
2097
2119
  args2 = ["-m", "litellm", "--config", configPath, "--port", port];
2098
2120
  }
2121
+ const dotenvPath = path14.join(projectDir, ".env");
2122
+ const dotenvVars = {};
2123
+ if (fs15.existsSync(dotenvPath)) {
2124
+ for (const line of fs15.readFileSync(dotenvPath, "utf-8").split("\n")) {
2125
+ const match = line.match(/^([A-Z_][A-Z0-9_]*_API_KEY)=(.*)$/);
2126
+ if (match) dotenvVars[match[1]] = match[2];
2127
+ }
2128
+ if (Object.keys(dotenvVars).length > 0) {
2129
+ logger.info(` Loaded API keys: ${Object.keys(dotenvVars).join(", ")}`);
2130
+ }
2131
+ }
2099
2132
  const { spawn: spawn2 } = await import("child_process");
2100
2133
  const child = spawn2(cmd, args2, {
2101
2134
  stdio: ["ignore", "pipe", "pipe"],
2102
2135
  detached: true,
2103
- env: process.env
2136
+ env: { ...process.env, ...dotenvVars }
2137
+ });
2138
+ let proxyStderr = "";
2139
+ child.stderr?.on("data", (chunk) => {
2140
+ proxyStderr += chunk.toString();
2104
2141
  });
2105
2142
  for (let i = 0; i < 30; i++) {
2106
2143
  await new Promise((r) => setTimeout(r, 2e3));
@@ -2109,6 +2146,9 @@ async function tryStartLitellm(url, projectDir) {
2109
2146
  return child;
2110
2147
  }
2111
2148
  }
2149
+ if (proxyStderr) {
2150
+ logger.warn(`LiteLLM stderr: ${proxyStderr.slice(-1e3)}`);
2151
+ }
2112
2152
  logger.warn("LiteLLM proxy failed to start within 60s");
2113
2153
  child.kill();
2114
2154
  return null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kody-ade/kody-engine-lite",
3
- "version": "0.1.22",
3
+ "version": "0.1.24",
4
4
  "description": "Autonomous SDLC pipeline: Kody orchestration + Claude Code + LiteLLM",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/prompts/review.md CHANGED
@@ -9,6 +9,8 @@ You are a code review agent. Review all changes made for the task described belo
9
9
 
10
10
  Use Bash to run `git diff` to see what changed. Use Read to examine modified files in full context.
11
11
 
12
+ CRITICAL: You MUST output a structured review in the EXACT format below. Do NOT output conversational text, status updates, or summaries. Your entire output must be the structured review markdown.
13
+
12
14
  Output markdown with this EXACT structure:
13
15
 
14
16
  ## Verdict: PASS | FAIL