kodi-dev
v1.5.1
Published
kodi.dev — Claude Code-native agent orchestrator CLI
Maintainers
Readme
kodi
kodi.dev — a Claude Code-native agent orchestrator. It installs a thin harness into
any project — a SessionStart bootstrap, phase skills, and a neutral team of sub-agents —
plus a deterministic CLI that proxies your ticket board and pull requests. It runs
inside a Claude Code session: you drive the phases, the agents do the work, and the CLI
is the only thing that touches your board or opens a PR.
Quick start
No global install needed — run it through npx:
cd your-project
npx kodi-dev init # required once per project (see below)
npx kodi-dev tickets listPrefer a global binary?
npm install -g kodi-dev
kodi initOr build & install from a local clone (no npm registry) — see the Makefile:
make install # build + install the kodi binary globally from sourcekodi init — required in every project
kodi init is the one command you must run before anything else. It:
- wires a
SessionStarthook (matchersstartup | resume | clear | compact) tokodi hook session-start, which injects the orchestrator persona + the two laws (ask-never-assume, ADR-is-law) into every session; - installs the commands (
/kodi.discover,/kodi.plan,/kodi.clarify,/kodi.tasks,/kodi.build) plus the on-demand ones (/kodi.security,/kodi.refactor), the sub-agents, and adocs/scaffold; - configures your board provider, and writes
.claude/kodi-dev.yaml— every field it can write, and every field it can't, is listed in full in Configuration reference below.
It is safe to re-run — and re-running is how you upgrade a project or change its
board provider. Every run reinstalls the kodi baseline: the packaged agents, skills
and rules are copied over the installed ones (so a project picks up the agents and
skills of your current kodi version, and local edits to them are replaced), and kodi's
.claude/settings.json block — the SessionStart hook, the permission rules, and the
env defaults — is re-asserted, restoring anything that was deleted or edited away.
Everything kodi does not ship is left alone: your own agents and skills, your own
hooks, permission rules and env vars all survive a re-run untouched. Agents and skills a
previous kodi shipped and the current one retired ARE deleted on re-run, so an
upgraded project ends up with exactly the current roster. In 1.5.0 that is the whole
hub-and-spoke planning roster (architect, ux-lead, detail, phases, qa-planning
and their leaves), the briefing agents (brief, brownfield-wu, greenfield-wu) and
the skills discover, oplan, oreplan, tickets, retickets, ticket-start,
security, refactor.
Choose a board provider
kodi tracks work on a board and drives ticket status through it. Pick one at init:
| Provider | Where tickets live | Status is driven by |
| ------------ | ------------------------------------------------- | ------------------------------------------ |
| local | one file per ticket under docs/tickets/ | a local status index — no external service |
| github | repo issues, added to a Projects v2 board | the board's single-select Status field |
| azure | Azure DevOps work items on a basic board | the board columns |
Auth is inherited from your already-logged-in gh / az CLIs — kodi never stores
credentials.
Local
Nothing to authenticate. Tickets are plain files under docs/tickets/, so the whole
backlog is visible in your repo and versioned with your code. Browse it visually with the
read-only board app (see The local board).
GitHub Projects
The github provider stores tickets as repo issues and drives their status through a
Projects v2 board's single-select Status field. Do this once:
gh auth login # authenticate the gh CLI
gh auth refresh -s project --hostname github.com # grant the Projects scope (NOT in default auth)kodi init discovers the rest for you:
| You provide | kodi discovers | | ------------------------------------------------------- | --------------------------------------------------------------------------- | | whether the board is owned by an org or a user | the project number (pick from a list) | | the owner login (user-owned defaults to your login) | the Status field's columns (map To Do / In Progress / To Review / Done) | | — | the repository (the current repo is offered first) |
[!NOTE] GitHub's built-in board has only
Todo/In Progress/Done— no "To Review". Map To Review onto another option, or add an "In Review" column to the board.
Interactive: kodi init --provider github and answer the prompts. Non-interactive:
kodi init --provider github \
--owner-type org --project-owner acme --project-number 5 \
--repository acme/app \
--todo-column "Todo" --in-progress-column "In Progress" \
--to-review-column "In Review" --done-column "Done"Azure DevOps
The azure provider stores tickets as work items on a basic board. kodi init lists
the real board columns and maps them to kodi's states; auth is inherited from az login.
Configuration reference (kodi-dev.yaml)
Everything kodi knows about a project lives in one file, .claude/kodi-dev.yaml. Some of
it is written for you by the kodi init wizard; the rest is intentionally not
prompted for — it exists for cases the common path doesn't need, and you set it by hand
editing the YAML.
Set by kodi init
| Field | Meaning | Set for |
| --------------- | ---------------------------------------------------------------------------------- | ----------------- |
| provider | Board provider: local | github | azure | always |
| prefix | Local ticket key prefix (default KODI) | local |
| organization | Azure DevOps org URL | azure |
| project | Azure DevOps project name | azure |
| team | Azure team that owns the board | azure |
| board | Azure board name (e.g. Issues) | azure |
| columnStates | Chosen column name → work-item state, discovered from the real board | azure |
| repository | Repo for PRs/issues (Azure: bare name; GitHub: owner/repo) | azure, github |
| projectOwner | GitHub Projects v2 owner login (org or user) | github |
| projectNumber | GitHub Projects v2 board number | github |
| columns | Status → column map (todo/inProgress/toReview/done) | github, azure |
| prTarget | Default target branch for kodi pr create, chosen from the remote's real branches | github, azure |
Additional configuration (not set by kodi init)
These exist for cases the wizard deliberately doesn't ask about — there's no sensible default to prompt for, so they're opt-in, hand-edited fields:
| Field | Meaning | Default when unset |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ |
| worktreesDir | Where kodi tickets start --worktree creates worktrees, relative to the project root | .claude/worktrees |
| sourceBranch | The branch kodi tickets start bases a new slice/kodi-<id> branch (or worktree) on. Ignored when the slice branch already exists — reusing one keeps its own base. | the current active branch (default git behavior) |
Example — a project on the azure board provider, with both additional fields set:
provider: azure
prefix: KODI
organization: https://dev.azure.com/acme
project: MyProject
team: MyProject Team
board: Issues
columns:
todo: To Do
inProgress: Doing
toReview: To Review
done: Done
columnStates:
To Do: To Do
Doing: Doing
To Review: Doing
Done: Done
repository: MyProject
prTarget: main
worktreesDir: .claude/worktrees # optional — this is the default anyway
sourceBranch: develop # optional — every new slice branches from developHow it works
kodi runs five explicit commands — no auto-advancing pipeline — each run by the
human, grilled on the main thread, and written by one sub-agent. Every hand-off is a
durable artifact, so a command can be re-run or resumed after a /clear or /compact.
The owner's words are copied verbatim into every artifact; nothing is paraphrased on the
way from the prompt to the ticket.
| Command | Writer | Output |
| --------------------------- | ------------------------ | ----------------------------------------------------------------------- |
| /kodi.discover | discover-writer | thin CLAUDE.md, rules, PRD 0000, founding ADRs; brownfield: as-built PRDs and ADRs |
| /kodi.plan <user story> | plan-writer | docs/prd/NNNN (WHAT/WHY) + docs/plan/NNNN (caveman technical plan) |
| /kodi.clarify <prd> | plan-writer | answers written back, ambiguous sentences replaced |
| /kodi.tasks <prd> | tasks-writer | docs/plan/NNNN.tasks.md + one ticket per user story on the board |
| /kodi.build <ticket> | build-orchestrator | ui-designer → engineers with their own QA → PR to To Review |
| /kodi.security, /kodi.refactor | main-loop | audit reports / a tidied target |
/kodi.plan is spec-kit's specify + plan in one pass: the story verbatim, at most
five questions with a recommended answer each, then a short PRD with inline
[NEEDS CLARIFICATION] markers and a plan that names files, contracts and data.
/kodi.tasks is spec-kit's tasks + tasks-to-issues: one vertical-slice ticket per
user story, its T0nn steps with exact paths, a requirement-to-ticket matrix the human
approves, then kodi tickets create in the current iteration.
Engineers know their role, not your stack — the stack lives in the thin CLAUDE.md
and in installable skill-packs (kodi add). No agent pins a model: every sub-agent
inherits the session's model.
[!TIP] For the full agent roster, per-phase diagrams, and how the agents communicate, see docs/agents.md.
CLI reference
All board/PR mutations proxy gh / az and are dry-run unless you pass --yes. The
provider is read from .claude/kodi-dev.yaml.
Every command also checks — at most once a day, capped at 1.5s, never on the critical
path — whether a newer kodi is published on npm, and installs it directly
(npm install -g kodi-dev@latest) rather than just telling you to. Set
KODI_NO_AUTO_UPDATE=1 to opt out (CI is skipped automatically).
Update
kodi update # force the self-update now, without waiting for the daily check
kodi update --force # …and reinstall even when already on the latest versionAsking for the update is the opt-in, so kodi update ignores both the once-a-day cache
and KODI_NO_AUTO_UPDATE/CI. It exits non-zero when an update was wanted but could not be
installed (registry unreachable, no npm, permissions, …).
Tickets
kodi tickets create -t "Title" -s "Summary" --ac "criterion" --dep KODI-001
kodi tickets list # open tickets (Done is not fetched)
kodi tickets list --all # …including the Done column
kodi tickets list-ready # dependency-aware readiness (+ the blocked set)
kodi tickets get KODI-001 # any ticket, Done or not
kodi tickets deps KODI-001 --add KODI-002 # read or declare dependencies
kodi tickets set-status KODI-001 Done
kodi tickets amend KODI-001 --file patch.yaml
kodi tickets start KODI-001 --yes # → In progress, assigns you, cuts slice/kodi-KODI-001
kodi tickets start KODI-001 --worktree --yes # …or an isolated worktree instead
kodi tickets start KODI-002 --no-branch --yes # bundling onto a branch another `start` already cut
kodi tickets hand-off KODI-001 --pr <url> # end of slice: → To Review, link the PR
kodi tickets iterations # list every iteration/sprint (azure/github only)
kodi tickets list --iteration "Sprint 12" # one specific iteration instead of the current one
kodi tickets list --all-iterations # disable iteration filtering — every ticket, every sprint
kodi tickets create ... --iteration "Sprint 12" --yes # assign to an iteration on create
kodi tickets amend KODI-001 --iteration "Sprint 12" --yes # …or after the factstart always cuts (or reuses) a slice/kodi-<id> git branch, based on the current
active branch — or, if sourceBranch is set in kodi-dev.yaml, on that fixed ref every
time, regardless of what's currently checked out (see Configuration
reference). With --worktree it creates that
branch as a separate worktree instead of switching the current checkout — under
.claude/worktrees/ by default, overridable per-project via worktreesDir.
--no-branch skips branch/worktree creation entirely, for bundling several tickets onto
one branch (--worktree and --no-branch together are rejected).
Every ticket is validated against a strict template before it is written or sent to the provider.
Listings stop at the Done column. Done is the one column that only grows, and nothing
that reads a listing renders it — tree drops Done nodes, and a dependency that has left
the listing is treated as satisfied rather than re-fetched to prove it. So list, tree
and list-ready pull open work only: on Azure the Done filter is applied inside the WIQL,
so finished descriptions never cross the wire; on GitHub, Done items are dropped before
their bodies are read, which is where the per-issue API calls (and the narrower rate
limit) bite. Done tickets are fetched on demand with tickets list --all, or individually
with tickets get <key>, which never filters. The trade-off: a dependency key that
matches nothing now reads as satisfied instead of blocking forever — create and amend
warn about unknown keys at write time, confirming each one with a targeted lookup so a
dependency on finished work stays silent.
Iterations/sprints — azure and github only (local has no such concept and
rejects --iteration/iterations with a clear error). list defaults to the current
iteration plus anything not yet scheduled into any sprint; --iteration <name> views one
specific (e.g. past) iteration instead, and --all-iterations disables the filter
entirely. kodi tickets iterations lists every iteration with its dates and marks the
current one. Assigning a ticket to an iteration is a separate, board-native step — via
--iteration on create/amend — never part of the portable ticket record itself, the
same way status is always trusted from the board rather than a stored copy.
The local board
With the local provider, tickets are separate files under docs/tickets/. Browse them
in a read-only board application built for navigating tickets and their dependencies:
kodi tickets serve # launch the board UI in your browser
kodi tickets open # alias of serve
kodi tickets serve --port 4000It is intentionally read-only — a fast way to see the backlog and its dependency graph, not to edit it. Mutations always go through the CLI.
Pull requests
Every PR follows a strict template validated in code (summary, type of change, included changes → features/fixes/improvements, related issues / work items, testing, and a checklist). Every section is always rendered — only notes is optional — so the created PR never collapses to a bare summary. Bodies are portable and capped so no provider truncates them.
kodi pr create --source feat/x --target main -t "Title" -s "Summary" --yes
kodi pr list
kodi pr abandon <id>Skill-packs
kodi add ./packs/fastapi-backend # install a skill-pack (skills + CLAUDE.md fragment)Everyday flow
kodi init # once per project — wires the harness + board
# in a Claude Code session:
/kodi.discover # → thin CLAUDE.md, rules, PRD 0000, founding ADRs
/kodi.plan I want a rate limiter… # → docs/prd/0001 + docs/plan/0001, approved by you
/kodi.clarify 0001 # → up to five questions, answers written back
/kodi.tasks 0001 # → docs/plan/0001.tasks.md + tickets on the board
/kodi.build KODI-001 # → build one slice, scoped regression, PR to To Review
/kodi.security diff # → audit a scope you name → docs/security/ reports
/kodi.refactor src/api/users.ts # → behavior-preserving cleanup of a target you name