@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
package/README.md
CHANGED
|
@@ -1,411 +1,342 @@
|
|
|
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
|
+
logbook init --mcp-client codex --no-linear
|
|
160
|
+
|
|
161
|
+
# workspace
|
|
162
|
+
logbook workspace:init
|
|
163
|
+
logbook workspace:status
|
|
164
|
+
|
|
165
|
+
# tasks
|
|
166
|
+
logbook task:create --title "x" --description "y" --definition-of-done "z" --project p --milestone m
|
|
167
|
+
logbook task:list --status "*"
|
|
168
|
+
logbook task:list --status in_progress
|
|
169
|
+
logbook task:current
|
|
170
|
+
logbook task:update --id <uuid> --new-status pending_review
|
|
171
|
+
logbook task:edit --id <uuid> --title "New title"
|
|
172
|
+
|
|
173
|
+
# epics and stories
|
|
174
|
+
logbook epic:create --title "Auth" --description "Login and session management" --outcome "Users can log in"
|
|
175
|
+
logbook story:create --epic-id <uuid> --title "JWT login" --description "..." --user-value "Users can authenticate"
|
|
176
|
+
|
|
177
|
+
# context
|
|
178
|
+
logbook context:create --title "Auth spec" --body "Use JWT RS256. See docs/auth.md."
|
|
179
|
+
logbook context:attach --context-entry-id <uuid> --task-id <uuid>
|
|
180
|
+
|
|
181
|
+
# Linear sync
|
|
182
|
+
logbook sync:linear:setup --team-url https://linear.app/<workspace>/team/<team>
|
|
183
|
+
logbook sync:linear:pull
|
|
184
|
+
logbook sync:linear:push --dry-run
|
|
185
|
+
logbook sync:linear:status
|
|
186
|
+
|
|
187
|
+
# v1 aliases (still work, emit a compatibility warning)
|
|
188
|
+
logbook create-task --title "..." --definition-of-done "..." --predicted-k-tokens 3
|
|
189
|
+
logbook list-tasks --status in_progress
|
|
176
190
|
```
|
|
177
191
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
> note: as mentioned, you can change .ts for any language, but the .yml / .yaml is required for configuration.
|
|
192
|
+
all commands write a single-line JSON envelope to stdout:
|
|
181
193
|
|
|
182
|
-
|
|
194
|
+
```json
|
|
195
|
+
{"ok":true,"data":{"task":{...}}}
|
|
196
|
+
{"ok":false,"error":{"code":"not_found","message":"task abc was not found"}}
|
|
197
|
+
```
|
|
183
198
|
|
|
184
|
-
|
|
199
|
+
## linear integration
|
|
185
200
|
|
|
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}
|
|
201
|
+
### setup
|
|
191
202
|
|
|
192
|
-
|
|
203
|
+
The preferred setup path is `logbook init`, which prompts for Linear sync setup.
|
|
204
|
+
To configure Linear separately:
|
|
193
205
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
206
|
+
1. create a Linear API key at **Linear → Settings → API → Personal API keys**
|
|
207
|
+
2. add it to `.env` or export it in your shell:
|
|
208
|
+
```bash
|
|
209
|
+
echo "LINEAR_API_KEY=lin_api_..." >> .env
|
|
210
|
+
```
|
|
211
|
+
3. configure Logbook from your Linear team URL:
|
|
212
|
+
```bash
|
|
213
|
+
logbook sync:linear:setup --team-url https://linear.app/bosun/team/BOSUN
|
|
214
|
+
```
|
|
197
215
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
DONE --> RD
|
|
216
|
+
The setup command resolves the workspace and team ids and writes the public config to `.logbook/config.json`.
|
|
217
|
+
It never writes the API key there. To let setup write `.env` for you, pass the token once:
|
|
201
218
|
|
|
202
|
-
|
|
219
|
+
```bash
|
|
220
|
+
logbook sync:linear:setup \
|
|
221
|
+
--team-url https://linear.app/bosun/team/BOSUN \
|
|
222
|
+
--api-token lin_api_... \
|
|
223
|
+
--write-env
|
|
203
224
|
```
|
|
204
225
|
|
|
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?
|
|
226
|
+
Manual setup is also supported:
|
|
215
227
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
228
|
+
```bash
|
|
229
|
+
logbook sync:linear:setup \
|
|
230
|
+
--workspace-id <workspace-id> \
|
|
231
|
+
--team-id <team-id>
|
|
232
|
+
```
|
|
219
233
|
|
|
220
|
-
|
|
234
|
+
This produces a `linear` block like:
|
|
221
235
|
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
236
|
+
```json
|
|
237
|
+
{
|
|
238
|
+
"linear": {
|
|
239
|
+
"apiTokenEnv": "LINEAR_API_KEY",
|
|
240
|
+
"workspaceId": "your-workspace-id",
|
|
241
|
+
"defaultTeamId": "your-team-id"
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
```
|
|
228
245
|
|
|
229
|
-
|
|
246
|
+
### pull / push
|
|
230
247
|
|
|
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
|
-
}
|
|
248
|
+
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
249
|
|
|
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
|
-
}
|
|
250
|
+
```bash
|
|
251
|
+
# pull issues from Linear since the last cursor
|
|
252
|
+
logbook sync:linear:pull
|
|
254
253
|
|
|
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
|
-
}
|
|
254
|
+
# pull with options
|
|
255
|
+
logbook sync:linear:pull --dry-run --team-id <id>
|
|
278
256
|
|
|
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
|
-
}
|
|
257
|
+
# push logbook tasks to Linear
|
|
258
|
+
logbook sync:linear:push
|
|
292
259
|
|
|
293
|
-
|
|
294
|
-
|
|
260
|
+
# push only specific tasks
|
|
261
|
+
logbook sync:linear:push --task-ids '["task_abc","task_xyz"]' --dry-run
|
|
295
262
|
|
|
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
|
-
}
|
|
263
|
+
# check status (connectivity + cursor position)
|
|
264
|
+
logbook sync:linear:status --check-provider
|
|
303
265
|
```
|
|
304
266
|
|
|
305
|
-
|
|
267
|
+
### conflicts
|
|
306
268
|
|
|
307
|
-
|
|
269
|
+
when the same record is modified in both logbook and Linear, a conflict entry is written to `sync-conflicts.jsonl`:
|
|
308
270
|
|
|
309
271
|
```bash
|
|
310
|
-
|
|
272
|
+
logbook sync:conflicts:list
|
|
273
|
+
logbook sync:conflicts:resolve --id <conflict-uuid> --resolution use_local
|
|
274
|
+
# resolutions: use_local | use_remote | manual
|
|
311
275
|
```
|
|
312
276
|
|
|
313
|
-
|
|
277
|
+
conflict states: `open` → `resolved` or `ignored`.
|
|
314
278
|
|
|
315
|
-
|
|
279
|
+
### external links
|
|
316
280
|
|
|
317
|
-
|
|
318
|
-
logbook --version
|
|
319
|
-
# or
|
|
320
|
-
logbook-mcp --version
|
|
321
|
-
```
|
|
281
|
+
bidirectional `linear:<id>` mappings are stored in `external-links.jsonl` and updated automatically by pull/push.
|
|
322
282
|
|
|
323
|
-
|
|
283
|
+
## hooks
|
|
324
284
|
|
|
325
|
-
|
|
285
|
+
hooks execute shell commands on task lifecycle events. configuration lives in `.logbook/hooks/<id>/config.json`:
|
|
326
286
|
|
|
327
|
-
|
|
287
|
+
```json
|
|
288
|
+
{
|
|
289
|
+
"id": "need-info-notify",
|
|
290
|
+
"event": "task.status_changed",
|
|
291
|
+
"condition": { "status": "need_info" },
|
|
292
|
+
"command": ["node", ".logbook/hooks/need-info-notify/script.mjs"],
|
|
293
|
+
"timeoutMs": 5000
|
|
294
|
+
}
|
|
295
|
+
```
|
|
328
296
|
|
|
329
|
-
|
|
330
|
-
- `tasks.jsonl` — the task store
|
|
331
|
-
- `hooks/` — directory for custom hooks
|
|
332
|
-
- `AGENTS.md` and `CLAUDE.md` — documentation for AI agents
|
|
297
|
+
two hooks are materialized by `workspace.init`:
|
|
333
298
|
|
|
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
|
|
299
|
+
- **`need-info-notify`** — prints the blocking comment when a task moves to `need_info`
|
|
300
|
+
- **`review-spawn`** — creates a review task and spawns a reviewer agent when a task moves to `pending_review`
|
|
338
301
|
|
|
339
|
-
|
|
302
|
+
hooks are stateless — execute and forget. the `command` field is an argv array; no shell expansion is performed.
|
|
340
303
|
|
|
341
|
-
|
|
304
|
+
## environment variables
|
|
342
305
|
|
|
343
306
|
| Variable | Default | Description |
|
|
344
307
|
|----------|---------|-------------|
|
|
345
|
-
| `
|
|
346
|
-
| `
|
|
347
|
-
| `
|
|
308
|
+
| `LOGBOOK_WORKSPACE_ROOT` | `process.cwd()` | workspace root used by the compiled binaries |
|
|
309
|
+
| `LOGBOOK_LOG_LEVEL` | `warn` | log level: `debug`, `info`, `warn`, `error` |
|
|
310
|
+
| `LINEAR_API_KEY` | — | Linear API token (or the env var named in `linear.apiTokenEnv`) |
|
|
348
311
|
|
|
349
|
-
|
|
312
|
+
## optional duckdb index
|
|
350
313
|
|
|
351
|
-
|
|
314
|
+
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
315
|
|
|
353
|
-
```
|
|
354
|
-
tasks
|
|
355
|
-
|
|
356
|
-
|
|
316
|
+
```sql
|
|
317
|
+
-- example: find all in_progress tasks for a specific project
|
|
318
|
+
SELECT id, title, status FROM read_json_auto('.logbook/storage/tasks.jsonl', format='newline_delimited')
|
|
319
|
+
WHERE status = 'in_progress' AND project = 'myapp'
|
|
357
320
|
```
|
|
358
321
|
|
|
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
|
|
322
|
+
the DuckDB path is opt-in via `workspace.status` and is non-canonical — the JSONL files remain the source of truth.
|
|
392
323
|
|
|
393
|
-
|
|
324
|
+
## migrating from v1
|
|
394
325
|
|
|
395
|
-
|
|
326
|
+
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
327
|
|
|
397
|
-
-
|
|
398
|
-
-
|
|
399
|
-
-
|
|
400
|
-
- if a condition throws or is malformed, the hook is skipped silently and execution continues — it fails safe.
|
|
328
|
+
- field names renamed from `snake_case` to `camelCase`
|
|
329
|
+
- `kind: "task"` injected on every record
|
|
330
|
+
- v1 comment shape converted to v2 shape
|
|
401
331
|
|
|
402
|
-
|
|
332
|
+
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
333
|
|
|
404
|
-
|
|
334
|
+
see `CHANGELOG.md` for the full v2.0.0 breaking-change list.
|
|
405
335
|
|
|
406
|
-
|
|
336
|
+
## stack
|
|
407
337
|
|
|
408
|
-
- **
|
|
409
|
-
- **
|
|
410
|
-
- **
|
|
411
|
-
- **
|
|
338
|
+
- **runtime**: Node.js / TypeScript
|
|
339
|
+
- **effect system**: Effect.ts — all async operations and errors modeled as `Effect<A, E, R>`
|
|
340
|
+
- **architecture**: ohtools plugin registry, hexagonal adapters (CLI + MCP), vertical slices per entity
|
|
341
|
+
- **persistence**: JSONL — append-only, one record per line, full-scan reads; DuckDB for optional ad-hoc queries
|
|
342
|
+
- **validation**: Zod at every public boundary (MCP input, CLI flags, filesystem reads)
|