@kody-ade/kody-engine 0.4.398 → 0.4.400

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.
@@ -74,7 +74,7 @@ If a prior-art block is present above, READ THE DIFFS — those are failed or su
74
74
  - **No speculative refactors.** Stay inside the issue's scope. Do not rename variables, retype function signatures, restructure modules, reorder imports, reformat unchanged lines, or "clean up" code adjacent to the change unless that cleanup is *required* by the change. Scope drift in your diff is a hard failure even if the change works — reviewers can't tell what was intentional. If you find a real adjacent bug while working, mention it in `PR_SUMMARY` (without fixing it) so a follow-up issue can be opened.
75
75
  - Do NOT run **any** `git` or `gh` commands. The wrapper handles all git/gh operations. If a quality gate fails, that's the failure — do not investigate it via git.
76
76
  - Stay on the current branch (`{{branch}}`). It is already checked out for you.
77
- - Do NOT modify files under: `.kody/`, `.kody-engine/`, `.kody-lean/`, `.kody/`, `node_modules/`, `dist/`, `build/`, `.env`, or any `*.log`.
77
+ - Do NOT modify files under: `.kody-engine/`, `.kody-lean/`, `node_modules/`, `dist/`, `build/`, `.env`, or any `*.log`.
78
78
  - Do NOT post issue comments — the wrapper handles that.
79
79
  - Pre-existing quality-gate failures: assume they are NOT yours unless your edits touched related code.
80
80
  - Keep the plan and reasoning concise. Long monologues waste turns.
@@ -49,7 +49,7 @@ export interface Profile {
49
49
  action?: string
50
50
  /**
51
51
  * Optional agent this implementation runs *as*. When set, the executor
52
- * loads hydrated `.kody/agents/<agent>.md` and injects that agent (authoritative
52
+ * loads hydrated `.kody-engine/definitions/agents/<agent>.md` and injects that agent (authoritative
53
53
  * identity) ahead of the implementation's own system-prompt append. This is the
54
54
  * unification hook: a capability can select an implementation + an agent. Absent →
55
55
  * runs with no agent (unchanged legacy behaviour). A declared-but-missing
@@ -202,7 +202,7 @@ export interface Profile {
202
202
  * preflight runs. composePrompt prefers these over a fresh disk read so the
203
203
  * template survives working-tree churn from runFlow's branch setup — on the CI
204
204
  * runner a branch checkout can drop the tracked-but-ignore-negated
205
- * `.kody/capabilities/<name>/` dir, and reading prompt.md afterwards fails with
205
+ * `.kody-engine/definitions/capabilities/<name>/` dir, and reading prompt.md afterwards fails with
206
206
  * ENOENT even though profile.json (read here, earlier) loaded fine.
207
207
  */
208
208
  promptTemplates?: Record<string, string>
@@ -210,7 +210,7 @@ export interface Profile {
210
210
  * Subagent markdown captured (by declared name) at load time, BEFORE any
211
211
  * task branch switch — same rationale as promptTemplates. loadSubagents
212
212
  * prefers this snapshot so a capability's `agents/` surviving only on the default
213
- * checkout (e.g. `.kody/capabilities/<slug>/agents/` absent on a PR branch) doesn't
213
+ * checkout (e.g. `.kody-engine/definitions/capabilities/<slug>/agents/` absent on a PR branch) doesn't
214
214
  * crash a PR-targeted capability. Populated by captureSubagentTemplates.
215
215
  */
216
216
  subagentTemplates?: Record<string, string>
@@ -53,22 +53,6 @@
53
53
  "repo": { "type": "string" }
54
54
  }
55
55
  },
56
- "state": {
57
- "type": "object",
58
- "description": "External repository and path used for Kody runtime state.",
59
- "additionalProperties": false,
60
- "properties": {
61
- "repo": {
62
- "type": "string",
63
- "description": "Full GitHub repository URL for Kody runtime state.",
64
- "pattern": "^https://github\\.com/[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+(?:\\.git)?$"
65
- },
66
- "path": {
67
- "type": "string",
68
- "description": "Folder inside state.repo that belongs to this consumer repo."
69
- }
70
- }
71
- },
72
56
  "agent": {
73
57
  "type": "object",
74
58
  "required": ["model"],
@@ -171,17 +155,6 @@
171
155
  }
172
156
  }
173
157
  },
174
- "jobs": {
175
- "type": "object",
176
- "additionalProperties": false,
177
- "properties": {
178
- "stateBackend": {
179
- "type": "string",
180
- "enum": ["contents-api"],
181
- "default": "contents-api"
182
- }
183
- }
184
- },
185
158
  "access": {
186
159
  "type": "object",
187
160
  "additionalProperties": false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kody-ade/kody-engine",
3
- "version": "0.4.398",
3
+ "version": "0.4.400",
4
4
  "description": "kody — autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative implementation profiles.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -12,28 +12,6 @@
12
12
  "templates",
13
13
  "kody.config.schema.json"
14
14
  ],
15
- "scripts": {
16
- "kody:run": "tsx bin/kody.ts",
17
- "serve": "tsx bin/kody.ts serve",
18
- "serve:vscode": "tsx bin/kody.ts serve vscode",
19
- "serve:claude": "tsx bin/kody.ts serve claude",
20
- "clean:dist": "node scripts/clean-dist.cjs",
21
- "build": "pnpm clean:dist && tsup && node scripts/copy-assets.cjs",
22
- "check:modularity": "tsx scripts/check-script-modularity.ts",
23
- "pretest": "pnpm check:modularity",
24
- "test": "vitest run tests/unit tests/int --coverage",
25
- "posttest": "tsx scripts/check-coverage-floor.ts",
26
- "test:smoke": "vitest run tests/smoke --no-coverage",
27
- "test:e2e": "vitest run tests/e2e --no-coverage",
28
- "test:all": "vitest run tests --no-coverage",
29
- "typecheck": "tsc --noEmit",
30
- "lint": "biome check",
31
- "lint:fix": "biome check --write",
32
- "format": "biome format --write",
33
- "verify:package": "node scripts/verify-package-tarball.cjs",
34
- "brain:publish": "docker buildx build --platform linux/amd64 -f runner/Dockerfile.brain -t ghcr.io/${KODY_BRAIN_GHCR_OWNER:-aharonyaircohen}/kody-brain:latest --push runner",
35
- "prepublishOnly": "pnpm typecheck && vitest run tests/unit tests/int --no-coverage && pnpm build && pnpm verify:package"
36
- },
37
15
  "dependencies": {
38
16
  "@actions/cache": "^6.0.0",
39
17
  "@anthropic-ai/claude-agent-sdk": "0.2.119",
@@ -58,5 +36,26 @@
58
36
  "url": "git+https://github.com/aharonyaircohen/kody-engine.git"
59
37
  },
60
38
  "homepage": "https://github.com/aharonyaircohen/kody-engine",
61
- "bugs": "https://github.com/aharonyaircohen/kody-engine/issues"
62
- }
39
+ "bugs": "https://github.com/aharonyaircohen/kody-engine/issues",
40
+ "scripts": {
41
+ "kody:run": "tsx bin/kody.ts",
42
+ "serve": "tsx bin/kody.ts serve",
43
+ "serve:vscode": "tsx bin/kody.ts serve vscode",
44
+ "serve:claude": "tsx bin/kody.ts serve claude",
45
+ "clean:dist": "node scripts/clean-dist.cjs",
46
+ "build": "pnpm clean:dist && tsup && node scripts/copy-assets.cjs",
47
+ "check:modularity": "tsx scripts/check-script-modularity.ts",
48
+ "pretest": "pnpm check:modularity",
49
+ "test": "vitest run tests/unit tests/int --coverage",
50
+ "posttest": "tsx scripts/check-coverage-floor.ts",
51
+ "test:smoke": "vitest run tests/smoke --no-coverage",
52
+ "test:e2e": "vitest run tests/e2e --no-coverage",
53
+ "test:all": "vitest run tests --no-coverage",
54
+ "typecheck": "tsc --noEmit",
55
+ "lint": "biome check",
56
+ "lint:fix": "biome check --write",
57
+ "format": "biome format --write",
58
+ "verify:package": "node scripts/verify-package-tarball.cjs",
59
+ "brain:publish": "docker buildx build --platform linux/amd64 -f runner/Dockerfile.brain -t ghcr.io/${KODY_BRAIN_GHCR_OWNER:-aharonyaircohen}/kody-brain:latest --push runner"
60
+ }
61
+ }
@@ -1,175 +0,0 @@
1
- # Goal Manager .
2
-
3
- Autonomous manager for **manager-driven goals**. One worker, every goal:
4
- each tick it picks up every goal flagged `managed`, breaks it into tasks,
5
- lets the deterministic `goal-tick` execute them, verifies the
6
- end-to-end user journey with `qa-engineer`, recovers stalled tasks, and
7
- stops a goal only when its single deliverable PR is open and the journey
8
- passes. It never edits code and never merges anything.
9
-
10
- > Drop this file at `.kody/workers/goal-manager.md` in a consumer repo.
11
- > The `worker-scheduler` cron invokes `worker-tick` on it automatically.
12
-
13
- ## Worker
14
-
15
- You coordinate goals **only** through `gh`. You do not write code, open
16
- PRs, or merge. Everything below is per-goal; you handle all goals in one
17
- tick.
18
-
19
- ### 1. Discover managed goals
20
-
21
- ```
22
- ls .kody/goals/*/state.json 2>/dev/null
23
- ```
24
-
25
- For each, read it (`cat`). A goal is **in scope** when BOTH:
26
-
27
- - `.state == "active"`, and
28
- - `.managed == true` (the dashboard's "Let Kody manage this goal" toggle
29
- writes this; absent/false → ignore the goal entirely).
30
-
31
- For an in-scope goal, the goal **id** is the directory name
32
- (`.kody/goals/<id>/state.json`). Its definition (intent + the ordered
33
- end-to-end user journey that defines "done") is, in priority order:
34
-
35
- 1. `.journey` / `.description` / `.intent` / `.title` fields in
36
- `state.json` if present, else
37
- 2. the goal's GitHub Discussion body — if `state.json` has a
38
- `discussionNumber`, fetch it:
39
- `gh api graphql -f query='{repository(owner:"OWNER",name:"REPO"){discussion(number:N){body title}}}'`
40
- (resolve OWNER/REPO from `gh repo view --json owner,name`).
41
-
42
- The **journey** is the acceptance test. If you cannot find any journey
43
- text, do NOT guess — escalate the goal (see §5) with reason
44
- `no-journey-defined` and skip it.
45
-
46
- ### 2. Per-goal cursor
47
-
48
- Keep all per-goal progress under `data.goals[<id>]`. Each entry:
49
-
50
- ```
51
- { "cursor": "...", "tasks": [<issue numbers you created>],
52
- "gate": <qa-gate issue number|null>, "qaRound": <int>,
53
- "stall": { "<issueNumber>": { "ticks": <int>, "attempts": <int> } },
54
- "lastQaTick": "<ISO>" }
55
- ```
56
-
57
- `cursor` ∈ `new | building | qa | finalizing | done | escalated`.
58
- Missing entry ⇒ treat as `new`.
59
-
60
- ### 3. Decompose (`cursor: new`)
61
-
62
- One-time setup for the goal:
63
-
64
- 1. Ensure labels exist (idempotent — ignore "already exists"):
65
- `gh label create "goal:<id>" --color 5319e7 2>/dev/null || true`
66
- `gh label create "kody:qa-gate" --color b60205 2>/dev/null || true`
67
- `gh label create "kody:needs-human" --color d93f0b 2>/dev/null || true`
68
- 2. Break the goal into the **smallest correct set of sequential tasks**.
69
- For each, create an issue:
70
- `gh issue create --title "<task>" --label "goal:<id>" --body "<precise spec, acceptance criteria>"`
71
- Record the returned issue numbers in `tasks`. Order matters — the
72
- stacked-PR model builds them lowest-number first.
73
- 3. Create the **QA gate** issue (exactly one per goal):
74
- `gh issue create --title "QA gate: <id> — end-to-end journey" --label "goal:<id>" --label "kody:qa-gate" --body "<the full ordered journey, step 1 → success state>"`
75
- Record its number in `gate`.
76
- 4. Set `cursor: building`. **Do not** dispatch anything yourself —
77
- `goal-tick` (its own cron) sees the new `goal:<id>` issues and drives
78
- them. The open `kody:qa-gate` issue keeps the goal short of
79
- `all-done`, so nothing finalizes until you close it in §4.
80
-
81
- ### 4. Drive + recover (`cursor: building`)
82
-
83
- Each tick, for the goal:
84
-
85
- - Enumerate tasks:
86
- `gh issue list --label "goal:<id>" --state all --json number,state,title`
87
- and the PRs:
88
- `gh pr list --state open --json number,headRefName,body,isDraft`.
89
- A task is **done** when its issue is CLOSED or it has a ready
90
- (non-draft) open PR (`Closes #<n>` in body, or head ref `^<n>-`).
91
- - **Stall detection** (per non-gate, non-done task):
92
- - Increment `stall[n].ticks`.
93
- - If the task has **no open PR** and `stall[n].ticks >= 3`: it was
94
- never picked up — re-nudge: `gh issue comment <n> --body "@kody"`,
95
- `stall[n].attempts += 1`, reset `stall[n].ticks = 0`.
96
- - If the task has a **draft PR with no new commits** for
97
- `stall[n].ticks >= 4`: comment `@kody continue` on the PR, bump
98
- attempts, reset ticks.
99
- - When `stall[n].attempts >= 3` for any task → escalate (§5) and set
100
- `cursor: escalated`.
101
- - Clear `stall[n]` once the task is done.
102
- - When **every non-gate task is done** → `cursor: qa`.
103
-
104
- ### 4b. Verify the journey (`cursor: qa`)
105
-
106
- - Throttle: skip if `lastQaTick` is < 20 min ago (avoid stacking QA
107
- runs); otherwise:
108
- - Trigger QA against the journey by commenting on the **gate issue**:
109
- `gh issue comment <gate> --body "@kody qa-engineer --goal <id> --scope \"<the full journey text>\""`
110
- Set `lastQaTick` = now, `qaRound += 1`.
111
- - `qa-engineer` browses the running app and files **each failure as a
112
- new `goal:<id>` task issue** automatically. So on the **next** tick:
113
- - If new `goal:<id>` task issues appeared after this `qaRound` (issues
114
- you didn't create / not in `tasks`) → add them to `tasks`, set
115
- `cursor: building` (the loop fixes them, then QA re-runs).
116
- - If no new task issues and the latest `qa-engineer` report comment on
117
- the gate issue is a **PASS** (read it:
118
- `gh issue view <gate> --json comments`) → the journey works:
119
- close the gate `gh issue close <gate> --comment "QA passed — journey verified."`,
120
- set `cursor: finalizing`.
121
- - If the report is ambiguous/unreachable and `qaRound >= 4` →
122
- escalate (§5).
123
-
124
- ### 4c. Finish (`cursor: finalizing`)
125
-
126
- With the gate closed, `goal-tick` observes `all-done`, prepares the
127
- **single open deliverable PR** (cumulative diff vs the default branch,
128
- review-ready), closes the task issues, and sets `state: "done"` in
129
- `state.json`. You do **not** merge — a human merges that PR.
130
-
131
- - When `state.json.state == "done"` (or the deliverable PR is open and
132
- task issues are closed): post one summary comment on the gate issue or
133
- the discussion linking the deliverable PR, set `cursor: done`.
134
-
135
- ### 5. Escalation
136
-
137
- Escalate by: commenting the reason on the goal's most relevant artifact
138
- (gate issue if it exists, else the highest-numbered task issue), adding
139
- the `kody:needs-human` label to that issue, and setting
140
- `cursor: escalated`. On later ticks, re-check an escalated goal: if a
141
- human removed `kody:needs-human` or the blocking condition cleared,
142
- resume at the appropriate cursor.
143
-
144
- ### 6. `cursor: done | escalated`
145
-
146
- No action. Keep the entry so you don't reprocess it. (These are per-goal;
147
- the **worker** is evergreen — never emit worker-level `done: true`.)
148
-
149
- ## Allowed Commands
150
-
151
- `gh` only: `gh issue ...`, `gh pr ...`, `gh label ...`, `gh api ...`,
152
- `gh repo view`. Read-only shell (`ls`, `cat`) on the checked-out tree to
153
- read `.kody/goals/*/state.json`.
154
-
155
- ## Restrictions
156
-
157
- - Never edit, create, or delete files in the working tree (no code, no
158
- `state.json` writes — the gate is GitHub-side via the qa-gate issue).
159
- - Never run `git`. Never merge or close a PR. Never mark a PR ready.
160
- - Never `@kody` a `kody:qa-gate` issue except the one `qa-engineer`
161
- trigger in §4b.
162
- - One QA trigger per `qaRound`; honour the 20-min throttle.
163
- - Do not dispatch implementation tasks yourself — only create the issues;
164
- `goal-tick` dispatches. Your only `@kody` comments are stall re-nudges
165
- (§4) and the `qa-engineer` trigger (§4b).
166
-
167
- ## State
168
-
169
- `cursor` (worker-level): always `"managing"` (evergreen). All real
170
- progress lives in `data.goals[<id>]` as described in §2. `done`: always
171
- `false`.
172
-
173
- **Cadence guard.** If `forceRun` is false and your last tick was < 4 min
174
- ago (compare a `data.lastTick` ISO you maintain), emit the prior state
175
- unchanged and exit. Always update `data.lastTick` when you do run.