@bosun-sh/logbook 1.0.0 → 2.0.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/CHANGELOG.md +139 -0
- package/README.md +252 -272
- package/bin/logbook.cjs +18 -0
- package/dist/context/attachments.d.ts +55 -0
- package/dist/context/attachments.d.ts.map +1 -0
- package/dist/context/attachments.js +329 -0
- package/dist/context/attachments.js.map +1 -0
- package/dist/context/create.d.ts +31 -0
- package/dist/context/create.d.ts.map +1 -0
- package/dist/context/create.js +101 -0
- package/dist/context/create.js.map +1 -0
- package/dist/context/delete.d.ts +20 -0
- package/dist/context/delete.d.ts.map +1 -0
- package/dist/context/delete.js +55 -0
- package/dist/context/delete.js.map +1 -0
- package/dist/context/get.d.ts +20 -0
- package/dist/context/get.d.ts.map +1 -0
- package/dist/context/get.js +55 -0
- package/dist/context/get.js.map +1 -0
- package/dist/context/list.d.ts +30 -0
- package/dist/context/list.d.ts.map +1 -0
- package/dist/context/list.js +172 -0
- package/dist/context/list.js.map +1 -0
- package/dist/context/schema.d.ts +156 -0
- package/dist/context/schema.d.ts.map +1 -0
- package/dist/context/schema.js +34 -0
- package/dist/context/schema.js.map +1 -0
- package/dist/context/search.d.ts +27 -0
- package/dist/context/search.d.ts.map +1 -0
- package/dist/context/search.js +266 -0
- package/dist/context/search.js.map +1 -0
- package/dist/context/topics.d.ts +4 -0
- package/dist/context/topics.d.ts.map +1 -0
- package/dist/context/topics.js +54 -0
- package/dist/context/topics.js.map +1 -0
- package/dist/context/update.d.ts +29 -0
- package/dist/context/update.d.ts.map +1 -0
- package/dist/context/update.js +134 -0
- package/dist/context/update.js.map +1 -0
- package/dist/epic/cascade-delete.d.ts +30 -0
- package/dist/epic/cascade-delete.d.ts.map +1 -0
- package/dist/epic/cascade-delete.js +173 -0
- package/dist/epic/cascade-delete.js.map +1 -0
- package/dist/epic/create.d.ts +24 -0
- package/dist/epic/create.d.ts.map +1 -0
- package/dist/epic/create.js +54 -0
- package/dist/epic/create.js.map +1 -0
- package/dist/epic/delete.d.ts +21 -0
- package/dist/epic/delete.d.ts.map +1 -0
- package/dist/epic/delete.js +42 -0
- package/dist/epic/delete.js.map +1 -0
- package/dist/epic/get.d.ts +19 -0
- package/dist/epic/get.d.ts.map +1 -0
- package/dist/epic/get.js +31 -0
- package/dist/epic/get.js.map +1 -0
- package/dist/epic/list.d.ts +25 -0
- package/dist/epic/list.d.ts.map +1 -0
- package/dist/epic/list.js +114 -0
- package/dist/epic/list.js.map +1 -0
- package/dist/epic/rules.d.ts +34 -0
- package/dist/epic/rules.d.ts.map +1 -0
- package/dist/epic/rules.js +127 -0
- package/dist/epic/rules.js.map +1 -0
- package/dist/epic/schema.d.ts +85 -0
- package/dist/epic/schema.d.ts.map +1 -0
- package/dist/epic/schema.js +14 -0
- package/dist/epic/schema.js.map +1 -0
- package/dist/epic/update.d.ts +25 -0
- package/dist/epic/update.d.ts.map +1 -0
- package/dist/epic/update.js +69 -0
- package/dist/epic/update.js.map +1 -0
- package/dist/hook/list.d.ts +71 -0
- package/dist/hook/list.d.ts.map +1 -0
- package/dist/hook/list.js +364 -0
- package/dist/hook/list.js.map +1 -0
- package/dist/hook/ports.d.ts +16 -0
- package/dist/hook/ports.d.ts.map +1 -0
- package/dist/hook/ports.js +3 -0
- package/dist/hook/ports.js.map +1 -0
- package/dist/hook/run.d.ts +24 -0
- package/dist/hook/run.d.ts.map +1 -0
- package/dist/hook/run.js +185 -0
- package/dist/hook/run.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin/hook-tools.d.ts +8 -0
- package/dist/plugin/hook-tools.d.ts.map +1 -0
- package/dist/plugin/hook-tools.js +31 -0
- package/dist/plugin/hook-tools.js.map +1 -0
- package/dist/plugin/linear-pull-tool.d.ts +20 -0
- package/dist/plugin/linear-pull-tool.d.ts.map +1 -0
- package/dist/plugin/linear-pull-tool.js +19 -0
- package/dist/plugin/linear-pull-tool.js.map +1 -0
- package/dist/plugin/linear-push-tool.d.ts +20 -0
- package/dist/plugin/linear-push-tool.d.ts.map +1 -0
- package/dist/plugin/linear-push-tool.js +27 -0
- package/dist/plugin/linear-push-tool.js.map +1 -0
- package/dist/plugin/linear-setup-tool.d.ts +2 -0
- package/dist/plugin/linear-setup-tool.d.ts.map +1 -0
- package/dist/plugin/linear-setup-tool.js +22 -0
- package/dist/plugin/linear-setup-tool.js.map +1 -0
- package/dist/plugin/linear-status-tool.d.ts +10 -0
- package/dist/plugin/linear-status-tool.d.ts.map +1 -0
- package/dist/plugin/linear-status-tool.js +10 -0
- package/dist/plugin/linear-status-tool.js.map +1 -0
- package/dist/plugin/list.d.ts +15 -0
- package/dist/plugin/list.d.ts.map +1 -0
- package/dist/plugin/list.js +87 -0
- package/dist/plugin/list.js.map +1 -0
- package/dist/plugin/public-schemas.d.ts +42 -0
- package/dist/plugin/public-schemas.d.ts.map +1 -0
- package/dist/plugin/public-schemas.js +577 -0
- package/dist/plugin/public-schemas.js.map +1 -0
- package/dist/plugin/registry.d.ts +3 -0
- package/dist/plugin/registry.d.ts.map +1 -0
- package/dist/plugin/registry.js +3 -0
- package/dist/plugin/registry.js.map +1 -0
- package/dist/plugin/results.d.ts +8 -0
- package/dist/plugin/results.d.ts.map +1 -0
- package/dist/plugin/results.js +114 -0
- package/dist/plugin/results.js.map +1 -0
- package/dist/plugin/sync-conflict-tools.d.ts +2 -0
- package/dist/plugin/sync-conflict-tools.d.ts.map +1 -0
- package/dist/plugin/sync-conflict-tools.js +5 -0
- package/dist/plugin/sync-conflict-tools.js.map +1 -0
- package/dist/plugin/tool-registry.d.ts +23 -0
- package/dist/plugin/tool-registry.d.ts.map +1 -0
- package/dist/plugin/tool-registry.js +251 -0
- package/dist/plugin/tool-registry.js.map +1 -0
- package/dist/plugin/workspace-init-tool.d.ts +2 -0
- package/dist/plugin/workspace-init-tool.d.ts.map +1 -0
- package/dist/plugin/workspace-init-tool.js +16 -0
- package/dist/plugin/workspace-init-tool.js.map +1 -0
- package/dist/plugin/workspace-status-tool.d.ts +2 -0
- package/dist/plugin/workspace-status-tool.d.ts.map +1 -0
- package/dist/plugin/workspace-status-tool.js +15 -0
- package/dist/plugin/workspace-status-tool.js.map +1 -0
- package/dist/shared/ids.d.ts +3 -0
- package/dist/shared/ids.d.ts.map +1 -0
- package/dist/shared/ids.js +15 -0
- package/dist/shared/ids.js.map +1 -0
- package/dist/shared/pagination.d.ts +19 -0
- package/dist/shared/pagination.d.ts.map +1 -0
- package/dist/shared/pagination.js +110 -0
- package/dist/shared/pagination.js.map +1 -0
- package/dist/shared/result.d.ts +20 -0
- package/dist/shared/result.d.ts.map +1 -0
- package/dist/shared/result.js +6 -0
- package/dist/shared/result.js.map +1 -0
- package/dist/shared/schema/value-objects.d.ts +363 -0
- package/dist/shared/schema/value-objects.d.ts.map +1 -0
- package/dist/shared/schema/value-objects.js +112 -0
- package/dist/shared/schema/value-objects.js.map +1 -0
- package/dist/shared/storage/atomic-write.d.ts +25 -0
- package/dist/shared/storage/atomic-write.d.ts.map +1 -0
- package/dist/shared/storage/atomic-write.js +71 -0
- package/dist/shared/storage/atomic-write.js.map +1 -0
- package/dist/shared/storage/jsonl-repository.d.ts +85 -0
- package/dist/shared/storage/jsonl-repository.d.ts.map +1 -0
- package/dist/shared/storage/jsonl-repository.js +278 -0
- package/dist/shared/storage/jsonl-repository.js.map +1 -0
- package/dist/shared/storage/transaction.d.ts +3 -0
- package/dist/shared/storage/transaction.d.ts.map +1 -0
- package/dist/shared/storage/transaction.js +22 -0
- package/dist/shared/storage/transaction.js.map +1 -0
- package/dist/shared/time.d.ts +3 -0
- package/dist/shared/time.d.ts.map +1 -0
- package/dist/shared/time.js +3 -0
- package/dist/shared/time.js.map +1 -0
- package/dist/story/cascade-delete.d.ts +22 -0
- package/dist/story/cascade-delete.d.ts.map +1 -0
- package/dist/story/cascade-delete.js +117 -0
- package/dist/story/cascade-delete.js.map +1 -0
- package/dist/story/create.d.ts +30 -0
- package/dist/story/create.d.ts.map +1 -0
- package/dist/story/create.js +69 -0
- package/dist/story/create.js.map +1 -0
- package/dist/story/delete.d.ts +21 -0
- package/dist/story/delete.d.ts.map +1 -0
- package/dist/story/delete.js +42 -0
- package/dist/story/delete.js.map +1 -0
- package/dist/story/get.d.ts +19 -0
- package/dist/story/get.d.ts.map +1 -0
- package/dist/story/get.js +31 -0
- package/dist/story/get.js.map +1 -0
- package/dist/story/hierarchy.d.ts +20 -0
- package/dist/story/hierarchy.d.ts.map +1 -0
- package/dist/story/hierarchy.js +30 -0
- package/dist/story/hierarchy.js.map +1 -0
- package/dist/story/list.d.ts +25 -0
- package/dist/story/list.d.ts.map +1 -0
- package/dist/story/list.js +118 -0
- package/dist/story/list.js.map +1 -0
- package/dist/story/rules.d.ts +34 -0
- package/dist/story/rules.d.ts.map +1 -0
- package/dist/story/rules.js +100 -0
- package/dist/story/rules.js.map +1 -0
- package/dist/story/schema.d.ts +65 -0
- package/dist/story/schema.d.ts.map +1 -0
- package/dist/story/schema.js +14 -0
- package/dist/story/schema.js.map +1 -0
- package/dist/story/update.d.ts +23 -0
- package/dist/story/update.d.ts.map +1 -0
- package/dist/story/update.js +67 -0
- package/dist/story/update.js.map +1 -0
- package/dist/sync/base-snapshot.d.ts +38 -0
- package/dist/sync/base-snapshot.d.ts.map +1 -0
- package/dist/sync/base-snapshot.js +86 -0
- package/dist/sync/base-snapshot.js.map +1 -0
- package/dist/sync/conflict-tools.d.ts +75 -0
- package/dist/sync/conflict-tools.d.ts.map +1 -0
- package/dist/sync/conflict-tools.js +53 -0
- package/dist/sync/conflict-tools.js.map +1 -0
- package/dist/sync/conflicts.d.ts +201 -0
- package/dist/sync/conflicts.d.ts.map +1 -0
- package/dist/sync/conflicts.js +526 -0
- package/dist/sync/conflicts.js.map +1 -0
- package/dist/sync/deferred-providers.d.ts +2 -0
- package/dist/sync/deferred-providers.d.ts.map +1 -0
- package/dist/sync/deferred-providers.js +6 -0
- package/dist/sync/deferred-providers.js.map +1 -0
- package/dist/sync/events.d.ts +401 -0
- package/dist/sync/events.d.ts.map +1 -0
- package/dist/sync/events.js +357 -0
- package/dist/sync/events.js.map +1 -0
- package/dist/sync/external-links.d.ts +154 -0
- package/dist/sync/external-links.d.ts.map +1 -0
- package/dist/sync/external-links.js +306 -0
- package/dist/sync/external-links.js.map +1 -0
- package/dist/sync/linear/config.d.ts +60 -0
- package/dist/sync/linear/config.d.ts.map +1 -0
- package/dist/sync/linear/config.js +302 -0
- package/dist/sync/linear/config.js.map +1 -0
- package/dist/sync/linear/mapping.d.ts +115 -0
- package/dist/sync/linear/mapping.d.ts.map +1 -0
- package/dist/sync/linear/mapping.js +159 -0
- package/dist/sync/linear/mapping.js.map +1 -0
- package/dist/sync/linear/pull.d.ts +33 -0
- package/dist/sync/linear/pull.d.ts.map +1 -0
- package/dist/sync/linear/pull.js +376 -0
- package/dist/sync/linear/pull.js.map +1 -0
- package/dist/sync/linear/push.d.ts +34 -0
- package/dist/sync/linear/push.d.ts.map +1 -0
- package/dist/sync/linear/push.js +681 -0
- package/dist/sync/linear/push.js.map +1 -0
- package/dist/sync/linear/setup.d.ts +33 -0
- package/dist/sync/linear/setup.d.ts.map +1 -0
- package/dist/sync/linear/setup.js +129 -0
- package/dist/sync/linear/setup.js.map +1 -0
- package/dist/sync/linear/status.d.ts +35 -0
- package/dist/sync/linear/status.d.ts.map +1 -0
- package/dist/sync/linear/status.js +138 -0
- package/dist/sync/linear/status.js.map +1 -0
- package/dist/sync/linear/transport.d.ts +47 -0
- package/dist/sync/linear/transport.d.ts.map +1 -0
- package/dist/sync/linear/transport.js +249 -0
- package/dist/sync/linear/transport.js.map +1 -0
- package/dist/sync/provider-port.d.ts +81 -0
- package/dist/sync/provider-port.d.ts.map +1 -0
- package/dist/sync/provider-port.js +16 -0
- package/dist/sync/provider-port.js.map +1 -0
- package/dist/sync/provider-registry.d.ts +38 -0
- package/dist/sync/provider-registry.d.ts.map +1 -0
- package/dist/sync/provider-registry.js +115 -0
- package/dist/sync/provider-registry.js.map +1 -0
- package/dist/sync/schema.d.ts +147 -0
- package/dist/sync/schema.d.ts.map +1 -0
- package/dist/sync/schema.js +28 -0
- package/dist/sync/schema.js.map +1 -0
- package/dist/task/comments.d.ts +9 -0
- package/dist/task/comments.d.ts.map +1 -0
- package/dist/task/comments.js +79 -0
- package/dist/task/comments.js.map +1 -0
- package/dist/task/create.d.ts +34 -0
- package/dist/task/create.d.ts.map +1 -0
- package/dist/task/create.js +126 -0
- package/dist/task/create.js.map +1 -0
- package/dist/task/current.d.ts +18 -0
- package/dist/task/current.d.ts.map +1 -0
- package/dist/task/current.js +105 -0
- package/dist/task/current.js.map +1 -0
- package/dist/task/edit.d.ts +22 -0
- package/dist/task/edit.d.ts.map +1 -0
- package/dist/task/edit.js +105 -0
- package/dist/task/edit.js.map +1 -0
- package/dist/task/estimate.d.ts +20 -0
- package/dist/task/estimate.d.ts.map +1 -0
- package/dist/task/estimate.js +141 -0
- package/dist/task/estimate.js.map +1 -0
- package/dist/task/get.d.ts +13 -0
- package/dist/task/get.d.ts.map +1 -0
- package/dist/task/get.js +29 -0
- package/dist/task/get.js.map +1 -0
- package/dist/task/hierarchy.d.ts +18 -0
- package/dist/task/hierarchy.d.ts.map +1 -0
- package/dist/task/hierarchy.js +56 -0
- package/dist/task/hierarchy.js.map +1 -0
- package/dist/task/lifecycle.d.ts +14 -0
- package/dist/task/lifecycle.d.ts.map +1 -0
- package/dist/task/lifecycle.js +80 -0
- package/dist/task/lifecycle.js.map +1 -0
- package/dist/task/list.d.ts +24 -0
- package/dist/task/list.d.ts.map +1 -0
- package/dist/task/list.js +116 -0
- package/dist/task/list.js.map +1 -0
- package/dist/task/model-assignment.d.ts +33 -0
- package/dist/task/model-assignment.d.ts.map +1 -0
- package/dist/task/model-assignment.js +145 -0
- package/dist/task/model-assignment.js.map +1 -0
- package/dist/task/ordering.d.ts +4 -0
- package/dist/task/ordering.d.ts.map +1 -0
- package/dist/task/ordering.js +14 -0
- package/dist/task/ordering.js.map +1 -0
- package/dist/task/ports.d.ts +37 -0
- package/dist/task/ports.d.ts.map +1 -0
- package/dist/task/ports.js +3 -0
- package/dist/task/ports.js.map +1 -0
- package/dist/task/schema.d.ts +447 -0
- package/dist/task/schema.d.ts.map +1 -0
- package/dist/task/schema.js +35 -0
- package/dist/task/schema.js.map +1 -0
- package/dist/task/session-assignment.d.ts +23 -0
- package/dist/task/session-assignment.d.ts.map +1 -0
- package/dist/task/session-assignment.js +197 -0
- package/dist/task/session-assignment.js.map +1 -0
- package/dist/task/session-registry.d.ts +8 -0
- package/dist/task/session-registry.d.ts.map +1 -0
- package/dist/task/session-registry.js +3 -0
- package/dist/task/session-registry.js.map +1 -0
- package/dist/task/update.d.ts +23 -0
- package/dist/task/update.d.ts.map +1 -0
- package/dist/task/update.js +92 -0
- package/dist/task/update.js.map +1 -0
- package/dist/task/v1-compat.d.ts +94 -0
- package/dist/task/v1-compat.d.ts.map +1 -0
- package/dist/task/v1-compat.js +181 -0
- package/dist/task/v1-compat.js.map +1 -0
- package/dist/workspace/bin-cli.d.ts +2 -0
- package/dist/workspace/bin-cli.d.ts.map +1 -0
- package/dist/workspace/bin-cli.js +36 -0
- package/dist/workspace/bin-cli.js.map +1 -0
- package/dist/workspace/cli-adapter.d.ts +16 -0
- package/dist/workspace/cli-adapter.d.ts.map +1 -0
- package/dist/workspace/cli-adapter.js +229 -0
- package/dist/workspace/cli-adapter.js.map +1 -0
- package/dist/workspace/cli-commands.d.ts +11 -0
- package/dist/workspace/cli-commands.d.ts.map +1 -0
- package/dist/workspace/cli-commands.js +12 -0
- package/dist/workspace/cli-commands.js.map +1 -0
- package/dist/workspace/duckdb-index.d.ts +56 -0
- package/dist/workspace/duckdb-index.d.ts.map +1 -0
- package/dist/workspace/duckdb-index.js +178 -0
- package/dist/workspace/duckdb-index.js.map +1 -0
- package/dist/workspace/hook-templates/need-info-notify/config.json +10 -0
- package/dist/workspace/hook-templates/need-info-notify/script.mjs +68 -0
- package/dist/workspace/hook-templates/review-spawn/config.json +10 -0
- package/dist/workspace/hook-templates/review-spawn/script.mjs +100 -0
- package/dist/workspace/init-onboarding.d.ts +9 -0
- package/dist/workspace/init-onboarding.d.ts.map +1 -0
- package/dist/workspace/init-onboarding.js +259 -0
- package/dist/workspace/init-onboarding.js.map +1 -0
- package/dist/workspace/init.d.ts +20 -0
- package/dist/workspace/init.d.ts.map +1 -0
- package/dist/workspace/init.js +288 -0
- package/dist/workspace/init.js.map +1 -0
- package/dist/workspace/layers.d.ts +127 -0
- package/dist/workspace/layers.d.ts.map +1 -0
- package/dist/workspace/layers.js +50 -0
- package/dist/workspace/layers.js.map +1 -0
- package/dist/workspace/mcp-server.d.ts +28 -0
- package/dist/workspace/mcp-server.d.ts.map +1 -0
- package/dist/workspace/mcp-server.js +190 -0
- package/dist/workspace/mcp-server.js.map +1 -0
- package/dist/workspace/mcp-stdio.d.ts +2 -0
- package/dist/workspace/mcp-stdio.d.ts.map +1 -0
- package/dist/workspace/mcp-stdio.js +66 -0
- package/dist/workspace/mcp-stdio.js.map +1 -0
- package/dist/workspace/mcp-tools.d.ts +24 -0
- package/dist/workspace/mcp-tools.d.ts.map +1 -0
- package/dist/workspace/mcp-tools.js +43 -0
- package/dist/workspace/mcp-tools.js.map +1 -0
- package/dist/workspace/migrate-v1.d.ts +12 -0
- package/dist/workspace/migrate-v1.d.ts.map +1 -0
- package/dist/workspace/migrate-v1.js +301 -0
- package/dist/workspace/migrate-v1.js.map +1 -0
- package/dist/workspace/ohtools-app.d.ts +3 -0
- package/dist/workspace/ohtools-app.d.ts.map +1 -0
- package/dist/workspace/ohtools-app.js +10 -0
- package/dist/workspace/ohtools-app.js.map +1 -0
- package/dist/workspace/repositories.d.ts +25 -0
- package/dist/workspace/repositories.d.ts.map +1 -0
- package/dist/workspace/repositories.js +76 -0
- package/dist/workspace/repositories.js.map +1 -0
- package/dist/workspace/runtime.d.ts +123 -0
- package/dist/workspace/runtime.d.ts.map +1 -0
- package/dist/workspace/runtime.js +4 -0
- package/dist/workspace/runtime.js.map +1 -0
- package/dist/workspace/session-liveness.d.ts +6 -0
- package/dist/workspace/session-liveness.d.ts.map +1 -0
- package/dist/workspace/session-liveness.js +3 -0
- package/dist/workspace/session-liveness.js.map +1 -0
- package/dist/workspace/status.d.ts +46 -0
- package/dist/workspace/status.d.ts.map +1 -0
- package/dist/workspace/status.js +345 -0
- package/dist/workspace/status.js.map +1 -0
- package/dist/workspace/storage-layout.d.ts +19 -0
- package/dist/workspace/storage-layout.d.ts.map +1 -0
- package/dist/workspace/storage-layout.js +55 -0
- package/dist/workspace/storage-layout.js.map +1 -0
- package/dist/workspace/storage-paths.d.ts +16 -0
- package/dist/workspace/storage-paths.d.ts.map +1 -0
- package/dist/workspace/storage-paths.js +15 -0
- package/dist/workspace/storage-paths.js.map +1 -0
- package/dist/workspace/v1-cli-aliases.d.ts +18 -0
- package/dist/workspace/v1-cli-aliases.d.ts.map +1 -0
- package/dist/workspace/v1-cli-aliases.js +223 -0
- package/dist/workspace/v1-cli-aliases.js.map +1 -0
- package/dist/workspace/v1-cli-task.d.ts +2 -0
- package/dist/workspace/v1-cli-task.d.ts.map +1 -0
- package/dist/workspace/v1-cli-task.js +53 -0
- package/dist/workspace/v1-cli-task.js.map +1 -0
- package/package.json +29 -12
- package/quickstart.md +163 -0
- package/hooks/need-info-notify/config.yml +0 -3
- package/hooks/need-info-notify/script.ts +0 -69
- package/hooks/review-spawn/config.yml +0 -3
- package/hooks/review-spawn/script.ts +0 -96
- package/src/cli/init.ts +0 -90
- package/src/domain/fibonacci.ts +0 -39
- package/src/domain/kTokens.ts +0 -65
- package/src/domain/status-machine.ts +0 -49
- package/src/domain/types.ts +0 -66
- package/src/hook/hook-executor.ts +0 -70
- package/src/hook/ports.ts +0 -16
- package/src/infra/hook-config-loader.ts +0 -111
- package/src/infra/jsonl-task-repository.ts +0 -157
- package/src/infra/logger.ts +0 -40
- package/src/infra/pid-session-registry.ts +0 -67
- package/src/mcp/error-codes.ts +0 -213
- package/src/mcp/server.ts +0 -413
- package/src/mcp/session.ts +0 -1
- package/src/mcp/tool-create-task.ts +0 -28
- package/src/mcp/tool-current-task.ts +0 -19
- package/src/mcp/tool-edit-task.ts +0 -40
- package/src/mcp/tool-list-tasks.ts +0 -34
- package/src/mcp/tool-update-task.ts +0 -55
- package/src/task/create-task.ts +0 -67
- package/src/task/current-task.ts +0 -111
- package/src/task/edit-task.ts +0 -59
- package/src/task/list-tasks.ts +0 -35
- package/src/task/ports.ts +0 -15
- package/src/task/session-registry.ts +0 -9
- package/src/task/update-task.ts +0 -160
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
import { appendFile, readFile, rename, writeFile } from "node:fs/promises"
|
|
2
|
-
import { Effect } from "effect"
|
|
3
|
-
import type { Status, Task, TaskError } from "../domain/types.js"
|
|
4
|
-
import { TaskSchema } from "../domain/types.js"
|
|
5
|
-
import type { TaskRepository } from "../task/ports.js"
|
|
6
|
-
import { logger } from "./logger.js"
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* JSONL-backed TaskRepository.
|
|
10
|
-
* Each line is a JSON-serialized Task.
|
|
11
|
-
* Reads scan the full file; writes are append-only for save, full-rewrite for update.
|
|
12
|
-
*/
|
|
13
|
-
export class JsonlTaskRepository implements TaskRepository {
|
|
14
|
-
constructor(private readonly filePath: string) {}
|
|
15
|
-
|
|
16
|
-
save(task: Task): Effect.Effect<void, TaskError> {
|
|
17
|
-
return Effect.tryPromise<void, TaskError>({
|
|
18
|
-
try: async () => {
|
|
19
|
-
const content = await readFile(this.filePath, "utf8").catch((e: unknown) => {
|
|
20
|
-
if (isEnoent(e)) return ""
|
|
21
|
-
throw e
|
|
22
|
-
})
|
|
23
|
-
const lines = splitLines(content)
|
|
24
|
-
const conflict = lines.some((line) => {
|
|
25
|
-
try {
|
|
26
|
-
const parsed = JSON.parse(line) as unknown
|
|
27
|
-
return (parsed as { id?: unknown }).id === task.id
|
|
28
|
-
} catch {
|
|
29
|
-
return false
|
|
30
|
-
}
|
|
31
|
-
})
|
|
32
|
-
if (conflict) {
|
|
33
|
-
throw mkTagged<TaskError>({ _tag: "conflict", taskId: task.id })
|
|
34
|
-
}
|
|
35
|
-
await appendFile(this.filePath, `${JSON.stringify(task)}\n`, "utf8")
|
|
36
|
-
},
|
|
37
|
-
catch: (e) => asTaskError(e, task.id),
|
|
38
|
-
})
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
update(task: Task): Effect.Effect<void, TaskError> {
|
|
42
|
-
return Effect.tryPromise<void, TaskError>({
|
|
43
|
-
try: async () => {
|
|
44
|
-
const content = await readFile(this.filePath, "utf8").catch((e: unknown) => {
|
|
45
|
-
if (isEnoent(e)) return ""
|
|
46
|
-
throw e
|
|
47
|
-
})
|
|
48
|
-
const lines = splitLines(content)
|
|
49
|
-
let found = false
|
|
50
|
-
const updated = lines.map((line) => {
|
|
51
|
-
try {
|
|
52
|
-
const parsed = JSON.parse(line) as unknown
|
|
53
|
-
if ((parsed as { id?: unknown }).id === task.id) {
|
|
54
|
-
found = true
|
|
55
|
-
return JSON.stringify(task)
|
|
56
|
-
}
|
|
57
|
-
} catch {
|
|
58
|
-
// keep malformed lines as-is
|
|
59
|
-
}
|
|
60
|
-
return line
|
|
61
|
-
})
|
|
62
|
-
if (!found) {
|
|
63
|
-
throw mkTagged<TaskError>({ _tag: "not_found", taskId: task.id })
|
|
64
|
-
}
|
|
65
|
-
const tmpPath = `${this.filePath}.tmp`
|
|
66
|
-
await writeFile(tmpPath, `${updated.join("\n")}\n`, "utf8")
|
|
67
|
-
await rename(tmpPath, this.filePath)
|
|
68
|
-
},
|
|
69
|
-
catch: (e) => asTaskError(e, task.id),
|
|
70
|
-
})
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
findById(id: string): Effect.Effect<Task, TaskError> {
|
|
74
|
-
return Effect.tryPromise<Task, TaskError>({
|
|
75
|
-
try: async () => {
|
|
76
|
-
const content = await readFile(this.filePath, "utf8").catch((e: unknown) => {
|
|
77
|
-
if (isEnoent(e)) return ""
|
|
78
|
-
throw e
|
|
79
|
-
})
|
|
80
|
-
const lines = splitLines(content)
|
|
81
|
-
for (const line of lines) {
|
|
82
|
-
const result = parseLine(line)
|
|
83
|
-
if (result._tag === "error") {
|
|
84
|
-
logger.warn("skipping malformed JSONL line", { line, reason: result.reason })
|
|
85
|
-
continue
|
|
86
|
-
}
|
|
87
|
-
if (result.task.id === id) return result.task
|
|
88
|
-
}
|
|
89
|
-
throw mkTagged<TaskError>({ _tag: "not_found", taskId: id })
|
|
90
|
-
},
|
|
91
|
-
catch: (e) => asTaskError(e, id),
|
|
92
|
-
})
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
findByStatus(status: Status | "*"): Effect.Effect<readonly Task[], TaskError> {
|
|
96
|
-
return Effect.tryPromise<readonly Task[], TaskError>({
|
|
97
|
-
try: async () => {
|
|
98
|
-
const content = await readFile(this.filePath, "utf8").catch((e: unknown) => {
|
|
99
|
-
if (isEnoent(e)) return ""
|
|
100
|
-
throw e
|
|
101
|
-
})
|
|
102
|
-
const lines = splitLines(content)
|
|
103
|
-
const tasks: Task[] = []
|
|
104
|
-
for (const line of lines) {
|
|
105
|
-
const result = parseLine(line)
|
|
106
|
-
if (result._tag === "error") {
|
|
107
|
-
throw mkTagged<TaskError>({ _tag: "validation_error", message: result.reason })
|
|
108
|
-
}
|
|
109
|
-
if (status === "*" || result.task.status === status) {
|
|
110
|
-
tasks.push(result.task)
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
return tasks
|
|
114
|
-
},
|
|
115
|
-
catch: (e) => asTaskError(e, ""),
|
|
116
|
-
})
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// ---------------------------------------------------------------------------
|
|
121
|
-
// Helpers (pure)
|
|
122
|
-
// ---------------------------------------------------------------------------
|
|
123
|
-
|
|
124
|
-
type ParseResult =
|
|
125
|
-
| { readonly _tag: "ok"; readonly task: Task }
|
|
126
|
-
| { readonly _tag: "error"; readonly reason: string }
|
|
127
|
-
|
|
128
|
-
const parseLine = (line: string): ParseResult => {
|
|
129
|
-
let raw: unknown
|
|
130
|
-
try {
|
|
131
|
-
raw = JSON.parse(line)
|
|
132
|
-
} catch (e) {
|
|
133
|
-
return { _tag: "error", reason: `invalid JSON: ${String(e)}` }
|
|
134
|
-
}
|
|
135
|
-
const result = TaskSchema.safeParse(raw)
|
|
136
|
-
if (!result.success) {
|
|
137
|
-
return { _tag: "error", reason: result.error.message }
|
|
138
|
-
}
|
|
139
|
-
return { _tag: "ok", task: result.data }
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
const splitLines = (content: string): readonly string[] =>
|
|
143
|
-
content.split("\n").filter((l) => l.trim() !== "")
|
|
144
|
-
|
|
145
|
-
const isEnoent = (e: unknown): boolean =>
|
|
146
|
-
typeof e === "object" && e !== null && (e as { code?: unknown }).code === "ENOENT"
|
|
147
|
-
|
|
148
|
-
/** Carries a typed TaskError through the tryPromise boundary. */
|
|
149
|
-
const mkTagged = <E>(value: E): E => value
|
|
150
|
-
|
|
151
|
-
const asTaskError = (e: unknown, _taskId: string): TaskError => {
|
|
152
|
-
if (isTaskError(e)) return e
|
|
153
|
-
return { _tag: "validation_error", message: String(e) } satisfies TaskError
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
const isTaskError = (e: unknown): e is TaskError =>
|
|
157
|
-
typeof e === "object" && e !== null && typeof (e as { _tag?: unknown })._tag === "string"
|
package/src/infra/logger.ts
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
type Level = "debug" | "info" | "warn" | "error"
|
|
2
|
-
type LogContext = Record<string, unknown>
|
|
3
|
-
|
|
4
|
-
interface Logger {
|
|
5
|
-
debug(msg: string, ctx?: LogContext): void
|
|
6
|
-
info(msg: string, ctx?: LogContext): void
|
|
7
|
-
warn(msg: string, ctx?: LogContext): void
|
|
8
|
-
error(msg: string, ctx?: LogContext): void
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const LEVEL_ORDER: readonly Level[] = ["debug", "info", "warn", "error"]
|
|
12
|
-
|
|
13
|
-
const levelIndex = (level: Level): number => LEVEL_ORDER.indexOf(level)
|
|
14
|
-
|
|
15
|
-
const makeLogger = (threshold: Level): Logger => {
|
|
16
|
-
const thresholdIdx = levelIndex(threshold)
|
|
17
|
-
|
|
18
|
-
const log = (level: Level, msg: string, ctx?: LogContext): void => {
|
|
19
|
-
if (levelIndex(level) < thresholdIdx) return
|
|
20
|
-
const entry = { level, ts: new Date().toISOString(), msg, ...ctx }
|
|
21
|
-
process.stderr.write(`${JSON.stringify(entry)}\n`)
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
return {
|
|
25
|
-
debug: (msg, ctx) => log("debug", msg, ctx),
|
|
26
|
-
info: (msg, ctx) => log("info", msg, ctx),
|
|
27
|
-
warn: (msg, ctx) => log("warn", msg, ctx),
|
|
28
|
-
error: (msg, ctx) => log("error", msg, ctx),
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const resolveThreshold = (): Level => {
|
|
33
|
-
const raw = process.env.LOGBOOK_LOG_LEVEL?.toLowerCase()
|
|
34
|
-
if (raw !== undefined && (LEVEL_ORDER as readonly string[]).includes(raw)) {
|
|
35
|
-
return raw as Level
|
|
36
|
-
}
|
|
37
|
-
return "warn"
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export const logger: Logger = makeLogger(resolveThreshold())
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { readFile, writeFile } from "node:fs/promises"
|
|
2
|
-
import * as path from "node:path"
|
|
3
|
-
import { Effect } from "effect"
|
|
4
|
-
import type { SessionRegistry } from "../task/session-registry.js"
|
|
5
|
-
|
|
6
|
-
type SessionMap = Record<string, number>
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* PID-based session registry persisted to sessions.json alongside the tasks file.
|
|
10
|
-
*
|
|
11
|
-
* Liveness is checked via `process.kill(pid, 0)`: throws if the PID is dead, succeeds otherwise.
|
|
12
|
-
* A missing entry (clean deregistration) is also considered dead.
|
|
13
|
-
*/
|
|
14
|
-
export class PidSessionRegistry implements SessionRegistry {
|
|
15
|
-
private readonly sessionsFile: string
|
|
16
|
-
|
|
17
|
-
constructor(tasksFile: string) {
|
|
18
|
-
this.sessionsFile = path.join(path.dirname(tasksFile), "sessions.json")
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
isAlive(sessionId: string): Effect.Effect<boolean, never> {
|
|
22
|
-
return Effect.promise(async () => {
|
|
23
|
-
const map = await this.readMap()
|
|
24
|
-
const pid = map[sessionId]
|
|
25
|
-
if (pid === undefined) return false
|
|
26
|
-
try {
|
|
27
|
-
process.kill(pid, 0)
|
|
28
|
-
return true
|
|
29
|
-
} catch {
|
|
30
|
-
// Dead PID — lazily remove to keep the file tidy
|
|
31
|
-
await this.removeEntry(sessionId)
|
|
32
|
-
return false
|
|
33
|
-
}
|
|
34
|
-
})
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
register(sessionId: string, pid: number): Effect.Effect<void, never> {
|
|
38
|
-
return Effect.promise(async () => {
|
|
39
|
-
const map = await this.readMap()
|
|
40
|
-
map[sessionId] = pid
|
|
41
|
-
await this.writeMap(map)
|
|
42
|
-
})
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
deregister(sessionId: string): Effect.Effect<void, never> {
|
|
46
|
-
return Effect.promise(() => this.removeEntry(sessionId))
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
private async readMap(): Promise<SessionMap> {
|
|
50
|
-
try {
|
|
51
|
-
const raw = await readFile(this.sessionsFile, "utf8")
|
|
52
|
-
return JSON.parse(raw) as SessionMap
|
|
53
|
-
} catch {
|
|
54
|
-
return {}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
private async writeMap(map: SessionMap): Promise<void> {
|
|
59
|
-
await writeFile(this.sessionsFile, JSON.stringify(map), "utf8")
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
private async removeEntry(sessionId: string): Promise<void> {
|
|
63
|
-
const map = await this.readMap()
|
|
64
|
-
delete map[sessionId]
|
|
65
|
-
await this.writeMap(map)
|
|
66
|
-
}
|
|
67
|
-
}
|
package/src/mcp/error-codes.ts
DELETED
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
import { allowedTransitions } from "../domain/status-machine.js"
|
|
2
|
-
import type { Status, TaskError } from "../domain/types.js"
|
|
3
|
-
|
|
4
|
-
export interface McpError {
|
|
5
|
-
code: number
|
|
6
|
-
message: string
|
|
7
|
-
data: Record<string, unknown>
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const NORMAL_FLOW = "backlog → todo → in_progress → pending_review → done"
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Builds a declarative error message for transition_not_allowed errors.
|
|
14
|
-
* Includes allowed transitions, review task hint, and corrective guidance.
|
|
15
|
-
*/
|
|
16
|
-
const buildTransitionErrorMessage = (
|
|
17
|
-
from: Status,
|
|
18
|
-
to: Status,
|
|
19
|
-
taskId?: string
|
|
20
|
-
): { message: string; data: Record<string, unknown> } => {
|
|
21
|
-
const isReviewTask = taskId?.startsWith("review-") ?? false
|
|
22
|
-
const allowed = allowedTransitions[from]
|
|
23
|
-
|
|
24
|
-
let message = `Status transition not allowed: cannot move from '${from}' to '${to}'.\n\n`
|
|
25
|
-
message += `Normal flow:\n ${NORMAL_FLOW}\n\n`
|
|
26
|
-
message += `Allowed transitions from '${from}': ${allowed.join(", ") || "none"}\n\n`
|
|
27
|
-
|
|
28
|
-
message += "Special cases:\n"
|
|
29
|
-
message +=
|
|
30
|
-
" - Review tasks (id starting with 'review-') can skip pending_review: in_progress → done\n"
|
|
31
|
-
message += " - blocked tasks return to in_progress\n"
|
|
32
|
-
message += " - need_info tasks return to in_progress\n"
|
|
33
|
-
message += " - Tasks in pending_review can return to in_progress or proceed to done\n\n"
|
|
34
|
-
|
|
35
|
-
if (allowed.length === 0) {
|
|
36
|
-
message += "This status is terminal. No further transitions are possible."
|
|
37
|
-
} else {
|
|
38
|
-
message += `To proceed: transition to one of [${allowed.join(", ")}] first.`
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const hint =
|
|
42
|
-
allowed.length === 0
|
|
43
|
-
? "No further transitions possible from done."
|
|
44
|
-
: `Try transitioning to ${allowed[0]} first.`
|
|
45
|
-
|
|
46
|
-
return {
|
|
47
|
-
message,
|
|
48
|
-
data: {
|
|
49
|
-
from,
|
|
50
|
-
to,
|
|
51
|
-
taskId,
|
|
52
|
-
allowedFrom: Object.keys(allowedTransitions).filter((s) =>
|
|
53
|
-
allowedTransitions[s as Status].includes(from)
|
|
54
|
-
),
|
|
55
|
-
allowedTo: allowed,
|
|
56
|
-
normalFlow: NORMAL_FLOW,
|
|
57
|
-
isReviewTask,
|
|
58
|
-
hint,
|
|
59
|
-
},
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Builds a declarative error message for missing_comment errors.
|
|
65
|
-
*/
|
|
66
|
-
const buildMissingCommentMessage = (
|
|
67
|
-
from?: Status,
|
|
68
|
-
to?: Status
|
|
69
|
-
): { message: string; data: Record<string, unknown> } => {
|
|
70
|
-
let message = "A comment is required for this transition.\n\n"
|
|
71
|
-
|
|
72
|
-
if (from && to) {
|
|
73
|
-
message += `Transition: ${from} → ${to} requires a comment.\n`
|
|
74
|
-
if (to === "need_info") {
|
|
75
|
-
message +=
|
|
76
|
-
"Reason: need_info status requires documentation of what information is needed.\n\n"
|
|
77
|
-
} else if (to === "blocked") {
|
|
78
|
-
message += "Reason: blocked status requires documentation of why the task is blocked.\n\n"
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
message += "Include a comment with non-empty content to proceed."
|
|
83
|
-
|
|
84
|
-
return {
|
|
85
|
-
message,
|
|
86
|
-
data: { from, to },
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Builds a declarative error message for validation_error messages.
|
|
92
|
-
* Matches known raw messages and enhances them with context.
|
|
93
|
-
*/
|
|
94
|
-
const buildValidationErrorMessage = (
|
|
95
|
-
rawMessage: string,
|
|
96
|
-
context?: Record<string, unknown>
|
|
97
|
-
): { message: string; data: Record<string, unknown> } => {
|
|
98
|
-
// Concurrent in_progress guard
|
|
99
|
-
if (rawMessage === "moving a second task to in_progress requires a justification comment") {
|
|
100
|
-
const inProgressTasks = (context?.inProgressTasks as Array<{ id: string; title: string }>) ?? []
|
|
101
|
-
let message =
|
|
102
|
-
"Cannot move this task to in_progress: another task is already in_progress for this session.\n\n"
|
|
103
|
-
|
|
104
|
-
if (inProgressTasks.length > 0) {
|
|
105
|
-
message += "Current in_progress tasks for this session:\n"
|
|
106
|
-
for (const t of inProgressTasks) {
|
|
107
|
-
message += ` - ${t.title} (id: ${t.id})\n`
|
|
108
|
-
}
|
|
109
|
-
message += "\n"
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
message +=
|
|
113
|
-
"When moving a second task to in_progress, you must provide a justification comment\n"
|
|
114
|
-
message += "explaining why this task takes priority over the existing one.\n\n"
|
|
115
|
-
message += "Include a non-empty comment explaining the priority change."
|
|
116
|
-
|
|
117
|
-
return {
|
|
118
|
-
message,
|
|
119
|
-
data: { message: rawMessage, ...context },
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// Reply on regular comment
|
|
124
|
-
if (rawMessage === "reply is only valid on need_info comments") {
|
|
125
|
-
const commentId = context?.commentId as string | undefined
|
|
126
|
-
const commentKind = context?.commentKind as string | undefined
|
|
127
|
-
|
|
128
|
-
let message = "Cannot reply to this comment.\n\n"
|
|
129
|
-
if (commentId) {
|
|
130
|
-
message += `Comment id: ${commentId}\n`
|
|
131
|
-
}
|
|
132
|
-
if (commentKind) {
|
|
133
|
-
message += `Comment kind: ${commentKind}\n`
|
|
134
|
-
}
|
|
135
|
-
message +=
|
|
136
|
-
"\nReplies are only allowed on 'need_info' comments. Regular comments cannot receive replies.\n\n"
|
|
137
|
-
message +=
|
|
138
|
-
"To proceed: either remove the reply field, or change the comment kind to 'need_info'."
|
|
139
|
-
|
|
140
|
-
return {
|
|
141
|
-
message,
|
|
142
|
-
data: { message: rawMessage, ...context },
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
// Blocking comment without reply
|
|
147
|
-
if (rawMessage.startsWith("blocking comment ") && rawMessage.endsWith(" has no reply")) {
|
|
148
|
-
const commentId = context?.commentId as string | undefined
|
|
149
|
-
const commentTitle = context?.commentTitle as string | undefined
|
|
150
|
-
const commentContent = context?.commentContent as string | undefined
|
|
151
|
-
const commentTimestamp = context?.commentTimestamp as Date | undefined
|
|
152
|
-
|
|
153
|
-
let message =
|
|
154
|
-
"Cannot transition from need_info to in_progress: blocking comment has no reply.\n\n"
|
|
155
|
-
message += "Blocking comment:\n"
|
|
156
|
-
if (commentId) message += ` - id: ${commentId}\n`
|
|
157
|
-
if (commentTitle) message += ` - title: ${commentTitle}\n`
|
|
158
|
-
if (commentContent) {
|
|
159
|
-
const truncated =
|
|
160
|
-
commentContent.length > 50 ? `${commentContent.slice(0, 50)}...` : commentContent
|
|
161
|
-
message += ` - content: ${truncated}\n`
|
|
162
|
-
}
|
|
163
|
-
if (commentTimestamp) message += ` - created: ${commentTimestamp.toISOString()}\n`
|
|
164
|
-
message += "\nYou must reply to this need_info comment before transitioning to in_progress.\n\n"
|
|
165
|
-
message += "Include a reply in your comment to proceed."
|
|
166
|
-
|
|
167
|
-
return {
|
|
168
|
-
message,
|
|
169
|
-
data: { message: rawMessage, ...context },
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// Empty blocked content
|
|
174
|
-
if (rawMessage === "blocked requires a non-empty comment") {
|
|
175
|
-
let message = "Cannot transition to blocked with an empty comment.\n\n"
|
|
176
|
-
message += "When blocking a task, you must provide a reason in the comment content.\n\n"
|
|
177
|
-
message += "Include a non-empty comment explaining why the task is blocked."
|
|
178
|
-
|
|
179
|
-
return {
|
|
180
|
-
message,
|
|
181
|
-
data: { message: rawMessage, ...context },
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// Fallback: pass through unknown validation errors
|
|
186
|
-
return {
|
|
187
|
-
message: rawMessage,
|
|
188
|
-
data: { message: rawMessage, ...context },
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
export const taskErrorToMcpError = (err: TaskError): McpError => {
|
|
193
|
-
switch (err._tag) {
|
|
194
|
-
case "not_found":
|
|
195
|
-
return { code: -32001, message: "Task not found", data: { taskId: err.taskId } }
|
|
196
|
-
case "transition_not_allowed": {
|
|
197
|
-
const { message, data } = buildTransitionErrorMessage(err.from, err.to, err.taskId)
|
|
198
|
-
return { code: -32002, message, data }
|
|
199
|
-
}
|
|
200
|
-
case "validation_error": {
|
|
201
|
-
const { message, data } = buildValidationErrorMessage(err.message, err.context)
|
|
202
|
-
return { code: -32003, message, data }
|
|
203
|
-
}
|
|
204
|
-
case "missing_comment": {
|
|
205
|
-
const { message, data } = buildMissingCommentMessage(err.from, err.to)
|
|
206
|
-
return { code: -32004, message, data }
|
|
207
|
-
}
|
|
208
|
-
case "conflict":
|
|
209
|
-
return { code: -32005, message: "Task already exists", data: { taskId: err.taskId } }
|
|
210
|
-
case "no_current_task":
|
|
211
|
-
return { code: -32006, message: "No current task for this session", data: {} }
|
|
212
|
-
}
|
|
213
|
-
}
|