wood-fired-tasks 2.0.5 → 2.1.0
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 +90 -0
- package/README.md +102 -89
- 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/auth/manual-pat.d.ts +99 -0
- package/dist/cli/auth/manual-pat.js +163 -0
- package/dist/cli/bin/tasks-client.js +6 -0
- package/dist/cli/bin/tasks.js +7 -0
- package/dist/cli/commands/login.d.ts +39 -0
- package/dist/cli/commands/login.js +99 -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/settings-set-models.d.ts +12 -0
- package/dist/cli/commands/settings-set-models.js +53 -0
- package/dist/cli/commands/setup.d.ts +24 -98
- package/dist/cli/commands/setup.js +89 -243
- package/dist/cli/output/formatters.js +13 -0
- package/dist/cli/util/prompt.d.ts +2 -2
- package/dist/cli/util/prompt.js +30 -11
- 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 +114 -6
- package/docs/INTERFACES.md +26 -14
- package/docs/MCP.md +61 -3
- package/docs/SETUP.md +29 -12
- 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,96 @@ vulnerabilities, supply-chain pinning) are always called out under `Security`.
|
|
|
13
13
|
|
|
14
14
|
_No changes yet._
|
|
15
15
|
|
|
16
|
+
## [v2.1.0] - 2026-06-09
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
- **Configurable Task Models** (PR #55, project 39 — 17 tasks). Route the
|
|
20
|
+
`/tasks:loop` worker (`execution`), verifier (`validation`), and planning
|
|
21
|
+
agents — decompose / audit / integration-auditor (`planning`) — to different
|
|
22
|
+
Anthropic models via a per-project + database-default `model_policy`.
|
|
23
|
+
- **Policy model:** six power categories (`minimal…maximum`, a 1:1 relabel of
|
|
24
|
+
the WSJF jobSize Fibonacci tiers) plus an `auto` sentinel; per-role
|
|
25
|
+
`byCategory` routing with a uniform `byCategory → constant → default →
|
|
26
|
+
null` slot walk, two-layer per-slot merge (`project ?? global`). Migration
|
|
27
|
+
016 adds `projects.model_policy` and the `app_settings` singleton.
|
|
28
|
+
- **Runtime model catalog:** live discovery via the Anthropic Models API
|
|
29
|
+
(set the optional `ANTHROPIC_API_KEY`) with a static fallback marked
|
|
30
|
+
`stale: true` — the read path never throws.
|
|
31
|
+
- **MCP:** four new tools — `list_models`, `resolve_model`,
|
|
32
|
+
`get_model_defaults`, `set_model_defaults` — on **both** the stdio and
|
|
33
|
+
remote servers (tool count 27 → 31).
|
|
34
|
+
- **REST:** `GET /models`, `GET|PUT /settings/model-policy`,
|
|
35
|
+
`GET /projects/:id/resolve-model`, and `model_policy` on project
|
|
36
|
+
create/update/get.
|
|
37
|
+
- **CLI:** `tasks models list`, `tasks project-set-models <id>`, and
|
|
38
|
+
`tasks settings-set-models` — the set-models commands fetch-merge-write
|
|
39
|
+
client-side, so incremental invocations never destroy earlier role config.
|
|
40
|
+
- **Skills:** a `/tasks:set-models` interview (one four-stage checklist
|
|
41
|
+
question per role, fixed option order, catalog-only options) and a
|
|
42
|
+
canonical, telemetry-grounded **Default Model Map** in `loop-shared.md` §R
|
|
43
|
+
that makes `auto` resolution deterministic (execution
|
|
44
|
+
sonnet/sonnet/opus/fable across the category ladder, validation
|
|
45
|
+
haiku/sonnet/opus/opus, planning opus). Optional
|
|
46
|
+
`--execution-model` / `--validation-model` / `--planning-model` run-arg
|
|
47
|
+
overrides ride LOOP-RUN frontmatter for replay provenance.
|
|
48
|
+
|
|
49
|
+
### Fixed
|
|
50
|
+
- **Test suite no longer launches the developer's real browser.**
|
|
51
|
+
`setup.remote.test.ts` drove the device flow with `openBrowser: true`, so
|
|
52
|
+
every `npm test` on a DISPLAY-set desktop spawned `xdg-open` at a mock
|
|
53
|
+
server. `openBrowser()` now honors `WFT_NO_BROWSER`, set for every test via
|
|
54
|
+
`vitest.setup.ts`.
|
|
55
|
+
- **Documentation counts drift.** README / `docs/INTERFACES.md` / `docs/MCP.md`
|
|
56
|
+
had stale tool (27 vs 31), route (52/45 vs 59/52), and CLI command (42 vs 45)
|
|
57
|
+
counts, plus a stale "model tools are stdio-only" claim from before remote
|
|
58
|
+
parity landed; the `interfaces-counts` drift guard now covers the model-tools
|
|
59
|
+
file so the next addition cannot dodge it.
|
|
60
|
+
|
|
61
|
+
### Security
|
|
62
|
+
- No security-relevant changes. The new `/models`, `/settings/model-policy`,
|
|
63
|
+
and `resolve-model` routes inherit the standard `/api/v1` auth chain; the
|
|
64
|
+
optional `ANTHROPIC_API_KEY` is only ever sent to the Anthropic Models API
|
|
65
|
+
and is never echoed in responses or logs.
|
|
66
|
+
|
|
67
|
+
## [v2.0.6] - 2026-06-08
|
|
68
|
+
|
|
69
|
+
### Added
|
|
70
|
+
- **`tasks login --token <pat>` — a manual-PAT login path.** `tasks login` was
|
|
71
|
+
device-flow only and **dead-ended on a remote non-`https` server**: the OAuth
|
|
72
|
+
device flow can't complete where Google rejects the non-`https` redirect URI,
|
|
73
|
+
and there was no way to supply a PAT instead. `login` now accepts `--token`
|
|
74
|
+
(validated against `GET /api/v1/me`, then persisted to the credentials file)
|
|
75
|
+
and, like `tasks setup`, applies the `canUseBrowserSso` gate — on a plain-`http`
|
|
76
|
+
non-localhost server it prints the `https`-required / how-to-mint-a-PAT
|
|
77
|
+
guidance and (on a TTY) prompts for one instead of launching a flow that can't
|
|
78
|
+
finish. The shared manual-PAT logic now lives in one module so `login` and
|
|
79
|
+
`setup` can't drift. (#857)
|
|
80
|
+
|
|
81
|
+
### Fixed
|
|
82
|
+
- **`tasks setup --remote --token <pat>` now actually authenticates you.** The
|
|
83
|
+
non-interactive `--token` path wrote the PAT to an **orphaned cache file that
|
|
84
|
+
no code reads** and never to the credentials file, so it reported success while
|
|
85
|
+
leaving *both* the CLI ("Not authenticated. Run: tasks login") and the remote
|
|
86
|
+
MCP bridge unauthenticated — the likely root cause of "remote MCP shows 0
|
|
87
|
+
projects" reports. The path now validates the PAT against `GET /api/v1/me` and
|
|
88
|
+
persists it to the credentials file (the same writer the device flow uses); the
|
|
89
|
+
bridge resolves its bearer token from there at runtime. The dead `remote-token`
|
|
90
|
+
cache (`cachePat`/`patCachePath`) was removed — the credentials file is the
|
|
91
|
+
single source of truth. (#858)
|
|
92
|
+
- **The interactive "Paste a personal access token:" prompt no longer hangs on a
|
|
93
|
+
real terminal.** `promptSecret` enables TTY raw mode to suppress echo, which
|
|
94
|
+
disables CR→LF translation, so the Enter key delivers a bare `\r` (0x0D) — but
|
|
95
|
+
the line reader only terminated on `\n`, so the read blocked forever (pasted
|
|
96
|
+
PAT buffered, Enter never recognized). Hit on Windows PowerShell during
|
|
97
|
+
`tasks setup --remote` manual-PAT entry; platform-independent. The reader now
|
|
98
|
+
treats `\r`, `\n`, or `\r\n` as the line terminator. (#856)
|
|
99
|
+
|
|
100
|
+
### Security
|
|
101
|
+
- The `--remote --token` PAT is now stored only in the `0600` credentials file
|
|
102
|
+
and is still **never** embedded in `~/.claude.json` (the remote MCP entry stays
|
|
103
|
+
URL-only, #810). The removed `remote-token` cache eliminates a second on-disk
|
|
104
|
+
copy of the secret.
|
|
105
|
+
|
|
16
106
|
## [v2.0.5] - 2026-06-08
|
|
17
107
|
|
|
18
108
|
### Changed
|
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
|
|
|
@@ -113,15 +146,13 @@ wood-fired-tasks service install # Linux: user-scoped systemd unit (admin-free
|
|
|
113
146
|
wood-fired-tasks self-update # npm i -g wood-fired-tasks@latest (no sudo)
|
|
114
147
|
```
|
|
115
148
|
|
|
116
|
-
**Point at a shared remote server**
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
REST API) and caches the PAT under your OS config dir. For a full
|
|
124
|
-
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:
|
|
125
156
|
[Multi-OS client fleet](docs/SETUP.md#multi-os-client-fleet-one-shared-on-prem-server).
|
|
126
157
|
|
|
127
158
|
Browse the bundled guides from anywhere with `wood-fired-tasks docs list` /
|
|
@@ -281,7 +312,7 @@ flowchart TB
|
|
|
281
312
|
| Interface | Access Method | Transport | Auth |
|
|
282
313
|
|-----------|--------------|-----------|------|
|
|
283
314
|
| REST API | HTTP endpoints | Port 3000 (configurable) | PAT (`Authorization: Bearer`) or OIDC session cookie |
|
|
284
|
-
| 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` |
|
|
285
316
|
| MCP Server | stdio JSON-RPC (local) or HTTP (remote variant) | MCP client integration | None for stdio (local access); Bearer PAT for remote |
|
|
286
317
|
| Slack subprocess | Slack Socket Mode | WebSocket to Slack | Slack signing secret + bot token |
|
|
287
318
|
|
|
@@ -423,7 +454,7 @@ The OIDC/session/PAT surface backing the auth model lives partly outside the tas
|
|
|
423
454
|
|
|
424
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.
|
|
425
456
|
|
|
426
|
-
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.
|
|
427
458
|
|
|
428
459
|
For detailed API documentation including request/response schemas, see [docs/API.md](docs/API.md).
|
|
429
460
|
|
|
@@ -431,11 +462,12 @@ For detailed API documentation including request/response schemas, see [docs/API
|
|
|
431
462
|
|
|
432
463
|
The `tasks` command provides terminal access to all task operations.
|
|
433
464
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
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.
|
|
439
471
|
|
|
440
472
|
**Global Flags:**
|
|
441
473
|
- `--json` - Output in machine-readable JSON format
|
|
@@ -505,7 +537,7 @@ full reference.
|
|
|
505
537
|
|
|
506
538
|
| Command | Description |
|
|
507
539
|
|---------|-------------|
|
|
508
|
-
| 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 |
|
|
509
541
|
| tasks logout | Revoke the active PAT and clear the local credentials |
|
|
510
542
|
| tasks whoami | Show the currently authenticated identity |
|
|
511
543
|
|
|
@@ -528,7 +560,7 @@ For detailed CLI documentation including all options and examples, see [docs/CLI
|
|
|
528
560
|
|
|
529
561
|
## MCP Tools Summary
|
|
530
562
|
|
|
531
|
-
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).
|
|
532
564
|
|
|
533
565
|
### Task Tools (9)
|
|
534
566
|
|
|
@@ -597,6 +629,15 @@ The MCP server exposes 27 tools and 1 resource for Claude Code integration — T
|
|
|
597
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 |
|
|
598
630
|
| wsjf_health | Non-blocking degeneracy/pitfall linter for a project's WSJF state (empty findings ⇔ healthy) |
|
|
599
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
|
+
|
|
600
641
|
### Resources (1)
|
|
601
642
|
|
|
602
643
|
| URI | Description |
|
|
@@ -729,66 +770,39 @@ variables) lives in [docs/SETUP.md → Environment Variables](docs/SETUP.md#envi
|
|
|
729
770
|
### Key Commands
|
|
730
771
|
|
|
731
772
|
```bash
|
|
732
|
-
#
|
|
733
|
-
npm run dev
|
|
734
|
-
|
|
735
|
-
# Run tests (~2600+ tests)
|
|
736
|
-
npm test
|
|
737
|
-
|
|
738
|
-
# Watch mode for tests
|
|
739
|
-
npm run test:watch
|
|
740
|
-
|
|
741
|
-
# Build TypeScript
|
|
742
|
-
npm run build
|
|
743
|
-
|
|
744
|
-
# Run CLI in development (without building)
|
|
745
|
-
npm run cli -- <command>
|
|
746
|
-
|
|
747
|
-
# Run MCP server in development
|
|
748
|
-
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
|
|
749
776
|
```
|
|
750
777
|
|
|
778
|
+
The canonical command table (focused tests, migrations, quality gate) lives in
|
|
779
|
+
[AGENTS.md → Essential commands](AGENTS.md#essential-commands).
|
|
780
|
+
|
|
751
781
|
### Database
|
|
752
782
|
|
|
753
|
-
SQLite with better-sqlite3 driver, WAL mode, and automatic
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
7. `007-completed-at.ts` — `completed_at` column on tasks (set on transition into `done`, backfilled from `updated_at`)
|
|
762
|
-
8. `008-identity-tables.ts` — `users` and `api_tokens` tables (OIDC/PAT identity)
|
|
763
|
-
9. `009-parallel-fk-columns.ts` — parallel `*_user_id` FK columns alongside the legacy TEXT identity columns
|
|
764
|
-
10. `010-identity-uniqueness-indexes.ts` — uniqueness indexes on user identity (oidc_sub, email)
|
|
765
|
-
11. `011-acceptance-criteria.ts` — `acceptance_criteria` column on tasks
|
|
766
|
-
12. `012-verification-evidence.ts` — `verification_evidence` column on tasks (verifier verdict + checks)
|
|
767
|
-
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
|
|
768
|
-
14. `014-value-charter.ts` — adds the nullable `value_charter` JSON column on `projects` (the per-project Business-Value reference frame)
|
|
769
|
-
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.
|
|
770
791
|
|
|
771
792
|
### Testing
|
|
772
793
|
|
|
773
|
-
~
|
|
774
|
-
|
|
775
|
-
-
|
|
776
|
-
-
|
|
777
|
-
|
|
778
|
-
- Event system tests (EventBus, SSEManager, events API)
|
|
779
|
-
- Claim protocol tests (including 20-agent concurrency)
|
|
780
|
-
- Workflow engine tests (auto-complete, auto-unblock, cascade depth)
|
|
781
|
-
- 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.
|
|
782
799
|
|
|
783
800
|
### Code Quality Roadmap
|
|
784
801
|
|
|
785
|
-
The
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
[docs/CODE_QUALITY_ROADMAP.md](docs/CODE_QUALITY_ROADMAP.md).
|
|
789
|
-
source of truth for the `Code Quality Uplift Roadmap` project tracked
|
|
790
|
-
in the bugs database and should be linked from future PR/release
|
|
791
|
-
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).
|
|
792
806
|
|
|
793
807
|
## Integrations
|
|
794
808
|
|
|
@@ -810,7 +824,7 @@ slash-command reference, channel subscription model, error handling.
|
|
|
810
824
|
### Claude Code (MCP)
|
|
811
825
|
|
|
812
826
|
The shipped MCP server registers as a stdio MCP target in `~/.claude.json`
|
|
813
|
-
and exposes
|
|
827
|
+
and exposes 31 tools plus the `/tasks:*` skill files. See
|
|
814
828
|
[docs/MCP.md](docs/MCP.md) and the "Claude Code Integration" section in
|
|
815
829
|
[docs/SETUP.md](docs/SETUP.md#claude-code-integration).
|
|
816
830
|
|
|
@@ -834,12 +848,11 @@ guarantee.
|
|
|
834
848
|
|
|
835
849
|
## Release Verification
|
|
836
850
|
|
|
837
|
-
Before publishing
|
|
838
|
-
|
|
839
|
-
`
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
`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).
|
|
843
856
|
|
|
844
857
|
## License
|
|
845
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.0` (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.0`. 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.
|