@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
package/src/task/current-task.ts
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import { Effect } from "effect"
|
|
2
|
-
import type { Agent, Task, TaskError } from "../domain/types.js"
|
|
3
|
-
import type { TaskRepository as TaskRepositoryType } from "./ports.js"
|
|
4
|
-
import { TaskRepository } from "./ports.js"
|
|
5
|
-
import { SessionRegistry } from "./session-registry.js"
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Returns the best available task for the given session, claiming it if needed.
|
|
9
|
-
*
|
|
10
|
-
* Priority chain:
|
|
11
|
-
* 1. Own in_progress — already assigned to this session → return highest-priority
|
|
12
|
-
* 2. Unassigned in_progress — no assignee → claim highest-priority, return
|
|
13
|
-
* 3. Orphaned in_progress — dead-session assignee → claim highest-priority, return
|
|
14
|
-
* 4. Highest-priority todo — auto-transition to in_progress, claim, return
|
|
15
|
-
* 5. Nothing → fail `no_current_task`
|
|
16
|
-
*
|
|
17
|
-
* Ties in priority are broken by in_progress_since ASC (oldest first).
|
|
18
|
-
* Claiming is a direct repo.update — no hooks, no HookRunner dependency.
|
|
19
|
-
*/
|
|
20
|
-
export const currentTask = (
|
|
21
|
-
sessionId: string
|
|
22
|
-
): Effect.Effect<Task, TaskError, TaskRepository | SessionRegistry> =>
|
|
23
|
-
Effect.flatMap(TaskRepository, (repo) =>
|
|
24
|
-
Effect.flatMap(repo.findByStatus("in_progress"), (inProgress) => {
|
|
25
|
-
const own = inProgress.filter((t) => t.assignee?.id === sessionId)
|
|
26
|
-
if (own.length > 0) return Effect.succeed(pickHighestPriority(own))
|
|
27
|
-
|
|
28
|
-
return stepUnassigned(inProgress, sessionId, repo).pipe(
|
|
29
|
-
Effect.catchTag("no_current_task", () =>
|
|
30
|
-
stepOrphan(sessionId, inProgress, repo).pipe(
|
|
31
|
-
Effect.catchTag("no_current_task", () => stepTodo(sessionId, repo))
|
|
32
|
-
)
|
|
33
|
-
)
|
|
34
|
-
)
|
|
35
|
-
})
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
const pickHighestPriority = <T extends Task>(tasks: readonly T[]): T => {
|
|
39
|
-
const sorted = [...tasks].sort((a, b) => {
|
|
40
|
-
if (b.priority !== a.priority) return b.priority - a.priority
|
|
41
|
-
const aTime = a.in_progress_since?.getTime() ?? Infinity
|
|
42
|
-
const bTime = b.in_progress_since?.getTime() ?? Infinity
|
|
43
|
-
return aTime - bTime
|
|
44
|
-
})
|
|
45
|
-
// biome-ignore lint/style/noNonNullAssertion: caller guarantees non-empty
|
|
46
|
-
return sorted[0]!
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const claimTask = (
|
|
50
|
-
task: Task,
|
|
51
|
-
newAssignee: Agent,
|
|
52
|
-
repo: TaskRepositoryType
|
|
53
|
-
): Effect.Effect<Task, TaskError, never> => {
|
|
54
|
-
const claimed = { ...task, assignee: newAssignee }
|
|
55
|
-
return Effect.map(repo.update(claimed), () => claimed)
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const stepUnassigned = (
|
|
59
|
-
inProgress: readonly Task[],
|
|
60
|
-
sessionId: string,
|
|
61
|
-
repo: TaskRepositoryType
|
|
62
|
-
): Effect.Effect<Task, TaskError, never> => {
|
|
63
|
-
const unassigned = inProgress.filter((t) => t.assignee === undefined)
|
|
64
|
-
if (unassigned.length === 0) return Effect.fail({ _tag: "no_current_task" as const })
|
|
65
|
-
const oldest = pickHighestPriority(unassigned)
|
|
66
|
-
return claimTask(oldest, { id: sessionId, title: "Agent", description: "" }, repo)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const stepOrphan = (
|
|
70
|
-
sessionId: string,
|
|
71
|
-
candidates: readonly Task[],
|
|
72
|
-
repo: TaskRepositoryType
|
|
73
|
-
): Effect.Effect<Task, TaskError, SessionRegistry> => {
|
|
74
|
-
const foreign = candidates.filter(
|
|
75
|
-
(t): t is Task & { assignee: Agent } => t.assignee !== undefined && t.assignee.id !== sessionId
|
|
76
|
-
)
|
|
77
|
-
if (foreign.length === 0) return Effect.fail({ _tag: "no_current_task" as const })
|
|
78
|
-
return Effect.flatMap(SessionRegistry, (registry) =>
|
|
79
|
-
Effect.flatMap(
|
|
80
|
-
Effect.forEach(foreign, (t) =>
|
|
81
|
-
registry.isAlive(t.assignee.id).pipe(Effect.map((alive) => ({ task: t, alive })))
|
|
82
|
-
),
|
|
83
|
-
(results) => {
|
|
84
|
-
const orphans = results.filter((r) => !r.alive).map((r) => r.task)
|
|
85
|
-
if (orphans.length === 0) return Effect.fail({ _tag: "no_current_task" as const })
|
|
86
|
-
const oldest = pickHighestPriority(orphans)
|
|
87
|
-
return claimTask(oldest, { ...oldest.assignee, id: sessionId }, repo)
|
|
88
|
-
}
|
|
89
|
-
)
|
|
90
|
-
)
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const stepTodo = (
|
|
94
|
-
sessionId: string,
|
|
95
|
-
repo: TaskRepositoryType
|
|
96
|
-
): Effect.Effect<Task, TaskError, never> =>
|
|
97
|
-
Effect.flatMap(repo.findByStatus("todo"), (todos) => {
|
|
98
|
-
if (todos.length === 0) return Effect.fail({ _tag: "no_current_task" as const })
|
|
99
|
-
// biome-ignore lint/style/noNonNullAssertion: length guard above
|
|
100
|
-
const best = [...todos].sort((a, b) => b.priority - a.priority)[0]!
|
|
101
|
-
const claimed: Task = {
|
|
102
|
-
...best,
|
|
103
|
-
status: "in_progress",
|
|
104
|
-
assignee: {
|
|
105
|
-
...(best.assignee ?? { title: "Agent", description: "" }),
|
|
106
|
-
id: sessionId,
|
|
107
|
-
},
|
|
108
|
-
in_progress_since: new Date(),
|
|
109
|
-
}
|
|
110
|
-
return Effect.map(repo.update(claimed), () => claimed)
|
|
111
|
-
})
|
package/src/task/edit-task.ts
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { Effect } from "effect"
|
|
2
|
-
import { estimateFromKTokens } from "../domain/kTokens.js"
|
|
3
|
-
import type { Task, TaskError } from "../domain/types.js"
|
|
4
|
-
import { TaskRepository } from "./ports.js"
|
|
5
|
-
|
|
6
|
-
export interface EditTaskInput {
|
|
7
|
-
title?: string
|
|
8
|
-
description?: string
|
|
9
|
-
definition_of_done?: string
|
|
10
|
-
predictedKTokens?: number
|
|
11
|
-
priority?: number
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Edits mutable fields of an existing task without changing its status.
|
|
16
|
-
* Derives Fibonacci estimation from predictedKTokens when provided.
|
|
17
|
-
* Fails with `not_found` for unknown id.
|
|
18
|
-
* Fails with `validation_error` when a `status` field is attempted via EditTaskInput.
|
|
19
|
-
*/
|
|
20
|
-
export const editTask = (
|
|
21
|
-
id: string,
|
|
22
|
-
updates: EditTaskInput
|
|
23
|
-
): Effect.Effect<Task, TaskError, TaskRepository> => {
|
|
24
|
-
// Check for attempted status modification (runtime guard against type system bypass)
|
|
25
|
-
if ("status" in updates) {
|
|
26
|
-
return Effect.fail({
|
|
27
|
-
_tag: "validation_error" as const,
|
|
28
|
-
message: "status field cannot be edited",
|
|
29
|
-
})
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// Derive estimation from predictedKTokens if present
|
|
33
|
-
if (updates.predictedKTokens !== undefined) {
|
|
34
|
-
return Effect.flatMap(estimateFromKTokens(updates.predictedKTokens), (estimation) =>
|
|
35
|
-
Effect.flatMap(TaskRepository, (repo) =>
|
|
36
|
-
Effect.flatMap(repo.findById(id), (task) => {
|
|
37
|
-
const { predictedKTokens: _, ...rest } = updates
|
|
38
|
-
const updatedTask: Task = {
|
|
39
|
-
...task,
|
|
40
|
-
...rest,
|
|
41
|
-
estimation,
|
|
42
|
-
}
|
|
43
|
-
return Effect.flatMap(repo.update(updatedTask), () => Effect.succeed(updatedTask))
|
|
44
|
-
})
|
|
45
|
-
)
|
|
46
|
-
)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// No estimation to derive, proceed directly with find and update
|
|
50
|
-
return Effect.flatMap(TaskRepository, (repo) =>
|
|
51
|
-
Effect.flatMap(repo.findById(id), (task) => {
|
|
52
|
-
const updatedTask: Task = {
|
|
53
|
-
...task,
|
|
54
|
-
...updates,
|
|
55
|
-
}
|
|
56
|
-
return Effect.flatMap(repo.update(updatedTask), () => Effect.succeed(updatedTask))
|
|
57
|
-
})
|
|
58
|
-
)
|
|
59
|
-
}
|
package/src/task/list-tasks.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { Effect } from "effect"
|
|
2
|
-
import type { Status, Task, TaskError } from "../domain/types.js"
|
|
3
|
-
import { TaskRepository } from "./ports.js"
|
|
4
|
-
|
|
5
|
-
type ListTasksOptions = {
|
|
6
|
-
status: Status | "*"
|
|
7
|
-
project?: string
|
|
8
|
-
milestone?: string
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const applyFilters = (tasks: readonly Task[], options: ListTasksOptions): readonly Task[] => {
|
|
12
|
-
let result = tasks
|
|
13
|
-
if (options.project !== undefined) {
|
|
14
|
-
result = result.filter((t) => t.project === options.project)
|
|
15
|
-
}
|
|
16
|
-
if (options.milestone !== undefined) {
|
|
17
|
-
result = result.filter((t) => t.milestone === options.milestone)
|
|
18
|
-
}
|
|
19
|
-
return result
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Returns tasks matching the given status (and optional project/milestone), or all tasks when status is '*'.
|
|
24
|
-
* Filters compose: all provided filters must match.
|
|
25
|
-
* Results are ordered by priority DESC.
|
|
26
|
-
* Fails with `validation_error` when the underlying data is malformed.
|
|
27
|
-
*/
|
|
28
|
-
export const listTasks = (
|
|
29
|
-
options: ListTasksOptions
|
|
30
|
-
): Effect.Effect<readonly Task[], TaskError, TaskRepository> =>
|
|
31
|
-
Effect.flatMap(TaskRepository, (repo) =>
|
|
32
|
-
Effect.map(repo.findByStatus(options.status), (tasks) =>
|
|
33
|
-
[...applyFilters(tasks, options)].sort((a, b) => b.priority - a.priority)
|
|
34
|
-
)
|
|
35
|
-
)
|
package/src/task/ports.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { Context, type Effect } from "effect"
|
|
2
|
-
import type { Status, Task, TaskError } from "../domain/types.js"
|
|
3
|
-
|
|
4
|
-
export interface TaskRepository {
|
|
5
|
-
/** Fails with `not_found` if id is absent. */
|
|
6
|
-
findById(id: string): Effect.Effect<Task, TaskError>
|
|
7
|
-
/** Returns empty array when nothing matches; fails with `validation_error` on malformed data. */
|
|
8
|
-
findByStatus(status: Status | "*"): Effect.Effect<readonly Task[], TaskError>
|
|
9
|
-
/** Fails with `conflict` if a task with the same id already exists. */
|
|
10
|
-
save(task: Task): Effect.Effect<void, TaskError>
|
|
11
|
-
/** Fails with `not_found` if id is absent. */
|
|
12
|
-
update(task: Task): Effect.Effect<void, TaskError>
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export const TaskRepository = Context.GenericTag<TaskRepository>("TaskRepository")
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { Context, type Effect } from "effect"
|
|
2
|
-
|
|
3
|
-
export interface SessionRegistry {
|
|
4
|
-
isAlive(sessionId: string): Effect.Effect<boolean, never>
|
|
5
|
-
register(sessionId: string, pid: number): Effect.Effect<void, never>
|
|
6
|
-
deregister(sessionId: string): Effect.Effect<void, never>
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export const SessionRegistry = Context.GenericTag<SessionRegistry>("SessionRegistry")
|
package/src/task/update-task.ts
DELETED
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
import { Effect } from "effect"
|
|
2
|
-
import { guardTransition } from "../domain/status-machine.js"
|
|
3
|
-
import type { Comment, Status, TaskError } from "../domain/types.js"
|
|
4
|
-
import { HookRunner } from "../hook/ports.js"
|
|
5
|
-
import { TaskRepository } from "./ports.js"
|
|
6
|
-
import { SessionRegistry } from "./session-registry.js"
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Transitions a task to a new status, optionally attaching or replying to a comment.
|
|
10
|
-
* Enforces transition rules, comment requirements, need_info reply cycle,
|
|
11
|
-
* and concurrent in_progress justification.
|
|
12
|
-
* Fires HookRunner after a successful status change.
|
|
13
|
-
*/
|
|
14
|
-
export const updateTask = (
|
|
15
|
-
id: string,
|
|
16
|
-
newStatus: Status,
|
|
17
|
-
comment: Comment | null,
|
|
18
|
-
sessionId: string
|
|
19
|
-
): Effect.Effect<void, TaskError, TaskRepository | HookRunner | SessionRegistry> =>
|
|
20
|
-
Effect.gen(function* () {
|
|
21
|
-
const repo = yield* TaskRepository
|
|
22
|
-
const hookRunner = yield* HookRunner
|
|
23
|
-
|
|
24
|
-
// Step 1: find task or fail with not_found
|
|
25
|
-
const task = yield* repo.findById(id)
|
|
26
|
-
|
|
27
|
-
// Step 2: guard transition (same→same is allowed by guardTransition too)
|
|
28
|
-
// Pass task id so review tasks can skip pending_review and go directly to done
|
|
29
|
-
yield* guardTransition(task.status, newStatus, task.id)
|
|
30
|
-
|
|
31
|
-
// Step 4: reply handling — comment id matches an existing comment
|
|
32
|
-
// Must run before the no-op check because a reply update is meaningful
|
|
33
|
-
// even when the status is not changing.
|
|
34
|
-
if (comment !== null) {
|
|
35
|
-
const existing = task.comments.find((c) => c.id === comment.id)
|
|
36
|
-
if (existing !== undefined) {
|
|
37
|
-
if (existing.kind === "regular") {
|
|
38
|
-
return yield* Effect.fail<TaskError>({
|
|
39
|
-
_tag: "validation_error",
|
|
40
|
-
message: "reply is only valid on need_info comments",
|
|
41
|
-
context: { commentId: existing.id, commentKind: existing.kind },
|
|
42
|
-
})
|
|
43
|
-
}
|
|
44
|
-
// existing.kind === 'need_info': merge reply and persist, no hook, no status change
|
|
45
|
-
const updatedComments = task.comments.map((c) =>
|
|
46
|
-
c.id === comment.id ? { ...c, reply: comment.reply } : c
|
|
47
|
-
)
|
|
48
|
-
const updatedTask = { ...task, comments: updatedComments }
|
|
49
|
-
yield* repo.update(updatedTask)
|
|
50
|
-
return
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// Step 3: no-op when status unchanged (and no reply was handled above)
|
|
55
|
-
if (task.status === newStatus) return
|
|
56
|
-
|
|
57
|
-
// Step 5: need_info requires a comment
|
|
58
|
-
if (newStatus === "need_info" && comment === null) {
|
|
59
|
-
return yield* Effect.fail<TaskError>({
|
|
60
|
-
_tag: "missing_comment",
|
|
61
|
-
from: task.status,
|
|
62
|
-
to: newStatus,
|
|
63
|
-
})
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Step 6: blocked requires a non-empty comment
|
|
67
|
-
if (newStatus === "blocked") {
|
|
68
|
-
if (comment === null) {
|
|
69
|
-
return yield* Effect.fail<TaskError>({
|
|
70
|
-
_tag: "missing_comment",
|
|
71
|
-
from: task.status,
|
|
72
|
-
to: newStatus,
|
|
73
|
-
})
|
|
74
|
-
}
|
|
75
|
-
if (comment.content.trim() === "") {
|
|
76
|
-
return yield* Effect.fail<TaskError>({
|
|
77
|
-
_tag: "validation_error",
|
|
78
|
-
message: "blocked requires a non-empty comment",
|
|
79
|
-
context: { from: task.status, to: newStatus },
|
|
80
|
-
})
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Step 7: transitioning FROM need_info — all need_info comments must have a reply
|
|
85
|
-
if (task.status === "need_info") {
|
|
86
|
-
const blocking = task.comments.find((c) => c.kind === "need_info" && c.reply === "")
|
|
87
|
-
if (blocking !== undefined) {
|
|
88
|
-
return yield* Effect.fail<TaskError>({
|
|
89
|
-
_tag: "validation_error",
|
|
90
|
-
message: `blocking comment ${blocking.id} has no reply`,
|
|
91
|
-
context: {
|
|
92
|
-
commentId: blocking.id,
|
|
93
|
-
commentTitle: blocking.title,
|
|
94
|
-
commentContent: blocking.content,
|
|
95
|
-
commentTimestamp: blocking.timestamp,
|
|
96
|
-
},
|
|
97
|
-
})
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Step 8b: ownership check — reject if a live foreign session owns this task
|
|
102
|
-
if (
|
|
103
|
-
newStatus === "in_progress" &&
|
|
104
|
-
task.assignee !== undefined &&
|
|
105
|
-
task.assignee.id !== sessionId
|
|
106
|
-
) {
|
|
107
|
-
const registry = yield* SessionRegistry
|
|
108
|
-
const alive = yield* registry.isAlive(task.assignee.id)
|
|
109
|
-
if (alive) {
|
|
110
|
-
return yield* Effect.fail<TaskError>({
|
|
111
|
-
_tag: "validation_error",
|
|
112
|
-
message: `task is owned by an active session (${task.assignee.id})`,
|
|
113
|
-
context: { task },
|
|
114
|
-
})
|
|
115
|
-
}
|
|
116
|
-
// dead session — fall through and let step 9 reassign
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Step 8: concurrent in_progress — second task for same session requires justification
|
|
120
|
-
if (newStatus === "in_progress") {
|
|
121
|
-
const inProgressTasks = yield* repo.findByStatus("in_progress")
|
|
122
|
-
const sessionInProgress = inProgressTasks.filter(
|
|
123
|
-
(t) => t.assignee?.id === sessionId && t.id !== task.id
|
|
124
|
-
)
|
|
125
|
-
if (sessionInProgress.length > 0) {
|
|
126
|
-
if (comment === null || comment.content.trim() === "") {
|
|
127
|
-
return yield* Effect.fail<TaskError>({
|
|
128
|
-
_tag: "validation_error",
|
|
129
|
-
message: "moving a second task to in_progress requires a justification comment",
|
|
130
|
-
context: {
|
|
131
|
-
inProgressTasks: sessionInProgress.map((t) => ({ id: t.id, title: t.title })),
|
|
132
|
-
},
|
|
133
|
-
})
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// Step 9: apply changes
|
|
139
|
-
const oldStatus = task.status
|
|
140
|
-
const updatedComments = comment !== null ? [...task.comments, comment] : task.comments
|
|
141
|
-
const updatedTask = {
|
|
142
|
-
...task,
|
|
143
|
-
status: newStatus,
|
|
144
|
-
comments: updatedComments,
|
|
145
|
-
...(newStatus === "in_progress"
|
|
146
|
-
? {
|
|
147
|
-
in_progress_since: new Date(),
|
|
148
|
-
assignee: { id: sessionId, title: "Agent", description: "" },
|
|
149
|
-
}
|
|
150
|
-
: {}),
|
|
151
|
-
}
|
|
152
|
-
yield* repo.update(updatedTask)
|
|
153
|
-
yield* hookRunner.run({
|
|
154
|
-
task_id: id,
|
|
155
|
-
old_status: oldStatus,
|
|
156
|
-
new_status: newStatus,
|
|
157
|
-
comment,
|
|
158
|
-
session_id: sessionId,
|
|
159
|
-
})
|
|
160
|
-
})
|