wood-fired-tasks 1.12.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 +112 -0
- package/CHANGELOG.md +271 -0
- package/CLAUDE.md +21 -0
- package/LICENSE +21 -0
- package/README.md +687 -0
- package/SECURITY.md +299 -0
- package/dist/api/hooks/error-handler.d.ts +6 -0
- package/dist/api/hooks/error-handler.js +128 -0
- package/dist/api/hooks/error-handler.js.map +1 -0
- package/dist/api/plugins/auth/index.d.ts +78 -0
- package/dist/api/plugins/auth/index.js +300 -0
- package/dist/api/plugins/auth/index.js.map +1 -0
- package/dist/api/plugins/auth/keys.d.ts +23 -0
- package/dist/api/plugins/auth/keys.js +100 -0
- package/dist/api/plugins/auth/keys.js.map +1 -0
- package/dist/api/plugins/auth/strategies/legacy.d.ts +46 -0
- package/dist/api/plugins/auth/strategies/legacy.js +87 -0
- package/dist/api/plugins/auth/strategies/legacy.js.map +1 -0
- package/dist/api/plugins/auth/strategies/pat.d.ts +37 -0
- package/dist/api/plugins/auth/strategies/pat.js +99 -0
- package/dist/api/plugins/auth/strategies/pat.js.map +1 -0
- package/dist/api/plugins/auth/strategies/session.d.ts +37 -0
- package/dist/api/plugins/auth/strategies/session.js +30 -0
- package/dist/api/plugins/auth/strategies/session.js.map +1 -0
- package/dist/api/plugins/auth/strategies/types.d.ts +12 -0
- package/dist/api/plugins/auth/strategies/types.js +2 -0
- package/dist/api/plugins/auth/strategies/types.js.map +1 -0
- package/dist/api/plugins/auth.d.ts +29 -0
- package/dist/api/plugins/auth.js +30 -0
- package/dist/api/plugins/auth.js.map +1 -0
- package/dist/api/plugins/swagger.d.ts +31 -0
- package/dist/api/plugins/swagger.js +83 -0
- package/dist/api/plugins/swagger.js.map +1 -0
- package/dist/api/routes/auth/auth-error.d.ts +23 -0
- package/dist/api/routes/auth/auth-error.js +68 -0
- package/dist/api/routes/auth/auth-error.js.map +1 -0
- package/dist/api/routes/auth/callback.d.ts +44 -0
- package/dist/api/routes/auth/callback.js +175 -0
- package/dist/api/routes/auth/callback.js.map +1 -0
- package/dist/api/routes/auth/csrf.d.ts +24 -0
- package/dist/api/routes/auth/csrf.js +75 -0
- package/dist/api/routes/auth/csrf.js.map +1 -0
- package/dist/api/routes/auth/device-code.d.ts +41 -0
- package/dist/api/routes/auth/device-code.js +51 -0
- package/dist/api/routes/auth/device-code.js.map +1 -0
- package/dist/api/routes/auth/device-disabled-stub.d.ts +33 -0
- package/dist/api/routes/auth/device-disabled-stub.js +16 -0
- package/dist/api/routes/auth/device-disabled-stub.js.map +1 -0
- package/dist/api/routes/auth/device-html.d.ts +41 -0
- package/dist/api/routes/auth/device-html.js +243 -0
- package/dist/api/routes/auth/device-html.js.map +1 -0
- package/dist/api/routes/auth/device-token.d.ts +38 -0
- package/dist/api/routes/auth/device-token.js +153 -0
- package/dist/api/routes/auth/device-token.js.map +1 -0
- package/dist/api/routes/auth/disabled-stub.d.ts +31 -0
- package/dist/api/routes/auth/disabled-stub.js +21 -0
- package/dist/api/routes/auth/disabled-stub.js.map +1 -0
- package/dist/api/routes/auth/index.d.ts +65 -0
- package/dist/api/routes/auth/index.js +47 -0
- package/dist/api/routes/auth/index.js.map +1 -0
- package/dist/api/routes/auth/login.d.ts +27 -0
- package/dist/api/routes/auth/login.js +91 -0
- package/dist/api/routes/auth/login.js.map +1 -0
- package/dist/api/routes/auth/logout.d.ts +29 -0
- package/dist/api/routes/auth/logout.js +43 -0
- package/dist/api/routes/auth/logout.js.map +1 -0
- package/dist/api/routes/comments/index.d.ts +3 -0
- package/dist/api/routes/comments/index.js +74 -0
- package/dist/api/routes/comments/index.js.map +1 -0
- package/dist/api/routes/comments/schemas.d.ts +37 -0
- package/dist/api/routes/comments/schemas.js +24 -0
- package/dist/api/routes/comments/schemas.js.map +1 -0
- package/dist/api/routes/dependencies/index.d.ts +3 -0
- package/dist/api/routes/dependencies/index.js +60 -0
- package/dist/api/routes/dependencies/index.js.map +1 -0
- package/dist/api/routes/dependencies/schemas.d.ts +24 -0
- package/dist/api/routes/dependencies/schemas.js +15 -0
- package/dist/api/routes/dependencies/schemas.js.map +1 -0
- package/dist/api/routes/events.d.ts +3 -0
- package/dist/api/routes/events.js +157 -0
- package/dist/api/routes/events.js.map +1 -0
- package/dist/api/routes/health.d.ts +27 -0
- package/dist/api/routes/health.js +231 -0
- package/dist/api/routes/health.js.map +1 -0
- package/dist/api/routes/me/index.d.ts +3 -0
- package/dist/api/routes/me/index.js +8 -0
- package/dist/api/routes/me/index.js.map +1 -0
- package/dist/api/routes/me/profile.d.ts +3 -0
- package/dist/api/routes/me/profile.js +58 -0
- package/dist/api/routes/me/profile.js.map +1 -0
- package/dist/api/routes/me/tokens.d.ts +3 -0
- package/dist/api/routes/me/tokens.js +410 -0
- package/dist/api/routes/me/tokens.js.map +1 -0
- package/dist/api/routes/projects/dependency-graph.d.ts +26 -0
- package/dist/api/routes/projects/dependency-graph.js +56 -0
- package/dist/api/routes/projects/dependency-graph.js.map +1 -0
- package/dist/api/routes/projects/index.d.ts +3 -0
- package/dist/api/routes/projects/index.js +96 -0
- package/dist/api/routes/projects/index.js.map +1 -0
- package/dist/api/routes/projects/schemas.d.ts +37 -0
- package/dist/api/routes/projects/schemas.js +27 -0
- package/dist/api/routes/projects/schemas.js.map +1 -0
- package/dist/api/routes/projects/topology.d.ts +27 -0
- package/dist/api/routes/projects/topology.js +51 -0
- package/dist/api/routes/projects/topology.js.map +1 -0
- package/dist/api/routes/tasks/index.d.ts +3 -0
- package/dist/api/routes/tasks/index.js +330 -0
- package/dist/api/routes/tasks/index.js.map +1 -0
- package/dist/api/routes/tasks/schemas.d.ts +316 -0
- package/dist/api/routes/tasks/schemas.js +129 -0
- package/dist/api/routes/tasks/schemas.js.map +1 -0
- package/dist/api/routes/web/index.d.ts +23 -0
- package/dist/api/routes/web/index.js +30 -0
- package/dist/api/routes/web/index.js.map +1 -0
- package/dist/api/routes/web/login.d.ts +20 -0
- package/dist/api/routes/web/login.js +20 -0
- package/dist/api/routes/web/login.js.map +1 -0
- package/dist/api/routes/web/me.d.ts +23 -0
- package/dist/api/routes/web/me.js +31 -0
- package/dist/api/routes/web/me.js.map +1 -0
- package/dist/api/routes/web/tokens.d.ts +29 -0
- package/dist/api/routes/web/tokens.js +65 -0
- package/dist/api/routes/web/tokens.js.map +1 -0
- package/dist/api/server.d.ts +44 -0
- package/dist/api/server.js +521 -0
- package/dist/api/server.js.map +1 -0
- package/dist/api/start.d.ts +1 -0
- package/dist/api/start.js +79 -0
- package/dist/api/start.js.map +1 -0
- package/dist/cli/api/client.d.ts +126 -0
- package/dist/cli/api/client.js +408 -0
- package/dist/cli/api/client.js.map +1 -0
- package/dist/cli/api/errors.d.ts +16 -0
- package/dist/cli/api/errors.js +20 -0
- package/dist/cli/api/errors.js.map +1 -0
- package/dist/cli/api/types.d.ts +205 -0
- package/dist/cli/api/types.js +15 -0
- package/dist/cli/api/types.js.map +1 -0
- package/dist/cli/auth/browser-open.d.ts +1 -0
- package/dist/cli/auth/browser-open.js +116 -0
- package/dist/cli/auth/browser-open.js.map +1 -0
- package/dist/cli/auth/credentials.d.ts +27 -0
- package/dist/cli/auth/credentials.js +179 -0
- package/dist/cli/auth/credentials.js.map +1 -0
- package/dist/cli/auth/device-flow.d.ts +75 -0
- package/dist/cli/auth/device-flow.js +149 -0
- package/dist/cli/auth/device-flow.js.map +1 -0
- package/dist/cli/bin/tasks-client.d.ts +2 -0
- package/dist/cli/bin/tasks-client.js +86 -0
- package/dist/cli/bin/tasks-client.js.map +1 -0
- package/dist/cli/bin/tasks.d.ts +3 -0
- package/dist/cli/bin/tasks.js +127 -0
- package/dist/cli/bin/tasks.js.map +1 -0
- package/dist/cli/commands/backup.d.ts +3 -0
- package/dist/cli/commands/backup.js +65 -0
- package/dist/cli/commands/backup.js.map +1 -0
- package/dist/cli/commands/claim.d.ts +2 -0
- package/dist/cli/commands/claim.js +37 -0
- package/dist/cli/commands/claim.js.map +1 -0
- package/dist/cli/commands/comment-add.d.ts +2 -0
- package/dist/cli/commands/comment-add.js +45 -0
- package/dist/cli/commands/comment-add.js.map +1 -0
- package/dist/cli/commands/comment-delete.d.ts +2 -0
- package/dist/cli/commands/comment-delete.js +56 -0
- package/dist/cli/commands/comment-delete.js.map +1 -0
- package/dist/cli/commands/comment-list.d.ts +2 -0
- package/dist/cli/commands/comment-list.js +56 -0
- package/dist/cli/commands/comment-list.js.map +1 -0
- package/dist/cli/commands/completed.d.ts +10 -0
- package/dist/cli/commands/completed.js +168 -0
- package/dist/cli/commands/completed.js.map +1 -0
- package/dist/cli/commands/completions.d.ts +10 -0
- package/dist/cli/commands/completions.js +179 -0
- package/dist/cli/commands/completions.js.map +1 -0
- package/dist/cli/commands/create.d.ts +2 -0
- package/dist/cli/commands/create.js +99 -0
- package/dist/cli/commands/create.js.map +1 -0
- package/dist/cli/commands/db-check.d.ts +3 -0
- package/dist/cli/commands/db-check.js +63 -0
- package/dist/cli/commands/db-check.js.map +1 -0
- package/dist/cli/commands/db-migrate-identities.d.ts +37 -0
- package/dist/cli/commands/db-migrate-identities.js +352 -0
- package/dist/cli/commands/db-migrate-identities.js.map +1 -0
- package/dist/cli/commands/db-mint-token.d.ts +33 -0
- package/dist/cli/commands/db-mint-token.js +150 -0
- package/dist/cli/commands/db-mint-token.js.map +1 -0
- package/dist/cli/commands/db.d.ts +10 -0
- package/dist/cli/commands/db.js +16 -0
- package/dist/cli/commands/db.js.map +1 -0
- package/dist/cli/commands/delete.d.ts +2 -0
- package/dist/cli/commands/delete.js +54 -0
- package/dist/cli/commands/delete.js.map +1 -0
- package/dist/cli/commands/dep-add.d.ts +2 -0
- package/dist/cli/commands/dep-add.js +43 -0
- package/dist/cli/commands/dep-add.js.map +1 -0
- package/dist/cli/commands/dep-list.d.ts +2 -0
- package/dist/cli/commands/dep-list.js +36 -0
- package/dist/cli/commands/dep-list.js.map +1 -0
- package/dist/cli/commands/dep-remove.d.ts +2 -0
- package/dist/cli/commands/dep-remove.js +55 -0
- package/dist/cli/commands/dep-remove.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +3 -0
- package/dist/cli/commands/doctor.js +139 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/health.d.ts +2 -0
- package/dist/cli/commands/health.js +28 -0
- package/dist/cli/commands/health.js.map +1 -0
- package/dist/cli/commands/list.d.ts +2 -0
- package/dist/cli/commands/list.js +103 -0
- package/dist/cli/commands/list.js.map +1 -0
- package/dist/cli/commands/login.d.ts +2 -0
- package/dist/cli/commands/login.js +210 -0
- package/dist/cli/commands/login.js.map +1 -0
- package/dist/cli/commands/logout.d.ts +31 -0
- package/dist/cli/commands/logout.js +184 -0
- package/dist/cli/commands/logout.js.map +1 -0
- package/dist/cli/commands/project-create.d.ts +2 -0
- package/dist/cli/commands/project-create.js +44 -0
- package/dist/cli/commands/project-create.js.map +1 -0
- package/dist/cli/commands/project-delete.d.ts +2 -0
- package/dist/cli/commands/project-delete.js +54 -0
- package/dist/cli/commands/project-delete.js.map +1 -0
- package/dist/cli/commands/project-list.d.ts +2 -0
- package/dist/cli/commands/project-list.js +55 -0
- package/dist/cli/commands/project-list.js.map +1 -0
- package/dist/cli/commands/project-show.d.ts +2 -0
- package/dist/cli/commands/project-show.js +38 -0
- package/dist/cli/commands/project-show.js.map +1 -0
- package/dist/cli/commands/project-update.d.ts +2 -0
- package/dist/cli/commands/project-update.js +56 -0
- package/dist/cli/commands/project-update.js.map +1 -0
- package/dist/cli/commands/show.d.ts +2 -0
- package/dist/cli/commands/show.js +38 -0
- package/dist/cli/commands/show.js.map +1 -0
- package/dist/cli/commands/stats.d.ts +3 -0
- package/dist/cli/commands/stats.js +81 -0
- package/dist/cli/commands/stats.js.map +1 -0
- package/dist/cli/commands/subtask-create.d.ts +2 -0
- package/dist/cli/commands/subtask-create.js +85 -0
- package/dist/cli/commands/subtask-create.js.map +1 -0
- package/dist/cli/commands/subtask-list.d.ts +2 -0
- package/dist/cli/commands/subtask-list.js +61 -0
- package/dist/cli/commands/subtask-list.js.map +1 -0
- package/dist/cli/commands/topology.d.ts +16 -0
- package/dist/cli/commands/topology.js +52 -0
- package/dist/cli/commands/topology.js.map +1 -0
- package/dist/cli/commands/update.d.ts +2 -0
- package/dist/cli/commands/update.js +90 -0
- package/dist/cli/commands/update.js.map +1 -0
- package/dist/cli/commands/whoami.d.ts +30 -0
- package/dist/cli/commands/whoami.js +201 -0
- package/dist/cli/commands/whoami.js.map +1 -0
- package/dist/cli/config/env.d.ts +4 -0
- package/dist/cli/config/env.js +25 -0
- package/dist/cli/config/env.js.map +1 -0
- package/dist/cli/output/error-handler.d.ts +5 -0
- package/dist/cli/output/error-handler.js +41 -0
- package/dist/cli/output/error-handler.js.map +1 -0
- package/dist/cli/output/formatters.d.ts +86 -0
- package/dist/cli/output/formatters.js +352 -0
- package/dist/cli/output/formatters.js.map +1 -0
- package/dist/cli/output/json-output.d.ts +39 -0
- package/dist/cli/output/json-output.js +50 -0
- package/dist/cli/output/json-output.js.map +1 -0
- package/dist/cli/output/spinner.d.ts +14 -0
- package/dist/cli/output/spinner.js +48 -0
- package/dist/cli/output/spinner.js.map +1 -0
- package/dist/cli/prompts/interactive.d.ts +25 -0
- package/dist/cli/prompts/interactive.js +80 -0
- package/dist/cli/prompts/interactive.js.map +1 -0
- package/dist/config/env.d.ts +182 -0
- package/dist/config/env.js +311 -0
- package/dist/config/env.js.map +1 -0
- package/dist/db/database.d.ts +11 -0
- package/dist/db/database.js +25 -0
- package/dist/db/database.js.map +1 -0
- package/dist/db/migrate.d.ts +10 -0
- package/dist/db/migrate.js +137 -0
- package/dist/db/migrate.js.map +1 -0
- package/dist/db/migrations/001-initial-schema.d.ts +3 -0
- package/dist/db/migrations/001-initial-schema.js +100 -0
- package/dist/db/migrations/001-initial-schema.js.map +1 -0
- package/dist/db/migrations/002-task-hierarchy-and-dependencies.d.ts +3 -0
- package/dist/db/migrations/002-task-hierarchy-and-dependencies.js +42 -0
- package/dist/db/migrations/002-task-hierarchy-and-dependencies.js.map +1 -0
- package/dist/db/migrations/003-comments-and-estimates.d.ts +3 -0
- package/dist/db/migrations/003-comments-and-estimates.js +36 -0
- package/dist/db/migrations/003-comments-and-estimates.js.map +1 -0
- package/dist/db/migrations/004-claim-protocol.d.ts +3 -0
- package/dist/db/migrations/004-claim-protocol.js +41 -0
- package/dist/db/migrations/004-claim-protocol.js.map +1 -0
- package/dist/db/migrations/005-backlogged-status.d.ts +3 -0
- package/dist/db/migrations/005-backlogged-status.js +156 -0
- package/dist/db/migrations/005-backlogged-status.js.map +1 -0
- package/dist/db/migrations/006-slack-channel-subscriptions.d.ts +3 -0
- package/dist/db/migrations/006-slack-channel-subscriptions.js +23 -0
- package/dist/db/migrations/006-slack-channel-subscriptions.js.map +1 -0
- package/dist/db/migrations/007-completed-at.d.ts +19 -0
- package/dist/db/migrations/007-completed-at.js +36 -0
- package/dist/db/migrations/007-completed-at.js.map +1 -0
- package/dist/db/migrations/008-identity-tables.d.ts +21 -0
- package/dist/db/migrations/008-identity-tables.js +84 -0
- package/dist/db/migrations/008-identity-tables.js.map +1 -0
- package/dist/db/migrations/009-parallel-fk-columns.d.ts +33 -0
- package/dist/db/migrations/009-parallel-fk-columns.js +62 -0
- package/dist/db/migrations/009-parallel-fk-columns.js.map +1 -0
- package/dist/db/migrations/010-identity-uniqueness-indexes.d.ts +47 -0
- package/dist/db/migrations/010-identity-uniqueness-indexes.js +65 -0
- package/dist/db/migrations/010-identity-uniqueness-indexes.js.map +1 -0
- package/dist/db/migrations/011-acceptance-criteria.d.ts +30 -0
- package/dist/db/migrations/011-acceptance-criteria.js +41 -0
- package/dist/db/migrations/011-acceptance-criteria.js.map +1 -0
- package/dist/db/migrations/012-verification-evidence.d.ts +41 -0
- package/dist/db/migrations/012-verification-evidence.js +49 -0
- package/dist/db/migrations/012-verification-evidence.js.map +1 -0
- package/dist/events/event-bus.d.ts +101 -0
- package/dist/events/event-bus.js +184 -0
- package/dist/events/event-bus.js.map +1 -0
- package/dist/events/sse-manager.d.ts +79 -0
- package/dist/events/sse-manager.js +220 -0
- package/dist/events/sse-manager.js.map +1 -0
- package/dist/events/types.d.ts +43 -0
- package/dist/events/types.js +22 -0
- package/dist/events/types.js.map +1 -0
- package/dist/index.d.ts +110 -0
- package/dist/index.js +209 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/audit/schema.d.ts +201 -0
- package/dist/lib/audit/schema.js +141 -0
- package/dist/lib/audit/schema.js.map +1 -0
- package/dist/lib/decompose/schema.d.ts +157 -0
- package/dist/lib/decompose/schema.js +138 -0
- package/dist/lib/decompose/schema.js.map +1 -0
- package/dist/lib/loop-run/integration-audit-schema.d.ts +78 -0
- package/dist/lib/loop-run/integration-audit-schema.js +68 -0
- package/dist/lib/loop-run/integration-audit-schema.js.map +1 -0
- package/dist/lib/loop-run/schema.d.ts +49 -0
- package/dist/lib/loop-run/schema.js +67 -0
- package/dist/lib/loop-run/schema.js.map +1 -0
- package/dist/mcp/errors.d.ts +11 -0
- package/dist/mcp/errors.js +29 -0
- package/dist/mcp/errors.js.map +1 -0
- package/dist/mcp/identity-resolution.d.ts +76 -0
- package/dist/mcp/identity-resolution.js +189 -0
- package/dist/mcp/identity-resolution.js.map +1 -0
- package/dist/mcp/index.d.ts +1 -0
- package/dist/mcp/index.js +126 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/remote/index.d.ts +21 -0
- package/dist/mcp/remote/index.js +95 -0
- package/dist/mcp/remote/index.js.map +1 -0
- package/dist/mcp/remote/register-tools.d.ts +26 -0
- package/dist/mcp/remote/register-tools.js +751 -0
- package/dist/mcp/remote/register-tools.js.map +1 -0
- package/dist/mcp/remote/rest-client.d.ts +66 -0
- package/dist/mcp/remote/rest-client.js +300 -0
- package/dist/mcp/remote/rest-client.js.map +1 -0
- package/dist/mcp/resources/events.d.ts +28 -0
- package/dist/mcp/resources/events.js +98 -0
- package/dist/mcp/resources/events.js.map +1 -0
- package/dist/mcp/server.d.ts +59 -0
- package/dist/mcp/server.js +72 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools/comment-tools.d.ts +12 -0
- package/dist/mcp/tools/comment-tools.js +115 -0
- package/dist/mcp/tools/comment-tools.js.map +1 -0
- package/dist/mcp/tools/dependency-tools.d.ts +3 -0
- package/dist/mcp/tools/dependency-tools.js +91 -0
- package/dist/mcp/tools/dependency-tools.js.map +1 -0
- package/dist/mcp/tools/health-tools.d.ts +9 -0
- package/dist/mcp/tools/health-tools.js +82 -0
- package/dist/mcp/tools/health-tools.js.map +1 -0
- package/dist/mcp/tools/project-tools.d.ts +13 -0
- package/dist/mcp/tools/project-tools.js +167 -0
- package/dist/mcp/tools/project-tools.js.map +1 -0
- package/dist/mcp/tools/task-tools.d.ts +41 -0
- package/dist/mcp/tools/task-tools.js +434 -0
- package/dist/mcp/tools/task-tools.js.map +1 -0
- package/dist/mcp/tools/topology-tools.d.ts +14 -0
- package/dist/mcp/tools/topology-tools.js +46 -0
- package/dist/mcp/tools/topology-tools.js.map +1 -0
- package/dist/repositories/api-token.repository.d.ts +40 -0
- package/dist/repositories/api-token.repository.js +63 -0
- package/dist/repositories/api-token.repository.js.map +1 -0
- package/dist/repositories/comment.repository.d.ts +17 -0
- package/dist/repositories/comment.repository.js +73 -0
- package/dist/repositories/comment.repository.js.map +1 -0
- package/dist/repositories/dependency.repository.d.ts +19 -0
- package/dist/repositories/dependency.repository.js +55 -0
- package/dist/repositories/dependency.repository.js.map +1 -0
- package/dist/repositories/errors.d.ts +29 -0
- package/dist/repositories/errors.js +48 -0
- package/dist/repositories/errors.js.map +1 -0
- package/dist/repositories/interfaces.d.ts +200 -0
- package/dist/repositories/interfaces.js +2 -0
- package/dist/repositories/interfaces.js.map +1 -0
- package/dist/repositories/project.repository.d.ts +21 -0
- package/dist/repositories/project.repository.js +97 -0
- package/dist/repositories/project.repository.js.map +1 -0
- package/dist/repositories/row-mapper.d.ts +40 -0
- package/dist/repositories/row-mapper.js +38 -0
- package/dist/repositories/row-mapper.js.map +1 -0
- package/dist/repositories/task.repository.d.ts +45 -0
- package/dist/repositories/task.repository.js +612 -0
- package/dist/repositories/task.repository.js.map +1 -0
- package/dist/repositories/types.d.ts +20 -0
- package/dist/repositories/types.js +11 -0
- package/dist/repositories/types.js.map +1 -0
- package/dist/repositories/user.repository.d.ts +121 -0
- package/dist/repositories/user.repository.js +209 -0
- package/dist/repositories/user.repository.js.map +1 -0
- package/dist/schemas/comment.schema.d.ts +24 -0
- package/dist/schemas/comment.schema.js +27 -0
- package/dist/schemas/comment.schema.js.map +1 -0
- package/dist/schemas/dependency-graph.schema.d.ts +181 -0
- package/dist/schemas/dependency-graph.schema.js +98 -0
- package/dist/schemas/dependency-graph.schema.js.map +1 -0
- package/dist/schemas/dependency.schema.d.ts +9 -0
- package/dist/schemas/dependency.schema.js +16 -0
- package/dist/schemas/dependency.schema.js.map +1 -0
- package/dist/schemas/idempotency.schema.d.ts +18 -0
- package/dist/schemas/idempotency.schema.js +22 -0
- package/dist/schemas/idempotency.schema.js.map +1 -0
- package/dist/schemas/task.schema.d.ts +369 -0
- package/dist/schemas/task.schema.js +276 -0
- package/dist/schemas/task.schema.js.map +1 -0
- package/dist/schemas/topology.schema.d.ts +56 -0
- package/dist/schemas/topology.schema.js +48 -0
- package/dist/schemas/topology.schema.js.map +1 -0
- package/dist/services/auth-audit.d.ts +46 -0
- package/dist/services/auth-audit.js +28 -0
- package/dist/services/auth-audit.js.map +1 -0
- package/dist/services/claim-release.service.d.ts +42 -0
- package/dist/services/claim-release.service.js +90 -0
- package/dist/services/claim-release.service.js.map +1 -0
- package/dist/services/comment.service.d.ts +44 -0
- package/dist/services/comment.service.js +96 -0
- package/dist/services/comment.service.js.map +1 -0
- package/dist/services/dependency-graph.service.d.ts +33 -0
- package/dist/services/dependency-graph.service.js +453 -0
- package/dist/services/dependency-graph.service.js.map +1 -0
- package/dist/services/dependency.service.d.ts +32 -0
- package/dist/services/dependency.service.js +79 -0
- package/dist/services/dependency.service.js.map +1 -0
- package/dist/services/device-flow-store.d.ts +155 -0
- package/dist/services/device-flow-store.js +323 -0
- package/dist/services/device-flow-store.js.map +1 -0
- package/dist/services/errors.d.ts +28 -0
- package/dist/services/errors.js +44 -0
- package/dist/services/errors.js.map +1 -0
- package/dist/services/idempotency.service.d.ts +37 -0
- package/dist/services/idempotency.service.js +54 -0
- package/dist/services/idempotency.service.js.map +1 -0
- package/dist/services/identity-seeder.d.ts +56 -0
- package/dist/services/identity-seeder.js +131 -0
- package/dist/services/identity-seeder.js.map +1 -0
- package/dist/services/oidc-boot.d.ts +73 -0
- package/dist/services/oidc-boot.js +66 -0
- package/dist/services/oidc-boot.js.map +1 -0
- package/dist/services/oidc-client.d.ts +99 -0
- package/dist/services/oidc-client.js +108 -0
- package/dist/services/oidc-client.js.map +1 -0
- package/dist/services/pat-hash.d.ts +23 -0
- package/dist/services/pat-hash.js +73 -0
- package/dist/services/pat-hash.js.map +1 -0
- package/dist/services/pat-touch-debounce.d.ts +65 -0
- package/dist/services/pat-touch-debounce.js +82 -0
- package/dist/services/pat-touch-debounce.js.map +1 -0
- package/dist/services/project.service.d.ts +41 -0
- package/dist/services/project.service.js +133 -0
- package/dist/services/project.service.js.map +1 -0
- package/dist/services/slack.service.d.ts +31 -0
- package/dist/services/slack.service.js +52 -0
- package/dist/services/slack.service.js.map +1 -0
- package/dist/services/task.service.d.ts +151 -0
- package/dist/services/task.service.js +425 -0
- package/dist/services/task.service.js.map +1 -0
- package/dist/services/topology.service.d.ts +65 -0
- package/dist/services/topology.service.js +170 -0
- package/dist/services/topology.service.js.map +1 -0
- package/dist/services/user-upsert.d.ts +43 -0
- package/dist/services/user-upsert.js +53 -0
- package/dist/services/user-upsert.js.map +1 -0
- package/dist/services/workflow-engine.d.ts +93 -0
- package/dist/services/workflow-engine.js +250 -0
- package/dist/services/workflow-engine.js.map +1 -0
- package/dist/slack/commands/tasks-command.d.ts +88 -0
- package/dist/slack/commands/tasks-command.js +920 -0
- package/dist/slack/commands/tasks-command.js.map +1 -0
- package/dist/slack/formatters/project-formatter.d.ts +19 -0
- package/dist/slack/formatters/project-formatter.js +94 -0
- package/dist/slack/formatters/project-formatter.js.map +1 -0
- package/dist/slack/notifier.d.ts +41 -0
- package/dist/slack/notifier.js +111 -0
- package/dist/slack/notifier.js.map +1 -0
- package/dist/slack/repositories/channel-subscription.repository.d.ts +25 -0
- package/dist/slack/repositories/channel-subscription.repository.js +51 -0
- package/dist/slack/repositories/channel-subscription.repository.js.map +1 -0
- package/dist/slack/task-formatter.d.ts +31 -0
- package/dist/slack/task-formatter.js +151 -0
- package/dist/slack/task-formatter.js.map +1 -0
- package/dist/slack/user-identity.d.ts +37 -0
- package/dist/slack/user-identity.js +70 -0
- package/dist/slack/user-identity.js.map +1 -0
- package/dist/types/identity.d.ts +84 -0
- package/dist/types/identity.js +6 -0
- package/dist/types/identity.js.map +1 -0
- package/dist/types/task.d.ts +202 -0
- package/dist/types/task.js +17 -0
- package/dist/types/task.js.map +1 -0
- package/dist/utils/cycle-detector.d.ts +25 -0
- package/dist/utils/cycle-detector.js +86 -0
- package/dist/utils/cycle-detector.js.map +1 -0
- package/dist/utils/exit-codes.d.ts +64 -0
- package/dist/utils/exit-codes.js +57 -0
- package/dist/utils/exit-codes.js.map +1 -0
- package/dist/utils/is-main.d.ts +12 -0
- package/dist/utils/is-main.js +24 -0
- package/dist/utils/is-main.js.map +1 -0
- package/dist/utils/version.d.ts +1 -0
- package/dist/utils/version.js +22 -0
- package/dist/utils/version.js.map +1 -0
- package/dist/web/html.d.ts +73 -0
- package/dist/web/html.js +154 -0
- package/dist/web/html.js.map +1 -0
- package/dist/web/pages/device.d.ts +19 -0
- package/dist/web/pages/device.js +76 -0
- package/dist/web/pages/device.js.map +1 -0
- package/dist/web/pages/error.d.ts +6 -0
- package/dist/web/pages/error.js +23 -0
- package/dist/web/pages/error.js.map +1 -0
- package/dist/web/pages/login.d.ts +5 -0
- package/dist/web/pages/login.js +22 -0
- package/dist/web/pages/login.js.map +1 -0
- package/dist/web/pages/me.d.ts +9 -0
- package/dist/web/pages/me.js +37 -0
- package/dist/web/pages/me.js.map +1 -0
- package/dist/web/pages/tokens.d.ts +20 -0
- package/dist/web/pages/tokens.js +89 -0
- package/dist/web/pages/tokens.js.map +1 -0
- package/dist/web/session-constants.d.ts +21 -0
- package/dist/web/session-constants.js +22 -0
- package/dist/web/session-constants.js.map +1 -0
- package/dist/web/session-flash.d.ts +15 -0
- package/dist/web/session-flash.js +11 -0
- package/dist/web/session-flash.js.map +1 -0
- package/dist/web/session-user.d.ts +59 -0
- package/dist/web/session-user.js +44 -0
- package/dist/web/session-user.js.map +1 -0
- package/docs/AGENT_CONTEXT.md +280 -0
- package/docs/README.md +49 -0
- package/llms.txt +33 -0
- package/package.json +129 -0
package/README.md
ADDED
|
@@ -0,0 +1,687 @@
|
|
|
1
|
+
# Wood Fired Tasks
|
|
2
|
+
|
|
3
|
+
[](https://github.com/Wood-Fired-Games/wood-fired-tasks/actions/workflows/ci.yml)
|
|
4
|
+
[](https://github.com/Wood-Fired-Games/wood-fired-tasks/actions/workflows/install-scripts.yml)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
|
|
7
|
+
Open-source task tracking system from Wood Fired Games.
|
|
8
|
+
|
|
9
|
+
Wood Fired Tasks is a centralized task management service providing a REST API, CLI tool, and MCP server for managing work items across all projects. LLM agents interact via REST or MCP; humans interact via CLI. All three interfaces share a common service layer and SQLite database with full feature parity. Real-time SSE event streaming enables multi-agent coordination with atomic task claiming and workflow automation.
|
|
10
|
+
|
|
11
|
+
**Key capabilities:**
|
|
12
|
+
|
|
13
|
+
- REST API with 47 route handlers across `src/api/routes/` (1 public `/health`; the rest authenticated) for full task lifecycle management — a single running instance serves up to 40 of them (the OIDC-disabled `/auth/*` stub handlers are mutually exclusive with the live OIDC routes)
|
|
14
|
+
- CLI (`tasks`) with 31 commands for terminal-based operations
|
|
15
|
+
- MCP server with 22 tools for native Claude Code integration (local SQLite or remote HTTP modes)
|
|
16
|
+
- 16 task-loop skill files that ship as Claude Code slash commands today; the underlying recipes are vendor-neutral and any agent harness can consume them
|
|
17
|
+
- Real-time Server-Sent Events (SSE) for task change notifications
|
|
18
|
+
- Atomic task claiming with optimistic locking for multi-agent coordination
|
|
19
|
+
- Workflow automation: parent auto-complete and dependency auto-unblock
|
|
20
|
+
- SQLite database with WAL mode, FTS5 full-text search, and automatic migrations
|
|
21
|
+
- Cross-platform installers for Linux/macOS and Windows
|
|
22
|
+
|
|
23
|
+
## For agents
|
|
24
|
+
|
|
25
|
+
Coding agents (Claude Code, Cursor, Gemini, Codex, and others) should start with:
|
|
26
|
+
|
|
27
|
+
1. [AGENTS.md](AGENTS.md) — first-read navigation hub.
|
|
28
|
+
2. [docs/AGENT_CONTEXT.md](docs/AGENT_CONTEXT.md) — the vendor-neutral context contract.
|
|
29
|
+
3. [.agent-context.json](.agent-context.json) — machine-readable manifest of canonical files and their budgets.
|
|
30
|
+
|
|
31
|
+
Vendor-specific files (`CLAUDE.md`, `.cursor/`, `.gemini/`, `.codex/`) are adapters and MUST NOT carry unique facts — see `docs/AGENT_CONTEXT.md` §6.
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Clone and install
|
|
37
|
+
git clone https://github.com/Wood-Fired-Games/wood-fired-tasks.git
|
|
38
|
+
cd wood-fired-tasks
|
|
39
|
+
npm install
|
|
40
|
+
npm run build
|
|
41
|
+
|
|
42
|
+
# Set environment variables
|
|
43
|
+
export API_KEYS="your-api-key-here"
|
|
44
|
+
export DATABASE_PATH="./data/tasks.db"
|
|
45
|
+
|
|
46
|
+
# Run database migrations
|
|
47
|
+
npm run migrate
|
|
48
|
+
|
|
49
|
+
# Start the API server
|
|
50
|
+
npm start
|
|
51
|
+
|
|
52
|
+
# Use the CLI
|
|
53
|
+
tasks list
|
|
54
|
+
tasks create --title "My first task" --project 1 --created-by "me"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
For detailed setup instructions, see [docs/SETUP.md](docs/SETUP.md).
|
|
58
|
+
|
|
59
|
+
## Self-hosting
|
|
60
|
+
|
|
61
|
+
For self-hosted production deploys (including the fork-and-deploy workflow for OSS operators): provision a host once with `deploy/install.sh`, then ship every subsequent release in place with `deploy/upgrade.sh` (atomic backup, migrate, restart, `/health` probe, manual rollback recipe on failure). The full walkthrough — first-time install, in-place upgrades, deploying your fork, manual rollback, and the migration safety contract — lives at [Self-hosting and upgrades](docs/SETUP.md#self-hosting-and-upgrades). When a deploy or a reboot goes sideways, the [Troubleshooting & Recovery runbook](docs/TROUBLESHOOTING.md) covers boot failures (`exit 78`), wrong/stale-database symptoms, and safe backup/restore.
|
|
62
|
+
|
|
63
|
+
## Security Model
|
|
64
|
+
|
|
65
|
+
**Read this before deploying.** Wood Fired Tasks is built for trusted multi-agent coordination. As of **v1.6** the REST API authenticates every `/api/v1` request through a three-strategy chain (`src/api/plugins/auth/index.ts`), tried in order — the first strategy that produces a valid user wins, and that user's id is stamped onto every write (`created_by_user_id`, `assignee_user_id`, …) and the per-request audit log (`user_id`, `token_id`, `auth_method`):
|
|
66
|
+
|
|
67
|
+
| Order | Strategy | Credential | Wire format |
|
|
68
|
+
|-------|----------|------------|-------------|
|
|
69
|
+
| 1 | **PAT** — recommended for machines/agents | row in `api_tokens` (SHA-256 hash stored) | `Authorization: Bearer wft_pat_<…>` |
|
|
70
|
+
| 2 | **Session** — recommended for humans | OIDC sign-in → sealed-box cookie | `Cookie: wft_session=<…>` |
|
|
71
|
+
| 3 | **Legacy** — deprecated but still supported (see below) | entry in `API_KEYS` env list | `X-API-Key: <…>` |
|
|
72
|
+
|
|
73
|
+
PATs are minted from a logged-in `/me` web session or offline via `tasks db mint-token`; the raw value is shown **once** at mint time (only a hash is stored) and revoked via the `/me` UI, `DELETE /me/tokens/:id`, or `tasks logout`. Sessions come from OIDC (`/auth/login` → provider → `/auth/callback`, protected by PKCE + state), are sealed-box-encrypted with `SESSION_COOKIE_SECRET`, and expire after 8h. The CLI and remote MCP client auto-select the header from the `wft_pat_` prefix, so the same env var accepts a PAT or a legacy key. Full detail: [SECURITY.md → Authentication Architecture](SECURITY.md#authentication-architecture).
|
|
74
|
+
|
|
75
|
+
### ⚠️ Authentication is NOT authorization — every identity is admin
|
|
76
|
+
|
|
77
|
+
**Read this before exposing the service to anything but trusted callers.**
|
|
78
|
+
|
|
79
|
+
- **Authentication ≠ authorization.** The auth chain only *identifies* the caller; it does **not** scope what they may do.
|
|
80
|
+
- **Every authenticated identity is effectively an admin.** Any valid credential — PAT, OIDC session, or legacy `X-API-Key` — can read, write, and delete **every** task, project, comment, and dependency across **every** project in the database.
|
|
81
|
+
- **There is NO RBAC, NO ACL, and NO per-project / per-tenant isolation.** These are not implemented; scoped/role-based permissions are tracked only as future work.
|
|
82
|
+
- **Do NOT expose this service on a public network, and do NOT run it multi-tenant, without an external authorization layer** (e.g. an authenticating reverse proxy that enforces its own per-tenant access control in front of the API). Treat any issued credential as full admin access to all data.
|
|
83
|
+
|
|
84
|
+
### Legacy `X-API-Key` is still supported (PAT / OIDC preferred)
|
|
85
|
+
|
|
86
|
+
The legacy `X-API-Key` strategy **still works today** — it is strategy #3 in the live auth chain (`src/api/plugins/auth/index.ts`), and `API_KEYS` is currently a **required** env var (see Configuration), so every deployment has at least one working key. It is marked **deprecated as of v1.6**: PAT and OIDC sessions are the preferred credentials going forward, but legacy keys have **not** been removed. Legacy-authed responses carry advisory RFC 8594 `Deprecation: true` + `Sunset: <LEGACY_AUTH_SUNSET_DATE>` headers (operator-controlled, default `2026-12-31`) and emit a `legacy_auth_used` warn log so operators can track migration progress. New deployments should issue **PATs** — one per machine/agent, so you can revoke an individual token without disturbing others — or use OIDC sessions. The `API_KEYS` env accepts a comma-separated list of `key` or `key:label` entries (the label surfaces in audit logs as `apiKeyLabel`; the raw key is never logged). See [SECURITY.md → Legacy Auth Sunset Timeline](SECURITY.md#legacy-auth-sunset-timeline) and `tasks db migrate-identities` for the planned migration path.
|
|
87
|
+
|
|
88
|
+
### Defense in depth
|
|
89
|
+
|
|
90
|
+
Auth is paired with two configurable protections, both mitigations rather than authorization:
|
|
91
|
+
|
|
92
|
+
- **Rate limiting** via `@fastify/rate-limit` (global, 1000 req/min default) — tunable through `RATE_LIMIT_MAX` and `RATE_LIMIT_TIME_WINDOW`.
|
|
93
|
+
- **SSE connection caps** — per-key, per-IP, and global limits on long-lived event-stream connections (`SSE_MAX_CONNECTIONS_PER_KEY` / `SSE_MAX_CONNECTIONS_PER_IP` / `SSE_MAX_CONNECTIONS`).
|
|
94
|
+
|
|
95
|
+
These reduce blast radius; they do not substitute for credential hygiene. For incident response (credential compromise, rotation, disclosure), see [SECURITY.md](SECURITY.md).
|
|
96
|
+
|
|
97
|
+
## Architecture
|
|
98
|
+
|
|
99
|
+
The service is a single Node process exposing three peer entry points
|
|
100
|
+
(REST, CLI, MCP) over a shared service layer, plus an optional Slack
|
|
101
|
+
subprocess that reuses the same services and database. Real-time events
|
|
102
|
+
flow through an in-process EventBus to the SSE Manager (browser/agent
|
|
103
|
+
consumers) and the Slack notifier (channel subscribers).
|
|
104
|
+
|
|
105
|
+
```mermaid
|
|
106
|
+
flowchart TB
|
|
107
|
+
subgraph clients[Clients]
|
|
108
|
+
HumanCLI[Terminal user<br/>tasks CLI]
|
|
109
|
+
HTTPAgent[HTTP / SSE agent]
|
|
110
|
+
ClaudeMCP[Claude Code<br/>MCP stdio]
|
|
111
|
+
SlackUser[Slack user<br/>/tasks slash]
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
subgraph entry[Entry points]
|
|
115
|
+
CLI[CLI<br/>Commander.js]
|
|
116
|
+
REST[REST API<br/>Fastify :3000]
|
|
117
|
+
MCP[MCP Server<br/>stdio + remote HTTP]
|
|
118
|
+
Slack[Slack subprocess<br/>@slack/bolt]
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
subgraph guards[Auth and validation]
|
|
122
|
+
Auth[auth plugin<br/>X-API-Key]
|
|
123
|
+
RL[Rate limiter<br/>RATE_LIMIT_*]
|
|
124
|
+
Zod[Zod schemas<br/>request/response]
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
subgraph core[Service layer - shared]
|
|
128
|
+
TS[TaskService]
|
|
129
|
+
PS[ProjectService]
|
|
130
|
+
DS[DependencyService]
|
|
131
|
+
CS[CommentService]
|
|
132
|
+
Workflow[Workflow Engine<br/>cascade: parent auto-complete,<br/>dependency auto-unblock,<br/>depth-limited]
|
|
133
|
+
Idem[Idempotency Service]
|
|
134
|
+
Claim[Claim/Release Service]
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
subgraph events[Events]
|
|
138
|
+
Bus[EventBus<br/>in-process]
|
|
139
|
+
SSE[SSE Manager<br/>per-key/IP/global caps]
|
|
140
|
+
Notifier[Slack Notifier<br/>per-channel retry]
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
subgraph storage[Persistence]
|
|
144
|
+
DB[(SQLite WAL<br/>tasks, projects, task_comments,<br/>task_dependencies, idempotency_keys,<br/>slack_channel_subscriptions)]
|
|
145
|
+
Subs[(Channel<br/>Subscription Repo)]
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
HumanCLI --> CLI
|
|
149
|
+
HTTPAgent -->|HTTP + X-API-Key| REST
|
|
150
|
+
ClaudeMCP -->|stdio JSON-RPC| MCP
|
|
151
|
+
SlackUser -->|Socket Mode| Slack
|
|
152
|
+
|
|
153
|
+
CLI -->|HTTP| REST
|
|
154
|
+
REST --> Auth --> RL --> Zod --> TS
|
|
155
|
+
Zod --> PS
|
|
156
|
+
Zod --> DS
|
|
157
|
+
Zod --> CS
|
|
158
|
+
MCP --> TS
|
|
159
|
+
MCP --> PS
|
|
160
|
+
MCP --> DS
|
|
161
|
+
MCP --> CS
|
|
162
|
+
Slack --> TS
|
|
163
|
+
Slack --> PS
|
|
164
|
+
Slack --> DS
|
|
165
|
+
Slack --> CS
|
|
166
|
+
Slack --> Subs
|
|
167
|
+
|
|
168
|
+
TS --> Workflow
|
|
169
|
+
TS --> Claim
|
|
170
|
+
Claim --> Idem
|
|
171
|
+
Workflow --> Bus
|
|
172
|
+
TS --> Bus
|
|
173
|
+
PS --> Bus
|
|
174
|
+
DS --> Bus
|
|
175
|
+
CS --> Bus
|
|
176
|
+
|
|
177
|
+
Bus --> SSE
|
|
178
|
+
Bus --> Notifier
|
|
179
|
+
Notifier --> Subs
|
|
180
|
+
SSE -->|text/event-stream| HTTPAgent
|
|
181
|
+
Notifier -->|chat.postMessage| SlackUser
|
|
182
|
+
|
|
183
|
+
TS --> DB
|
|
184
|
+
PS --> DB
|
|
185
|
+
DS --> DB
|
|
186
|
+
CS --> DB
|
|
187
|
+
Claim --> DB
|
|
188
|
+
Subs --> DB
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
| Interface | Access Method | Transport | Auth |
|
|
192
|
+
|-----------|--------------|-----------|------|
|
|
193
|
+
| REST API | HTTP endpoints | Port 3000 (configurable) | PAT (`Authorization: Bearer`), session cookie, or legacy `X-API-Key` |
|
|
194
|
+
| CLI | `tasks` command | HTTP to API server (most cmds); direct SQLite for offline ops (`backup`, `doctor`, `stats`, `db-check`, `completed`) | `API_KEY` env var (accepts a PAT or legacy key) |
|
|
195
|
+
| MCP Server | stdio JSON-RPC (local) or HTTP (remote variant) | MCP client integration | None for stdio (local access); Bearer PAT or `X-API-Key` for remote |
|
|
196
|
+
| Slack subprocess | Slack Socket Mode | WebSocket to Slack | Slack signing secret + bot token |
|
|
197
|
+
|
|
198
|
+
All entry points share the same TypeScript services
|
|
199
|
+
(TaskService, ProjectService, DependencyService, CommentService), the
|
|
200
|
+
Workflow Engine (cascades parent auto-complete and dependency
|
|
201
|
+
auto-unblock; depth-limited and wrapped in a transaction), and the same
|
|
202
|
+
SQLite database in WAL mode. The Slack notifier is a downstream
|
|
203
|
+
EventBus subscriber — it never blocks task mutations, retries transient
|
|
204
|
+
errors twice, and short-circuits permanent errors
|
|
205
|
+
(`not_in_channel`, `channel_not_found`, `invalid_auth`, `token_revoked`).
|
|
206
|
+
|
|
207
|
+
## Data Model
|
|
208
|
+
|
|
209
|
+
### Entities
|
|
210
|
+
|
|
211
|
+
| Entity | Key Fields |
|
|
212
|
+
|--------|------------|
|
|
213
|
+
| **projects** | id, name, description, created_at, updated_at |
|
|
214
|
+
| **tasks** | id, title, description, status, priority, project_id, parent_task_id, estimated_minutes, assignee, created_by, due_date, version, claimed_at, **completed_at**, created_at, updated_at |
|
|
215
|
+
| **task_tags** | id, task_id, tag |
|
|
216
|
+
| **task_dependencies** | id, task_id, blocks_task_id, created_at |
|
|
217
|
+
| **task_comments** | id, task_id, author, content, created_at, updated_at |
|
|
218
|
+
| **idempotency_keys** | key, response, created_at |
|
|
219
|
+
| **slack_channel_subscriptions** | id, channel_id, project_id, event_type, created_at (UNIQUE on the triple) |
|
|
220
|
+
| **users** | id, oidc_sub, oidc_provider, email, display_name, slack_user_id, is_legacy, is_service_account, created_at, disabled_at |
|
|
221
|
+
| **api_tokens** | id, user_id, name, prefix, suffix, hash, scopes, created_at, last_used_at, revoked_at, expires_at |
|
|
222
|
+
|
|
223
|
+
### Task Statuses
|
|
224
|
+
|
|
225
|
+
Valid statuses: `open`, `in_progress`, `done`, `closed`, `blocked`, `backlogged`
|
|
226
|
+
|
|
227
|
+
- `backlogged` is "deferred but not abandoned" — distinct from `closed` (won't-do / archive).
|
|
228
|
+
- `completed_at` is populated only when a task transitions **into** `done`,
|
|
229
|
+
and cleared if it transitions back out (e.g. `done → open`). `closed` is
|
|
230
|
+
intentionally not treated as completion (separate terminal state).
|
|
231
|
+
|
|
232
|
+
### Task Priorities
|
|
233
|
+
|
|
234
|
+
Valid priorities: `low`, `medium`, `high`, `urgent`
|
|
235
|
+
|
|
236
|
+
### Status Transitions
|
|
237
|
+
|
|
238
|
+
| From Status | Allowed Transitions |
|
|
239
|
+
|-------------|---------------------|
|
|
240
|
+
| open | in_progress, blocked, closed, backlogged |
|
|
241
|
+
| in_progress | done, blocked, open |
|
|
242
|
+
| blocked | open, in_progress |
|
|
243
|
+
| backlogged | open |
|
|
244
|
+
| done | closed, open |
|
|
245
|
+
| closed | open |
|
|
246
|
+
|
|
247
|
+
(Canonical source: `VALID_STATUS_TRANSITIONS` in [`src/types/task.ts`](src/types/task.ts).)
|
|
248
|
+
|
|
249
|
+
## API Summary
|
|
250
|
+
|
|
251
|
+
All `/api/v1` endpoints require authentication — a PAT (`Authorization: Bearer wft_pat_…`), an OIDC session cookie, or a legacy `X-API-Key` header (deprecated). `GET /health` is public; the OIDC sign-in flow lives under `/auth/*` (outside `/api/v1`).
|
|
252
|
+
|
|
253
|
+
Base URL: `http://localhost:3000`
|
|
254
|
+
|
|
255
|
+
### Health
|
|
256
|
+
|
|
257
|
+
| Method | Path | Description |
|
|
258
|
+
|--------|------|-------------|
|
|
259
|
+
| GET | /health | Minimal public liveness check — returns only `{ status, timestamp, version }` (no auth required). Pings the DB and returns 503 in the same shape on failure; intentionally leaks no deployment fingerprint. |
|
|
260
|
+
| GET | /health/detailed | Authenticated diagnostic check — adds resolved DB path/fingerprint, component checks (database, eventBus, sseManager, oidc), OIDC discovery detail, and runtime stats. |
|
|
261
|
+
|
|
262
|
+
### Projects
|
|
263
|
+
|
|
264
|
+
| Method | Path | Description |
|
|
265
|
+
|--------|------|-------------|
|
|
266
|
+
| POST | /api/v1/projects | Create a new project |
|
|
267
|
+
| GET | /api/v1/projects | List all projects |
|
|
268
|
+
| GET | /api/v1/projects/:id | Get project by ID |
|
|
269
|
+
| PUT | /api/v1/projects/:id | Update project |
|
|
270
|
+
| DELETE | /api/v1/projects/:id | Delete project |
|
|
271
|
+
| GET | /api/v1/projects/:id/topology | Classify the project's dependency graph (FLAT / DAG / DAG_CYCLIC) |
|
|
272
|
+
| GET | /api/v1/projects/:id/dependency-graph | Dashboard tree-view of the project's task dependency graph |
|
|
273
|
+
|
|
274
|
+
### Tasks
|
|
275
|
+
|
|
276
|
+
| Method | Path | Description |
|
|
277
|
+
|--------|------|-------------|
|
|
278
|
+
| POST | /api/v1/tasks | Create a new task |
|
|
279
|
+
| GET | /api/v1/tasks | List tasks with filters |
|
|
280
|
+
| GET | /api/v1/tasks/completion-report | Completion dashboard for a time window (per-project/assignee/priority aggregates) |
|
|
281
|
+
| GET | /api/v1/tasks/:id | Get task by ID |
|
|
282
|
+
| PUT | /api/v1/tasks/:id | Update task |
|
|
283
|
+
| DELETE | /api/v1/tasks/:id | Delete task |
|
|
284
|
+
| POST | /api/v1/tasks/:id/claim | Atomically claim an unassigned task |
|
|
285
|
+
| GET | /api/v1/tasks/:id/subtasks | Get subtasks of a task |
|
|
286
|
+
|
|
287
|
+
### Comments
|
|
288
|
+
|
|
289
|
+
| Method | Path | Description |
|
|
290
|
+
|--------|------|-------------|
|
|
291
|
+
| POST | /api/v1/tasks/:id/comments | Add comment to task |
|
|
292
|
+
| GET | /api/v1/tasks/:id/comments | List comments for task |
|
|
293
|
+
| DELETE | /api/v1/tasks/:id/comments/:commentId | Delete comment |
|
|
294
|
+
|
|
295
|
+
### Dependencies
|
|
296
|
+
|
|
297
|
+
| Method | Path | Description |
|
|
298
|
+
|--------|------|-------------|
|
|
299
|
+
| POST | /api/v1/tasks/:id/dependencies | Add dependency (this task blocks another) |
|
|
300
|
+
| GET | /api/v1/tasks/:id/dependencies | Get dependencies for task |
|
|
301
|
+
| DELETE | /api/v1/tasks/:id/dependencies/:blocksTaskId | Remove dependency |
|
|
302
|
+
|
|
303
|
+
### Events
|
|
304
|
+
|
|
305
|
+
| Method | Path | Description |
|
|
306
|
+
|--------|------|-------------|
|
|
307
|
+
| GET | /api/v1/events | Subscribe to real-time SSE event stream |
|
|
308
|
+
|
|
309
|
+
### Authentication & Identity
|
|
310
|
+
|
|
311
|
+
The OIDC/session/PAT surface backing the auth model lives partly outside the task API:
|
|
312
|
+
|
|
313
|
+
| Method | Path | Description |
|
|
314
|
+
|--------|------|-------------|
|
|
315
|
+
| GET | /auth/login | Begin OIDC sign-in (redirects to provider; PKCE + state) |
|
|
316
|
+
| GET | /auth/callback | OIDC redirect callback → sets the session cookie |
|
|
317
|
+
| POST | /auth/logout | Revoke the active PAT and clear the session |
|
|
318
|
+
| GET | /auth/error | OIDC/session error landing page (session-expiry, 403 destinations) |
|
|
319
|
+
| GET | /api/v1/me | Current authenticated user's profile (accepts session, PAT, or legacy auth) |
|
|
320
|
+
| GET | /api/v1/me/tokens | List the caller's personal access tokens |
|
|
321
|
+
| DELETE | /api/v1/me/tokens/active | Revoke the caller's currently-active token |
|
|
322
|
+
| DELETE | /api/v1/me/tokens/:id | Revoke a personal access token by ID |
|
|
323
|
+
|
|
324
|
+
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.
|
|
325
|
+
|
|
326
|
+
This brings the full registered surface to **47 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 **40** of them: the 7 OIDC-disabled stub handlers are mutually exclusive with the 8 live OIDC `/auth/*` routes.
|
|
327
|
+
|
|
328
|
+
For detailed API documentation including request/response schemas, see [docs/API.md](docs/API.md).
|
|
329
|
+
|
|
330
|
+
## CLI Summary
|
|
331
|
+
|
|
332
|
+
The `tasks` command provides terminal access to all task operations.
|
|
333
|
+
|
|
334
|
+
**Global Flags:**
|
|
335
|
+
- `--json` - Output in machine-readable JSON format
|
|
336
|
+
- `--no-input` - Disable interactive prompts
|
|
337
|
+
- `--force` - Skip confirmation prompts
|
|
338
|
+
|
|
339
|
+
### Task Commands
|
|
340
|
+
|
|
341
|
+
| Command | Description |
|
|
342
|
+
|---------|-------------|
|
|
343
|
+
| tasks create | Create a new task (interactive or with options) |
|
|
344
|
+
| tasks list | List tasks with filters |
|
|
345
|
+
| tasks show \<id\> | Show task details |
|
|
346
|
+
| tasks update \<id\> | Update task fields |
|
|
347
|
+
| tasks delete \<id\> | Delete a task |
|
|
348
|
+
| tasks claim \<id\> | Atomically claim an unassigned task |
|
|
349
|
+
|
|
350
|
+
### Project Commands
|
|
351
|
+
|
|
352
|
+
| Command | Description |
|
|
353
|
+
|---------|-------------|
|
|
354
|
+
| tasks project-create | Create a new project |
|
|
355
|
+
| tasks project-list | List all projects |
|
|
356
|
+
| tasks project-show \<id\> | Show project details |
|
|
357
|
+
| tasks project-update \<id\> | Update project |
|
|
358
|
+
| tasks project-delete \<id\> | Delete project |
|
|
359
|
+
|
|
360
|
+
### Dependency Commands
|
|
361
|
+
|
|
362
|
+
| Command | Description |
|
|
363
|
+
|---------|-------------|
|
|
364
|
+
| tasks dep-add \<taskId\> \<blocksTaskId\> | Add dependency relationship |
|
|
365
|
+
| tasks dep-remove \<taskId\> \<blocksTaskId\> | Remove dependency |
|
|
366
|
+
| tasks dep-list \<taskId\> | List dependencies for task |
|
|
367
|
+
| tasks topology \<projectId\> | Classify a project's dependency graph (FLAT / DAG / DAG_CYCLIC) |
|
|
368
|
+
|
|
369
|
+
### Comment Commands
|
|
370
|
+
|
|
371
|
+
| Command | Description |
|
|
372
|
+
|---------|-------------|
|
|
373
|
+
| tasks comment-add \<taskId\> | Add comment to task |
|
|
374
|
+
| tasks comment-list \<taskId\> | List comments for task |
|
|
375
|
+
| tasks comment-delete \<commentId\> | Delete comment |
|
|
376
|
+
|
|
377
|
+
### Subtask Commands
|
|
378
|
+
|
|
379
|
+
| Command | Description |
|
|
380
|
+
|---------|-------------|
|
|
381
|
+
| tasks subtask-create \<parentTaskId\> | Create a subtask |
|
|
382
|
+
| tasks subtask-list \<parentTaskId\> | List subtasks |
|
|
383
|
+
|
|
384
|
+
### Health
|
|
385
|
+
|
|
386
|
+
| Command | Description |
|
|
387
|
+
|---------|-------------|
|
|
388
|
+
| tasks health | Check server health |
|
|
389
|
+
|
|
390
|
+
### Authentication Commands
|
|
391
|
+
|
|
392
|
+
| Command | Description |
|
|
393
|
+
|---------|-------------|
|
|
394
|
+
| tasks login | OIDC sign-in; caches a PAT to the local credentials file |
|
|
395
|
+
| tasks logout | Revoke the active PAT and clear the local credentials |
|
|
396
|
+
| tasks whoami | Show the currently authenticated identity |
|
|
397
|
+
|
|
398
|
+
### Admin & Offline Commands
|
|
399
|
+
|
|
400
|
+
These talk to SQLite directly (no running server required):
|
|
401
|
+
|
|
402
|
+
| Command | Description |
|
|
403
|
+
|---------|-------------|
|
|
404
|
+
| tasks backup | Back up the SQLite database to a file |
|
|
405
|
+
| tasks doctor | Diagnose database / config health |
|
|
406
|
+
| tasks stats | Show task / project statistics |
|
|
407
|
+
| tasks completed | List recently completed tasks |
|
|
408
|
+
| tasks db-check | Verify the database schema / integrity |
|
|
409
|
+
| tasks db mint-token | Mint a PAT offline (`--user`, `--name`, optional `--expires-at`) |
|
|
410
|
+
| tasks db migrate-identities | Backfill identity FK columns (preparation for the legacy-auth migration path) |
|
|
411
|
+
| tasks completions | Generate shell completion scripts |
|
|
412
|
+
|
|
413
|
+
For detailed CLI documentation including all options and examples, see [docs/CLI.md](docs/CLI.md).
|
|
414
|
+
|
|
415
|
+
## MCP Tools Summary
|
|
416
|
+
|
|
417
|
+
The MCP server exposes 22 tools and 1 resource for Claude Code integration. A second entry point (`npm run mcp:remote`) exposes the full REST-backed tool surface (22 tools, at parity with local) for clients running on a different host than the bugs API — see [docs/MCP.md#remote-mcp-server](docs/MCP.md#remote-mcp-server).
|
|
418
|
+
|
|
419
|
+
### Task Tools (9)
|
|
420
|
+
|
|
421
|
+
| Tool | Description |
|
|
422
|
+
|------|-------------|
|
|
423
|
+
| create_task | Create a new task in a project |
|
|
424
|
+
| get_task | Get a task by its ID |
|
|
425
|
+
| update_task | Update an existing task |
|
|
426
|
+
| list_tasks | List tasks with optional filters and pagination |
|
|
427
|
+
| delete_task | Delete a task by its ID |
|
|
428
|
+
| claim_task | Atomically claim an unassigned task |
|
|
429
|
+
| list_subtasks | Paginated list of subtasks for a parent task |
|
|
430
|
+
| get_subtasks | Paginated subtasks for a parent task (alternative shape) |
|
|
431
|
+
| completion_report | Dashboard of tasks completed in a window with per-project/assignee/priority aggregates |
|
|
432
|
+
|
|
433
|
+
### Project Tools (5)
|
|
434
|
+
|
|
435
|
+
| Tool | Description |
|
|
436
|
+
|------|-------------|
|
|
437
|
+
| create_project | Create a new project |
|
|
438
|
+
| get_project | Get a project by its ID |
|
|
439
|
+
| list_projects | List all projects |
|
|
440
|
+
| update_project | Update an existing project |
|
|
441
|
+
| delete_project | Delete a project by its ID |
|
|
442
|
+
|
|
443
|
+
### Comment Tools (3)
|
|
444
|
+
|
|
445
|
+
| Tool | Description |
|
|
446
|
+
|------|-------------|
|
|
447
|
+
| add_comment | Add a comment to a task |
|
|
448
|
+
| get_comments | Get all comments for a task |
|
|
449
|
+
| delete_comment | Delete a comment by ID |
|
|
450
|
+
|
|
451
|
+
### Dependency Tools (3)
|
|
452
|
+
|
|
453
|
+
| Tool | Description |
|
|
454
|
+
|------|-------------|
|
|
455
|
+
| add_dependency | Add a dependency relationship between tasks |
|
|
456
|
+
| remove_dependency | Remove a dependency relationship |
|
|
457
|
+
| get_dependencies | Get all dependencies for a task |
|
|
458
|
+
|
|
459
|
+
### Health Tools (1)
|
|
460
|
+
|
|
461
|
+
| Tool | Description |
|
|
462
|
+
|------|-------------|
|
|
463
|
+
| check_health | Check service health status |
|
|
464
|
+
|
|
465
|
+
### Topology Tools (1)
|
|
466
|
+
|
|
467
|
+
| Tool | Description |
|
|
468
|
+
|------|-------------|
|
|
469
|
+
| topology_check | Classify a project's dependency graph as FLAT / DAG / DAG_CYCLIC |
|
|
470
|
+
|
|
471
|
+
### Resources (1)
|
|
472
|
+
|
|
473
|
+
| URI | Description |
|
|
474
|
+
|-----|-------------|
|
|
475
|
+
| events://stream | SSE event stream discovery documentation |
|
|
476
|
+
|
|
477
|
+
For detailed MCP documentation including tool schemas and Claude Code skill files, see [docs/MCP.md](docs/MCP.md).
|
|
478
|
+
|
|
479
|
+
## Real-Time Events
|
|
480
|
+
|
|
481
|
+
Wood Fired Tasks streams real-time task and project change notifications via Server-Sent Events (SSE).
|
|
482
|
+
|
|
483
|
+
### Event Types
|
|
484
|
+
|
|
485
|
+
| Event | Trigger |
|
|
486
|
+
|-------|---------|
|
|
487
|
+
| task.created | New task created |
|
|
488
|
+
| task.updated | Task fields modified |
|
|
489
|
+
| task.deleted | Task deleted |
|
|
490
|
+
| task.status_changed | Task status transition |
|
|
491
|
+
| task.claimed | Task claimed by agent |
|
|
492
|
+
| project.created | New project created |
|
|
493
|
+
| project.updated | Project modified |
|
|
494
|
+
| project.deleted | Project deleted |
|
|
495
|
+
|
|
496
|
+
### Subscribing
|
|
497
|
+
|
|
498
|
+
```bash
|
|
499
|
+
# Subscribe to all events
|
|
500
|
+
curl -N -H "X-API-Key: your-key" \
|
|
501
|
+
http://localhost:3000/api/v1/events
|
|
502
|
+
|
|
503
|
+
# Filter by project
|
|
504
|
+
curl -N -H "X-API-Key: your-key" \
|
|
505
|
+
"http://localhost:3000/api/v1/events?project_id=1"
|
|
506
|
+
|
|
507
|
+
# Filter by event type
|
|
508
|
+
curl -N -H "X-API-Key: your-key" \
|
|
509
|
+
"http://localhost:3000/api/v1/events?event_types=task.created,task.claimed"
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
### Reconnection
|
|
513
|
+
|
|
514
|
+
Include `Last-Event-ID` header to resume from where you left off:
|
|
515
|
+
|
|
516
|
+
```bash
|
|
517
|
+
curl -N -H "X-API-Key: your-key" \
|
|
518
|
+
-H "Last-Event-ID: 42" \
|
|
519
|
+
http://localhost:3000/api/v1/events
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
## Multi-Agent Coordination
|
|
523
|
+
|
|
524
|
+
### Atomic Task Claiming
|
|
525
|
+
|
|
526
|
+
Multiple agents can race to claim the same task. Exactly one wins; the rest receive a 409 Conflict. This uses optimistic locking with a version field and `BEGIN IMMEDIATE` transactions in SQLite.
|
|
527
|
+
|
|
528
|
+
```bash
|
|
529
|
+
# Claim a task
|
|
530
|
+
curl -X POST http://localhost:3000/api/v1/tasks/42/claim \
|
|
531
|
+
-H "X-API-Key: your-key" \
|
|
532
|
+
-H "Content-Type: application/json" \
|
|
533
|
+
-d '{"assignee": "agent-1"}'
|
|
534
|
+
|
|
535
|
+
# With idempotency key (safe to retry)
|
|
536
|
+
curl -X POST http://localhost:3000/api/v1/tasks/42/claim \
|
|
537
|
+
-H "X-API-Key: your-key" \
|
|
538
|
+
-H "X-Idempotency-Key: unique-key-123" \
|
|
539
|
+
-H "Content-Type: application/json" \
|
|
540
|
+
-d '{"assignee": "agent-1"}'
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
- Verified with 20 concurrent agents: exactly 1 success, 19 conflicts, 0 errors
|
|
544
|
+
- Stale claims auto-released after 30 minutes of inactivity
|
|
545
|
+
- Idempotency keys prevent duplicate claims (24h TTL)
|
|
546
|
+
|
|
547
|
+
### Workflow Automation
|
|
548
|
+
|
|
549
|
+
When tasks change status, the system automatically:
|
|
550
|
+
|
|
551
|
+
- **Parent auto-complete:** When all subtasks reach `done`, parent task transitions to `done`
|
|
552
|
+
- **Dependency auto-unblock:** When a blocking task completes, blocked dependents transition from `blocked` to `open`
|
|
553
|
+
|
|
554
|
+
Cascades are depth-limited (max 5 levels) and wrapped in transactions for atomicity.
|
|
555
|
+
|
|
556
|
+
## Configuration
|
|
557
|
+
|
|
558
|
+
### Environment Variables
|
|
559
|
+
|
|
560
|
+
| Variable | Description | Default |
|
|
561
|
+
|----------|-------------|---------|
|
|
562
|
+
| PORT | HTTP server port | 3000 |
|
|
563
|
+
| HOST | HTTP server host. Defaults to loopback only; set to `0.0.0.0` (or a specific LAN IP) to expose on the network. | 127.0.0.1 |
|
|
564
|
+
| API_KEYS | Comma-separated legacy API keys (`key` or `key:label`). **Required** — the Zod config schema rejects an empty/unset value (`src/config/env.ts`), so the server exits with code 78 (`EX_CONFIG`) at startup when it is missing. There is no "auth-disabled" mode. | (required — no default) |
|
|
565
|
+
| LOG_LEVEL | Logging level (debug, info, warn, error) | info |
|
|
566
|
+
| NODE_ENV | Environment (development, production) | (none) |
|
|
567
|
+
| DATABASE_PATH | Path to SQLite database file (canonical; MCP server also accepts legacy `DB_PATH`) | ./data/tasks.db |
|
|
568
|
+
| API_BASE_URL | Base URL for CLI API calls | http://localhost:3000 |
|
|
569
|
+
| API_KEY | API key for CLI authentication | (none) |
|
|
570
|
+
| SLACK_BOT_TOKEN / SLACK_APP_TOKEN / SLACK_SIGNING_SECRET | Optional Slack integration (all three required together) — see [docs/SLACK.md](docs/SLACK.md) | (none) |
|
|
571
|
+
| RATE_LIMIT_MAX / RATE_LIMIT_TIME_WINDOW | Global rate limiter knobs | 1000 / "1 minute" |
|
|
572
|
+
| SSE_MAX_CONNECTIONS_PER_KEY / SSE_MAX_CONNECTIONS_PER_IP / SSE_MAX_CONNECTIONS | SSE connection caps | 4 / 8 / 200 |
|
|
573
|
+
| ENABLE_SWAGGER_IN_PRODUCTION | Opt-in to expose Swagger UI when `NODE_ENV=production` | false |
|
|
574
|
+
|
|
575
|
+
[NOTE] The full env-var reference (including server timeouts and installer
|
|
576
|
+
variables) lives in [docs/SETUP.md → Environment Variables](docs/SETUP.md#environment-variables).
|
|
577
|
+
|
|
578
|
+
## Development
|
|
579
|
+
|
|
580
|
+
### Key Commands
|
|
581
|
+
|
|
582
|
+
```bash
|
|
583
|
+
# Development mode with hot reload
|
|
584
|
+
npm run dev
|
|
585
|
+
|
|
586
|
+
# Run tests (2640 tests across 204 files)
|
|
587
|
+
npm test
|
|
588
|
+
|
|
589
|
+
# Watch mode for tests
|
|
590
|
+
npm run test:watch
|
|
591
|
+
|
|
592
|
+
# Build TypeScript
|
|
593
|
+
npm run build
|
|
594
|
+
|
|
595
|
+
# Run CLI in development (without building)
|
|
596
|
+
npm run cli -- <command>
|
|
597
|
+
|
|
598
|
+
# Run MCP server in development
|
|
599
|
+
npm run mcp:dev
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
### Database
|
|
603
|
+
|
|
604
|
+
SQLite with better-sqlite3 driver, WAL mode, and automatic migrations via Umzug. Twelve migration files in `src/db/migrations/`:
|
|
605
|
+
|
|
606
|
+
1. `001-initial-schema.ts` — projects, tasks, task_tags (plus the tasks_fts FTS5 virtual table and sync triggers)
|
|
607
|
+
2. `002-task-hierarchy-and-dependencies.ts` — adds `parent_task_id` to tasks and creates the `task_dependencies` table
|
|
608
|
+
3. `003-comments-and-estimates.ts` — creates the `task_comments` table and adds `estimated_minutes` to tasks
|
|
609
|
+
4. `004-claim-protocol.ts` — version field, claimed_at, idempotency_keys table
|
|
610
|
+
5. `005-backlogged-status.ts` — adds `backlogged` to the status CHECK constraint (rebuilds tasks table; preserves FTS triggers)
|
|
611
|
+
6. `006-slack-channel-subscriptions.ts` — `slack_channel_subscriptions` table for the Slack notifier
|
|
612
|
+
7. `007-completed-at.ts` — `completed_at` column on tasks (set on transition into `done`, backfilled from `updated_at`)
|
|
613
|
+
8. `008-identity-tables.ts` — `users` and `api_tokens` tables (OIDC/PAT identity)
|
|
614
|
+
9. `009-parallel-fk-columns.ts` — parallel `*_user_id` FK columns alongside the legacy TEXT identity columns
|
|
615
|
+
10. `010-identity-uniqueness-indexes.ts` — uniqueness indexes on user identity (oidc_sub, email)
|
|
616
|
+
11. `011-acceptance-criteria.ts` — `acceptance_criteria` column on tasks
|
|
617
|
+
12. `012-verification-evidence.ts` — `verification_evidence` column on tasks (verifier verdict + checks)
|
|
618
|
+
|
|
619
|
+
### Testing
|
|
620
|
+
|
|
621
|
+
2640 tests across 204 test files covering:
|
|
622
|
+
- Service layer unit tests
|
|
623
|
+
- API route integration tests (all endpoints)
|
|
624
|
+
- MCP tool tests (all tools)
|
|
625
|
+
- CLI command tests
|
|
626
|
+
- Event system tests (EventBus, SSEManager, events API)
|
|
627
|
+
- Claim protocol tests (including 20-agent concurrency)
|
|
628
|
+
- Workflow engine tests (auto-complete, auto-unblock, cascade depth)
|
|
629
|
+
- Skill file validation tests
|
|
630
|
+
|
|
631
|
+
### Code Quality Roadmap
|
|
632
|
+
|
|
633
|
+
The current TypeScript service quality baseline and the prioritized
|
|
634
|
+
uplift roadmap (lint/format gate, stricter compiler flags, architecture
|
|
635
|
+
guardrails, migration safety, CI/release automation) live in
|
|
636
|
+
[docs/CODE_QUALITY_ROADMAP.md](docs/CODE_QUALITY_ROADMAP.md). It is the
|
|
637
|
+
source of truth for the `Code Quality Uplift Roadmap` project tracked
|
|
638
|
+
in the bugs database and should be linked from future PR/release
|
|
639
|
+
quality checklist work.
|
|
640
|
+
|
|
641
|
+
## Integrations
|
|
642
|
+
|
|
643
|
+
### Slack
|
|
644
|
+
|
|
645
|
+
Wood Fired Tasks ships an **optional** Slack integration:
|
|
646
|
+
|
|
647
|
+
- `/tasks` slash command (read, create, update, claim, subscribe channels to notifications, …)
|
|
648
|
+
- A notifier that posts Block Kit messages to subscribed channels when
|
|
649
|
+
task events fire on the internal EventBus.
|
|
650
|
+
|
|
651
|
+
Slack is fully optional — leave `SLACK_BOT_TOKEN`, `SLACK_APP_TOKEN`, and
|
|
652
|
+
`SLACK_SIGNING_SECRET` unset and the service runs without it. The three
|
|
653
|
+
variables are validated as a group (all three, or none).
|
|
654
|
+
|
|
655
|
+
See [docs/SLACK.md](docs/SLACK.md) for: app manifest, required scopes,
|
|
656
|
+
slash-command reference, channel subscription model, error handling.
|
|
657
|
+
|
|
658
|
+
### Claude Code (MCP)
|
|
659
|
+
|
|
660
|
+
The shipped MCP server registers as a stdio MCP target in `~/.claude.json`
|
|
661
|
+
and exposes 22 tools plus the `/tasks:*` skill files. See
|
|
662
|
+
[docs/MCP.md](docs/MCP.md) and the "Claude Code Integration" section in
|
|
663
|
+
[docs/SETUP.md](docs/SETUP.md#claude-code-integration).
|
|
664
|
+
|
|
665
|
+
The `/tasks:*` skills automate the plan→execute→audit loop. Start with
|
|
666
|
+
**`/tasks:decompose --project <id> --goal "..." --success "..."`** to turn a
|
|
667
|
+
project-level goal into 8–25 well-formed tasks (or a dependency DAG) — it
|
|
668
|
+
advises `/tasks:loop` (FLAT backlog, drained sequentially) or
|
|
669
|
+
`/tasks:loop-dag` (DAG backlog, drained wave-by-wave in parallel), then
|
|
670
|
+
`/tasks:audit` grades the run. Decompose only plans; it never executes the
|
|
671
|
+
tasks it creates, refuses blast-radius goals, and supports `--dry-run` to
|
|
672
|
+
preview the breakdown without touching the database. See
|
|
673
|
+
[skills/tasks/decompose.md](skills/tasks/decompose.md) and its design at
|
|
674
|
+
[docs/tasks-decompose-design.md](docs/tasks-decompose-design.md).
|
|
675
|
+
|
|
676
|
+
## Release Verification
|
|
677
|
+
|
|
678
|
+
Before publishing to npm, run `npm run pack:check` (alias for
|
|
679
|
+
`npm pack --dry-run`) and inspect the printed file list. Confirm that
|
|
680
|
+
`dist/` JS + `.d.ts` files, `LICENSE`, `README.md`, `CHANGELOG.md`, and
|
|
681
|
+
`SECURITY.md` are present, and that `src/`, `.env*`, `data/*.db`,
|
|
682
|
+
`.planning/`, and test files are **absent**. The package uses an explicit
|
|
683
|
+
`files` allowlist in `package.json` — adjust it there if the output drifts.
|
|
684
|
+
|
|
685
|
+
## License
|
|
686
|
+
|
|
687
|
+
MIT
|