@kody-ade/kody-engine-lite 0.1.25 → 0.1.26

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 (71) hide show
  1. package/README.md +37 -0
  2. package/dist/agent-runner.d.ts +4 -0
  3. package/dist/agent-runner.js +122 -0
  4. package/dist/bin/cli.js +336 -99
  5. package/dist/ci/parse-inputs.d.ts +6 -0
  6. package/dist/ci/parse-inputs.js +76 -0
  7. package/dist/ci/parse-safety.d.ts +6 -0
  8. package/dist/ci/parse-safety.js +22 -0
  9. package/dist/cli/args.d.ts +13 -0
  10. package/dist/cli/args.js +42 -0
  11. package/dist/cli/litellm.d.ts +2 -0
  12. package/dist/cli/litellm.js +85 -0
  13. package/dist/cli/task-resolution.d.ts +2 -0
  14. package/dist/cli/task-resolution.js +41 -0
  15. package/dist/config.d.ts +49 -0
  16. package/dist/config.js +72 -0
  17. package/dist/context.d.ts +4 -0
  18. package/dist/context.js +83 -0
  19. package/dist/definitions.d.ts +3 -0
  20. package/dist/definitions.js +59 -0
  21. package/dist/entry.d.ts +1 -0
  22. package/dist/entry.js +236 -0
  23. package/dist/git-utils.d.ts +13 -0
  24. package/dist/git-utils.js +174 -0
  25. package/dist/github-api.d.ts +14 -0
  26. package/dist/github-api.js +114 -0
  27. package/dist/kody-utils.d.ts +1 -0
  28. package/dist/kody-utils.js +9 -0
  29. package/dist/learning/auto-learn.d.ts +2 -0
  30. package/dist/learning/auto-learn.js +169 -0
  31. package/dist/logger.d.ts +14 -0
  32. package/dist/logger.js +51 -0
  33. package/dist/memory.d.ts +1 -0
  34. package/dist/memory.js +20 -0
  35. package/dist/observer.d.ts +9 -0
  36. package/dist/observer.js +80 -0
  37. package/dist/pipeline/complexity.d.ts +3 -0
  38. package/dist/pipeline/complexity.js +12 -0
  39. package/dist/pipeline/executor-registry.d.ts +3 -0
  40. package/dist/pipeline/executor-registry.js +20 -0
  41. package/dist/pipeline/hooks.d.ts +17 -0
  42. package/dist/pipeline/hooks.js +110 -0
  43. package/dist/pipeline/questions.d.ts +2 -0
  44. package/dist/pipeline/questions.js +44 -0
  45. package/dist/pipeline/runner-selection.d.ts +2 -0
  46. package/dist/pipeline/runner-selection.js +13 -0
  47. package/dist/pipeline/state.d.ts +4 -0
  48. package/dist/pipeline/state.js +37 -0
  49. package/dist/pipeline.d.ts +3 -0
  50. package/dist/pipeline.js +213 -0
  51. package/dist/preflight.d.ts +1 -0
  52. package/dist/preflight.js +69 -0
  53. package/dist/retrospective.d.ts +26 -0
  54. package/dist/retrospective.js +211 -0
  55. package/dist/stages/agent.d.ts +2 -0
  56. package/dist/stages/agent.js +94 -0
  57. package/dist/stages/gate.d.ts +2 -0
  58. package/dist/stages/gate.js +32 -0
  59. package/dist/stages/review.d.ts +2 -0
  60. package/dist/stages/review.js +32 -0
  61. package/dist/stages/ship.d.ts +3 -0
  62. package/dist/stages/ship.js +154 -0
  63. package/dist/stages/verify.d.ts +2 -0
  64. package/dist/stages/verify.js +94 -0
  65. package/dist/types.d.ts +61 -0
  66. package/dist/types.js +1 -0
  67. package/dist/validators.d.ts +8 -0
  68. package/dist/validators.js +42 -0
  69. package/dist/verify-runner.d.ts +11 -0
  70. package/dist/verify-runner.js +110 -0
  71. package/package.json +1 -1
package/README.md CHANGED
@@ -265,6 +265,43 @@ npm publish --access public # Publish
265
265
 
266
266
  Only GitHub collaborators (COLLABORATOR, MEMBER, OWNER) can trigger `@kody`. External contributors cannot.
267
267
 
268
+ ## Branching Convention (Recommended)
269
+
270
+ Give Kody a dedicated unprotected branch so it can push freely, while keeping your default branch protected for human review.
271
+
272
+ ```
273
+ main (protected — require PR + review + status checks)
274
+ └── kody/develop (unprotected — Kody's integration branch)
275
+ ├── kody/task-123 (per-task, short-lived)
276
+ └── kody/task-456
277
+ ```
278
+
279
+ ### Workflow
280
+
281
+ 1. **Task start** — Kody creates `kody/task-<id>` from `kody/develop`
282
+ 2. **Work** — Kody pushes freely (commits, quality gates, iterations)
283
+ 3. **Task done** — Kody merges task branch into `kody/develop` (squash or fast-forward)
284
+ 4. **Ship batch** — PR from `kody/develop` → `main` (human reviews accumulated features)
285
+ 5. **After merge** — Rebase `kody/develop` onto updated `main`
286
+
287
+ ### GitHub Setup
288
+
289
+ Configure via **Settings → Rules → Rulesets**:
290
+
291
+ | Branch pattern | Protection |
292
+ |---|---|
293
+ | `main` | Require PR, require review, require status checks |
294
+ | `kody/**` | No protection (optionally require status checks for CI) |
295
+
296
+ Add your GitHub Actions bot as a **bypass actor** so Kody can push to `kody/*` branches even under org-wide rules.
297
+
298
+ ### Guidelines
299
+
300
+ - **Keep `kody/develop` fresh** — rebase onto `main` after each merge to avoid drift
301
+ - **Always branch from HEAD** — task branches should come from current `kody/develop`
302
+ - **Critical fixes bypass** — for urgent fixes, Kody can branch directly from `main` and PR to `main`, skipping `kody/develop`
303
+ - **Batch size** — PR to `main` after 2-3 related tasks, or on a regular cadence
304
+
268
305
  ## License
269
306
 
270
307
  MIT
@@ -0,0 +1,4 @@
1
+ import type { AgentRunner } from "./types.js";
2
+ import type { KodyConfig } from "./config.js";
3
+ export declare function createClaudeCodeRunner(): AgentRunner;
4
+ export declare function createRunners(config: KodyConfig): Record<string, AgentRunner>;
@@ -0,0 +1,122 @@
1
+ import { spawn, execFileSync } from "child_process";
2
+ const SIGKILL_GRACE_MS = 5000;
3
+ const STDERR_TAIL_CHARS = 500;
4
+ function writeStdin(child, prompt) {
5
+ return new Promise((resolve, reject) => {
6
+ if (!child.stdin) {
7
+ resolve();
8
+ return;
9
+ }
10
+ child.stdin.write(prompt, (err) => {
11
+ if (err)
12
+ reject(err);
13
+ else {
14
+ child.stdin.end();
15
+ resolve();
16
+ }
17
+ });
18
+ });
19
+ }
20
+ function waitForProcess(child, timeout) {
21
+ return new Promise((resolve) => {
22
+ const stdoutChunks = [];
23
+ const stderrChunks = [];
24
+ child.stdout?.on("data", (chunk) => stdoutChunks.push(chunk));
25
+ child.stderr?.on("data", (chunk) => stderrChunks.push(chunk));
26
+ const timer = setTimeout(() => {
27
+ child.kill("SIGTERM");
28
+ setTimeout(() => {
29
+ if (!child.killed)
30
+ child.kill("SIGKILL");
31
+ }, SIGKILL_GRACE_MS);
32
+ }, timeout);
33
+ child.on("exit", (code) => {
34
+ clearTimeout(timer);
35
+ resolve({
36
+ code,
37
+ stdout: Buffer.concat(stdoutChunks).toString(),
38
+ stderr: Buffer.concat(stderrChunks).toString(),
39
+ });
40
+ });
41
+ child.on("error", (err) => {
42
+ clearTimeout(timer);
43
+ resolve({ code: -1, stdout: "", stderr: err.message });
44
+ });
45
+ });
46
+ }
47
+ async function runSubprocess(command, args, prompt, timeout, options) {
48
+ const child = spawn(command, args, {
49
+ cwd: options?.cwd ?? process.cwd(),
50
+ env: {
51
+ ...process.env,
52
+ SKIP_BUILD: "1",
53
+ SKIP_HOOKS: "1",
54
+ ...options?.env,
55
+ },
56
+ stdio: ["pipe", "pipe", "pipe"],
57
+ });
58
+ try {
59
+ await writeStdin(child, prompt);
60
+ }
61
+ catch (err) {
62
+ return {
63
+ outcome: "failed",
64
+ error: `Failed to send prompt: ${err instanceof Error ? err.message : String(err)}`,
65
+ };
66
+ }
67
+ const { code, stdout, stderr } = await waitForProcess(child, timeout);
68
+ if (code === 0) {
69
+ return { outcome: "completed", output: stdout };
70
+ }
71
+ return {
72
+ outcome: code === null ? "timed_out" : "failed",
73
+ error: `Exit code ${code}\n${stderr.slice(-STDERR_TAIL_CHARS)}`,
74
+ };
75
+ }
76
+ function checkCommand(command, args) {
77
+ try {
78
+ execFileSync(command, args, { timeout: 10_000, stdio: "pipe" });
79
+ return true;
80
+ }
81
+ catch {
82
+ return false;
83
+ }
84
+ }
85
+ // ─── Claude Code Runner ──────────────────────────────────────────────────────
86
+ export function createClaudeCodeRunner() {
87
+ return {
88
+ async run(_stageName, prompt, model, timeout, _taskDir, options) {
89
+ return runSubprocess("claude", [
90
+ "--print",
91
+ "--model", model,
92
+ "--dangerously-skip-permissions",
93
+ "--allowedTools", "Bash,Edit,Read,Write,Glob,Grep",
94
+ ], prompt, timeout, options);
95
+ },
96
+ async healthCheck() {
97
+ return checkCommand("claude", ["--version"]);
98
+ },
99
+ };
100
+ }
101
+ // ─── Runner Factory ──────────────────────────────────────────────────────────
102
+ const RUNNER_FACTORIES = {
103
+ "claude-code": createClaudeCodeRunner,
104
+ };
105
+ export function createRunners(config) {
106
+ // New multi-runner config
107
+ if (config.agent.runners && Object.keys(config.agent.runners).length > 0) {
108
+ const runners = {};
109
+ for (const [name, runnerConfig] of Object.entries(config.agent.runners)) {
110
+ const factory = RUNNER_FACTORIES[runnerConfig.type];
111
+ if (factory) {
112
+ runners[name] = factory();
113
+ }
114
+ }
115
+ return runners;
116
+ }
117
+ // Legacy single-runner fallback
118
+ const runnerType = config.agent.runner ?? "claude-code";
119
+ const factory = RUNNER_FACTORIES[runnerType];
120
+ const defaultName = config.agent.defaultRunner ?? "claude";
121
+ return { [defaultName]: factory ? factory() : createClaudeCodeRunner() };
122
+ }