wood-fired-tasks 2.0.6 → 2.1.1
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/AGENTS.md +4 -2
- package/CHANGELOG.md +69 -1
- package/README.md +103 -93
- package/SECURITY.md +3 -3
- package/dist/api/api-response.d.ts +76 -0
- package/dist/api/routes/models/index.d.ts +14 -0
- package/dist/api/routes/models/index.js +48 -0
- package/dist/api/routes/projects/index.js +6 -0
- package/dist/api/routes/projects/resolve-model.d.ts +3 -0
- package/dist/api/routes/projects/resolve-model.js +65 -0
- package/dist/api/routes/projects/schemas.d.ts +114 -0
- package/dist/api/routes/projects/schemas.js +8 -0
- package/dist/api/routes/settings/model-policy.d.ts +18 -0
- package/dist/api/routes/settings/model-policy.js +58 -0
- package/dist/api/server.d.ts +9 -0
- package/dist/api/server.js +29 -0
- package/dist/cli/api/client.d.ts +27 -0
- package/dist/cli/api/client.js +23 -0
- package/dist/cli/api/types.d.ts +9 -0
- package/dist/cli/auth/browser-open.js +11 -0
- package/dist/cli/bin/tasks-client.js +6 -0
- package/dist/cli/bin/tasks.js +7 -0
- package/dist/cli/commands/models.d.ts +44 -0
- package/dist/cli/commands/models.js +142 -0
- package/dist/cli/commands/project-set-models.d.ts +12 -0
- package/dist/cli/commands/project-set-models.js +66 -0
- package/dist/cli/commands/self-update.d.ts +16 -3
- package/dist/cli/commands/self-update.js +21 -0
- package/dist/cli/commands/settings-set-models.d.ts +12 -0
- package/dist/cli/commands/settings-set-models.js +53 -0
- package/dist/cli/output/formatters.js +13 -0
- package/dist/db/migrations/016-model-policy.d.ts +33 -0
- package/dist/db/migrations/016-model-policy.js +47 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +15 -0
- package/dist/lib/loop-run/schema.d.ts +3 -0
- package/dist/lib/loop-run/schema.js +16 -0
- package/dist/mcp/index.js +25 -1
- package/dist/mcp/remote/register-tools.d.ts +7 -1
- package/dist/mcp/remote/register-tools.js +126 -1
- package/dist/mcp/remote/rest-client.d.ts +46 -0
- package/dist/mcp/remote/rest-client.js +46 -0
- package/dist/mcp/server.d.ts +9 -3
- package/dist/mcp/server.js +27 -3
- package/dist/mcp/tools/model-tools.d.ts +52 -0
- package/dist/mcp/tools/model-tools.js +147 -0
- package/dist/mcp/tools/project-tools.js +6 -2
- package/dist/repositories/project.repository.js +44 -7
- package/dist/repositories/settings.repository.d.ts +26 -0
- package/dist/repositories/settings.repository.js +50 -0
- package/dist/schemas/model-policy.schema.d.ts +120 -0
- package/dist/schemas/model-policy.schema.js +60 -0
- package/dist/schemas/project.schema.d.ts +76 -0
- package/dist/schemas/project.schema.js +3 -0
- package/dist/schemas/task.schema.d.ts +20 -20
- package/dist/schemas/wsjf.schema.d.ts +4 -4
- package/dist/services/model-catalog.service.d.ts +62 -0
- package/dist/services/model-catalog.service.js +111 -0
- package/dist/services/model-policy.service.d.ts +58 -0
- package/dist/services/model-policy.service.js +76 -0
- package/dist/services/project.service.js +7 -3
- package/dist/services/settings.service.d.ts +50 -0
- package/dist/services/settings.service.js +39 -0
- package/dist/skills/agents/integration-auditor.md +11 -0
- package/dist/skills/tasks/audit.md +29 -3
- package/dist/skills/tasks/decompose.md +38 -8
- package/dist/skills/tasks/loop-dag.md +8 -5
- package/dist/skills/tasks/loop-shared.md +40 -0
- package/dist/skills/tasks/loop.md +5 -3
- package/dist/skills/tasks/set-models.md +221 -0
- package/dist/types/task.d.ts +35 -0
- package/docs/API.md +34 -2
- package/docs/CLI.md +95 -0
- package/docs/INTERFACES.md +26 -14
- package/docs/MCP.md +61 -3
- package/docs/SETUP.md +14 -3
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -95,8 +95,10 @@ Treat these as off-limits unless your task explicitly requires touching them.
|
|
|
95
95
|
## Task-orchestration skills (`/tasks:*`)
|
|
96
96
|
|
|
97
97
|
This repo ships agent skills under `skills/tasks/` that automate the
|
|
98
|
-
plan→execute→audit loop over a wood-fired-tasks project. They
|
|
99
|
-
`~/.claude/commands/tasks/`
|
|
98
|
+
plan→execute→audit loop over a wood-fired-tasks project. They are copied to
|
|
99
|
+
`~/.claude/commands/tasks/` by `wood-fired-tasks setup` (the published-npm
|
|
100
|
+
install path; the old root `install.sh` is a deprecated shim that just delegates
|
|
101
|
+
to `setup`). The orchestration set:
|
|
100
102
|
|
|
101
103
|
| Skill | Status | One-line purpose |
|
|
102
104
|
|---|---|---|
|
package/CHANGELOG.md
CHANGED
|
@@ -13,6 +13,72 @@ vulnerabilities, supply-chain pinning) are always called out under `Security`.
|
|
|
13
13
|
|
|
14
14
|
_No changes yet._
|
|
15
15
|
|
|
16
|
+
## [v2.1.1] - 2026-06-09
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
- **`tasks self-update` now re-syncs bundled skills/agents into `~/.claude`**
|
|
20
|
+
(PR #57, task #934). The command previously only ran
|
|
21
|
+
`npm i -g wood-fired-tasks@latest`, so a release that added or changed a
|
|
22
|
+
skill (first hit: v2.1.0's `/tasks:set-models`) left self-updaters with
|
|
23
|
+
stale `~/.claude/commands/tasks/` while reporting success — violating the
|
|
24
|
+
README's "keep it up to date" contract. After a clean install, self-update
|
|
25
|
+
now runs the same idempotent `copySkills()`/`copyAgents()` sync `tasks
|
|
26
|
+
setup` uses, reports what it refreshed, and exits non-zero with a
|
|
27
|
+
`tasks setup` remediation hint if the sync itself fails. A contract test
|
|
28
|
+
pins the default sync to setup's own implementation so the update and
|
|
29
|
+
onboarding paths cannot drift.
|
|
30
|
+
|
|
31
|
+
## [v2.1.0] - 2026-06-09
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
- **Configurable Task Models** (PR #55, project 39 — 17 tasks). Route the
|
|
35
|
+
`/tasks:loop` worker (`execution`), verifier (`validation`), and planning
|
|
36
|
+
agents — decompose / audit / integration-auditor (`planning`) — to different
|
|
37
|
+
Anthropic models via a per-project + database-default `model_policy`.
|
|
38
|
+
- **Policy model:** six power categories (`minimal…maximum`, a 1:1 relabel of
|
|
39
|
+
the WSJF jobSize Fibonacci tiers) plus an `auto` sentinel; per-role
|
|
40
|
+
`byCategory` routing with a uniform `byCategory → constant → default →
|
|
41
|
+
null` slot walk, two-layer per-slot merge (`project ?? global`). Migration
|
|
42
|
+
016 adds `projects.model_policy` and the `app_settings` singleton.
|
|
43
|
+
- **Runtime model catalog:** live discovery via the Anthropic Models API
|
|
44
|
+
(set the optional `ANTHROPIC_API_KEY`) with a static fallback marked
|
|
45
|
+
`stale: true` — the read path never throws.
|
|
46
|
+
- **MCP:** four new tools — `list_models`, `resolve_model`,
|
|
47
|
+
`get_model_defaults`, `set_model_defaults` — on **both** the stdio and
|
|
48
|
+
remote servers (tool count 27 → 31).
|
|
49
|
+
- **REST:** `GET /models`, `GET|PUT /settings/model-policy`,
|
|
50
|
+
`GET /projects/:id/resolve-model`, and `model_policy` on project
|
|
51
|
+
create/update/get.
|
|
52
|
+
- **CLI:** `tasks models list`, `tasks project-set-models <id>`, and
|
|
53
|
+
`tasks settings-set-models` — the set-models commands fetch-merge-write
|
|
54
|
+
client-side, so incremental invocations never destroy earlier role config.
|
|
55
|
+
- **Skills:** a `/tasks:set-models` interview (one four-stage checklist
|
|
56
|
+
question per role, fixed option order, catalog-only options) and a
|
|
57
|
+
canonical, telemetry-grounded **Default Model Map** in `loop-shared.md` §R
|
|
58
|
+
that makes `auto` resolution deterministic (execution
|
|
59
|
+
sonnet/sonnet/opus/fable across the category ladder, validation
|
|
60
|
+
haiku/sonnet/opus/opus, planning opus). Optional
|
|
61
|
+
`--execution-model` / `--validation-model` / `--planning-model` run-arg
|
|
62
|
+
overrides ride LOOP-RUN frontmatter for replay provenance.
|
|
63
|
+
|
|
64
|
+
### Fixed
|
|
65
|
+
- **Test suite no longer launches the developer's real browser.**
|
|
66
|
+
`setup.remote.test.ts` drove the device flow with `openBrowser: true`, so
|
|
67
|
+
every `npm test` on a DISPLAY-set desktop spawned `xdg-open` at a mock
|
|
68
|
+
server. `openBrowser()` now honors `WFT_NO_BROWSER`, set for every test via
|
|
69
|
+
`vitest.setup.ts`.
|
|
70
|
+
- **Documentation counts drift.** README / `docs/INTERFACES.md` / `docs/MCP.md`
|
|
71
|
+
had stale tool (27 vs 31), route (52/45 vs 59/52), and CLI command (42 vs 45)
|
|
72
|
+
counts, plus a stale "model tools are stdio-only" claim from before remote
|
|
73
|
+
parity landed; the `interfaces-counts` drift guard now covers the model-tools
|
|
74
|
+
file so the next addition cannot dodge it.
|
|
75
|
+
|
|
76
|
+
### Security
|
|
77
|
+
- No security-relevant changes. The new `/models`, `/settings/model-policy`,
|
|
78
|
+
and `resolve-model` routes inherit the standard `/api/v1` auth chain; the
|
|
79
|
+
optional `ANTHROPIC_API_KEY` is only ever sent to the Anthropic Models API
|
|
80
|
+
and is never echoed in responses or logs.
|
|
81
|
+
|
|
16
82
|
## [v2.0.6] - 2026-06-08
|
|
17
83
|
|
|
18
84
|
### Added
|
|
@@ -763,7 +829,9 @@ and the task/project/dependency/comment/subtask domain model.
|
|
|
763
829
|
- Task hierarchy (subtasks), dependency service, comments, time estimates
|
|
764
830
|
(phase 06).
|
|
765
831
|
|
|
766
|
-
[Unreleased]: https://github.com/Wood-Fired-Games/wood-fired-tasks/compare/v2.
|
|
832
|
+
[Unreleased]: https://github.com/Wood-Fired-Games/wood-fired-tasks/compare/v2.1.1...HEAD
|
|
833
|
+
[v2.1.1]: https://github.com/Wood-Fired-Games/wood-fired-tasks/compare/v2.1.0...v2.1.1
|
|
834
|
+
[v2.1.0]: https://github.com/Wood-Fired-Games/wood-fired-tasks/compare/v2.0.6...v2.1.0
|
|
767
835
|
[v2.0.0]: https://github.com/Wood-Fired-Games/wood-fired-tasks/compare/v1.18.2...v2.0.0
|
|
768
836
|
[v1.15]: https://github.com/Wood-Fired-Games/wood-fired-tasks/compare/v1.14...v1.15
|
|
769
837
|
[v1.14]: https://github.com/Wood-Fired-Games/wood-fired-tasks/compare/v1.13...v1.14
|
package/README.md
CHANGED
|
@@ -15,8 +15,8 @@ Wood Fired Tasks is open-source coordination infrastructure for fleets of AI cod
|
|
|
15
15
|
**Key capabilities:**
|
|
16
16
|
|
|
17
17
|
- `/tasks:*` skill files implementing the plan→decompose→loop→audit lifecycle (ship as Claude Code slash commands; the recipes are vendor-neutral)
|
|
18
|
-
- MCP server with
|
|
19
|
-
- REST API with
|
|
18
|
+
- MCP server with 31 tools for native agent integration (local SQLite or remote HTTP modes) + a single cross-platform npm install (Linux/macOS/Windows)
|
|
19
|
+
- REST API with 59 route handlers across `src/api/routes/` (1 public `/health`; the rest authenticated; a single instance serves up to 52 — OIDC-disabled stubs are mutually exclusive with the live OIDC routes) and a `tasks` CLI with 45 commands
|
|
20
20
|
- Atomic task claiming with optimistic locking + workflow automation (parent auto-complete, dependency auto-unblock) for multi-agent coordination
|
|
21
21
|
- Real-time Server-Sent Events (SSE) for task/project change notifications
|
|
22
22
|
- SQLite database with WAL mode, FTS5 full-text search, and automatic migrations
|
|
@@ -62,25 +62,58 @@ Coding agents (Claude Code, Cursor, Gemini, Codex, and others) should start with
|
|
|
62
62
|
2. [docs/AGENT_CONTEXT.md](docs/AGENT_CONTEXT.md) — the vendor-neutral context contract.
|
|
63
63
|
3. [.agent-context.json](.agent-context.json) — machine-readable manifest of canonical files and their budgets.
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
A root [`llms.txt`](llms.txt) (the emerging agent-discovery convention) also
|
|
66
|
+
points here, and both it and the curated agent docs ship inside the npm tarball.
|
|
67
|
+
Vendor-specific files (`CLAUDE.md`, `.cursor/`, `.gemini/`, `.codex/`) are
|
|
68
|
+
adapters and MUST NOT carry unique facts — see `docs/AGENT_CONTEXT.md` §6.
|
|
66
69
|
|
|
67
|
-
##
|
|
70
|
+
## Install & run modes
|
|
68
71
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
+
**One install, no git clone, no build, no admin rights.** Installing from npm
|
|
73
|
+
ships the API server, the `tasks` CLI, the MCP bridge, the `wft-router`
|
|
74
|
+
automation daemon, and the `/tasks:*` skills together — the *same* install backs
|
|
75
|
+
every way you might run it.
|
|
72
76
|
|
|
73
77
|
```bash
|
|
74
|
-
|
|
75
|
-
|
|
78
|
+
npm i -g wood-fired-tasks # never needs sudo — see the admin-free note below
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
This puts three identical CLI entry points on your PATH — `wood-fired-tasks`,
|
|
82
|
+
`tasks`, and the short alias `wft` — plus `wft-router`. Requires **Node ≥ 22**;
|
|
83
|
+
works on Linux, macOS, and Windows. (There is no `curl | bash` bootstrap and the
|
|
84
|
+
old `install.sh` / `install.ps1` git-clone scripts are retired — npm is the one
|
|
85
|
+
supported install path.)
|
|
86
|
+
|
|
87
|
+
### Pick how to run it
|
|
88
|
+
|
|
89
|
+
The install is the same everywhere; what differs is *where the database and API
|
|
90
|
+
server live*. Pick the row that matches your environment:
|
|
91
|
+
|
|
92
|
+
| Run mode | Use it when | After installing, run | Guide |
|
|
93
|
+
|----------|-------------|-----------------------|-------|
|
|
94
|
+
| **Solo / local** | You want a tracker on your own machine, backed by a local SQLite DB. | `wood-fired-tasks setup` → `wood-fired-tasks serve` | [Local setup](docs/SETUP.md#frictionless-install-npm--no-clone) |
|
|
95
|
+
| **Background service** | Keep the local API running across logout/reboot (user-scoped, admin-free). | `wood-fired-tasks service install` | [Background service](docs/SETUP.md#background-service-keep-the-server-running) |
|
|
96
|
+
| **Remote client** | A shared server already exists — point this machine at it. | `wood-fired-tasks setup --remote <url> --token wft_pat_…` *(or `tasks login`)* | [Setup modes](docs/SETUP.md#setup-modes) |
|
|
97
|
+
| **Self-hosted server** | Stand up the shared API for a team to point at. | `deploy/install.sh` on the host | [Self-hosting & upgrades](docs/SETUP.md#self-hosting-and-upgrades) |
|
|
98
|
+
| **Multi-OS fleet** | Many Windows/Linux/macOS machines on one shared backlog. | self-host once, then `setup --remote` per client | [Multi-OS fleet](docs/SETUP.md#multi-os-client-fleet-one-shared-on-prem-server) |
|
|
99
|
+
|
|
100
|
+
> **New here? Start with Solo / local** — three commands and the `/tasks:*`
|
|
101
|
+
> workflow is live in Claude Code. Nothing is wasted if you move to a shared
|
|
102
|
+
> server later: the modes coexist (a Local stdio entry and a Remote bridge entry
|
|
103
|
+
> can both live in `~/.claude.json` at once).
|
|
76
104
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
105
|
+
### Solo / local — fastest start
|
|
106
|
+
|
|
107
|
+
After `npm i -g wood-fired-tasks` (above), two commands wire it into Claude Code
|
|
108
|
+
and run the server:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
# Merge the local stdio MCP server into ~/.claude.json and copy the /tasks:*
|
|
112
|
+
# skills + subagents — idempotent, no manual JSON editing.
|
|
80
113
|
wood-fired-tasks setup
|
|
81
114
|
|
|
82
|
-
#
|
|
83
|
-
#
|
|
115
|
+
# Run the API. Migrates the OS app-data DB on start; listens on 127.0.0.1:3000
|
|
116
|
+
# (set HOST=0.0.0.0 to expose on the LAN).
|
|
84
117
|
wood-fired-tasks serve
|
|
85
118
|
```
|
|
86
119
|
|
|
@@ -110,21 +143,16 @@ user scope.
|
|
|
110
143
|
|
|
111
144
|
```bash
|
|
112
145
|
wood-fired-tasks service install # Linux: user-scoped systemd unit (admin-free)
|
|
113
|
-
wood-fired-tasks self-update # npm i -g
|
|
146
|
+
wood-fired-tasks self-update # npm i -g @latest + re-sync skills (no sudo)
|
|
114
147
|
```
|
|
115
148
|
|
|
116
|
-
**Point at a shared remote server**
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
to the REST API) and persists the validated PAT to the CLI credentials file —
|
|
124
|
-
the same file `tasks login` writes; the bridge reads its bearer token from there
|
|
125
|
-
at runtime (the PAT is never stored in `~/.claude.json`). Omit `--token` to run
|
|
126
|
-
the interactive device-flow / manual-PAT onboarding instead. For a full
|
|
127
|
-
Windows/Linux/macOS fleet on one on-prem server, see
|
|
149
|
+
**Point at a shared remote server** (the *Remote client* mode above) with
|
|
150
|
+
`wood-fired-tasks setup --remote https://tasks.example.com --token wft_pat_…`: it
|
|
151
|
+
writes a URL-only `wood-fired-tasks-remote` MCP entry (proxying every tool to the
|
|
152
|
+
REST API) and persists the validated PAT to the CLI credentials file — the same
|
|
153
|
+
file `tasks login` writes; the bridge reads its bearer token from there at
|
|
154
|
+
runtime, never from `~/.claude.json`. Omit `--token` for the interactive
|
|
155
|
+
device-flow / manual-PAT onboarding. Full fleet recipe:
|
|
128
156
|
[Multi-OS client fleet](docs/SETUP.md#multi-os-client-fleet-one-shared-on-prem-server).
|
|
129
157
|
|
|
130
158
|
Browse the bundled guides from anywhere with `wood-fired-tasks docs list` /
|
|
@@ -284,7 +312,7 @@ flowchart TB
|
|
|
284
312
|
| Interface | Access Method | Transport | Auth |
|
|
285
313
|
|-----------|--------------|-----------|------|
|
|
286
314
|
| REST API | HTTP endpoints | Port 3000 (configurable) | PAT (`Authorization: Bearer`) or OIDC session cookie |
|
|
287
|
-
| CLI | `tasks` command | HTTP to API server (most cmds); direct SQLite for offline ops (`backup`, `doctor`, `stats`, `db-check`, `completed`) | `API_KEY` env
|
|
315
|
+
| CLI | `tasks` command | HTTP to API server (most cmds); direct SQLite for offline ops (`backup`, `doctor`, `stats`, `db-check`, `completed`) | Credentials file from `tasks login` / `setup --remote --token` (preferred); else `API_KEY` env or `--token` flag — each a PAT sent as `Authorization: Bearer` |
|
|
288
316
|
| MCP Server | stdio JSON-RPC (local) or HTTP (remote variant) | MCP client integration | None for stdio (local access); Bearer PAT for remote |
|
|
289
317
|
| Slack subprocess | Slack Socket Mode | WebSocket to Slack | Slack signing secret + bot token |
|
|
290
318
|
|
|
@@ -426,7 +454,7 @@ The OIDC/session/PAT surface backing the auth model lives partly outside the tas
|
|
|
426
454
|
|
|
427
455
|
A device-authorization flow under `/auth/device*` (`GET /auth/device`, `POST /auth/device/code`, `POST /auth/device/token`, `POST /auth/device/verify`) supports headless PAT minting. When OIDC is **not** configured, the `/auth/*` and `/auth/device/*` routes are replaced by disabled-stub handlers (HTTP 501), so they exist in both modes but only one set is live per instance. When `SESSION_COOKIE_SECRET` is set, top-level HTML web routes (`GET /login`, `GET /me`, `GET /me/tokens`, `POST /me/tokens/:id/revoke`) are also served for the browser sign-in UI.
|
|
428
456
|
|
|
429
|
-
This brings the full registered surface to **
|
|
457
|
+
This brings the full registered surface to **59 route handlers** under `src/api/routes/` — derived by counting `fastify.<verb>(` / `server.<verb>(` registrations across the route files (excluding tests). A single running instance serves up to **52** of them: the 7 OIDC-disabled stub handlers are mutually exclusive with the live OIDC `/auth/*` routes.
|
|
430
458
|
|
|
431
459
|
For detailed API documentation including request/response schemas, see [docs/API.md](docs/API.md).
|
|
432
460
|
|
|
@@ -434,11 +462,12 @@ For detailed API documentation including request/response schemas, see [docs/API
|
|
|
434
462
|
|
|
435
463
|
The `tasks` command provides terminal access to all task operations.
|
|
436
464
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
465
|
+
If you installed from npm (`npm i -g wood-fired-tasks`), the `tasks`, `wft`, and
|
|
466
|
+
`wood-fired-tasks` commands are already on your PATH and every `tasks <command>`
|
|
467
|
+
example below works verbatim. Working from a clone instead? Use
|
|
468
|
+
`npm run cli -- <command>` (everything after `--` is forwarded verbatim), or run
|
|
469
|
+
`npm link` once from the project root to install a global `tasks`. See
|
|
470
|
+
[docs/CLI.md](docs/CLI.md) for the full reference.
|
|
442
471
|
|
|
443
472
|
**Global Flags:**
|
|
444
473
|
- `--json` - Output in machine-readable JSON format
|
|
@@ -508,7 +537,7 @@ full reference.
|
|
|
508
537
|
|
|
509
538
|
| Command | Description |
|
|
510
539
|
|---------|-------------|
|
|
511
|
-
| tasks login | OIDC sign-in;
|
|
540
|
+
| tasks login | OIDC device-flow sign-in, or `--token <pat>` for a manual PAT (required for remote non-`https` servers); writes a PAT to the local credentials file |
|
|
512
541
|
| tasks logout | Revoke the active PAT and clear the local credentials |
|
|
513
542
|
| tasks whoami | Show the currently authenticated identity |
|
|
514
543
|
|
|
@@ -531,7 +560,7 @@ For detailed CLI documentation including all options and examples, see [docs/CLI
|
|
|
531
560
|
|
|
532
561
|
## MCP Tools Summary
|
|
533
562
|
|
|
534
|
-
The MCP server exposes
|
|
563
|
+
The MCP server exposes 31 tools and 1 resource for Claude Code integration — Task (9), Project (5), Comment (3), Dependency (3), Health (1), Topology (1), Wait (1), WSJF (4), and Model (4). A second entry point (`npm run mcp:remote`) exposes the same 31 tools REST-backed (the four Model tools proxy `GET /models`, `GET /projects/:id/resolve-model`, and `GET|PUT /settings/model-policy`; `wait_for_unblock` resolves over the SSE event stream rather than the in-process EventBus) for clients running on a different host than the bugs API — see [docs/MCP.md#remote-mcp-server](docs/MCP.md#remote-mcp-server).
|
|
535
564
|
|
|
536
565
|
### Task Tools (9)
|
|
537
566
|
|
|
@@ -600,6 +629,15 @@ The MCP server exposes 27 tools and 1 resource for Claude Code integration — T
|
|
|
600
629
|
| rescore_project | (Mutation) Deterministically rescore a project's scored tasks against the current value charter; skips locked components; returns evaluated/changed/skipped-locked counts |
|
|
601
630
|
| wsjf_health | Non-blocking degeneracy/pitfall linter for a project's WSJF state (empty findings ⇔ healthy) |
|
|
602
631
|
|
|
632
|
+
### Model Tools (4)
|
|
633
|
+
|
|
634
|
+
| Tool | Description |
|
|
635
|
+
|------|-------------|
|
|
636
|
+
| list_models | Runtime-discovered Claude model catalog (Anthropic Models API, TTL-cached); `stale: true` when serving the static fallback |
|
|
637
|
+
| resolve_model | Resolve the model for a pipeline role (`execution` \| `validation` \| `planning`) for a project, optionally task-scoped for jobSize→category routing; returns `{ model }` or `null` (inherit the session model) |
|
|
638
|
+
| get_model_defaults | Read the database-wide default `ModelPolicy` (`null` when unset) |
|
|
639
|
+
| set_model_defaults | (Mutation) Set or clear the database-wide default `ModelPolicy` |
|
|
640
|
+
|
|
603
641
|
### Resources (1)
|
|
604
642
|
|
|
605
643
|
| URI | Description |
|
|
@@ -732,66 +770,39 @@ variables) lives in [docs/SETUP.md → Environment Variables](docs/SETUP.md#envi
|
|
|
732
770
|
### Key Commands
|
|
733
771
|
|
|
734
772
|
```bash
|
|
735
|
-
#
|
|
736
|
-
npm run dev
|
|
737
|
-
|
|
738
|
-
# Run tests (~2600+ tests)
|
|
739
|
-
npm test
|
|
740
|
-
|
|
741
|
-
# Watch mode for tests
|
|
742
|
-
npm run test:watch
|
|
743
|
-
|
|
744
|
-
# Build TypeScript
|
|
745
|
-
npm run build
|
|
746
|
-
|
|
747
|
-
# Run CLI in development (without building)
|
|
748
|
-
npm run cli -- <command>
|
|
749
|
-
|
|
750
|
-
# Run MCP server in development
|
|
751
|
-
npm run mcp:dev
|
|
773
|
+
npm run dev # REST API, hot reload npm run build # typecheck + compile
|
|
774
|
+
npm test # full suite (~3,700+) npm run mcp:dev # MCP server (stdio)
|
|
775
|
+
npm run cli -- <command> # run the CLI in-tree npm run lint # biome check
|
|
752
776
|
```
|
|
753
777
|
|
|
778
|
+
The canonical command table (focused tests, migrations, quality gate) lives in
|
|
779
|
+
[AGENTS.md → Essential commands](AGENTS.md#essential-commands).
|
|
780
|
+
|
|
754
781
|
### Database
|
|
755
782
|
|
|
756
|
-
SQLite with better-sqlite3 driver, WAL mode, and automatic
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
7. `007-completed-at.ts` — `completed_at` column on tasks (set on transition into `done`, backfilled from `updated_at`)
|
|
765
|
-
8. `008-identity-tables.ts` — `users` and `api_tokens` tables (OIDC/PAT identity)
|
|
766
|
-
9. `009-parallel-fk-columns.ts` — parallel `*_user_id` FK columns alongside the legacy TEXT identity columns
|
|
767
|
-
10. `010-identity-uniqueness-indexes.ts` — uniqueness indexes on user identity (oidc_sub, email)
|
|
768
|
-
11. `011-acceptance-criteria.ts` — `acceptance_criteria` column on tasks
|
|
769
|
-
12. `012-verification-evidence.ts` — `verification_evidence` column on tasks (verifier verdict + checks)
|
|
770
|
-
13. `013-wsjf-fields.ts` — adds the per-task WSJF columns: four Fibonacci-constrained component columns (`wsjf_value`, `wsjf_time_criticality`, `wsjf_risk_opportunity`, `wsjf_job_size`) plus five JSON metadata columns (`wsjf_evidence`, `wsjf_locked`, `wsjf_source`, `wsjf_classifications`, `wsjf_features`); all-four-or-none invariant enforced at the DTO boundary
|
|
771
|
-
14. `014-value-charter.ts` — adds the nullable `value_charter` JSON column on `projects` (the per-project Business-Value reference frame)
|
|
772
|
-
15. `015-wsjf-audit.ts` — creates the three append-only audit tables: `wsjf_rescore_run`, `wsjf_score_history` (one immutable row per score write), and `project_charter_history` (full charter snapshot per interview version)
|
|
783
|
+
SQLite with the better-sqlite3 driver, WAL mode, and automatic forward
|
|
784
|
+
migrations via Umzug. The 15 migration files in `src/db/migrations/` are the
|
|
785
|
+
canonical, self-documenting schema history — from `001-initial-schema` (projects,
|
|
786
|
+
tasks, FTS5) through the identity tables (`008`–`010`, OIDC/PAT), acceptance
|
|
787
|
+
criteria + verification evidence (`011`–`012`), and the WSJF columns, value
|
|
788
|
+
charter, and append-only audit tables (`013`–`015`). Read the files directly for
|
|
789
|
+
exact DDL; [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) covers how they fit
|
|
790
|
+
together.
|
|
773
791
|
|
|
774
792
|
### Testing
|
|
775
793
|
|
|
776
|
-
~
|
|
777
|
-
|
|
778
|
-
-
|
|
779
|
-
-
|
|
780
|
-
|
|
781
|
-
- Event system tests (EventBus, SSEManager, events API)
|
|
782
|
-
- Claim protocol tests (including 20-agent concurrency)
|
|
783
|
-
- Workflow engine tests (auto-complete, auto-unblock, cascade depth)
|
|
784
|
-
- Skill file validation tests
|
|
794
|
+
~3,700+ vitest tests span the service layer, every API route, every MCP tool,
|
|
795
|
+
the CLI, the event system (EventBus/SSEManager), the claim protocol (including
|
|
796
|
+
20-agent concurrency), the workflow engine (auto-complete/auto-unblock/cascade
|
|
797
|
+
depth), and skill-file validation. Run `npm test`; see
|
|
798
|
+
[docs/WORKFLOWS.md](docs/WORKFLOWS.md) for focused-run recipes.
|
|
785
799
|
|
|
786
800
|
### Code Quality Roadmap
|
|
787
801
|
|
|
788
|
-
The
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
[docs/CODE_QUALITY_ROADMAP.md](docs/CODE_QUALITY_ROADMAP.md).
|
|
792
|
-
source of truth for the `Code Quality Uplift Roadmap` project tracked
|
|
793
|
-
in the bugs database and should be linked from future PR/release
|
|
794
|
-
quality checklist work.
|
|
802
|
+
The TypeScript quality baseline and the prioritized uplift roadmap (lint/format
|
|
803
|
+
gate, stricter compiler flags, architecture guardrails, migration safety,
|
|
804
|
+
CI/release automation) live in
|
|
805
|
+
[docs/CODE_QUALITY_ROADMAP.md](docs/CODE_QUALITY_ROADMAP.md).
|
|
795
806
|
|
|
796
807
|
## Integrations
|
|
797
808
|
|
|
@@ -813,7 +824,7 @@ slash-command reference, channel subscription model, error handling.
|
|
|
813
824
|
### Claude Code (MCP)
|
|
814
825
|
|
|
815
826
|
The shipped MCP server registers as a stdio MCP target in `~/.claude.json`
|
|
816
|
-
and exposes
|
|
827
|
+
and exposes 31 tools plus the `/tasks:*` skill files. See
|
|
817
828
|
[docs/MCP.md](docs/MCP.md) and the "Claude Code Integration" section in
|
|
818
829
|
[docs/SETUP.md](docs/SETUP.md#claude-code-integration).
|
|
819
830
|
|
|
@@ -837,12 +848,11 @@ guarantee.
|
|
|
837
848
|
|
|
838
849
|
## Release Verification
|
|
839
850
|
|
|
840
|
-
Before publishing
|
|
841
|
-
|
|
842
|
-
`
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
`files` allowlist in `package.json` — adjust it there if the output drifts.
|
|
851
|
+
Before publishing, `npm run pack:check` (`npm pack --dry-run`) prints the tarball
|
|
852
|
+
file list — confirm `dist/` + `.d.ts`, `LICENSE`, `README.md`, `CHANGELOG.md`,
|
|
853
|
+
`SECURITY.md` are present and `src/`, `.env*`, `data/*.db`, `.planning/`, and
|
|
854
|
+
tests are absent. The `files` allowlist in `package.json` controls this. Full
|
|
855
|
+
release procedure: [docs/RELEASE.md](docs/RELEASE.md).
|
|
846
856
|
|
|
847
857
|
## License
|
|
848
858
|
|
package/SECURITY.md
CHANGED
|
@@ -14,11 +14,11 @@ security updates. Older tags are provided as-is.
|
|
|
14
14
|
| Version | Supported |
|
|
15
15
|
| ----------------- | ------------------ |
|
|
16
16
|
| `main` (HEAD) | :white_check_mark: |
|
|
17
|
-
| `
|
|
18
|
-
| `v1.0` – `
|
|
17
|
+
| `v2.1.1` (latest) | :white_check_mark: |
|
|
18
|
+
| `v1.0` – `v2.0.6` | :x: |
|
|
19
19
|
|
|
20
20
|
"Latest" tracks whichever tag is most recent on GitHub; at the time of
|
|
21
|
-
writing that is `
|
|
21
|
+
writing that is `v2.1.1`. If you are reading this on an older checkout,
|
|
22
22
|
verify the current latest release via
|
|
23
23
|
`git tag --sort=-creatordate | head -1` or the GitHub Releases page.
|
|
24
24
|
|
|
@@ -115,6 +115,44 @@ export declare function parseProjectResponse(payload: unknown, endpoint: string)
|
|
|
115
115
|
interview_version: number;
|
|
116
116
|
updated_at: string;
|
|
117
117
|
} | null | undefined;
|
|
118
|
+
model_policy?: {
|
|
119
|
+
execution?: {
|
|
120
|
+
byCategory?: {
|
|
121
|
+
minimal?: string | undefined;
|
|
122
|
+
light?: string | undefined;
|
|
123
|
+
moderate?: string | undefined;
|
|
124
|
+
strong?: string | undefined;
|
|
125
|
+
heavy?: string | undefined;
|
|
126
|
+
maximum?: string | undefined;
|
|
127
|
+
} | undefined;
|
|
128
|
+
constant?: string | undefined;
|
|
129
|
+
default?: string | undefined;
|
|
130
|
+
} | undefined;
|
|
131
|
+
validation?: {
|
|
132
|
+
byCategory?: {
|
|
133
|
+
minimal?: string | undefined;
|
|
134
|
+
light?: string | undefined;
|
|
135
|
+
moderate?: string | undefined;
|
|
136
|
+
strong?: string | undefined;
|
|
137
|
+
heavy?: string | undefined;
|
|
138
|
+
maximum?: string | undefined;
|
|
139
|
+
} | undefined;
|
|
140
|
+
constant?: string | undefined;
|
|
141
|
+
default?: string | undefined;
|
|
142
|
+
} | undefined;
|
|
143
|
+
planning?: {
|
|
144
|
+
byCategory?: {
|
|
145
|
+
minimal?: string | undefined;
|
|
146
|
+
light?: string | undefined;
|
|
147
|
+
moderate?: string | undefined;
|
|
148
|
+
strong?: string | undefined;
|
|
149
|
+
heavy?: string | undefined;
|
|
150
|
+
maximum?: string | undefined;
|
|
151
|
+
} | undefined;
|
|
152
|
+
constant?: string | undefined;
|
|
153
|
+
default?: string | undefined;
|
|
154
|
+
} | undefined;
|
|
155
|
+
} | null | undefined;
|
|
118
156
|
};
|
|
119
157
|
/** Convenience: validate a task list (envelope or bare array). */
|
|
120
158
|
export declare function parseTaskListResponse(payload: unknown, endpoint: string): {
|
|
@@ -174,6 +212,44 @@ export declare function parseProjectListResponse(payload: unknown, endpoint: str
|
|
|
174
212
|
interview_version: number;
|
|
175
213
|
updated_at: string;
|
|
176
214
|
} | null | undefined;
|
|
215
|
+
model_policy?: {
|
|
216
|
+
execution?: {
|
|
217
|
+
byCategory?: {
|
|
218
|
+
minimal?: string | undefined;
|
|
219
|
+
light?: string | undefined;
|
|
220
|
+
moderate?: string | undefined;
|
|
221
|
+
strong?: string | undefined;
|
|
222
|
+
heavy?: string | undefined;
|
|
223
|
+
maximum?: string | undefined;
|
|
224
|
+
} | undefined;
|
|
225
|
+
constant?: string | undefined;
|
|
226
|
+
default?: string | undefined;
|
|
227
|
+
} | undefined;
|
|
228
|
+
validation?: {
|
|
229
|
+
byCategory?: {
|
|
230
|
+
minimal?: string | undefined;
|
|
231
|
+
light?: string | undefined;
|
|
232
|
+
moderate?: string | undefined;
|
|
233
|
+
strong?: string | undefined;
|
|
234
|
+
heavy?: string | undefined;
|
|
235
|
+
maximum?: string | undefined;
|
|
236
|
+
} | undefined;
|
|
237
|
+
constant?: string | undefined;
|
|
238
|
+
default?: string | undefined;
|
|
239
|
+
} | undefined;
|
|
240
|
+
planning?: {
|
|
241
|
+
byCategory?: {
|
|
242
|
+
minimal?: string | undefined;
|
|
243
|
+
light?: string | undefined;
|
|
244
|
+
moderate?: string | undefined;
|
|
245
|
+
strong?: string | undefined;
|
|
246
|
+
heavy?: string | undefined;
|
|
247
|
+
maximum?: string | undefined;
|
|
248
|
+
} | undefined;
|
|
249
|
+
constant?: string | undefined;
|
|
250
|
+
default?: string | undefined;
|
|
251
|
+
} | undefined;
|
|
252
|
+
} | null | undefined;
|
|
177
253
|
}[];
|
|
178
254
|
total: number;
|
|
179
255
|
limit: number;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { FastifyPluginAsyncZod } from 'fastify-type-provider-zod';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
/** The `{ models, stale }` envelope returned by GET /models. */
|
|
4
|
+
export declare const ModelCatalogResponseSchema: z.ZodObject<{
|
|
5
|
+
models: z.ZodArray<z.ZodObject<{
|
|
6
|
+
id: z.ZodString;
|
|
7
|
+
display_name: z.ZodString;
|
|
8
|
+
family: z.ZodString;
|
|
9
|
+
created_at: z.ZodString;
|
|
10
|
+
}, z.core.$strip>>;
|
|
11
|
+
stale: z.ZodBoolean;
|
|
12
|
+
}, z.core.$strip>;
|
|
13
|
+
declare const modelsRoutes: FastifyPluginAsyncZod;
|
|
14
|
+
export default modelsRoutes;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Configurable Task Models (Task 13) — GET /api/v1/models
|
|
4
|
+
*
|
|
5
|
+
* Exposes the runtime-discovered Claude model catalog (task #917's
|
|
6
|
+
* `model-catalog.service`) over REST so the remote MCP proxy / dashboard /
|
|
7
|
+
* `set-models` interview can enumerate the available models. The 200 body is
|
|
8
|
+
* `{ models, stale }` — identical to the service's `ModelCatalog` and the
|
|
9
|
+
* stdio MCP `list_models` tool's structured output.
|
|
10
|
+
*
|
|
11
|
+
* `stale: true` signals the catalog was served from the static fallback (no
|
|
12
|
+
* ANTHROPIC_API_KEY, non-OK Models API response, or a network error). The
|
|
13
|
+
* service NEVER throws from `list()`, so this route always returns 200.
|
|
14
|
+
*
|
|
15
|
+
* Auth: inherits the standard `/api/v1` auth chain (the parent plugin is
|
|
16
|
+
* mounted inside the `/api/v1` scope that wires `authPlugin`). No custom guard.
|
|
17
|
+
*/
|
|
18
|
+
/** One discovered model, mirroring `ModelCatalogEntry` from the catalog service. */
|
|
19
|
+
const ModelCatalogEntrySchema = z.object({
|
|
20
|
+
id: z.string(),
|
|
21
|
+
display_name: z.string(),
|
|
22
|
+
family: z.string(),
|
|
23
|
+
created_at: z.string(),
|
|
24
|
+
});
|
|
25
|
+
/** The `{ models, stale }` envelope returned by GET /models. */
|
|
26
|
+
export const ModelCatalogResponseSchema = z.object({
|
|
27
|
+
models: z.array(ModelCatalogEntrySchema),
|
|
28
|
+
stale: z.boolean(),
|
|
29
|
+
});
|
|
30
|
+
const modelsRoutes = async (fastify) => {
|
|
31
|
+
fastify.get('/', {
|
|
32
|
+
schema: {
|
|
33
|
+
tags: ['models'],
|
|
34
|
+
description: 'List the available Claude model catalog (runtime-discovered via the ' +
|
|
35
|
+
'Anthropic Models API, TTL-cached). Returns `{ models, stale }`; ' +
|
|
36
|
+
'`stale: true` means the static fallback was served (no API key / ' +
|
|
37
|
+
'unreachable Models API).',
|
|
38
|
+
response: {
|
|
39
|
+
200: ModelCatalogResponseSchema,
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
}, async (_request, reply) => {
|
|
43
|
+
const catalog = await fastify.modelCatalogService.list();
|
|
44
|
+
return reply.send(catalog);
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
export default modelsRoutes;
|
|
48
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -3,6 +3,7 @@ import { CreateProjectSchema, UpdateProjectSchema } from '../../../schemas/task.
|
|
|
3
3
|
import { ProjectResponseSchema, ProjectListPaginatedResponseSchema } from './schemas.js';
|
|
4
4
|
import dependencyGraphRoutes from './dependency-graph.js';
|
|
5
5
|
import topologyRoutes from './topology.js';
|
|
6
|
+
import resolveModelRoutes from './resolve-model.js';
|
|
6
7
|
import projectWsjfRoutes from './wsjf.js';
|
|
7
8
|
// Pagination query schema for GET /projects. Mirrors task list bounds.
|
|
8
9
|
const QueryProjectListSchema = z.object({
|
|
@@ -78,6 +79,11 @@ const projectRoutes = async (fastify) => {
|
|
|
78
79
|
// MCP `topology_check` proxy tool. Registered as a child plugin alongside
|
|
79
80
|
// dependency-graph so its colocated `schema:` block lives in its own file.
|
|
80
81
|
await fastify.register(topologyRoutes);
|
|
82
|
+
// GET /:id/resolve-model — model-policy resolver over REST (task #926),
|
|
83
|
+
// backing the remote MCP `resolve_model` proxy tool. Registered as a child
|
|
84
|
+
// plugin alongside topology so its colocated `schema:` block lives in its
|
|
85
|
+
// own file.
|
|
86
|
+
await fastify.register(resolveModelRoutes);
|
|
81
87
|
// WSJF 4.5 (#645): GET /:id/charter-history + GET /:id/rescore-runs.
|
|
82
88
|
// Registered as a child plugin alongside topology so its colocated `schema:`
|
|
83
89
|
// blocks live in their own file.
|