@bosun-sh/logbook 1.1.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 +248 -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/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 +28 -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/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
package/README.md
CHANGED
|
@@ -1,411 +1,341 @@
|
|
|
1
|
-
# logbook
|
|
1
|
+
# logbook — kanban for ai agents
|
|
2
2
|
|
|
3
|
-
logbook is a kanban board
|
|
3
|
+
logbook is a file-system kanban board for autonomous AI agents. It tracks epics, stories, tasks, and context entries across a structured lifecycle so agents and humans share a single source of truth without context bloat.
|
|
4
4
|
|
|
5
|
-
→ **new here?** see [quickstart.md](quickstart.md) to get running in
|
|
5
|
+
→ **new here?** see [quickstart.md](quickstart.md) to get running in 5 minutes.
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## why logbook
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
autonomous agents work in parallel, forget context across sessions, and have no shared task state. logbook solves three problems:
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
- **human visibility** — agents record every task they touch in a file the whole team can read and diff
|
|
12
|
+
- **agent coordination** — `task.current` resolves FIFO per-session, so multiple agents can't claim the same task
|
|
13
|
+
- **context budget** — structured JSONL with a DuckDB optional query layer lets agents find relevant records without loading the whole store
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
- hard for agents to track tasks in-progress and done: **not a centralized way to track tasks so each instance haves to figure this out**
|
|
15
|
-
- existing tools add too much overload and are human-centered: **if an agent is going to use it, then it should be tailored for agents**
|
|
15
|
+
v2 adds: *epics → stories → tasks* hierarchy, reusable *context entries* (knowledge that survives across tasks), and Linear two-way sync as a first-class plugin.
|
|
16
16
|
|
|
17
|
-
##
|
|
18
|
-
|
|
19
|
-
logbook is a file-system based kanban board that uses jsonl files to enter one task per line in a structured and clean approach and gives the agent the right tools to use it:
|
|
20
|
-
|
|
21
|
-
### tools
|
|
22
|
-
|
|
23
|
-
- the agent can call `list_tasks(status)` and receive a list of the tasks in that status _(in_progress by default)_
|
|
24
|
-
- the agent can call `current_task()` and receive the highest-priority in_progress task for the current session, resolved via this priority chain:
|
|
25
|
-
|
|
26
|
-
| priority | condition | action |
|
|
27
|
-
|----------|-----------|--------|
|
|
28
|
-
| 1 | task already assigned to this session | return highest priority (tie-break: oldest) |
|
|
29
|
-
| 2 | unassigned `in_progress` task | claim highest priority, return |
|
|
30
|
-
| 3 | `in_progress` task with a dead-session assignee | claim highest priority, return |
|
|
31
|
-
| 4 | `todo` task | auto-transition highest priority to `in_progress`, claim, return |
|
|
32
|
-
| 5 | nothing available | fail with `no_current_task` |
|
|
33
|
-
- the agent can call `update_task(id, new_status, comment)` to transition a task, add a comment, or reply to a `need_info` blocking comment
|
|
34
|
-
- the agent can call `create_task(input)` to open a new task in `backlog`, passing `predictedKTokens` so the server derives a Fibonacci estimation automatically
|
|
35
|
-
- the agent can call `edit_task(id, updates)` to change mutable fields without altering status
|
|
36
|
-
|
|
37
|
-
each one of these tools has the sole purpose of removing overload from the agent context, handling the _"heavy load"_ programmatically on the MCP server or CLI.
|
|
38
|
-
|
|
39
|
-
### cli
|
|
40
|
-
|
|
41
|
-
in addition to the MCP server, logbook provides a CLI for direct command-line usage:
|
|
17
|
+
## quickstart
|
|
42
18
|
|
|
43
19
|
```bash
|
|
44
|
-
#
|
|
45
|
-
logbook
|
|
46
|
-
|
|
47
|
-
--
|
|
20
|
+
npm install -g @bosun-sh/logbook # install the CLI
|
|
21
|
+
logbook init # scaffold .logbook/, configure MCP, optionally set up Linear
|
|
22
|
+
logbook task:create \
|
|
23
|
+
--title "Implement login endpoint" \
|
|
24
|
+
--description "JWT auth, see docs/auth.md" \
|
|
25
|
+
--definition-of-done "Tests pass and endpoint is documented" \
|
|
26
|
+
--project myapp --milestone v1
|
|
27
|
+
logbook task:list --status "*"
|
|
28
|
+
```
|
|
48
29
|
|
|
49
|
-
|
|
50
|
-
logbook list-tasks --status in_progress
|
|
51
|
-
logbook list-tasks --status "*"
|
|
30
|
+
see [quickstart.md](quickstart.md) for the full walkthrough including Linear sync.
|
|
52
31
|
|
|
53
|
-
|
|
54
|
-
logbook
|
|
32
|
+
for one-off local use, run commands through your package manager, for example
|
|
33
|
+
`npx @bosun-sh/logbook --help` or `bunx @bosun-sh/logbook --help`.
|
|
55
34
|
|
|
56
|
-
|
|
57
|
-
logbook update-task --id <uuid> --new-status in_progress
|
|
35
|
+
## workspace layout
|
|
58
36
|
|
|
59
|
-
|
|
60
|
-
logbook edit-task --id <uuid> --title "New title"
|
|
37
|
+
`logbook init` creates the following structure through `workspace.init`:
|
|
61
38
|
|
|
62
|
-
# initialize project
|
|
63
|
-
logbook init
|
|
64
|
-
logbook init --force # ensures both AGENTS.md and CLAUDE.md exist
|
|
65
39
|
```
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
40
|
+
.logbook/
|
|
41
|
+
├── config.json # workspace config (Linear credentials, hook overrides)
|
|
42
|
+
├── workspace.json # workspace metadata
|
|
43
|
+
├── hooks/
|
|
44
|
+
│ ├── review-spawn/ # spawns a reviewer agent on pending_review
|
|
45
|
+
│ │ ├── config.json
|
|
46
|
+
│ │ └── script.mjs
|
|
47
|
+
│ └── need-info-notify/ # notifies user when a task needs info
|
|
48
|
+
│ ├── config.json
|
|
49
|
+
│ └── script.mjs
|
|
50
|
+
└── storage/
|
|
51
|
+
├── epics.jsonl
|
|
52
|
+
├── stories.jsonl
|
|
53
|
+
├── tasks.jsonl
|
|
54
|
+
├── context-entries.jsonl
|
|
55
|
+
├── external-links.jsonl
|
|
56
|
+
├── sync-events.jsonl
|
|
57
|
+
└── sync-conflicts.jsonl
|
|
72
58
|
```
|
|
73
59
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
## walkthrough
|
|
60
|
+
add `.logbook/storage/` to `.gitignore` to keep runtime data out of version control:
|
|
77
61
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
**1. agent starts — get current task**
|
|
81
|
-
|
|
82
|
-
```
|
|
83
|
-
current_task()
|
|
84
|
-
→ { id: "abc-123", title: "implement login endpoint", status: "in_progress", ... }
|
|
62
|
+
```gitignore
|
|
63
|
+
.logbook/storage/
|
|
85
64
|
```
|
|
86
65
|
|
|
87
|
-
|
|
66
|
+
## mcp tools by plugin
|
|
88
67
|
|
|
89
|
-
|
|
90
|
-
update_task("abc-123", "need_info", {
|
|
91
|
-
title: "which auth provider?",
|
|
92
|
-
content: "should i use jwt or session-based auth? the spec doesn't say.",
|
|
93
|
-
kind: "need_info"
|
|
94
|
-
})
|
|
95
|
-
→ hook fires: user is notified with the comment
|
|
96
|
-
```
|
|
68
|
+
connect `logbook mcp` as an MCP server and call any of the 38 tools below.
|
|
97
69
|
|
|
98
|
-
|
|
70
|
+
### task plugin
|
|
99
71
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
72
|
+
| Tool ID | Purpose |
|
|
73
|
+
|---------|---------|
|
|
74
|
+
| `task.create` | Create a task in backlog |
|
|
75
|
+
| `task.get` | Load one task by id |
|
|
76
|
+
| `task.list` | List tasks (default status: `in_progress`) |
|
|
77
|
+
| `task.current` | Claim and return the highest-priority in-progress task for this session |
|
|
78
|
+
| `task.update` | Transition task status, add comments, reply to need_info |
|
|
79
|
+
| `task.edit` | Edit mutable fields without status change |
|
|
80
|
+
| `task.assign.session` | Assign a session to a task |
|
|
81
|
+
| `task.assign.model` | Assign a model to a task |
|
|
82
|
+
| `task.assign.phase-model` | Set a per-phase model override |
|
|
83
|
+
| `task.estimate` | Compute or re-compute a Fibonacci estimation |
|
|
110
84
|
|
|
111
|
-
|
|
85
|
+
`task.current` priority chain: session-owned in_progress → unassigned in_progress → orphaned in_progress (dead session) → highest-priority todo (auto-transitions) → `no_current_task` error.
|
|
112
86
|
|
|
113
|
-
|
|
114
|
-
update_task("abc-123", "pending_review", {
|
|
115
|
-
title: "implementation complete",
|
|
116
|
-
content: "jwt login endpoint implemented, tests passing",
|
|
117
|
-
kind: "regular"
|
|
118
|
-
})
|
|
119
|
-
→ review-spawn hook fires: review task created, reviewer agent spawned
|
|
120
|
-
```
|
|
87
|
+
### epic plugin
|
|
121
88
|
|
|
122
|
-
|
|
89
|
+
| Tool ID | Purpose |
|
|
90
|
+
|---------|---------|
|
|
91
|
+
| `epic.create` | Create an epic |
|
|
92
|
+
| `epic.get` | Load one epic |
|
|
93
|
+
| `epic.list` | List epics |
|
|
94
|
+
| `epic.update` | Update an epic |
|
|
95
|
+
| `epic.delete` | Tombstone an epic |
|
|
123
96
|
|
|
124
|
-
|
|
125
|
-
# reviewer agent calls:
|
|
126
|
-
current_task() → gets the review task
|
|
127
|
-
update_task("<review-task-id>", "done")
|
|
128
|
-
→ original task abc-123 → done automatically
|
|
129
|
-
```
|
|
97
|
+
### story plugin
|
|
130
98
|
|
|
131
|
-
|
|
99
|
+
| Tool ID | Purpose |
|
|
100
|
+
|---------|---------|
|
|
101
|
+
| `story.create` | Create a story within an epic |
|
|
102
|
+
| `story.get` | Load one story |
|
|
103
|
+
| `story.list` | List stories |
|
|
104
|
+
| `story.update` | Update a story |
|
|
105
|
+
| `story.delete` | Tombstone a story |
|
|
132
106
|
|
|
133
|
-
|
|
107
|
+
### context plugin
|
|
134
108
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
109
|
+
| Tool ID | Purpose |
|
|
110
|
+
|---------|---------|
|
|
111
|
+
| `context.create` | Create a reusable context entry |
|
|
112
|
+
| `context.get` | Load one context entry |
|
|
113
|
+
| `context.list` | List context entries |
|
|
114
|
+
| `context.update` | Update a context entry |
|
|
115
|
+
| `context.delete` | Tombstone a context entry |
|
|
116
|
+
| `context.attach` | Attach a context entry to an epic, story, or task |
|
|
117
|
+
| `context.detach` | Remove an attachment |
|
|
118
|
+
| `context.search` | Full-text search over context entries |
|
|
138
119
|
|
|
139
|
-
|
|
120
|
+
### sync plugin (Linear)
|
|
140
121
|
|
|
141
|
-
|
|
122
|
+
| Tool ID | Purpose |
|
|
123
|
+
|---------|---------|
|
|
124
|
+
| `sync.linear.pull` | Pull issues from Linear into logbook (since-cursor pagination) |
|
|
125
|
+
| `sync.linear.push` | Push logbook tasks to Linear |
|
|
126
|
+
| `sync.linear.setup` | Configure Linear sync from a team URL or explicit ids |
|
|
127
|
+
| `sync.linear.status` | Check Linear configuration and connectivity |
|
|
128
|
+
| `sync.conflicts.list` | List unresolved sync conflicts |
|
|
129
|
+
| `sync.conflicts.resolve` | Resolve a conflict (`use_local`, `use_remote`, or `manual`) |
|
|
142
130
|
|
|
143
|
-
|
|
144
|
-
- **effect system**: Effect.ts — all async operations and errors are modeled as `Effect<A, E, R>`
|
|
145
|
-
- **architecture**: hexagonal (ports & adapters), organized by vertical slices per domain concept (task, hook)
|
|
146
|
-
- **validation**: Zod at every system boundary (MCP input, filesystem reads)
|
|
147
|
-
- **persistence**: JSONL — one task per line, append-only writes, full file scan for reads
|
|
131
|
+
### workspace plugin
|
|
148
132
|
|
|
149
|
-
|
|
133
|
+
| Tool ID | Purpose |
|
|
134
|
+
|---------|---------|
|
|
135
|
+
| `workspace.init` | Initialize or re-scaffold the `.logbook/` workspace |
|
|
136
|
+
| `workspace.status` | Report workspace health and provider status |
|
|
150
137
|
|
|
151
|
-
###
|
|
138
|
+
### hook plugin
|
|
152
139
|
|
|
153
|
-
|
|
154
|
-
|
|
140
|
+
| Tool ID | Purpose |
|
|
141
|
+
|---------|---------|
|
|
142
|
+
| `hook.list` | List registered hooks |
|
|
143
|
+
| `hook.run` | Run a hook manually |
|
|
155
144
|
|
|
156
|
-
|
|
157
|
-
- after moving a task to `pending_review`, a reviewer sub-agent spawns and a review task is automatically generated for it.
|
|
158
|
-
- when a second task is moved to `in_progress`, a built-in hook fires and requires a comment justifying the overlap before proceeding.
|
|
145
|
+
### plugin plugin
|
|
159
146
|
|
|
160
|
-
|
|
147
|
+
| Tool ID | Purpose |
|
|
148
|
+
|---------|---------|
|
|
149
|
+
| `plugin.list` | List all registered plugins and their tool IDs |
|
|
161
150
|
|
|
162
|
-
|
|
163
|
-
hooks/
|
|
164
|
-
└── example_hook/
|
|
165
|
-
├── config.yml
|
|
166
|
-
└── script.ts
|
|
167
|
-
```
|
|
151
|
+
## cli
|
|
168
152
|
|
|
169
|
-
|
|
153
|
+
every tool is available as `logbook <tool-id-with-colons>`:
|
|
170
154
|
|
|
171
|
-
```
|
|
172
|
-
#
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
155
|
+
```bash
|
|
156
|
+
# preferred onboarding
|
|
157
|
+
logbook init
|
|
158
|
+
logbook init --mcp-client claude --no-linear
|
|
159
|
+
|
|
160
|
+
# workspace
|
|
161
|
+
logbook workspace:init
|
|
162
|
+
logbook workspace:status
|
|
163
|
+
|
|
164
|
+
# tasks
|
|
165
|
+
logbook task:create --title "x" --description "y" --definition-of-done "z" --project p --milestone m
|
|
166
|
+
logbook task:list --status "*"
|
|
167
|
+
logbook task:list --status in_progress
|
|
168
|
+
logbook task:current
|
|
169
|
+
logbook task:update --id <uuid> --new-status pending_review
|
|
170
|
+
logbook task:edit --id <uuid> --title "New title"
|
|
171
|
+
|
|
172
|
+
# epics and stories
|
|
173
|
+
logbook epic:create --title "Auth" --description "Login and session management" --outcome "Users can log in"
|
|
174
|
+
logbook story:create --epic-id <uuid> --title "JWT login" --description "..." --user-value "Users can authenticate"
|
|
175
|
+
|
|
176
|
+
# context
|
|
177
|
+
logbook context:create --title "Auth spec" --body "Use JWT RS256. See docs/auth.md."
|
|
178
|
+
logbook context:attach --context-entry-id <uuid> --task-id <uuid>
|
|
179
|
+
|
|
180
|
+
# Linear sync
|
|
181
|
+
logbook sync:linear:setup --team-url https://linear.app/<workspace>/team/<team>
|
|
182
|
+
logbook sync:linear:pull
|
|
183
|
+
logbook sync:linear:push --dry-run
|
|
184
|
+
logbook sync:linear:status
|
|
185
|
+
|
|
186
|
+
# v1 aliases (still work, emit a compatibility warning)
|
|
187
|
+
logbook create-task --title "..." --definition-of-done "..." --predicted-k-tokens 3
|
|
188
|
+
logbook list-tasks --status in_progress
|
|
176
189
|
```
|
|
177
190
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
> note: as mentioned, you can change .ts for any language, but the .yml / .yaml is required for configuration.
|
|
191
|
+
all commands write a single-line JSON envelope to stdout:
|
|
181
192
|
|
|
182
|
-
|
|
193
|
+
```json
|
|
194
|
+
{"ok":true,"data":{"task":{...}}}
|
|
195
|
+
{"ok":false,"error":{"code":"not_found","message":"task abc was not found"}}
|
|
196
|
+
```
|
|
183
197
|
|
|
184
|
-
|
|
198
|
+
## linear integration
|
|
185
199
|
|
|
186
|
-
|
|
187
|
-
flowchart TD
|
|
188
|
-
PR[task: pending_review]
|
|
189
|
-
PR -->|review-spawn hook| SPAWN[review task created\nreviewer agent spawned]
|
|
190
|
-
SPAWN --> CL{classify findings}
|
|
200
|
+
### setup
|
|
191
201
|
|
|
192
|
-
|
|
202
|
+
The preferred setup path is `logbook init`, which prompts for Linear sync setup.
|
|
203
|
+
To configure Linear separately:
|
|
193
204
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
205
|
+
1. create a Linear API key at **Linear → Settings → API → Personal API keys**
|
|
206
|
+
2. add it to `.env` or export it in your shell:
|
|
207
|
+
```bash
|
|
208
|
+
echo "LINEAR_API_KEY=lin_api_..." >> .env
|
|
209
|
+
```
|
|
210
|
+
3. configure Logbook from your Linear team URL:
|
|
211
|
+
```bash
|
|
212
|
+
logbook sync:linear:setup --team-url https://linear.app/bosun/team/BOSUN
|
|
213
|
+
```
|
|
197
214
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
DONE --> RD
|
|
215
|
+
The setup command resolves the workspace and team ids and writes the public config to `.logbook/config.json`.
|
|
216
|
+
It never writes the API key there. To let setup write `.env` for you, pass the token once:
|
|
201
217
|
|
|
202
|
-
|
|
218
|
+
```bash
|
|
219
|
+
logbook sync:linear:setup \
|
|
220
|
+
--team-url https://linear.app/bosun/team/BOSUN \
|
|
221
|
+
--api-token lin_api_... \
|
|
222
|
+
--write-env
|
|
203
223
|
```
|
|
204
224
|
|
|
205
|
-
|
|
206
|
-
|-----------------|---------------|-------------|-------------|
|
|
207
|
-
| **must-fix** | `→ in_progress` + `need_info` | `→ done` | — |
|
|
208
|
-
| **consider** | `→ in_progress` + `need_info` | `→ done` | implementer replies: fix now or backlog |
|
|
209
|
-
| **nice-to-have** | unchanged | — | `[tech debt]` backlog task created |
|
|
210
|
-
| **clean** | `→ done` | `→ done` | — |
|
|
211
|
-
|
|
212
|
-
nice-to-have findings are always handled silently — they never block progress or ping the implementer.
|
|
213
|
-
|
|
214
|
-
#### why hooks?
|
|
225
|
+
Manual setup is also supported:
|
|
215
226
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
227
|
+
```bash
|
|
228
|
+
logbook sync:linear:setup \
|
|
229
|
+
--workspace-id <workspace-id> \
|
|
230
|
+
--team-id <team-id>
|
|
231
|
+
```
|
|
219
232
|
|
|
220
|
-
|
|
233
|
+
This produces a `linear` block like:
|
|
221
234
|
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
235
|
+
```json
|
|
236
|
+
{
|
|
237
|
+
"linear": {
|
|
238
|
+
"apiTokenEnv": "LINEAR_API_KEY",
|
|
239
|
+
"workspaceId": "your-workspace-id",
|
|
240
|
+
"defaultTeamId": "your-team-id"
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
```
|
|
228
244
|
|
|
229
|
-
|
|
245
|
+
### pull / push
|
|
230
246
|
|
|
231
|
-
|
|
232
|
-
id: string,
|
|
233
|
-
timestamp: Date,
|
|
234
|
-
title: string,
|
|
235
|
-
content: string,
|
|
236
|
-
reply: string, // user's reply, populated when responding to a need_info comment
|
|
237
|
-
kind: 'need_info' | 'regular' // drives the reply cycle — only need_info comments accept replies
|
|
238
|
-
}
|
|
247
|
+
when Logbook runs through MCP, task-facing tools automatically pull before the call and push successful task writes back to Linear. the explicit commands below are still available for manual refreshes, dry runs, and targeted syncs.
|
|
239
248
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
id: string,
|
|
244
|
-
title: string,
|
|
245
|
-
definition_of_done: string,
|
|
246
|
-
description: string,
|
|
247
|
-
estimation: number, // fibonacci number derived from predictedKTokens at creation time
|
|
248
|
-
comments: Comment[],
|
|
249
|
-
assignee: Agent,
|
|
250
|
-
status: Status,
|
|
251
|
-
in_progress_since?: Date // set when task enters in_progress; used as tie-breaker in current_task
|
|
252
|
-
priority: number // integer ≥ 0; higher = more urgent; defaults to 0
|
|
253
|
-
}
|
|
249
|
+
```bash
|
|
250
|
+
# pull issues from Linear since the last cursor
|
|
251
|
+
logbook sync:linear:pull
|
|
254
252
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
type ListTasks = (options: { status: Status | '*', project?: string, milestone?: string }) => Task[]
|
|
258
|
-
|
|
259
|
-
// returns the highest-priority task for the current session using a priority chain:
|
|
260
|
-
// 1. own in_progress → 2. unassigned in_progress → 3. orphaned in_progress
|
|
261
|
-
// (dead-session assignee) → 4. highest-priority todo (auto-transitioned) → 5. no_current_task error.
|
|
262
|
-
// within each step, tasks are ordered by priority DESC, tie-broken by in_progress_since ASC.
|
|
263
|
-
// if a second task is moved to in_progress, a built-in hook fires and
|
|
264
|
-
// requires a comment justifying the overlap.
|
|
265
|
-
type GetCurrentTask = () => Task
|
|
266
|
-
|
|
267
|
-
// transitions a task to a new status; sessionId is injected server-side.
|
|
268
|
-
// to reply to a need_info comment, pass a comment with the existing comment's id and a reply string.
|
|
269
|
-
type UpdateTask = (id: string, new_status: Status, comment: CommentInput | null, sessionId: string) => void
|
|
270
|
-
|
|
271
|
-
type CommentInput = {
|
|
272
|
-
id?: string, // existing comment id — only when replying to a need_info comment
|
|
273
|
-
title: string,
|
|
274
|
-
content: string,
|
|
275
|
-
reply?: string, // reply text — only meaningful when id refers to a need_info comment
|
|
276
|
-
kind: 'need_info' | 'regular'
|
|
277
|
-
}
|
|
253
|
+
# pull with options
|
|
254
|
+
logbook sync:linear:pull --dry-run --team-id <id>
|
|
278
255
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
type CreateTask = (input: CreateTaskInput, sessionId: string) => Task
|
|
282
|
-
|
|
283
|
-
type CreateTaskInput = {
|
|
284
|
-
project: string,
|
|
285
|
-
milestone: string,
|
|
286
|
-
title: string,
|
|
287
|
-
definition_of_done: string,
|
|
288
|
-
description: string,
|
|
289
|
-
predictedKTokens: number, // positive number; server maps this to a Fibonacci estimation (max 20)
|
|
290
|
-
priority?: number // integer ≥ 0; defaults to 0
|
|
291
|
-
}
|
|
256
|
+
# push logbook tasks to Linear
|
|
257
|
+
logbook sync:linear:push
|
|
292
258
|
|
|
293
|
-
|
|
294
|
-
|
|
259
|
+
# push only specific tasks
|
|
260
|
+
logbook sync:linear:push --task-ids '["task_abc","task_xyz"]' --dry-run
|
|
295
261
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
description?: string,
|
|
299
|
-
definition_of_done?: string,
|
|
300
|
-
predictedKTokens?: number, // re-derives estimation if provided
|
|
301
|
-
priority?: number // integer ≥ 0; re-assigns priority if provided
|
|
302
|
-
}
|
|
262
|
+
# check status (connectivity + cursor position)
|
|
263
|
+
logbook sync:linear:status --check-provider
|
|
303
264
|
```
|
|
304
265
|
|
|
305
|
-
|
|
266
|
+
### conflicts
|
|
306
267
|
|
|
307
|
-
|
|
268
|
+
when the same record is modified in both logbook and Linear, a conflict entry is written to `sync-conflicts.jsonl`:
|
|
308
269
|
|
|
309
270
|
```bash
|
|
310
|
-
|
|
271
|
+
logbook sync:conflicts:list
|
|
272
|
+
logbook sync:conflicts:resolve --id <conflict-uuid> --resolution use_local
|
|
273
|
+
# resolutions: use_local | use_remote | manual
|
|
311
274
|
```
|
|
312
275
|
|
|
313
|
-
|
|
276
|
+
conflict states: `open` → `resolved` or `ignored`.
|
|
314
277
|
|
|
315
|
-
|
|
278
|
+
### external links
|
|
316
279
|
|
|
317
|
-
|
|
318
|
-
logbook --version
|
|
319
|
-
# or
|
|
320
|
-
logbook-mcp --version
|
|
321
|
-
```
|
|
280
|
+
bidirectional `linear:<id>` mappings are stored in `external-links.jsonl` and updated automatically by pull/push.
|
|
322
281
|
|
|
323
|
-
|
|
282
|
+
## hooks
|
|
324
283
|
|
|
325
|
-
|
|
284
|
+
hooks execute shell commands on task lifecycle events. configuration lives in `.logbook/hooks/<id>/config.json`:
|
|
326
285
|
|
|
327
|
-
|
|
286
|
+
```json
|
|
287
|
+
{
|
|
288
|
+
"id": "need-info-notify",
|
|
289
|
+
"event": "task.status_changed",
|
|
290
|
+
"condition": { "status": "need_info" },
|
|
291
|
+
"command": ["node", ".logbook/hooks/need-info-notify/script.mjs"],
|
|
292
|
+
"timeoutMs": 5000
|
|
293
|
+
}
|
|
294
|
+
```
|
|
328
295
|
|
|
329
|
-
|
|
330
|
-
- `tasks.jsonl` — the task store
|
|
331
|
-
- `hooks/` — directory for custom hooks
|
|
332
|
-
- `AGENTS.md` and `CLAUDE.md` — documentation for AI agents
|
|
296
|
+
two hooks are materialized by `workspace.init`:
|
|
333
297
|
|
|
334
|
-
|
|
335
|
-
-
|
|
336
|
-
- if only AGENTS.md exists → appends logbook docs to AGENTS.md
|
|
337
|
-
- if only CLAUDE.md exists → appends logbook docs to CLAUDE.md
|
|
298
|
+
- **`need-info-notify`** — prints the blocking comment when a task moves to `need_info`
|
|
299
|
+
- **`review-spawn`** — creates a review task and spawns a reviewer agent when a task moves to `pending_review`
|
|
338
300
|
|
|
339
|
-
|
|
301
|
+
hooks are stateless — execute and forget. the `command` field is an argv array; no shell expansion is performed.
|
|
340
302
|
|
|
341
|
-
|
|
303
|
+
## environment variables
|
|
342
304
|
|
|
343
305
|
| Variable | Default | Description |
|
|
344
306
|
|----------|---------|-------------|
|
|
345
|
-
| `
|
|
346
|
-
| `
|
|
347
|
-
| `
|
|
307
|
+
| `LOGBOOK_WORKSPACE_ROOT` | `process.cwd()` | workspace root used by the compiled binaries |
|
|
308
|
+
| `LOGBOOK_LOG_LEVEL` | `warn` | log level: `debug`, `info`, `warn`, `error` |
|
|
309
|
+
| `LINEAR_API_KEY` | — | Linear API token (or the env var named in `linear.apiTokenEnv`) |
|
|
348
310
|
|
|
349
|
-
|
|
311
|
+
## optional duckdb index
|
|
350
312
|
|
|
351
|
-
|
|
313
|
+
logbook uses `@duckdb/node-api` to run ad-hoc SQL over the canonical JSONL files. the index is in-memory — no separate index file is written or maintained:
|
|
352
314
|
|
|
353
|
-
```
|
|
354
|
-
tasks
|
|
355
|
-
|
|
356
|
-
|
|
315
|
+
```sql
|
|
316
|
+
-- example: find all in_progress tasks for a specific project
|
|
317
|
+
SELECT id, title, status FROM read_json_auto('.logbook/storage/tasks.jsonl', format='newline_delimited')
|
|
318
|
+
WHERE status = 'in_progress' AND project = 'myapp'
|
|
357
319
|
```
|
|
358
320
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
### client setup
|
|
362
|
-
|
|
363
|
-
**Claude Code** — add to `.claude/settings.json`:
|
|
364
|
-
|
|
365
|
-
```json
|
|
366
|
-
{
|
|
367
|
-
"mcpServers": {
|
|
368
|
-
"logbook": {
|
|
369
|
-
"command": "logbook-mcp"
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
```
|
|
374
|
-
|
|
375
|
-
**OpenCode** — add to `opencode.json`:
|
|
376
|
-
|
|
377
|
-
```json
|
|
378
|
-
{
|
|
379
|
-
"mcp": {
|
|
380
|
-
"logbook": {
|
|
381
|
-
"type": "local",
|
|
382
|
-
"command": ["logbook-mcp"],
|
|
383
|
-
"enabled": true
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
```
|
|
388
|
-
|
|
389
|
-
## security
|
|
390
|
-
|
|
391
|
-
### hook conditions are trusted code
|
|
321
|
+
the DuckDB path is opt-in via `workspace.status` and is non-canonical — the JSONL files remain the source of truth.
|
|
392
322
|
|
|
393
|
-
|
|
323
|
+
## migrating from v1
|
|
394
324
|
|
|
395
|
-
|
|
325
|
+
if your project has a `tasks.jsonl` at the repository root, `workspace.init` detects it and migrates all records to `.logbook/storage/tasks.jsonl` automatically:
|
|
396
326
|
|
|
397
|
-
-
|
|
398
|
-
-
|
|
399
|
-
-
|
|
400
|
-
- if a condition throws or is malformed, the hook is skipped silently and execution continues — it fails safe.
|
|
327
|
+
- field names renamed from `snake_case` to `camelCase`
|
|
328
|
+
- `kind: "task"` injected on every record
|
|
329
|
+
- v1 comment shape converted to v2 shape
|
|
401
330
|
|
|
402
|
-
|
|
331
|
+
v1 CLI commands (`create-task`, `list-tasks`, `current-task`, `update-task`, `edit-task`, `init`) remain registered and emit a `compatibility_mapping_applied` warning. remove the deprecated commands from your scripts when ready.
|
|
403
332
|
|
|
404
|
-
|
|
333
|
+
see `CHANGELOG.md` for the full v2.0.0 breaking-change list.
|
|
405
334
|
|
|
406
|
-
|
|
335
|
+
## stack
|
|
407
336
|
|
|
408
|
-
- **
|
|
409
|
-
- **
|
|
410
|
-
- **
|
|
411
|
-
- **
|
|
337
|
+
- **runtime**: Node.js / TypeScript
|
|
338
|
+
- **effect system**: Effect.ts — all async operations and errors modeled as `Effect<A, E, R>`
|
|
339
|
+
- **architecture**: ohtools plugin registry, hexagonal adapters (CLI + MCP), vertical slices per entity
|
|
340
|
+
- **persistence**: JSONL — append-only, one record per line, full-scan reads; DuckDB for optional ad-hoc queries
|
|
341
|
+
- **validation**: Zod at every public boundary (MCP input, CLI flags, filesystem reads)
|