@bosun-sh/logbook 1.1.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +145 -0
- package/README.md +249 -318
- 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/shared/version.d.ts +2 -0
- package/dist/shared/version.d.ts.map +1 -0
- package/dist/shared/version.js +2 -0
- package/dist/shared/version.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 +17 -0
- package/dist/workspace/cli-adapter.d.ts.map +1 -0
- package/dist/workspace/cli-adapter.js +230 -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 +335 -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 +191 -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 +174 -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/cli.ts +0 -489
- package/src/cli/init.ts +0 -230
- 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/layer.ts +0 -34
- 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 -396
- 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,96 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
|
2
|
-
import { appendFile, readFile } from "node:fs/promises"
|
|
3
|
-
|
|
4
|
-
const taskId = process.env.LOGBOOK_TASK_ID ?? ""
|
|
5
|
-
const dataFile = process.env.LOGBOOK_TASKS_FILE ?? "./tasks.jsonl"
|
|
6
|
-
|
|
7
|
-
if (taskId === "") process.exit(0)
|
|
8
|
-
|
|
9
|
-
const readLines = async (filePath: string): Promise<readonly string[]> => {
|
|
10
|
-
const content = await readFile(filePath, "utf8").catch((e: unknown) => {
|
|
11
|
-
if (isEnoent(e)) return ""
|
|
12
|
-
throw e
|
|
13
|
-
})
|
|
14
|
-
return content.split("\n").filter((l) => l.trim() !== "")
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
interface RawAgent {
|
|
18
|
-
id: string
|
|
19
|
-
title: string
|
|
20
|
-
description: string
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
interface RawTask {
|
|
24
|
-
project: string
|
|
25
|
-
milestone: string
|
|
26
|
-
id: string
|
|
27
|
-
title: string
|
|
28
|
-
definition_of_done: string
|
|
29
|
-
description: string
|
|
30
|
-
estimation: number
|
|
31
|
-
comments: unknown[]
|
|
32
|
-
assignee: RawAgent
|
|
33
|
-
status: string
|
|
34
|
-
in_progress_since?: string
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const parseTask = (line: string): RawTask | null => {
|
|
38
|
-
try {
|
|
39
|
-
return JSON.parse(line) as RawTask
|
|
40
|
-
} catch {
|
|
41
|
-
return null
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const isEnoent = (e: unknown): boolean =>
|
|
46
|
-
typeof e === "object" && e !== null && (e as { code?: unknown }).code === "ENOENT"
|
|
47
|
-
|
|
48
|
-
const lines = await readLines(dataFile)
|
|
49
|
-
|
|
50
|
-
let original: RawTask | null = null
|
|
51
|
-
for (const line of lines) {
|
|
52
|
-
const task = parseTask(line)
|
|
53
|
-
if (task !== null && task.id === taskId) {
|
|
54
|
-
original = task
|
|
55
|
-
break
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
if (original === null) process.exit(0)
|
|
60
|
-
|
|
61
|
-
// Guard: don't create a review-of-a-review (circular flow)
|
|
62
|
-
if (original.id.startsWith("review-")) process.exit(0)
|
|
63
|
-
|
|
64
|
-
const reviewId = `review-${original.id}`
|
|
65
|
-
|
|
66
|
-
// Idempotency check: skip if a task with the review id already exists
|
|
67
|
-
const alreadyExists = lines.some((line) => {
|
|
68
|
-
const task = parseTask(line)
|
|
69
|
-
return task !== null && task.id === reviewId
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
if (alreadyExists) process.exit(0)
|
|
73
|
-
|
|
74
|
-
const reviewTask: RawTask = {
|
|
75
|
-
project: original.project,
|
|
76
|
-
milestone: original.milestone,
|
|
77
|
-
id: reviewId,
|
|
78
|
-
title: `Review: ${original.title}`,
|
|
79
|
-
definition_of_done: "Review approved",
|
|
80
|
-
description: `Review task for ${original.id}`,
|
|
81
|
-
estimation: 1,
|
|
82
|
-
comments: [],
|
|
83
|
-
assignee: original.assignee,
|
|
84
|
-
status: "todo",
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
await appendFile(dataFile, `${JSON.stringify(reviewTask)}\n`, "utf8")
|
|
88
|
-
|
|
89
|
-
const { execSync } = await import("node:child_process")
|
|
90
|
-
const path = await import("node:path")
|
|
91
|
-
const projectRoot = path.dirname(process.env.LOGBOOK_TASKS_FILE ?? "./tasks.jsonl")
|
|
92
|
-
const mcpConfig = path.join(projectRoot, ".claude/mcp-config.json")
|
|
93
|
-
execSync(
|
|
94
|
-
`claude --model claude-haiku-4-5-20251001 --mcp-config ${mcpConfig} --agent reviewer -p "review task ${reviewId}"`,
|
|
95
|
-
{ stdio: "inherit", env: { ...process.env, LOGBOOK_TASKS_FILE: dataFile } }
|
|
96
|
-
)
|
package/src/cli/cli.ts
DELETED
|
@@ -1,489 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
|
2
|
-
import { existsSync } from "node:fs"
|
|
3
|
-
import { readFile, writeFile } from "node:fs/promises"
|
|
4
|
-
import { Effect } from "effect"
|
|
5
|
-
import { createLayer, type LayerConfig } from "../infra/layer.js"
|
|
6
|
-
import { taskErrorToMcpError } from "../mcp/error-codes.js"
|
|
7
|
-
import { newSessionId } from "../mcp/session.js"
|
|
8
|
-
import { toolCreateTask } from "../mcp/tool-create-task.js"
|
|
9
|
-
import { toolCurrentTask } from "../mcp/tool-current-task.js"
|
|
10
|
-
import { toolEditTask } from "../mcp/tool-edit-task.js"
|
|
11
|
-
import { toolListTasks } from "../mcp/tool-list-tasks.js"
|
|
12
|
-
import { toolUpdateTask } from "../mcp/tool-update-task.js"
|
|
13
|
-
import { runInit } from "./init.js"
|
|
14
|
-
|
|
15
|
-
const DEFAULT_TASKS_FILE = "./tasks.jsonl"
|
|
16
|
-
const DEFAULT_HOOKS_DIR = "./hooks"
|
|
17
|
-
const SESSION_FILE = ".logbook-session"
|
|
18
|
-
|
|
19
|
-
const helpText = `# logbook - File-system kanban board CLI
|
|
20
|
-
|
|
21
|
-
## SYNOPSIS
|
|
22
|
-
|
|
23
|
-
logbook <command> [options]
|
|
24
|
-
|
|
25
|
-
## DESCRIPTION
|
|
26
|
-
|
|
27
|
-
Logbook is a file-system kanban board for AI agents. It tracks tasks across a structured
|
|
28
|
-
lifecycle so agents and humans share a single source of truth without context bloat.
|
|
29
|
-
|
|
30
|
-
## COMMANDS
|
|
31
|
-
|
|
32
|
-
### logbook create-task
|
|
33
|
-
|
|
34
|
-
Create a new task in backlog. The task is assigned a unique ID and estimated Fibonacci
|
|
35
|
-
number based on the predicted context size (predictedKTokens).
|
|
36
|
-
|
|
37
|
-
Required arguments:
|
|
38
|
-
--project <name> Project name (e.g., "myproject")
|
|
39
|
-
--milestone <name> Milestone name (e.g., "v1")
|
|
40
|
-
--title <text> Task title
|
|
41
|
-
--definition-of-done <text> What "done" means for this task
|
|
42
|
-
--description <text> Detailed description
|
|
43
|
-
--predicted-k-tokens <n> Estimated context size in thousands of tokens (drives model selection)
|
|
44
|
-
|
|
45
|
-
Optional arguments:
|
|
46
|
-
--priority <n> Priority (higher = more urgent, default: 0)
|
|
47
|
-
|
|
48
|
-
Example:
|
|
49
|
-
logbook create-task --project myproject --milestone v1 --title "Fix bug" \\
|
|
50
|
-
--definition-of-done "Bug fixed and tested" --description "Details..." \\
|
|
51
|
-
--predicted-k-tokens 3
|
|
52
|
-
|
|
53
|
-
### logbook list-tasks
|
|
54
|
-
|
|
55
|
-
List tasks, optionally filtered by status, project, or milestone.
|
|
56
|
-
|
|
57
|
-
Optional arguments:
|
|
58
|
-
--status <status> Filter by status (default: "in_progress")
|
|
59
|
-
Valid values: backlog, todo, need_info, blocked, in_progress,
|
|
60
|
-
pending_review, done, or "*" for all
|
|
61
|
-
--project <name> Filter by project name
|
|
62
|
-
--milestone <name> Filter by milestone name
|
|
63
|
-
|
|
64
|
-
Examples:
|
|
65
|
-
logbook list-tasks
|
|
66
|
-
logbook list-tasks --status "*"
|
|
67
|
-
logbook list-tasks --status todo --project myproject
|
|
68
|
-
|
|
69
|
-
### logbook current-task
|
|
70
|
-
|
|
71
|
-
Return the highest-priority in_progress task for this session. If no task is assigned
|
|
72
|
-
to this session, it will claim an unassigned task or transition a todo task to in_progress.
|
|
73
|
-
|
|
74
|
-
This command automatically claims a task if none is currently assigned to the session.
|
|
75
|
-
|
|
76
|
-
Example:
|
|
77
|
-
logbook current-task
|
|
78
|
-
|
|
79
|
-
### logbook update-task
|
|
80
|
-
|
|
81
|
-
Transition a task's status. Some transitions require a comment.
|
|
82
|
-
|
|
83
|
-
Required arguments:
|
|
84
|
-
--id <uuid> Task ID
|
|
85
|
-
--new-status <status> Target status
|
|
86
|
-
|
|
87
|
-
Optional arguments:
|
|
88
|
-
--comment-title <text> Comment title
|
|
89
|
-
--comment-content <text> Comment body
|
|
90
|
-
--comment-kind <kind> Comment type: "regular" or "need_info" (default: regular)
|
|
91
|
-
|
|
92
|
-
Status transitions require a comment in these cases:
|
|
93
|
-
- Transitioning to need_info (must document what info is needed)
|
|
94
|
-
- Transitioning to blocked (must document why blocked)
|
|
95
|
-
- Moving a second task to in_progress (must explain priority)
|
|
96
|
-
- Transitioning to pending_review (should document review request)
|
|
97
|
-
|
|
98
|
-
Use --comment-title and --comment-content together. To reply to a need_info comment,
|
|
99
|
-
include the original comment's ID via the MCP interface.
|
|
100
|
-
|
|
101
|
-
Examples:
|
|
102
|
-
logbook update-task --id <uuid> --new-status in_progress
|
|
103
|
-
logbook update-task --id <uuid> --new-status pending_review \\
|
|
104
|
-
--comment-title "Review please" --comment-content "Done!"
|
|
105
|
-
logbook update-task --id <uuid> --new-status need_info \\
|
|
106
|
-
--comment-title "Need info" --comment-content "What does X mean?"
|
|
107
|
-
|
|
108
|
-
### logbook edit-task
|
|
109
|
-
|
|
110
|
-
Edit mutable fields of a task without changing its status.
|
|
111
|
-
|
|
112
|
-
Required arguments:
|
|
113
|
-
--id <uuid> Task ID
|
|
114
|
-
|
|
115
|
-
Optional arguments:
|
|
116
|
-
--title <text> New title
|
|
117
|
-
--description <text> New description
|
|
118
|
-
--definition-of-done <text> New definition of done
|
|
119
|
-
--predicted-k-tokens <n> New predicted context size (will recalculate estimation)
|
|
120
|
-
--priority <n> New priority
|
|
121
|
-
|
|
122
|
-
Example:
|
|
123
|
-
logbook edit-task --id <uuid> --title "New title"
|
|
124
|
-
|
|
125
|
-
### logbook init
|
|
126
|
-
|
|
127
|
-
Initialize the project: create tasks.jsonl, hooks/, AGENTS.md, and CLAUDE.md if they
|
|
128
|
-
don't exist. If they exist, append logbook documentation to them.
|
|
129
|
-
|
|
130
|
-
By default:
|
|
131
|
-
- If neither AGENTS.md nor CLAUDE.md exists → creates AGENTS.md and symlinks CLAUDE.md to it
|
|
132
|
-
- If only AGENTS.md exists → appends to AGENTS.md
|
|
133
|
-
- If only CLAUDE.md exists → appends to CLAUDE.md
|
|
134
|
-
|
|
135
|
-
Optional arguments:
|
|
136
|
-
--force Force creation/sync of both files. Appends to existing,
|
|
137
|
-
creates/symlinks missing. Ensures both files exist.
|
|
138
|
-
|
|
139
|
-
This command scaffolds the basic structure needed to use logbook.
|
|
140
|
-
|
|
141
|
-
Examples:
|
|
142
|
-
logbook init
|
|
143
|
-
logbook init --force
|
|
144
|
-
|
|
145
|
-
## TASK LIFECYCLE
|
|
146
|
-
|
|
147
|
-
backlog → todo → in_progress → pending_review → done
|
|
148
|
-
|
|
149
|
-
Side-exits from in_progress:
|
|
150
|
-
- need_info: task needs clarification (return to in_progress once resolved)
|
|
151
|
-
- blocked: task is blocked by external dependency (return to in_progress once resolved)
|
|
152
|
-
|
|
153
|
-
## ENVIRONMENT
|
|
154
|
-
|
|
155
|
-
LOGBOOK_TASKS_FILE Path to JSONL task store (default: ./tasks.jsonl)
|
|
156
|
-
LOGBOOK_HOOKS_DIR Directory for hook definitions (default: ./hooks)
|
|
157
|
-
LOGBOOK_SESSION_ID Session ID to use (auto-generated if not provided)
|
|
158
|
-
|
|
159
|
-
## GLOBAL OPTIONS
|
|
160
|
-
|
|
161
|
-
--tasks-file <path> Path to JSONL task store
|
|
162
|
-
--hooks-dir <path> Directory for hook definitions
|
|
163
|
-
--session <id> Session ID to use
|
|
164
|
-
--version, -v Print version
|
|
165
|
-
--help, -h Show this help
|
|
166
|
-
|
|
167
|
-
## OUTPUT FORMAT
|
|
168
|
-
|
|
169
|
-
All commands output JSON to stdout:
|
|
170
|
-
|
|
171
|
-
Success: { "ok": true, ...result }
|
|
172
|
-
Error: { "ok": false, "error": { "code": <n>, "message": <text>, ... } }
|
|
173
|
-
|
|
174
|
-
Exit code: 0 on success, 1 on error.
|
|
175
|
-
`
|
|
176
|
-
|
|
177
|
-
interface CliArgs {
|
|
178
|
-
tasksFile: string
|
|
179
|
-
hooksDir: string
|
|
180
|
-
sessionId: string | null
|
|
181
|
-
command: string | null
|
|
182
|
-
commandArgs: Record<string, string>
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
const parseArgs = (): CliArgs => {
|
|
186
|
-
const args = process.argv.slice(2)
|
|
187
|
-
const result: CliArgs = {
|
|
188
|
-
tasksFile: process.env.LOGBOOK_TASKS_FILE ?? DEFAULT_TASKS_FILE,
|
|
189
|
-
hooksDir: process.env.LOGBOOK_HOOKS_DIR ?? DEFAULT_HOOKS_DIR,
|
|
190
|
-
sessionId: process.env.LOGBOOK_SESSION_ID ?? null,
|
|
191
|
-
command: null,
|
|
192
|
-
commandArgs: {},
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
let i = 0
|
|
196
|
-
while (i < args.length) {
|
|
197
|
-
const arg = args[i]
|
|
198
|
-
if (arg === "--tasks-file" && i + 1 < args.length) {
|
|
199
|
-
result.tasksFile = args[i + 1] ?? ""
|
|
200
|
-
i += 2
|
|
201
|
-
} else if (arg === "--hooks-dir" && i + 1 < args.length) {
|
|
202
|
-
result.hooksDir = args[i + 1] ?? ""
|
|
203
|
-
i += 2
|
|
204
|
-
} else if (arg === "--session" && i + 1 < args.length) {
|
|
205
|
-
result.sessionId = args[i + 1] ?? null
|
|
206
|
-
i += 2
|
|
207
|
-
} else if (arg === "--version" || arg === "-v") {
|
|
208
|
-
printVersion()
|
|
209
|
-
} else if (arg === "--help" || arg === "-h") {
|
|
210
|
-
printHelp()
|
|
211
|
-
} else if (arg && !arg.startsWith("-")) {
|
|
212
|
-
result.command = arg
|
|
213
|
-
i++
|
|
214
|
-
while (i < args.length) {
|
|
215
|
-
const cmdArg = args[i]
|
|
216
|
-
if (cmdArg?.startsWith("-") && cmdArg.includes("=")) {
|
|
217
|
-
const [key, ...valueParts] = cmdArg.slice(2).split("=")
|
|
218
|
-
if (key) {
|
|
219
|
-
result.commandArgs[key] = valueParts.join("=")
|
|
220
|
-
}
|
|
221
|
-
i++
|
|
222
|
-
} else if (
|
|
223
|
-
cmdArg?.startsWith("-") &&
|
|
224
|
-
i + 1 < args.length &&
|
|
225
|
-
args[i + 1] &&
|
|
226
|
-
!args[i + 1]?.startsWith("-")
|
|
227
|
-
) {
|
|
228
|
-
result.commandArgs[cmdArg.slice(2)] = args[i + 1] ?? ""
|
|
229
|
-
i += 2
|
|
230
|
-
} else if (
|
|
231
|
-
cmdArg?.startsWith("-") &&
|
|
232
|
-
(i + 1 >= args.length || args[i + 1]?.startsWith("-"))
|
|
233
|
-
) {
|
|
234
|
-
result.commandArgs[cmdArg.slice(2)] = "true"
|
|
235
|
-
i++
|
|
236
|
-
} else {
|
|
237
|
-
i++
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
break
|
|
241
|
-
} else {
|
|
242
|
-
i++
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
return result
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
const printVersion = async (): Promise<void> => {
|
|
250
|
-
const pkg = await import("../../package.json", { with: { type: "json" } })
|
|
251
|
-
console.log(pkg.default.version)
|
|
252
|
-
process.exit(0)
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
const printHelp = (): void => {
|
|
256
|
-
console.log(helpText)
|
|
257
|
-
process.exit(0)
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
const getOrCreateSession = async (explicitSessionId: string | null): Promise<string> => {
|
|
261
|
-
if (explicitSessionId) {
|
|
262
|
-
return explicitSessionId
|
|
263
|
-
}
|
|
264
|
-
try {
|
|
265
|
-
if (existsSync(SESSION_FILE)) {
|
|
266
|
-
const stored = await readFile(SESSION_FILE, "utf8")
|
|
267
|
-
const parsed = JSON.parse(stored)
|
|
268
|
-
if (parsed.sessionId && typeof parsed.sessionId === "string") {
|
|
269
|
-
return parsed.sessionId
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
} catch {}
|
|
273
|
-
const newSession = newSessionId()
|
|
274
|
-
await writeFile(SESSION_FILE, JSON.stringify({ sessionId: newSession }), "utf8")
|
|
275
|
-
return newSession
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
const _saveSession = async (sessionId: string): Promise<void> => {
|
|
279
|
-
await writeFile(SESSION_FILE, JSON.stringify({ sessionId }), "utf8")
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
const output = (result: unknown): void => {
|
|
283
|
-
process.stdout.write(`${JSON.stringify(result)}\n`)
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
const outputError = (error: unknown, _command?: string): void => {
|
|
287
|
-
let code = -32603
|
|
288
|
-
let message = "Internal error"
|
|
289
|
-
let hint = ""
|
|
290
|
-
let extra: Record<string, unknown> = {}
|
|
291
|
-
|
|
292
|
-
if (isTaskError(error)) {
|
|
293
|
-
const mcpErr = taskErrorToMcpError(error)
|
|
294
|
-
code = mcpErr.code
|
|
295
|
-
message = mcpErr.message
|
|
296
|
-
extra = mcpErr.data
|
|
297
|
-
|
|
298
|
-
const hints: string[] = []
|
|
299
|
-
|
|
300
|
-
switch (error._tag) {
|
|
301
|
-
case "not_found":
|
|
302
|
-
hints.push("Use: logbook list-tasks --status '*' to find available tasks")
|
|
303
|
-
hints.push("Use: logbook list-tasks --status <status> to list tasks by status")
|
|
304
|
-
break
|
|
305
|
-
case "transition_not_allowed":
|
|
306
|
-
if (error.from && error.to) {
|
|
307
|
-
hints.push(`Use: logbook update-task --id=${error.taskId} --new-status=<valid-status>`)
|
|
308
|
-
if (error.from === "backlog") {
|
|
309
|
-
hints.push("Note: Tasks must move: backlog → todo → in_progress")
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
break
|
|
313
|
-
case "validation_error":
|
|
314
|
-
if (error.message.includes("second task to in_progress")) {
|
|
315
|
-
hints.push(
|
|
316
|
-
"Use: logbook update-task --id=<uuid> --new-status=in_progress --comment-title='...' --comment-content='justification'"
|
|
317
|
-
)
|
|
318
|
-
} else if (error.message.includes("need_info") && error.message.includes("reply")) {
|
|
319
|
-
hints.push("Include a non-empty reply in your comment to proceed")
|
|
320
|
-
}
|
|
321
|
-
break
|
|
322
|
-
case "missing_comment":
|
|
323
|
-
hints.push(
|
|
324
|
-
"Use: logbook update-task --id=<uuid> --new-status=<status> --comment-title='...' --comment-content='...'"
|
|
325
|
-
)
|
|
326
|
-
break
|
|
327
|
-
case "no_current_task":
|
|
328
|
-
hints.push("Use: logbook list-tasks --status=todo to find available tasks")
|
|
329
|
-
hints.push("Use: logbook create-task ... to create a new task")
|
|
330
|
-
break
|
|
331
|
-
case "conflict":
|
|
332
|
-
hints.push(
|
|
333
|
-
"Use a different task ID or check existing tasks with: logbook list-tasks --status='*'"
|
|
334
|
-
)
|
|
335
|
-
break
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
if (hints.length > 0) {
|
|
339
|
-
hint = `\n\nHints:\n${hints.map((h) => ` - ${h}`).join("\n")}`
|
|
340
|
-
}
|
|
341
|
-
} else if (error instanceof Error) {
|
|
342
|
-
message = error.message
|
|
343
|
-
if (message.includes("Missing required")) {
|
|
344
|
-
hint = "\n\nRun: logbook <command> --help for usage information"
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
const fullMessage = message + hint
|
|
349
|
-
output({ ok: false, error: { code, message: fullMessage, ...extra } })
|
|
350
|
-
process.exit(1)
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
const isTaskError = (e: unknown): e is import("../domain/types.js").TaskError =>
|
|
354
|
-
typeof e === "object" &&
|
|
355
|
-
e !== null &&
|
|
356
|
-
typeof (e as { _tag?: unknown })._tag === "string" &&
|
|
357
|
-
[
|
|
358
|
-
"not_found",
|
|
359
|
-
"transition_not_allowed",
|
|
360
|
-
"validation_error",
|
|
361
|
-
"missing_comment",
|
|
362
|
-
"conflict",
|
|
363
|
-
"no_current_task",
|
|
364
|
-
].includes((e as { _tag: string })._tag)
|
|
365
|
-
|
|
366
|
-
const runCommand = async (args: CliArgs): Promise<void> => {
|
|
367
|
-
const sessionId = await getOrCreateSession(args.sessionId)
|
|
368
|
-
const config: LayerConfig = {
|
|
369
|
-
tasksFile: args.tasksFile,
|
|
370
|
-
hooksDir: args.hooksDir,
|
|
371
|
-
}
|
|
372
|
-
const layer = await createLayer(config)
|
|
373
|
-
|
|
374
|
-
const dispatch = async (): Promise<unknown> => {
|
|
375
|
-
switch (args.command) {
|
|
376
|
-
case "init": {
|
|
377
|
-
await runInit(process.cwd(), { force: !!args.commandArgs.force })
|
|
378
|
-
return { ok: true }
|
|
379
|
-
}
|
|
380
|
-
case "create-task": {
|
|
381
|
-
const input = {
|
|
382
|
-
project: args.commandArgs.project,
|
|
383
|
-
milestone: args.commandArgs.milestone,
|
|
384
|
-
title: args.commandArgs.title,
|
|
385
|
-
definition_of_done: args.commandArgs["definition-of-done"],
|
|
386
|
-
description: args.commandArgs.description,
|
|
387
|
-
predictedKTokens: parseInt(args.commandArgs["predicted-k-tokens"] ?? "0", 10),
|
|
388
|
-
priority: args.commandArgs.priority ? parseInt(args.commandArgs.priority, 10) : 0,
|
|
389
|
-
}
|
|
390
|
-
if (
|
|
391
|
-
!input.project ||
|
|
392
|
-
!input.milestone ||
|
|
393
|
-
!input.title ||
|
|
394
|
-
!input.definition_of_done ||
|
|
395
|
-
!input.description ||
|
|
396
|
-
!input.predictedKTokens
|
|
397
|
-
) {
|
|
398
|
-
throw new Error(
|
|
399
|
-
"Missing required arguments: project, milestone, title, definition-of-done, description, predicted-k-tokens"
|
|
400
|
-
)
|
|
401
|
-
}
|
|
402
|
-
return toolCreateTask(input, sessionId, layer)
|
|
403
|
-
}
|
|
404
|
-
case "list-tasks": {
|
|
405
|
-
const input = {
|
|
406
|
-
status: args.commandArgs.status ?? "in_progress",
|
|
407
|
-
project: args.commandArgs.project,
|
|
408
|
-
milestone: args.commandArgs.milestone,
|
|
409
|
-
}
|
|
410
|
-
return toolListTasks(input, layer)
|
|
411
|
-
}
|
|
412
|
-
case "current-task": {
|
|
413
|
-
return toolCurrentTask(sessionId, layer)
|
|
414
|
-
}
|
|
415
|
-
case "update-task": {
|
|
416
|
-
const input: Record<string, unknown> = {
|
|
417
|
-
id: args.commandArgs.id,
|
|
418
|
-
new_status: args.commandArgs["new-status"],
|
|
419
|
-
}
|
|
420
|
-
if (args.commandArgs["comment-title"] || args.commandArgs["comment-content"]) {
|
|
421
|
-
input.comment = {
|
|
422
|
-
title: args.commandArgs["comment-title"] ?? "",
|
|
423
|
-
content: args.commandArgs["comment-content"] ?? "",
|
|
424
|
-
kind: args.commandArgs["comment-kind"] ?? "regular",
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
if (!input.id || !input.new_status) {
|
|
428
|
-
throw new Error("Missing required arguments: id, new-status")
|
|
429
|
-
}
|
|
430
|
-
return toolUpdateTask(input, sessionId, layer)
|
|
431
|
-
}
|
|
432
|
-
case "edit-task": {
|
|
433
|
-
const input: Record<string, unknown> = { id: args.commandArgs.id }
|
|
434
|
-
if (args.commandArgs.title) input.title = args.commandArgs.title
|
|
435
|
-
if (args.commandArgs.description) input.description = args.commandArgs.description
|
|
436
|
-
if (args.commandArgs["definition-of-done"])
|
|
437
|
-
input.definition_of_done = args.commandArgs["definition-of-done"]
|
|
438
|
-
if (args.commandArgs["predicted-k-tokens"])
|
|
439
|
-
input.predictedKTokens = parseInt(args.commandArgs["predicted-k-tokens"], 10)
|
|
440
|
-
if (args.commandArgs.priority) input.priority = parseInt(args.commandArgs.priority, 10)
|
|
441
|
-
if (!input.id) {
|
|
442
|
-
throw new Error("Missing required argument: id")
|
|
443
|
-
}
|
|
444
|
-
return toolEditTask(input, layer)
|
|
445
|
-
}
|
|
446
|
-
default:
|
|
447
|
-
throw new Error(`Unknown command: ${args.command ?? "none"}`)
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
try {
|
|
452
|
-
const result = await dispatch()
|
|
453
|
-
output({ ok: true, ...(result as object) })
|
|
454
|
-
} catch (err) {
|
|
455
|
-
outputError(err, args.command ?? undefined)
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
const cleanup = async (sessionId: string): Promise<void> => {
|
|
460
|
-
try {
|
|
461
|
-
const tasksFile = process.env.LOGBOOK_TASKS_FILE ?? DEFAULT_TASKS_FILE
|
|
462
|
-
const { PidSessionRegistry } = await import("../infra/pid-session-registry.js")
|
|
463
|
-
const registry = new PidSessionRegistry(tasksFile)
|
|
464
|
-
await Effect.runPromise(registry.deregister(sessionId))
|
|
465
|
-
} catch {}
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
const main = async (): Promise<void> => {
|
|
469
|
-
const args = parseArgs()
|
|
470
|
-
|
|
471
|
-
if (!args.command) {
|
|
472
|
-
printHelp()
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
const sessionId = await getOrCreateSession(args.sessionId)
|
|
476
|
-
|
|
477
|
-
process.on("SIGINT", async () => {
|
|
478
|
-
await cleanup(sessionId)
|
|
479
|
-
process.exit(0)
|
|
480
|
-
})
|
|
481
|
-
process.on("SIGTERM", async () => {
|
|
482
|
-
await cleanup(sessionId)
|
|
483
|
-
process.exit(0)
|
|
484
|
-
})
|
|
485
|
-
|
|
486
|
-
await runCommand(args)
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
main()
|