@kody-ade/kody-engine-lite 0.1.19 → 0.1.21
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/README.md +167 -298
- package/dist/bin/cli.js +99 -36
- package/kody.config.schema.json +170 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,401 +1,270 @@
|
|
|
1
1
|
# Kody Engine Lite
|
|
2
2
|
|
|
3
|
-
Autonomous SDLC pipeline
|
|
3
|
+
Autonomous SDLC pipeline. Comment `@kody` on a GitHub issue → Kody classifies, plans, builds, tests, reviews, fixes, and ships a PR. Zero human intervention required.
|
|
4
4
|
|
|
5
5
|
## How it works
|
|
6
6
|
|
|
7
7
|
```
|
|
8
|
-
@kody
|
|
9
|
-
|
|
10
|
-
GitHub Actions workflow
|
|
11
|
-
|
|
12
|
-
Kody Engine Lite (npm package)
|
|
13
|
-
↓
|
|
8
|
+
@kody (comment on a GitHub issue)
|
|
9
|
+
↓
|
|
10
|
+
GitHub Actions workflow
|
|
11
|
+
↓
|
|
14
12
|
7-stage pipeline:
|
|
15
|
-
1. taskify — classify
|
|
16
|
-
2. plan —
|
|
17
|
-
3. build — implement code changes (
|
|
18
|
-
4. verify —
|
|
19
|
-
5. review — code review (
|
|
20
|
-
6. review-fix — fix
|
|
21
|
-
7. ship — push branch + create PR
|
|
22
|
-
|
|
23
|
-
PR created
|
|
13
|
+
1. taskify — classify task, detect complexity, ask questions if unclear
|
|
14
|
+
2. plan — TDD implementation plan (opus — deep reasoning)
|
|
15
|
+
3. build — implement code changes (sonnet — tool use via Claude Code)
|
|
16
|
+
4. verify — typecheck + tests + lint (auto-fix on failure)
|
|
17
|
+
5. review — code review with severity levels (opus)
|
|
18
|
+
6. review-fix — fix Critical/Major findings (sonnet)
|
|
19
|
+
7. ship — push branch + create PR with Closes #N
|
|
20
|
+
↓
|
|
21
|
+
PR created with What/Scope/Changes description
|
|
24
22
|
```
|
|
25
23
|
|
|
26
24
|
## Quick Start
|
|
27
25
|
|
|
28
|
-
### 1. Install
|
|
29
|
-
|
|
30
26
|
```bash
|
|
27
|
+
# Install
|
|
31
28
|
npm install -g @kody-ade/kody-engine-lite
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
### 2. Init (run in your project root)
|
|
35
29
|
|
|
36
|
-
|
|
30
|
+
# Init (in your project root) — auto-detects everything
|
|
37
31
|
cd your-project
|
|
38
32
|
kody-engine-lite init
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
This will:
|
|
42
|
-
- Copy `.github/workflows/kody.yml` to your repo
|
|
43
|
-
- Create `kody.config.json` (edit this)
|
|
44
|
-
- Create `.kody/memory/architecture.md` (auto-detected)
|
|
45
|
-
- Create `.kody/memory/conventions.md` (seed)
|
|
46
|
-
- Add `.tasks/` to `.gitignore`
|
|
47
|
-
- Run health checks (prerequisites, GitHub auth, secrets)
|
|
48
|
-
|
|
49
|
-
### 3. Configure
|
|
50
|
-
|
|
51
|
-
Edit `kody.config.json`:
|
|
52
|
-
|
|
53
|
-
```json
|
|
54
|
-
{
|
|
55
|
-
"quality": {
|
|
56
|
-
"typecheck": "pnpm tsc --noEmit",
|
|
57
|
-
"lint": "pnpm lint",
|
|
58
|
-
"lintFix": "pnpm lint:fix",
|
|
59
|
-
"format": "",
|
|
60
|
-
"formatFix": "",
|
|
61
|
-
"testUnit": "pnpm test"
|
|
62
|
-
},
|
|
63
|
-
"git": {
|
|
64
|
-
"defaultBranch": "main"
|
|
65
|
-
},
|
|
66
|
-
"github": {
|
|
67
|
-
"owner": "your-org",
|
|
68
|
-
"repo": "your-repo"
|
|
69
|
-
},
|
|
70
|
-
"paths": {
|
|
71
|
-
"taskDir": ".tasks"
|
|
72
|
-
},
|
|
73
|
-
"agent": {
|
|
74
|
-
"runner": "claude-code",
|
|
75
|
-
"modelMap": {
|
|
76
|
-
"cheap": "haiku",
|
|
77
|
-
"mid": "sonnet",
|
|
78
|
-
"strong": "opus"
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
### 4. GitHub Setup
|
|
85
|
-
|
|
86
|
-
#### Required Secret
|
|
87
|
-
|
|
88
|
-
Add `ANTHROPIC_API_KEY` to your repo secrets:
|
|
89
|
-
|
|
90
|
-
```bash
|
|
91
|
-
gh secret set ANTHROPIC_API_KEY --repo owner/repo
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
#### Required Permissions
|
|
95
|
-
|
|
96
|
-
Go to **Settings → Actions → General → Workflow permissions**:
|
|
97
33
|
|
|
98
|
-
|
|
99
|
-
2. Check **"Allow GitHub Actions to create and approve pull requests"**
|
|
100
|
-
3. Save
|
|
101
|
-
|
|
102
|
-
Without this, the ship stage cannot create PRs.
|
|
103
|
-
|
|
104
|
-
### 5. Push and Use
|
|
105
|
-
|
|
106
|
-
```bash
|
|
34
|
+
# Push and use
|
|
107
35
|
git add .github/workflows/kody.yml kody.config.json .kody/
|
|
108
36
|
git commit -m "chore: add kody engine"
|
|
109
37
|
git push
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
Then comment on any issue:
|
|
113
38
|
|
|
114
|
-
|
|
39
|
+
# Comment on any issue
|
|
115
40
|
@kody
|
|
116
41
|
```
|
|
117
42
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
### Run locally
|
|
121
|
-
|
|
122
|
-
```bash
|
|
123
|
-
# Run against current directory
|
|
124
|
-
kody-engine-lite run --task "Add a sum function to src/math.ts with tests"
|
|
125
|
-
|
|
126
|
-
# Run against a different project
|
|
127
|
-
kody-engine-lite run --task "Add feature X" --cwd /path/to/project
|
|
128
|
-
|
|
129
|
-
# Run from a GitHub issue (fetches issue body as task)
|
|
130
|
-
kody-engine-lite run --issue-number 1 --cwd /path/to/project
|
|
131
|
-
|
|
132
|
-
# Dry run (no agent calls)
|
|
133
|
-
kody-engine-lite run --task "Test" --dry-run
|
|
134
|
-
|
|
135
|
-
# Resume from a failed/paused stage (auto-detects which stage)
|
|
136
|
-
kody-engine-lite rerun --issue-number 1
|
|
43
|
+
### What `init` does
|
|
137
44
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
kody-engine-lite status --task-id my-task
|
|
146
|
-
```
|
|
45
|
+
Spawns Claude Code to analyze your project and auto-generates:
|
|
46
|
+
- `.github/workflows/kody.yml` — full CI/CD workflow
|
|
47
|
+
- `kody.config.json` — quality commands auto-detected from `package.json`
|
|
48
|
+
- `.kody/memory/architecture.md` — project-specific tech stack and structure
|
|
49
|
+
- `.kody/memory/conventions.md` — coding patterns, references to existing docs
|
|
50
|
+
- 14 GitHub labels — lifecycle, complexity, and type labels
|
|
51
|
+
- Health checks — CLI tools, GitHub auth, secrets, config validation
|
|
147
52
|
|
|
148
|
-
###
|
|
53
|
+
### GitHub Setup
|
|
149
54
|
|
|
55
|
+
**Required secret:**
|
|
150
56
|
```bash
|
|
151
|
-
|
|
152
|
-
kody-engine-lite init # setup workflow, config, memory
|
|
153
|
-
kody-engine-lite init --force # overwrite existing workflow
|
|
57
|
+
gh secret set ANTHROPIC_API_KEY --repo owner/repo
|
|
154
58
|
```
|
|
155
59
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
Comment on any issue:
|
|
159
|
-
|
|
160
|
-
```
|
|
161
|
-
@kody # Run full pipeline (auto-generates task-id)
|
|
162
|
-
@kody full <task-id> # Run with specific task-id
|
|
163
|
-
@kody rerun # Resume latest task (auto-detects stage)
|
|
164
|
-
@kody rerun --from <stage> # Resume from specific stage
|
|
165
|
-
@kody fix # Re-build from build stage (skip taskify/plan)
|
|
166
|
-
@kody fix --feedback "Use X instead of Y" # Fix with specific guidance
|
|
167
|
-
@kody approve # Approve + provide answers to questions
|
|
168
|
-
@kody status <task-id> # Check status
|
|
169
|
-
```
|
|
60
|
+
**Required permission:**
|
|
61
|
+
Settings → Actions → General → "Allow GitHub Actions to create and approve pull requests"
|
|
170
62
|
|
|
171
|
-
|
|
63
|
+
## Commands
|
|
172
64
|
|
|
173
|
-
|
|
65
|
+
### GitHub Comments
|
|
174
66
|
|
|
175
67
|
```
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
68
|
+
@kody Run full pipeline (auto-generates task-id)
|
|
69
|
+
@kody approve Answer questions and resume paused pipeline
|
|
70
|
+
@kody fix Re-build from build stage (on issues or PRs)
|
|
71
|
+
@kody fix Comment body = feedback for the fix
|
|
72
|
+
fix the auth middleware
|
|
73
|
+
to return 401 not 500
|
|
74
|
+
@kody rerun Resume from failed/paused stage
|
|
75
|
+
@kody rerun --from <stage> Resume from specific stage
|
|
181
76
|
```
|
|
182
77
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
```
|
|
186
|
-
@kody approve
|
|
78
|
+
### CLI
|
|
187
79
|
|
|
188
|
-
|
|
189
|
-
|
|
80
|
+
```bash
|
|
81
|
+
kody-engine-lite run --task "Add feature X" --cwd /path/to/project
|
|
82
|
+
kody-engine-lite run --issue-number 42 --cwd /path/to/project
|
|
83
|
+
kody-engine-lite fix --issue-number 42 --feedback "Use middleware pattern"
|
|
84
|
+
kody-engine-lite rerun --issue-number 42
|
|
85
|
+
kody-engine-lite status --task-id <id>
|
|
86
|
+
kody-engine-lite init [--force]
|
|
190
87
|
```
|
|
191
88
|
|
|
192
|
-
Kody resumes automatically from where it paused, with your answers injected as context.
|
|
193
|
-
|
|
194
89
|
## Pipeline Stages
|
|
195
90
|
|
|
196
91
|
| Stage | Model | What it does |
|
|
197
92
|
|-------|-------|-------------|
|
|
198
|
-
| taskify | haiku |
|
|
199
|
-
| plan | opus |
|
|
200
|
-
| build | sonnet |
|
|
201
|
-
| verify | — |
|
|
202
|
-
| review | opus |
|
|
203
|
-
| review-fix | sonnet |
|
|
204
|
-
| ship | — |
|
|
93
|
+
| taskify | haiku | Classify task → `task.json` (type, scope, risk, questions) |
|
|
94
|
+
| plan | opus | Create TDD plan → `plan.md` (deep reasoning) |
|
|
95
|
+
| build | sonnet | Implement code using Claude Code tools (Read/Write/Edit/Bash) |
|
|
96
|
+
| verify | — | Run typecheck + tests + lint from `kody.config.json` |
|
|
97
|
+
| review | opus | Code review → `review.md` (PASS/FAIL + Critical/Major/Minor) |
|
|
98
|
+
| review-fix | sonnet | Fix Critical and Major findings |
|
|
99
|
+
| ship | — | Push branch, create PR, comment on issue |
|
|
205
100
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
On every run/rerun/fix, Kody automatically:
|
|
209
|
-
1. Checks out (or creates) the feature branch
|
|
210
|
-
2. Pulls latest from the default branch and merges into the feature branch
|
|
211
|
-
3. If there's a merge conflict, skips the sync and warns
|
|
101
|
+
## Key Features
|
|
212
102
|
|
|
213
|
-
|
|
103
|
+
### Question Gates
|
|
214
104
|
|
|
215
|
-
|
|
105
|
+
Kody asks before building if something is unclear:
|
|
216
106
|
|
|
217
|
-
- **
|
|
218
|
-
- **
|
|
107
|
+
- **Taskify** asks product/requirements questions ("Should search be case-sensitive?")
|
|
108
|
+
- **Plan** asks architecture/technical questions ("Recommend middleware pattern — approve?")
|
|
109
|
+
- Pipeline pauses with `kody:waiting` label
|
|
110
|
+
- Resume with `@kody approve` + your answers in the comment body
|
|
219
111
|
|
|
220
|
-
|
|
112
|
+
### Complexity-Based Stage Skipping
|
|
221
113
|
|
|
222
|
-
|
|
114
|
+
Auto-detected from taskify's risk assessment, or override with `--complexity`:
|
|
223
115
|
|
|
224
|
-
|
|
225
|
-
|
|
116
|
+
| Complexity | Runs | Skips |
|
|
117
|
+
|-----------|------|-------|
|
|
118
|
+
| low | taskify → build → verify → ship | plan, review, review-fix |
|
|
119
|
+
| medium | taskify → plan → build → verify → review → ship | review-fix |
|
|
120
|
+
| high | all 7 stages | nothing |
|
|
226
121
|
|
|
227
|
-
|
|
122
|
+
### Branch Syncing
|
|
228
123
|
|
|
229
|
-
|
|
124
|
+
Every run merges latest from the default branch into the feature branch before building.
|
|
230
125
|
|
|
231
|
-
###
|
|
126
|
+
### Verify + Autofix Loop
|
|
232
127
|
|
|
233
|
-
|
|
234
|
-
|-------|-------------|---------|
|
|
235
|
-
| `quality.typecheck` | Typecheck command | `pnpm -s tsc --noEmit` |
|
|
236
|
-
| `quality.lint` | Lint command | `pnpm -s lint` |
|
|
237
|
-
| `quality.lintFix` | Lint fix command | `pnpm lint:fix` |
|
|
238
|
-
| `quality.format` | Format check command | `""` |
|
|
239
|
-
| `quality.formatFix` | Format fix command | `""` |
|
|
240
|
-
| `quality.testUnit` | Test command | `pnpm -s test` |
|
|
241
|
-
| `git.defaultBranch` | Default branch | `dev` |
|
|
242
|
-
| `github.owner` | GitHub org/user | `""` |
|
|
243
|
-
| `github.repo` | GitHub repo name | `""` |
|
|
244
|
-
| `paths.taskDir` | Task artifacts directory | `.tasks` |
|
|
245
|
-
| `agent.modelMap.cheap` | Model for taskify | `haiku` |
|
|
246
|
-
| `agent.modelMap.mid` | Model for build/review-fix/autofix | `sonnet` |
|
|
247
|
-
| `agent.modelMap.strong` | Model for plan/review (deep reasoning) | `opus` |
|
|
128
|
+
If verify fails: runs lint-fix → format-fix → autofix agent → retries (up to 2 attempts).
|
|
248
129
|
|
|
249
|
-
###
|
|
130
|
+
### Review + Fix Loop
|
|
250
131
|
|
|
251
|
-
|
|
252
|
-
|----------|----------|-------------|
|
|
253
|
-
| `ANTHROPIC_API_KEY` | Yes | Claude API key (set as repo secret) |
|
|
254
|
-
| `GH_TOKEN` | Auto | GitHub token (provided by Actions) |
|
|
255
|
-
| `GH_PAT` | No | Personal access token (preferred over GH_TOKEN) |
|
|
256
|
-
| `LOG_LEVEL` | No | `debug`, `info`, `warn`, `error` (default: `info`) |
|
|
257
|
-
| `LITELLM_BASE_URL` | No | LiteLLM proxy URL for model routing |
|
|
132
|
+
If review verdict is FAIL: runs review-fix agent → re-reviews.
|
|
258
133
|
|
|
259
|
-
|
|
134
|
+
### Rich PR Description
|
|
260
135
|
|
|
261
|
-
|
|
136
|
+
```markdown
|
|
137
|
+
## What
|
|
138
|
+
Add authentication middleware to 8 unprotected API routes
|
|
262
139
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
"defaultRunner": "claude",
|
|
267
|
-
"runners": {
|
|
268
|
-
"claude": { "type": "claude-code" },
|
|
269
|
-
"opencode": { "type": "opencode" }
|
|
270
|
-
},
|
|
271
|
-
"stageRunners": {
|
|
272
|
-
"taskify": "opencode",
|
|
273
|
-
"plan": "opencode",
|
|
274
|
-
"build": "claude",
|
|
275
|
-
"review": "opencode",
|
|
276
|
-
"review-fix": "claude",
|
|
277
|
-
"autofix": "claude"
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
```
|
|
140
|
+
## Scope
|
|
141
|
+
- `src/middleware/auth.ts`
|
|
142
|
+
- `src/app/api/cron/route.ts`
|
|
282
143
|
|
|
283
|
-
|
|
284
|
-
- `claude-code` — Claude Code CLI (`claude --print`). Supports tool use (Read, Write, Edit, Bash).
|
|
285
|
-
- `opencode` — OpenCode CLI (`opencode github run`). Supports MiniMax, OpenAI, Anthropic, Gemini.
|
|
144
|
+
**Type:** bugfix | **Risk:** high
|
|
286
145
|
|
|
287
|
-
|
|
146
|
+
## Changes
|
|
147
|
+
Added auth middleware to all cron routes and copilotkit endpoint.
|
|
288
148
|
|
|
289
|
-
|
|
149
|
+
**Review:** ✅ PASS
|
|
150
|
+
**Verify:** ✅ typecheck + tests + lint passed
|
|
290
151
|
|
|
291
|
-
|
|
152
|
+
<details><summary>📋 Implementation plan</summary>
|
|
153
|
+
...
|
|
154
|
+
</details>
|
|
292
155
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
kody-engine-lite run --task-id fix-typo --task "Fix typo in README" --complexity low
|
|
156
|
+
Closes #42
|
|
157
|
+
```
|
|
296
158
|
|
|
297
|
-
|
|
298
|
-
kody-engine-lite run --task-id add-feature --task "Add search" --complexity medium
|
|
159
|
+
### Labels
|
|
299
160
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
161
|
+
`init` creates 14 labels:
|
|
162
|
+
- **Lifecycle:** `kody:planning`, `kody:building`, `kody:review`, `kody:done`, `kody:failed`, `kody:waiting`
|
|
163
|
+
- **Complexity:** `kody:low`, `kody:medium`, `kody:high`
|
|
164
|
+
- **Type:** `kody:feature`, `kody:bugfix`, `kody:refactor`, `kody:docs`, `kody:chore`
|
|
303
165
|
|
|
304
|
-
|
|
305
|
-
|-----------|--------|---------|
|
|
306
|
-
| low | taskify → build → verify → ship | plan, review, review-fix |
|
|
307
|
-
| medium | taskify → plan → build → verify → review → ship | review-fix |
|
|
308
|
-
| high | taskify → plan → build → verify → review → review-fix → ship | none |
|
|
166
|
+
### Memory System
|
|
309
167
|
|
|
310
|
-
|
|
168
|
+
`.kody/memory/` files are prepended to every agent prompt:
|
|
169
|
+
- `architecture.md` — auto-generated by `init`
|
|
170
|
+
- `conventions.md` — auto-learned after each successful run
|
|
311
171
|
|
|
312
|
-
##
|
|
172
|
+
## Using Non-Anthropic Models (LiteLLM)
|
|
313
173
|
|
|
314
|
-
|
|
174
|
+
Claude Code can use **any model** through a LiteLLM proxy. Tested with MiniMax (full tool use: Write, Read, Edit, Bash, Grep).
|
|
315
175
|
|
|
316
176
|
```bash
|
|
317
|
-
|
|
318
|
-
|
|
177
|
+
# Start LiteLLM proxy
|
|
178
|
+
docker run -d -p 4000:4000 \
|
|
179
|
+
-e MINIMAX_API_KEY=your-key \
|
|
180
|
+
-v config.yaml:/app/config.yaml \
|
|
181
|
+
ghcr.io/berriai/litellm:main-latest --config /app/config.yaml
|
|
319
182
|
```
|
|
320
183
|
|
|
321
|
-
|
|
184
|
+
```yaml
|
|
185
|
+
# config.yaml
|
|
186
|
+
model_list:
|
|
187
|
+
- model_name: minimax
|
|
188
|
+
litellm_params:
|
|
189
|
+
model: minimax/MiniMax-M2.7-highspeed
|
|
190
|
+
api_key: os.environ/MINIMAX_API_KEY
|
|
191
|
+
```
|
|
322
192
|
|
|
323
193
|
```json
|
|
194
|
+
// kody.config.json
|
|
324
195
|
{
|
|
325
196
|
"agent": {
|
|
326
197
|
"litellmUrl": "http://localhost:4000",
|
|
327
|
-
"modelMap": { "cheap": "
|
|
198
|
+
"modelMap": { "cheap": "minimax", "mid": "minimax", "strong": "minimax" }
|
|
328
199
|
}
|
|
329
200
|
}
|
|
330
201
|
```
|
|
331
202
|
|
|
332
|
-
|
|
203
|
+
LiteLLM translates Anthropic's tool-use protocol to the target provider's format. No code changes needed.
|
|
333
204
|
|
|
334
|
-
|
|
205
|
+
## Configuration
|
|
335
206
|
|
|
336
|
-
|
|
337
|
-
|------|-----------|---------|
|
|
338
|
-
| `task.md` | entry / issue fetch | Task description |
|
|
339
|
-
| `task.json` | taskify stage | Structured classification |
|
|
340
|
-
| `plan.md` | plan stage | Implementation steps |
|
|
341
|
-
| `verify.md` | verify stage | Quality gate results |
|
|
342
|
-
| `review.md` | review stage | Code review + verdict |
|
|
343
|
-
| `ship.md` | ship stage | PR URL |
|
|
344
|
-
| `status.json` | state machine | Pipeline state (per-stage) |
|
|
207
|
+
### `kody.config.json`
|
|
345
208
|
|
|
346
|
-
|
|
209
|
+
| Field | Description | Default |
|
|
210
|
+
|-------|-------------|---------|
|
|
211
|
+
| `quality.typecheck` | Typecheck command | `pnpm -s tsc --noEmit` |
|
|
212
|
+
| `quality.lint` | Lint command | `""` |
|
|
213
|
+
| `quality.lintFix` | Auto-fix lint | `""` |
|
|
214
|
+
| `quality.testUnit` | Unit test command | `pnpm -s test` |
|
|
215
|
+
| `git.defaultBranch` | Default branch | `dev` |
|
|
216
|
+
| `github.owner` | GitHub org/user | auto-detected |
|
|
217
|
+
| `github.repo` | Repository name | auto-detected |
|
|
218
|
+
| `agent.modelMap.cheap` | Taskify model | `haiku` |
|
|
219
|
+
| `agent.modelMap.mid` | Build/fix model | `sonnet` |
|
|
220
|
+
| `agent.modelMap.strong` | Plan/review model | `opus` |
|
|
221
|
+
| `agent.litellmUrl` | LiteLLM proxy URL | — |
|
|
347
222
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
│ ├── review.md
|
|
356
|
-
│ ├── review-fix.md
|
|
357
|
-
│ └── autofix.md
|
|
358
|
-
└── templates/
|
|
359
|
-
└── kody.yml — GitHub Actions workflow template
|
|
360
|
-
```
|
|
223
|
+
### Environment Variables
|
|
224
|
+
|
|
225
|
+
| Variable | Required | Description |
|
|
226
|
+
|----------|----------|-------------|
|
|
227
|
+
| `ANTHROPIC_API_KEY` | Yes | Claude API key (repo secret) |
|
|
228
|
+
| `GH_TOKEN` | Auto | GitHub token (provided by Actions) |
|
|
229
|
+
| `LOG_LEVEL` | No | `debug`, `info`, `warn`, `error` |
|
|
361
230
|
|
|
362
|
-
|
|
231
|
+
## Architecture
|
|
363
232
|
|
|
364
233
|
```
|
|
365
234
|
src/
|
|
366
|
-
├── entry.ts — CLI
|
|
235
|
+
├── entry.ts — CLI: run/rerun/fix/status, arg parsing, CI mode
|
|
236
|
+
├── state-machine.ts — Pipeline loop, stage dispatch, question gates, complexity
|
|
237
|
+
├── agent-runner.ts — Claude Code subprocess wrapper (thin — spawn, pipe, timeout)
|
|
238
|
+
├── context.ts — Prompt assembly + memory + task context injection
|
|
239
|
+
├── definitions.ts — 7-stage pipeline config
|
|
367
240
|
├── types.ts — TypeScript interfaces
|
|
368
|
-
├──
|
|
369
|
-
├──
|
|
370
|
-
├──
|
|
371
|
-
├── context.ts — Prompt assembly + task context injection
|
|
372
|
-
├── memory.ts — Project memory reader
|
|
373
|
-
├── config.ts — Config loading (kody.config.json)
|
|
374
|
-
├── logger.ts — Structured logging
|
|
375
|
-
├── preflight.ts — Startup checks
|
|
376
|
-
├── validators.ts — Output validation
|
|
241
|
+
├── config.ts — kody.config.json loader + constants
|
|
242
|
+
├── git-utils.ts — Branch, commit, push, sync, diff
|
|
243
|
+
├── github-api.ts — Issues, labels, PRs, comments via gh CLI
|
|
377
244
|
├── verify-runner.ts — Quality gate execution
|
|
245
|
+
├── validators.ts — Output validation (task.json, plan.md, review.md)
|
|
246
|
+
├── memory.ts — .kody/memory/ reader
|
|
247
|
+
├── logger.ts — Structured logging with CI groups
|
|
248
|
+
├── preflight.ts — Startup health checks
|
|
378
249
|
├── kody-utils.ts — Task directory utilities
|
|
379
|
-
|
|
380
|
-
├── github-api.ts — GitHub API via gh CLI
|
|
381
|
-
└── bin/cli.ts — Package CLI (init, run, version)
|
|
250
|
+
└── bin/cli.ts — Package CLI: init (LLM-powered), run, version
|
|
382
251
|
```
|
|
383
252
|
|
|
384
253
|
## Development
|
|
385
254
|
|
|
386
255
|
```bash
|
|
387
|
-
# Install deps
|
|
388
|
-
pnpm
|
|
256
|
+
pnpm install # Install deps
|
|
257
|
+
pnpm typecheck # Type check
|
|
258
|
+
pnpm test # 125 tests (16 files)
|
|
259
|
+
pnpm build # Build npm package
|
|
260
|
+
pnpm kody run ... # Dev mode (tsx)
|
|
261
|
+
npm publish --access public # Publish
|
|
262
|
+
```
|
|
389
263
|
|
|
390
|
-
|
|
391
|
-
pnpm typecheck
|
|
264
|
+
## Security
|
|
392
265
|
|
|
393
|
-
|
|
394
|
-
pnpm kody run --task-id test --task "Add feature" --cwd /path/to/project
|
|
266
|
+
Only GitHub collaborators (COLLABORATOR, MEMBER, OWNER) can trigger `@kody`. External contributors cannot.
|
|
395
267
|
|
|
396
|
-
|
|
397
|
-
pnpm build
|
|
268
|
+
## License
|
|
398
269
|
|
|
399
|
-
|
|
400
|
-
npm publish --access public
|
|
401
|
-
```
|
|
270
|
+
MIT
|
package/dist/bin/cli.js
CHANGED
|
@@ -107,26 +107,6 @@ function createClaudeCodeRunner() {
|
|
|
107
107
|
}
|
|
108
108
|
};
|
|
109
109
|
}
|
|
110
|
-
function createOpenCodeRunner() {
|
|
111
|
-
return {
|
|
112
|
-
async run(stageName, prompt, model, timeout, _taskDir, options) {
|
|
113
|
-
const args2 = ["run", "--agent", "build"];
|
|
114
|
-
if (model) {
|
|
115
|
-
args2.push("--model", model);
|
|
116
|
-
}
|
|
117
|
-
return runSubprocess(
|
|
118
|
-
"opencode",
|
|
119
|
-
args2,
|
|
120
|
-
prompt,
|
|
121
|
-
timeout,
|
|
122
|
-
options
|
|
123
|
-
);
|
|
124
|
-
},
|
|
125
|
-
async healthCheck() {
|
|
126
|
-
return checkCommand("opencode", ["--version"]);
|
|
127
|
-
}
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
110
|
function createRunners(config) {
|
|
131
111
|
if (config.agent.runners && Object.keys(config.agent.runners).length > 0) {
|
|
132
112
|
const runners = {};
|
|
@@ -150,8 +130,7 @@ var init_agent_runner = __esm({
|
|
|
150
130
|
SIGKILL_GRACE_MS = 5e3;
|
|
151
131
|
STDERR_TAIL_CHARS = 500;
|
|
152
132
|
RUNNER_FACTORIES = {
|
|
153
|
-
"claude-code": createClaudeCodeRunner
|
|
154
|
-
"opencode": createOpenCodeRunner
|
|
133
|
+
"claude-code": createClaudeCodeRunner
|
|
155
134
|
};
|
|
156
135
|
}
|
|
157
136
|
});
|
|
@@ -552,11 +531,20 @@ function getCurrentBranch(cwd) {
|
|
|
552
531
|
}
|
|
553
532
|
function ensureFeatureBranch(issueNumber, title, cwd) {
|
|
554
533
|
const current = getCurrentBranch(cwd);
|
|
555
|
-
|
|
534
|
+
const branchName = deriveBranchName(issueNumber, title);
|
|
535
|
+
if (current === branchName || current.startsWith(`${issueNumber}-`)) {
|
|
556
536
|
logger.info(` Already on feature branch: ${current}`);
|
|
557
537
|
return current;
|
|
558
538
|
}
|
|
559
|
-
|
|
539
|
+
if (!BASE_BRANCHES.includes(current) && current !== "") {
|
|
540
|
+
const defaultBranch2 = getDefaultBranch(cwd);
|
|
541
|
+
logger.info(` Switching from ${current} to ${defaultBranch2} before creating ${branchName}`);
|
|
542
|
+
try {
|
|
543
|
+
git(["checkout", defaultBranch2], { cwd });
|
|
544
|
+
} catch {
|
|
545
|
+
logger.warn(` Failed to checkout ${defaultBranch2}`);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
560
548
|
try {
|
|
561
549
|
git(["fetch", "origin"], { cwd, timeout: 3e4 });
|
|
562
550
|
} catch {
|
|
@@ -1711,6 +1699,60 @@ function parseArgs() {
|
|
|
1711
1699
|
complexity: getArg(args2, "--complexity") ?? process.env.COMPLEXITY
|
|
1712
1700
|
};
|
|
1713
1701
|
}
|
|
1702
|
+
async function checkLitellmHealth(url) {
|
|
1703
|
+
try {
|
|
1704
|
+
const response = await fetch(`${url}/health`, { signal: AbortSignal.timeout(3e3) });
|
|
1705
|
+
return response.ok;
|
|
1706
|
+
} catch {
|
|
1707
|
+
return false;
|
|
1708
|
+
}
|
|
1709
|
+
}
|
|
1710
|
+
async function tryStartLitellm(url, projectDir) {
|
|
1711
|
+
const configPath = path5.join(projectDir, "litellm-config.yaml");
|
|
1712
|
+
if (!fs6.existsSync(configPath)) {
|
|
1713
|
+
logger.warn("litellm-config.yaml not found \u2014 cannot start proxy");
|
|
1714
|
+
return null;
|
|
1715
|
+
}
|
|
1716
|
+
const portMatch = url.match(/:(\d+)/);
|
|
1717
|
+
const port = portMatch ? portMatch[1] : "4000";
|
|
1718
|
+
try {
|
|
1719
|
+
execFileSync7("litellm", ["--version"], { timeout: 5e3, stdio: "pipe" });
|
|
1720
|
+
} catch {
|
|
1721
|
+
try {
|
|
1722
|
+
execFileSync7("python3", ["-m", "litellm", "--version"], { timeout: 5e3, stdio: "pipe" });
|
|
1723
|
+
} catch {
|
|
1724
|
+
logger.warn("litellm not installed (pip install 'litellm[proxy]')");
|
|
1725
|
+
return null;
|
|
1726
|
+
}
|
|
1727
|
+
}
|
|
1728
|
+
logger.info(`Starting LiteLLM proxy on port ${port}...`);
|
|
1729
|
+
let cmd;
|
|
1730
|
+
let args2;
|
|
1731
|
+
try {
|
|
1732
|
+
execFileSync7("litellm", ["--version"], { timeout: 5e3, stdio: "pipe" });
|
|
1733
|
+
cmd = "litellm";
|
|
1734
|
+
args2 = ["--config", configPath, "--port", port];
|
|
1735
|
+
} catch {
|
|
1736
|
+
cmd = "python3";
|
|
1737
|
+
args2 = ["-m", "litellm", "--config", configPath, "--port", port];
|
|
1738
|
+
}
|
|
1739
|
+
const { spawn: spawn2 } = await import("child_process");
|
|
1740
|
+
const child = spawn2(cmd, args2, {
|
|
1741
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
1742
|
+
detached: true,
|
|
1743
|
+
env: process.env
|
|
1744
|
+
});
|
|
1745
|
+
for (let i = 0; i < 30; i++) {
|
|
1746
|
+
await new Promise((r) => setTimeout(r, 2e3));
|
|
1747
|
+
if (await checkLitellmHealth(url)) {
|
|
1748
|
+
logger.info(`LiteLLM proxy ready at ${url}`);
|
|
1749
|
+
return child;
|
|
1750
|
+
}
|
|
1751
|
+
}
|
|
1752
|
+
logger.warn("LiteLLM proxy failed to start within 60s");
|
|
1753
|
+
child.kill();
|
|
1754
|
+
return null;
|
|
1755
|
+
}
|
|
1714
1756
|
function findLatestTaskForIssue(issueNumber, projectDir) {
|
|
1715
1757
|
const tasksDir = path5.join(projectDir, ".tasks");
|
|
1716
1758
|
if (!fs6.existsSync(tasksDir)) return null;
|
|
@@ -1838,11 +1880,31 @@ ${issue.body ?? ""}`;
|
|
|
1838
1880
|
process.exit(1);
|
|
1839
1881
|
}
|
|
1840
1882
|
} else {
|
|
1841
|
-
|
|
1842
|
-
|
|
1883
|
+
logger.info("No status.json found \u2014 running full pipeline with feedback");
|
|
1884
|
+
input.command = "run";
|
|
1843
1885
|
}
|
|
1844
1886
|
}
|
|
1845
1887
|
const config = getProjectConfig();
|
|
1888
|
+
let litellmProcess = null;
|
|
1889
|
+
const cleanupLitellm = () => {
|
|
1890
|
+
if (litellmProcess) {
|
|
1891
|
+
litellmProcess.kill();
|
|
1892
|
+
litellmProcess = null;
|
|
1893
|
+
}
|
|
1894
|
+
};
|
|
1895
|
+
process.on("exit", cleanupLitellm);
|
|
1896
|
+
if (config.agent.litellmUrl) {
|
|
1897
|
+
const proxyRunning = await checkLitellmHealth(config.agent.litellmUrl);
|
|
1898
|
+
if (!proxyRunning) {
|
|
1899
|
+
litellmProcess = await tryStartLitellm(config.agent.litellmUrl, projectDir);
|
|
1900
|
+
if (!litellmProcess) {
|
|
1901
|
+
logger.warn("LiteLLM not available \u2014 falling back to Anthropic models");
|
|
1902
|
+
config.agent.litellmUrl = void 0;
|
|
1903
|
+
}
|
|
1904
|
+
} else {
|
|
1905
|
+
logger.info(`LiteLLM proxy already running at ${config.agent.litellmUrl}`);
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1846
1908
|
const runners = createRunners(config);
|
|
1847
1909
|
const defaultRunnerName = config.agent.defaultRunner ?? Object.keys(runners)[0] ?? "claude";
|
|
1848
1910
|
const defaultRunner = runners[defaultRunnerName];
|
|
@@ -2139,8 +2201,7 @@ function detectBasicConfig(cwd) {
|
|
|
2139
2201
|
}
|
|
2140
2202
|
} catch {
|
|
2141
2203
|
}
|
|
2142
|
-
|
|
2143
|
-
return { defaultBranch, owner, repo, pm, hasOpenCode };
|
|
2204
|
+
return { defaultBranch, owner, repo, pm };
|
|
2144
2205
|
}
|
|
2145
2206
|
function smartInit(cwd) {
|
|
2146
2207
|
const basic = detectBasicConfig(cwd);
|
|
@@ -2190,14 +2251,14 @@ ${srcDirs.join(", ")}
|
|
|
2190
2251
|
} catch {
|
|
2191
2252
|
}
|
|
2192
2253
|
const existingFiles = [];
|
|
2193
|
-
for (const f of [".env.example", "CLAUDE.md", ".ai-docs", "
|
|
2254
|
+
for (const f of [".env.example", "CLAUDE.md", ".ai-docs", "vitest.config.ts", "vitest.config.mts", "jest.config.ts", "playwright.config.ts", ".eslintrc.js", "eslint.config.mjs", ".prettierrc"]) {
|
|
2194
2255
|
if (fs7.existsSync(path6.join(cwd, f))) existingFiles.push(f);
|
|
2195
2256
|
}
|
|
2196
2257
|
if (existingFiles.length) context += `## Config files present
|
|
2197
2258
|
${existingFiles.join(", ")}
|
|
2198
2259
|
|
|
2199
2260
|
`;
|
|
2200
|
-
context += `## Detected: package manager=${basic.pm}, default branch=${basic.defaultBranch}, github=${basic.owner}/${basic.repo}
|
|
2261
|
+
context += `## Detected: package manager=${basic.pm}, default branch=${basic.defaultBranch}, github=${basic.owner}/${basic.repo}
|
|
2201
2262
|
`;
|
|
2202
2263
|
const prompt = `You are analyzing a project to configure Kody (an autonomous SDLC pipeline).
|
|
2203
2264
|
|
|
@@ -2217,8 +2278,8 @@ Given this project context, output ONLY a JSON object with EXACTLY this structur
|
|
|
2217
2278
|
"github": { "owner": "${basic.owner}", "repo": "${basic.repo}" },
|
|
2218
2279
|
"paths": { "taskDir": ".tasks" },
|
|
2219
2280
|
"agent": {
|
|
2220
|
-
"runner": "${
|
|
2221
|
-
"defaultRunner": "${
|
|
2281
|
+
"runner": "${"claude-code"}",
|
|
2282
|
+
"defaultRunner": "${"claude"}",
|
|
2222
2283
|
"modelMap": { "cheap": "haiku", "mid": "sonnet", "strong": "opus" }
|
|
2223
2284
|
}
|
|
2224
2285
|
},
|
|
@@ -2269,12 +2330,13 @@ ${context}`;
|
|
|
2269
2330
|
if (!config.github) config.github = {};
|
|
2270
2331
|
if (!config.paths) config.paths = {};
|
|
2271
2332
|
if (!config.agent) config.agent = {};
|
|
2333
|
+
config["$schema"] = "https://raw.githubusercontent.com/aharonyaircohen/Kody-Engine-Lite/main/kody.config.schema.json";
|
|
2272
2334
|
config.git.defaultBranch = config.git.defaultBranch || basic.defaultBranch;
|
|
2273
2335
|
config.github.owner = config.github.owner || basic.owner;
|
|
2274
2336
|
config.github.repo = config.github.repo || basic.repo;
|
|
2275
2337
|
config.paths.taskDir = config.paths.taskDir || ".tasks";
|
|
2276
|
-
config.agent.runner = config.agent.runner ||
|
|
2277
|
-
config.agent.defaultRunner = config.agent.defaultRunner ||
|
|
2338
|
+
config.agent.runner = config.agent.runner || "claude-code";
|
|
2339
|
+
config.agent.defaultRunner = config.agent.defaultRunner || "claude";
|
|
2278
2340
|
if (!config.agent.modelMap) {
|
|
2279
2341
|
config.agent.modelMap = { cheap: "haiku", mid: "sonnet", strong: "opus" };
|
|
2280
2342
|
}
|
|
@@ -2343,6 +2405,7 @@ function buildFallbackConfig(cwd, basic) {
|
|
|
2343
2405
|
return "";
|
|
2344
2406
|
};
|
|
2345
2407
|
return {
|
|
2408
|
+
"$schema": "https://raw.githubusercontent.com/aharonyaircohen/Kody-Engine-Lite/main/kody.config.schema.json",
|
|
2346
2409
|
quality: {
|
|
2347
2410
|
typecheck: find("typecheck", "type-check") || (pkg.devDependencies?.typescript ? `${basic.pm} tsc --noEmit` : ""),
|
|
2348
2411
|
lint: find("lint"),
|
|
@@ -2355,8 +2418,8 @@ function buildFallbackConfig(cwd, basic) {
|
|
|
2355
2418
|
github: { owner: basic.owner, repo: basic.repo },
|
|
2356
2419
|
paths: { taskDir: ".tasks" },
|
|
2357
2420
|
agent: {
|
|
2358
|
-
runner:
|
|
2359
|
-
defaultRunner:
|
|
2421
|
+
runner: "claude-code",
|
|
2422
|
+
defaultRunner: "claude",
|
|
2360
2423
|
modelMap: { cheap: "haiku", mid: "sonnet", strong: "opus" }
|
|
2361
2424
|
}
|
|
2362
2425
|
};
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"title": "Kody Engine Lite Configuration",
|
|
4
|
+
"description": "Configuration for the Kody autonomous SDLC pipeline. See https://github.com/aharonyaircohen/Kody-Engine-Lite",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"quality": {
|
|
8
|
+
"type": "object",
|
|
9
|
+
"description": "Quality gate commands run during the verify stage. Leave empty string to skip.",
|
|
10
|
+
"properties": {
|
|
11
|
+
"typecheck": {
|
|
12
|
+
"type": "string",
|
|
13
|
+
"description": "TypeScript type checking command (e.g., 'pnpm typecheck', 'pnpm tsc --noEmit')",
|
|
14
|
+
"default": "pnpm -s tsc --noEmit"
|
|
15
|
+
},
|
|
16
|
+
"lint": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"description": "Lint command (e.g., 'pnpm lint'). Empty to skip.",
|
|
19
|
+
"default": ""
|
|
20
|
+
},
|
|
21
|
+
"lintFix": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"description": "Auto-fix lint command, run when verify fails (e.g., 'pnpm lint:fix')",
|
|
24
|
+
"default": ""
|
|
25
|
+
},
|
|
26
|
+
"format": {
|
|
27
|
+
"type": "string",
|
|
28
|
+
"description": "Format check command (e.g., 'pnpm format:check'). Empty to skip.",
|
|
29
|
+
"default": ""
|
|
30
|
+
},
|
|
31
|
+
"formatFix": {
|
|
32
|
+
"type": "string",
|
|
33
|
+
"description": "Auto-fix format command, run when verify fails (e.g., 'pnpm format')",
|
|
34
|
+
"default": ""
|
|
35
|
+
},
|
|
36
|
+
"testUnit": {
|
|
37
|
+
"type": "string",
|
|
38
|
+
"description": "Unit test command. Use test:unit to exclude integration/e2e tests (e.g., 'pnpm test:unit')",
|
|
39
|
+
"default": "pnpm -s test"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"additionalProperties": false
|
|
43
|
+
},
|
|
44
|
+
"git": {
|
|
45
|
+
"type": "object",
|
|
46
|
+
"description": "Git configuration",
|
|
47
|
+
"properties": {
|
|
48
|
+
"defaultBranch": {
|
|
49
|
+
"type": "string",
|
|
50
|
+
"description": "Default branch for PR base and branch syncing (e.g., 'main', 'dev')",
|
|
51
|
+
"default": "dev"
|
|
52
|
+
},
|
|
53
|
+
"userEmail": {
|
|
54
|
+
"type": "string",
|
|
55
|
+
"description": "Git user email for CI commits (optional, defaults to github-actions bot)"
|
|
56
|
+
},
|
|
57
|
+
"userName": {
|
|
58
|
+
"type": "string",
|
|
59
|
+
"description": "Git user name for CI commits (optional, defaults to github-actions bot)"
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"additionalProperties": false
|
|
63
|
+
},
|
|
64
|
+
"github": {
|
|
65
|
+
"type": "object",
|
|
66
|
+
"description": "GitHub repository settings. Auto-detected from git remote by init.",
|
|
67
|
+
"properties": {
|
|
68
|
+
"owner": {
|
|
69
|
+
"type": "string",
|
|
70
|
+
"description": "GitHub organization or username (e.g., 'my-org')"
|
|
71
|
+
},
|
|
72
|
+
"repo": {
|
|
73
|
+
"type": "string",
|
|
74
|
+
"description": "GitHub repository name (e.g., 'my-repo')"
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
"additionalProperties": false
|
|
78
|
+
},
|
|
79
|
+
"paths": {
|
|
80
|
+
"type": "object",
|
|
81
|
+
"description": "File path configuration",
|
|
82
|
+
"properties": {
|
|
83
|
+
"taskDir": {
|
|
84
|
+
"type": "string",
|
|
85
|
+
"description": "Directory for pipeline artifacts and state (gitignored)",
|
|
86
|
+
"default": ".tasks"
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
"additionalProperties": false
|
|
90
|
+
},
|
|
91
|
+
"agent": {
|
|
92
|
+
"type": "object",
|
|
93
|
+
"description": "Agent execution configuration",
|
|
94
|
+
"properties": {
|
|
95
|
+
"runner": {
|
|
96
|
+
"type": "string",
|
|
97
|
+
"description": "Agent runner type",
|
|
98
|
+
"enum": ["claude-code"],
|
|
99
|
+
"default": "claude-code"
|
|
100
|
+
},
|
|
101
|
+
"defaultRunner": {
|
|
102
|
+
"type": "string",
|
|
103
|
+
"description": "Name of the default runner to use",
|
|
104
|
+
"default": "claude"
|
|
105
|
+
},
|
|
106
|
+
"modelMap": {
|
|
107
|
+
"type": "object",
|
|
108
|
+
"description": "Maps model tiers to actual model names. Use LiteLLM aliases when litellmUrl is set.",
|
|
109
|
+
"properties": {
|
|
110
|
+
"cheap": {
|
|
111
|
+
"type": "string",
|
|
112
|
+
"description": "Fast/cheap model for taskify stage (e.g., 'haiku' or LiteLLM alias)",
|
|
113
|
+
"default": "haiku"
|
|
114
|
+
},
|
|
115
|
+
"mid": {
|
|
116
|
+
"type": "string",
|
|
117
|
+
"description": "Mid-tier model for build, review-fix, autofix (e.g., 'sonnet' or LiteLLM alias)",
|
|
118
|
+
"default": "sonnet"
|
|
119
|
+
},
|
|
120
|
+
"strong": {
|
|
121
|
+
"type": "string",
|
|
122
|
+
"description": "Strongest model for plan, review — deep reasoning (e.g., 'opus' or LiteLLM alias)",
|
|
123
|
+
"default": "opus"
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
"additionalProperties": false
|
|
127
|
+
},
|
|
128
|
+
"litellmUrl": {
|
|
129
|
+
"type": "string",
|
|
130
|
+
"description": "LiteLLM proxy URL for using non-Anthropic models (e.g., 'http://localhost:4000'). Sets ANTHROPIC_BASE_URL for Claude Code.",
|
|
131
|
+
"examples": ["http://localhost:4000"]
|
|
132
|
+
},
|
|
133
|
+
"usePerStageRouting": {
|
|
134
|
+
"type": "boolean",
|
|
135
|
+
"description": "When true, uses stage name as the LiteLLM model alias instead of modelMap tier",
|
|
136
|
+
"default": false
|
|
137
|
+
},
|
|
138
|
+
"runners": {
|
|
139
|
+
"type": "object",
|
|
140
|
+
"description": "Named runner definitions (advanced)",
|
|
141
|
+
"additionalProperties": {
|
|
142
|
+
"type": "object",
|
|
143
|
+
"properties": {
|
|
144
|
+
"type": {
|
|
145
|
+
"type": "string",
|
|
146
|
+
"enum": ["claude-code"]
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
"required": ["type"]
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
"stageRunners": {
|
|
153
|
+
"type": "object",
|
|
154
|
+
"description": "Per-stage runner assignment (advanced). Maps stage name to runner name.",
|
|
155
|
+
"properties": {
|
|
156
|
+
"taskify": { "type": "string" },
|
|
157
|
+
"plan": { "type": "string" },
|
|
158
|
+
"build": { "type": "string" },
|
|
159
|
+
"autofix": { "type": "string" },
|
|
160
|
+
"review": { "type": "string" },
|
|
161
|
+
"review-fix": { "type": "string" }
|
|
162
|
+
},
|
|
163
|
+
"additionalProperties": false
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
"additionalProperties": false
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
"additionalProperties": false
|
|
170
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kody-ade/kody-engine-lite",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.21",
|
|
4
4
|
"description": "Autonomous SDLC pipeline: Kody orchestration + Claude Code + LiteLLM",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
"files": [
|
|
11
11
|
"dist",
|
|
12
12
|
"prompts",
|
|
13
|
-
"templates"
|
|
13
|
+
"templates",
|
|
14
|
+
"kody.config.schema.json"
|
|
14
15
|
],
|
|
15
16
|
"scripts": {
|
|
16
17
|
"kody": "tsx src/entry.ts",
|