opentasks 0.0.6 → 0.0.7
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/README.md +68 -0
- package/dist/__tests__/cli-tools.test.d.ts +8 -0
- package/dist/__tests__/cli-tools.test.d.ts.map +1 -0
- package/dist/__tests__/cli-tools.test.js +546 -0
- package/dist/__tests__/cli-tools.test.js.map +1 -0
- package/dist/__tests__/cli.test.d.ts +5 -0
- package/dist/__tests__/cli.test.d.ts.map +1 -0
- package/dist/__tests__/cli.test.js +77 -0
- package/dist/__tests__/cli.test.js.map +1 -0
- package/dist/__tests__/p1-p3-gaps.test.d.ts +2 -0
- package/dist/__tests__/p1-p3-gaps.test.d.ts.map +1 -0
- package/dist/__tests__/p1-p3-gaps.test.js +463 -0
- package/dist/__tests__/p1-p3-gaps.test.js.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +64 -0
- package/dist/cli.js.map +1 -1
- package/dist/client/__tests__/client-crud.test.d.ts +7 -0
- package/dist/client/__tests__/client-crud.test.d.ts.map +1 -0
- package/dist/client/__tests__/client-crud.test.js +404 -0
- package/dist/client/__tests__/client-crud.test.js.map +1 -0
- package/dist/client/__tests__/client.test.d.ts +5 -0
- package/dist/client/__tests__/client.test.d.ts.map +1 -0
- package/dist/client/__tests__/client.test.js +518 -0
- package/dist/client/__tests__/client.test.js.map +1 -0
- package/dist/client/client.d.ts +47 -1
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js +71 -0
- package/dist/client/client.js.map +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/config/__tests__/defaults.test.d.ts +2 -0
- package/dist/config/__tests__/defaults.test.d.ts.map +1 -0
- package/dist/config/__tests__/defaults.test.js +57 -0
- package/dist/config/__tests__/defaults.test.js.map +1 -0
- package/dist/config/__tests__/env.test.d.ts +2 -0
- package/dist/config/__tests__/env.test.d.ts.map +1 -0
- package/dist/config/__tests__/env.test.js +136 -0
- package/dist/config/__tests__/env.test.js.map +1 -0
- package/dist/config/__tests__/index.test.d.ts +2 -0
- package/dist/config/__tests__/index.test.d.ts.map +1 -0
- package/dist/config/__tests__/index.test.js +113 -0
- package/dist/config/__tests__/index.test.js.map +1 -0
- package/dist/config/__tests__/loader.test.d.ts +2 -0
- package/dist/config/__tests__/loader.test.d.ts.map +1 -0
- package/dist/config/__tests__/loader.test.js +128 -0
- package/dist/config/__tests__/loader.test.js.map +1 -0
- package/dist/config/__tests__/merge.test.d.ts +2 -0
- package/dist/config/__tests__/merge.test.d.ts.map +1 -0
- package/dist/config/__tests__/merge.test.js +79 -0
- package/dist/config/__tests__/merge.test.js.map +1 -0
- package/dist/config/__tests__/schema.test.d.ts +2 -0
- package/dist/config/__tests__/schema.test.d.ts.map +1 -0
- package/dist/config/__tests__/schema.test.js +300 -0
- package/dist/config/__tests__/schema.test.js.map +1 -0
- package/dist/config/schema.d.ts +178 -4
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +109 -7
- package/dist/config/schema.js.map +1 -1
- package/dist/context-files/context-files.d.ts +72 -0
- package/dist/context-files/context-files.d.ts.map +1 -0
- package/dist/context-files/context-files.js +145 -0
- package/dist/context-files/context-files.js.map +1 -0
- package/dist/context-files/index.d.ts +16 -0
- package/dist/context-files/index.d.ts.map +1 -0
- package/dist/context-files/index.js +14 -0
- package/dist/context-files/index.js.map +1 -0
- package/dist/context-files/resolver.d.ts +43 -0
- package/dist/context-files/resolver.d.ts.map +1 -0
- package/dist/context-files/resolver.js +127 -0
- package/dist/context-files/resolver.js.map +1 -0
- package/dist/context-files/types.d.ts +94 -0
- package/dist/context-files/types.d.ts.map +1 -0
- package/dist/context-files/types.js +10 -0
- package/dist/context-files/types.js.map +1 -0
- package/dist/context-files/watcher-integration.d.ts +47 -0
- package/dist/context-files/watcher-integration.d.ts.map +1 -0
- package/dist/context-files/watcher-integration.js +47 -0
- package/dist/context-files/watcher-integration.js.map +1 -0
- package/dist/core/__tests__/conditional-redirects.test.d.ts +2 -0
- package/dist/core/__tests__/conditional-redirects.test.d.ts.map +1 -0
- package/dist/core/__tests__/conditional-redirects.test.js +83 -0
- package/dist/core/__tests__/conditional-redirects.test.js.map +1 -0
- package/dist/core/__tests__/connections.test.d.ts +2 -0
- package/dist/core/__tests__/connections.test.d.ts.map +1 -0
- package/dist/core/__tests__/connections.test.js +158 -0
- package/dist/core/__tests__/connections.test.js.map +1 -0
- package/dist/core/__tests__/hash.test.d.ts +2 -0
- package/dist/core/__tests__/hash.test.d.ts.map +1 -0
- package/dist/core/__tests__/hash.test.js +139 -0
- package/dist/core/__tests__/hash.test.js.map +1 -0
- package/dist/core/__tests__/id.test.d.ts +2 -0
- package/dist/core/__tests__/id.test.d.ts.map +1 -0
- package/dist/core/__tests__/id.test.js +142 -0
- package/dist/core/__tests__/id.test.js.map +1 -0
- package/dist/core/__tests__/location.test.d.ts +2 -0
- package/dist/core/__tests__/location.test.d.ts.map +1 -0
- package/dist/core/__tests__/location.test.js +77 -0
- package/dist/core/__tests__/location.test.js.map +1 -0
- package/dist/core/__tests__/merge-driver.test.d.ts +2 -0
- package/dist/core/__tests__/merge-driver.test.d.ts.map +1 -0
- package/dist/core/__tests__/merge-driver.test.js +218 -0
- package/dist/core/__tests__/merge-driver.test.js.map +1 -0
- package/dist/core/__tests__/redirects.test.d.ts +2 -0
- package/dist/core/__tests__/redirects.test.d.ts.map +1 -0
- package/dist/core/__tests__/redirects.test.js +123 -0
- package/dist/core/__tests__/redirects.test.js.map +1 -0
- package/dist/core/__tests__/resolve-location-target.test.d.ts +8 -0
- package/dist/core/__tests__/resolve-location-target.test.d.ts.map +1 -0
- package/dist/core/__tests__/resolve-location-target.test.js +303 -0
- package/dist/core/__tests__/resolve-location-target.test.js.map +1 -0
- package/dist/core/__tests__/uri.test.d.ts +2 -0
- package/dist/core/__tests__/uri.test.d.ts.map +1 -0
- package/dist/core/__tests__/uri.test.js +159 -0
- package/dist/core/__tests__/uri.test.js.map +1 -0
- package/dist/core/__tests__/worktree.test.d.ts +2 -0
- package/dist/core/__tests__/worktree.test.d.ts.map +1 -0
- package/dist/core/__tests__/worktree.test.js +120 -0
- package/dist/core/__tests__/worktree.test.js.map +1 -0
- package/dist/core/merge-driver.d.ts +5 -0
- package/dist/core/merge-driver.d.ts.map +1 -1
- package/dist/core/merge-driver.js +35 -0
- package/dist/core/merge-driver.js.map +1 -1
- package/dist/daemon/__tests__/flush.test.d.ts +5 -0
- package/dist/daemon/__tests__/flush.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/flush.test.js +213 -0
- package/dist/daemon/__tests__/flush.test.js.map +1 -0
- package/dist/daemon/__tests__/integration.test.d.ts +7 -0
- package/dist/daemon/__tests__/integration.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/integration.test.js +276 -0
- package/dist/daemon/__tests__/integration.test.js.map +1 -0
- package/dist/daemon/__tests__/ipc.test.d.ts +5 -0
- package/dist/daemon/__tests__/ipc.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/ipc.test.js +314 -0
- package/dist/daemon/__tests__/ipc.test.js.map +1 -0
- package/dist/daemon/__tests__/lifecycle.test.d.ts +5 -0
- package/dist/daemon/__tests__/lifecycle.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/lifecycle.test.js +301 -0
- package/dist/daemon/__tests__/lifecycle.test.js.map +1 -0
- package/dist/daemon/__tests__/lock.test.d.ts +5 -0
- package/dist/daemon/__tests__/lock.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/lock.test.js +192 -0
- package/dist/daemon/__tests__/lock.test.js.map +1 -0
- package/dist/daemon/__tests__/methods/graph.test.d.ts +5 -0
- package/dist/daemon/__tests__/methods/graph.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/methods/graph.test.js +309 -0
- package/dist/daemon/__tests__/methods/graph.test.js.map +1 -0
- package/dist/daemon/__tests__/methods/provider.test.d.ts +7 -0
- package/dist/daemon/__tests__/methods/provider.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/methods/provider.test.js +181 -0
- package/dist/daemon/__tests__/methods/provider.test.js.map +1 -0
- package/dist/daemon/__tests__/methods/tools.test.d.ts +5 -0
- package/dist/daemon/__tests__/methods/tools.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/methods/tools.test.js +587 -0
- package/dist/daemon/__tests__/methods/tools.test.js.map +1 -0
- package/dist/daemon/__tests__/multi-location.test.d.ts +8 -0
- package/dist/daemon/__tests__/multi-location.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/multi-location.test.js +669 -0
- package/dist/daemon/__tests__/multi-location.test.js.map +1 -0
- package/dist/daemon/__tests__/registry.test.d.ts +5 -0
- package/dist/daemon/__tests__/registry.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/registry.test.js +208 -0
- package/dist/daemon/__tests__/registry.test.js.map +1 -0
- package/dist/daemon/__tests__/watcher.test.d.ts +5 -0
- package/dist/daemon/__tests__/watcher.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/watcher.test.js +234 -0
- package/dist/daemon/__tests__/watcher.test.js.map +1 -0
- package/dist/daemon/index.d.ts +6 -4
- package/dist/daemon/index.d.ts.map +1 -1
- package/dist/daemon/index.js +3 -2
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon/ipc.d.ts.map +1 -1
- package/dist/daemon/ipc.js +8 -1
- package/dist/daemon/ipc.js.map +1 -1
- package/dist/daemon/lifecycle.d.ts.map +1 -1
- package/dist/daemon/lifecycle.js +138 -25
- package/dist/daemon/lifecycle.js.map +1 -1
- package/dist/daemon/location-state.d.ts +12 -6
- package/dist/daemon/location-state.d.ts.map +1 -1
- package/dist/daemon/location-state.js +50 -20
- package/dist/daemon/location-state.js.map +1 -1
- package/dist/daemon/methods/__tests__/graph.test.d.ts +5 -0
- package/dist/daemon/methods/__tests__/graph.test.d.ts.map +1 -0
- package/dist/daemon/methods/__tests__/graph.test.js +274 -0
- package/dist/daemon/methods/__tests__/graph.test.js.map +1 -0
- package/dist/daemon/methods/__tests__/provider.test.d.ts +5 -0
- package/dist/daemon/methods/__tests__/provider.test.d.ts.map +1 -0
- package/dist/daemon/methods/__tests__/provider.test.js +184 -0
- package/dist/daemon/methods/__tests__/provider.test.js.map +1 -0
- package/dist/daemon/methods/__tests__/tools.test.d.ts +5 -0
- package/dist/daemon/methods/__tests__/tools.test.d.ts.map +1 -0
- package/dist/daemon/methods/__tests__/tools.test.js +295 -0
- package/dist/daemon/methods/__tests__/tools.test.js.map +1 -0
- package/dist/daemon/methods/context-files.d.ts +14 -0
- package/dist/daemon/methods/context-files.d.ts.map +1 -0
- package/dist/daemon/methods/context-files.js +95 -0
- package/dist/daemon/methods/context-files.js.map +1 -0
- package/dist/daemon/methods/provider.d.ts.map +1 -1
- package/dist/daemon/methods/provider.js +15 -0
- package/dist/daemon/methods/provider.js.map +1 -1
- package/dist/daemon/methods/tools.d.ts +1 -1
- package/dist/daemon/methods/tools.d.ts.map +1 -1
- package/dist/daemon/methods/tools.js +3 -2
- package/dist/daemon/methods/tools.js.map +1 -1
- package/dist/daemon/sessionlog-linker.d.ts +71 -0
- package/dist/daemon/sessionlog-linker.d.ts.map +1 -0
- package/dist/daemon/sessionlog-linker.js +472 -0
- package/dist/daemon/sessionlog-linker.js.map +1 -0
- package/dist/daemon/sessionlog-watcher.d.ts +79 -0
- package/dist/daemon/sessionlog-watcher.d.ts.map +1 -0
- package/dist/daemon/sessionlog-watcher.js +289 -0
- package/dist/daemon/sessionlog-watcher.js.map +1 -0
- package/dist/graph/__tests__/EdgeTypeRegistry.test.d.ts +2 -0
- package/dist/graph/__tests__/EdgeTypeRegistry.test.d.ts.map +1 -0
- package/dist/graph/__tests__/EdgeTypeRegistry.test.js +212 -0
- package/dist/graph/__tests__/EdgeTypeRegistry.test.js.map +1 -0
- package/dist/graph/__tests__/FederatedGraph.test.d.ts +2 -0
- package/dist/graph/__tests__/FederatedGraph.test.d.ts.map +1 -0
- package/dist/graph/__tests__/FederatedGraph.test.js +661 -0
- package/dist/graph/__tests__/FederatedGraph.test.js.map +1 -0
- package/dist/graph/__tests__/GraphologyAdapter.test.d.ts +2 -0
- package/dist/graph/__tests__/GraphologyAdapter.test.d.ts.map +1 -0
- package/dist/graph/__tests__/GraphologyAdapter.test.js +326 -0
- package/dist/graph/__tests__/GraphologyAdapter.test.js.map +1 -0
- package/dist/graph/__tests__/HydratingFederatedGraph.test.d.ts +2 -0
- package/dist/graph/__tests__/HydratingFederatedGraph.test.d.ts.map +1 -0
- package/dist/graph/__tests__/HydratingFederatedGraph.test.js +587 -0
- package/dist/graph/__tests__/HydratingFederatedGraph.test.js.map +1 -0
- package/dist/graph/__tests__/debounce.test.d.ts +5 -0
- package/dist/graph/__tests__/debounce.test.d.ts.map +1 -0
- package/dist/graph/__tests__/debounce.test.js +195 -0
- package/dist/graph/__tests__/debounce.test.js.map +1 -0
- package/dist/graph/__tests__/edge-cases.test.d.ts +8 -0
- package/dist/graph/__tests__/edge-cases.test.d.ts.map +1 -0
- package/dist/graph/__tests__/edge-cases.test.js +472 -0
- package/dist/graph/__tests__/edge-cases.test.js.map +1 -0
- package/dist/graph/__tests__/expansion.test.d.ts +2 -0
- package/dist/graph/__tests__/expansion.test.d.ts.map +1 -0
- package/dist/graph/__tests__/expansion.test.js +105 -0
- package/dist/graph/__tests__/expansion.test.js.map +1 -0
- package/dist/graph/__tests__/provider-store.test.d.ts +5 -0
- package/dist/graph/__tests__/provider-store.test.d.ts.map +1 -0
- package/dist/graph/__tests__/provider-store.test.js +791 -0
- package/dist/graph/__tests__/provider-store.test.js.map +1 -0
- package/dist/graph/__tests__/query.test.d.ts +5 -0
- package/dist/graph/__tests__/query.test.d.ts.map +1 -0
- package/dist/graph/__tests__/query.test.js +774 -0
- package/dist/graph/__tests__/query.test.js.map +1 -0
- package/dist/graph/__tests__/store.test.d.ts +5 -0
- package/dist/graph/__tests__/store.test.d.ts.map +1 -0
- package/dist/graph/__tests__/store.test.js +489 -0
- package/dist/graph/__tests__/store.test.js.map +1 -0
- package/dist/graph/__tests__/sync.test.d.ts +5 -0
- package/dist/graph/__tests__/sync.test.d.ts.map +1 -0
- package/dist/graph/__tests__/sync.test.js +129 -0
- package/dist/graph/__tests__/sync.test.js.map +1 -0
- package/dist/graph/__tests__/validation.test.d.ts +2 -0
- package/dist/graph/__tests__/validation.test.d.ts.map +1 -0
- package/dist/graph/__tests__/validation.test.js +521 -0
- package/dist/graph/__tests__/validation.test.js.map +1 -0
- package/dist/graph/index.d.ts +1 -1
- package/dist/graph/index.d.ts.map +1 -1
- package/dist/graph/index.js.map +1 -1
- package/dist/graph/provider-store.d.ts +78 -4
- package/dist/graph/provider-store.d.ts.map +1 -1
- package/dist/graph/provider-store.js +579 -55
- package/dist/graph/provider-store.js.map +1 -1
- package/dist/graph/store.d.ts.map +1 -1
- package/dist/graph/store.js +3 -0
- package/dist/graph/store.js.map +1 -1
- package/dist/graph/types.d.ts +16 -0
- package/dist/graph/types.d.ts.map +1 -1
- package/dist/graph/types.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -3
- package/dist/index.js.map +1 -1
- package/dist/materialization/git-archive-store.js +2 -2
- package/dist/materialization/git-archive-store.js.map +1 -1
- package/dist/materialization/git-remote-store.js +2 -2
- package/dist/materialization/git-remote-store.js.map +1 -1
- package/dist/materialization/snapshot.js +4 -4
- package/dist/materialization/snapshot.js.map +1 -1
- package/dist/mcp/index.d.ts +8 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +8 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/server.d.ts +39 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +677 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/stdio.d.ts +14 -0
- package/dist/mcp/stdio.d.ts.map +1 -0
- package/dist/mcp/stdio.js +19 -0
- package/dist/mcp/stdio.js.map +1 -0
- package/dist/providers/__tests__/beads.test.d.ts +5 -0
- package/dist/providers/__tests__/beads.test.d.ts.map +1 -0
- package/dist/providers/__tests__/beads.test.js +591 -0
- package/dist/providers/__tests__/beads.test.js.map +1 -0
- package/dist/providers/__tests__/claude-tasks.test.d.ts +5 -0
- package/dist/providers/__tests__/claude-tasks.test.d.ts.map +1 -0
- package/dist/providers/__tests__/claude-tasks.test.js +392 -0
- package/dist/providers/__tests__/claude-tasks.test.js.map +1 -0
- package/dist/providers/__tests__/from-config.test.d.ts +5 -0
- package/dist/providers/__tests__/from-config.test.d.ts.map +1 -0
- package/dist/providers/__tests__/from-config.test.js +152 -0
- package/dist/providers/__tests__/from-config.test.js.map +1 -0
- package/dist/providers/__tests__/materialization.test.d.ts +5 -0
- package/dist/providers/__tests__/materialization.test.d.ts.map +1 -0
- package/dist/providers/__tests__/materialization.test.js +407 -0
- package/dist/providers/__tests__/materialization.test.js.map +1 -0
- package/dist/providers/__tests__/native.test.d.ts +5 -0
- package/dist/providers/__tests__/native.test.d.ts.map +1 -0
- package/dist/providers/__tests__/native.test.js +566 -0
- package/dist/providers/__tests__/native.test.js.map +1 -0
- package/dist/providers/__tests__/registry.test.d.ts +5 -0
- package/dist/providers/__tests__/registry.test.d.ts.map +1 -0
- package/dist/providers/__tests__/registry.test.js +183 -0
- package/dist/providers/__tests__/registry.test.js.map +1 -0
- package/dist/providers/beads.d.ts.map +1 -1
- package/dist/providers/beads.js +17 -1
- package/dist/providers/beads.js.map +1 -1
- package/dist/providers/claude-tasks-fs.d.ts +22 -0
- package/dist/providers/claude-tasks-fs.d.ts.map +1 -0
- package/dist/providers/claude-tasks-fs.js +158 -0
- package/dist/providers/claude-tasks-fs.js.map +1 -0
- package/dist/providers/claude-tasks.d.ts +13 -4
- package/dist/providers/claude-tasks.d.ts.map +1 -1
- package/dist/providers/claude-tasks.js +318 -5
- package/dist/providers/claude-tasks.js.map +1 -1
- package/dist/providers/from-config.d.ts.map +1 -1
- package/dist/providers/from-config.js +35 -17
- package/dist/providers/from-config.js.map +1 -1
- package/dist/providers/global.d.ts.map +1 -1
- package/dist/providers/global.js +5 -0
- package/dist/providers/global.js.map +1 -1
- package/dist/providers/index.d.ts +6 -4
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +4 -3
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/map.d.ts.map +1 -1
- package/dist/providers/map.js +5 -0
- package/dist/providers/map.js.map +1 -1
- package/dist/providers/materialization.d.ts +23 -5
- package/dist/providers/materialization.d.ts.map +1 -1
- package/dist/providers/materialization.js +95 -4
- package/dist/providers/materialization.js.map +1 -1
- package/dist/providers/native.d.ts.map +1 -1
- package/dist/providers/native.js +5 -0
- package/dist/providers/native.js.map +1 -1
- package/dist/providers/sessionlog.d.ts +81 -0
- package/dist/providers/sessionlog.d.ts.map +1 -0
- package/dist/providers/sessionlog.js +478 -0
- package/dist/providers/sessionlog.js.map +1 -0
- package/dist/providers/sudocode.d.ts.map +1 -1
- package/dist/providers/sudocode.js +17 -1
- package/dist/providers/sudocode.js.map +1 -1
- package/dist/providers/traits/Reconcilable.d.ts +57 -0
- package/dist/providers/traits/Reconcilable.d.ts.map +1 -0
- package/dist/providers/traits/Reconcilable.js +18 -0
- package/dist/providers/traits/Reconcilable.js.map +1 -0
- package/dist/providers/traits/__tests__/RelationshipQueryable.test.d.ts +2 -0
- package/dist/providers/traits/__tests__/RelationshipQueryable.test.d.ts.map +1 -0
- package/dist/providers/traits/__tests__/RelationshipQueryable.test.js +169 -0
- package/dist/providers/traits/__tests__/RelationshipQueryable.test.js.map +1 -0
- package/dist/providers/traits/__tests__/TaskManageable.test.d.ts +2 -0
- package/dist/providers/traits/__tests__/TaskManageable.test.d.ts.map +1 -0
- package/dist/providers/traits/__tests__/TaskManageable.test.js +172 -0
- package/dist/providers/traits/__tests__/TaskManageable.test.js.map +1 -0
- package/dist/providers/traits/index.d.ts +2 -0
- package/dist/providers/traits/index.d.ts.map +1 -1
- package/dist/providers/traits/index.js +1 -0
- package/dist/providers/traits/index.js.map +1 -1
- package/dist/providers/types.d.ts +63 -0
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/providers/types.js +22 -0
- package/dist/providers/types.js.map +1 -1
- package/dist/schema/__tests__/validation.test.d.ts +2 -0
- package/dist/schema/__tests__/validation.test.d.ts.map +1 -0
- package/dist/schema/__tests__/validation.test.js +241 -0
- package/dist/schema/__tests__/validation.test.js.map +1 -0
- package/dist/schema/edges.d.ts +3 -3
- package/dist/schema/edges.d.ts.map +1 -1
- package/dist/sessionlog/agent/agents/claude-code.d.ts +76 -0
- package/dist/sessionlog/agent/agents/claude-code.d.ts.map +1 -0
- package/dist/sessionlog/agent/agents/claude-code.js +759 -0
- package/dist/sessionlog/agent/agents/claude-code.js.map +1 -0
- package/dist/sessionlog/agent/agents/cursor.d.ts +35 -0
- package/dist/sessionlog/agent/agents/cursor.d.ts.map +1 -0
- package/dist/sessionlog/agent/agents/cursor.js +294 -0
- package/dist/sessionlog/agent/agents/cursor.js.map +1 -0
- package/dist/sessionlog/agent/agents/gemini-cli.d.ts +62 -0
- package/dist/sessionlog/agent/agents/gemini-cli.d.ts.map +1 -0
- package/dist/sessionlog/agent/agents/gemini-cli.js +462 -0
- package/dist/sessionlog/agent/agents/gemini-cli.js.map +1 -0
- package/dist/sessionlog/agent/agents/opencode.d.ts +100 -0
- package/dist/sessionlog/agent/agents/opencode.d.ts.map +1 -0
- package/dist/sessionlog/agent/agents/opencode.js +423 -0
- package/dist/sessionlog/agent/agents/opencode.js.map +1 -0
- package/dist/sessionlog/agent/registry.d.ts +54 -0
- package/dist/sessionlog/agent/registry.d.ts.map +1 -0
- package/dist/sessionlog/agent/registry.js +123 -0
- package/dist/sessionlog/agent/registry.js.map +1 -0
- package/dist/sessionlog/agent/session-types.d.ts +45 -0
- package/dist/sessionlog/agent/session-types.d.ts.map +1 -0
- package/dist/sessionlog/agent/session-types.js +50 -0
- package/dist/sessionlog/agent/session-types.js.map +1 -0
- package/dist/sessionlog/agent/types.d.ts +126 -0
- package/dist/sessionlog/agent/types.d.ts.map +1 -0
- package/dist/sessionlog/agent/types.js +39 -0
- package/dist/sessionlog/agent/types.js.map +1 -0
- package/dist/sessionlog/commands/clean.d.ts +40 -0
- package/dist/sessionlog/commands/clean.d.ts.map +1 -0
- package/dist/sessionlog/commands/clean.js +105 -0
- package/dist/sessionlog/commands/clean.js.map +1 -0
- package/dist/sessionlog/commands/disable.d.ts +23 -0
- package/dist/sessionlog/commands/disable.d.ts.map +1 -0
- package/dist/sessionlog/commands/disable.js +57 -0
- package/dist/sessionlog/commands/disable.js.map +1 -0
- package/dist/sessionlog/commands/doctor.d.ts +43 -0
- package/dist/sessionlog/commands/doctor.d.ts.map +1 -0
- package/dist/sessionlog/commands/doctor.js +97 -0
- package/dist/sessionlog/commands/doctor.js.map +1 -0
- package/dist/sessionlog/commands/enable.d.ts +31 -0
- package/dist/sessionlog/commands/enable.d.ts.map +1 -0
- package/dist/sessionlog/commands/enable.js +102 -0
- package/dist/sessionlog/commands/enable.js.map +1 -0
- package/dist/sessionlog/commands/explain.d.ts +69 -0
- package/dist/sessionlog/commands/explain.d.ts.map +1 -0
- package/dist/sessionlog/commands/explain.js +185 -0
- package/dist/sessionlog/commands/explain.js.map +1 -0
- package/dist/sessionlog/commands/reset.d.ts +23 -0
- package/dist/sessionlog/commands/reset.d.ts.map +1 -0
- package/dist/sessionlog/commands/reset.js +68 -0
- package/dist/sessionlog/commands/reset.js.map +1 -0
- package/dist/sessionlog/commands/resume.d.ts +42 -0
- package/dist/sessionlog/commands/resume.d.ts.map +1 -0
- package/dist/sessionlog/commands/resume.js +134 -0
- package/dist/sessionlog/commands/resume.js.map +1 -0
- package/dist/sessionlog/commands/rewind.d.ts +40 -0
- package/dist/sessionlog/commands/rewind.d.ts.map +1 -0
- package/dist/sessionlog/commands/rewind.js +155 -0
- package/dist/sessionlog/commands/rewind.js.map +1 -0
- package/dist/sessionlog/commands/status.d.ts +54 -0
- package/dist/sessionlog/commands/status.d.ts.map +1 -0
- package/dist/sessionlog/commands/status.js +95 -0
- package/dist/sessionlog/commands/status.js.map +1 -0
- package/dist/sessionlog/config.d.ts +40 -0
- package/dist/sessionlog/config.d.ts.map +1 -0
- package/dist/sessionlog/config.js +126 -0
- package/dist/sessionlog/config.js.map +1 -0
- package/dist/sessionlog/git-operations.d.ts +173 -0
- package/dist/sessionlog/git-operations.d.ts.map +1 -0
- package/dist/sessionlog/git-operations.js +399 -0
- package/dist/sessionlog/git-operations.js.map +1 -0
- package/dist/sessionlog/hooks/git-hooks.d.ts +22 -0
- package/dist/sessionlog/hooks/git-hooks.d.ts.map +1 -0
- package/dist/sessionlog/hooks/git-hooks.js +145 -0
- package/dist/sessionlog/hooks/git-hooks.js.map +1 -0
- package/dist/sessionlog/hooks/lifecycle.d.ts +21 -0
- package/dist/sessionlog/hooks/lifecycle.d.ts.map +1 -0
- package/dist/sessionlog/hooks/lifecycle.js +179 -0
- package/dist/sessionlog/hooks/lifecycle.js.map +1 -0
- package/dist/sessionlog/index.d.ts +69 -0
- package/dist/sessionlog/index.d.ts.map +1 -0
- package/dist/sessionlog/index.js +154 -0
- package/dist/sessionlog/index.js.map +1 -0
- package/dist/sessionlog/security/redaction.d.ts +35 -0
- package/dist/sessionlog/security/redaction.d.ts.map +1 -0
- package/dist/sessionlog/security/redaction.js +221 -0
- package/dist/sessionlog/security/redaction.js.map +1 -0
- package/dist/sessionlog/session/state-machine.d.ts +90 -0
- package/dist/sessionlog/session/state-machine.d.ts.map +1 -0
- package/dist/sessionlog/session/state-machine.js +347 -0
- package/dist/sessionlog/session/state-machine.js.map +1 -0
- package/dist/sessionlog/store/checkpoint-store.d.ts +47 -0
- package/dist/sessionlog/store/checkpoint-store.d.ts.map +1 -0
- package/dist/sessionlog/store/checkpoint-store.js +309 -0
- package/dist/sessionlog/store/checkpoint-store.js.map +1 -0
- package/dist/sessionlog/store/native-store.d.ts +21 -0
- package/dist/sessionlog/store/native-store.d.ts.map +1 -0
- package/dist/sessionlog/store/native-store.js +162 -0
- package/dist/sessionlog/store/native-store.js.map +1 -0
- package/dist/sessionlog/store/provider-types.d.ts +78 -0
- package/dist/sessionlog/store/provider-types.d.ts.map +1 -0
- package/dist/sessionlog/store/provider-types.js +12 -0
- package/dist/sessionlog/store/provider-types.js.map +1 -0
- package/dist/sessionlog/store/session-store.d.ts +28 -0
- package/dist/sessionlog/store/session-store.d.ts.map +1 -0
- package/dist/sessionlog/store/session-store.js +187 -0
- package/dist/sessionlog/store/session-store.js.map +1 -0
- package/dist/sessionlog/strategy/attribution.d.ts +39 -0
- package/dist/sessionlog/strategy/attribution.d.ts.map +1 -0
- package/dist/sessionlog/strategy/attribution.js +227 -0
- package/dist/sessionlog/strategy/attribution.js.map +1 -0
- package/dist/sessionlog/strategy/common.d.ts +60 -0
- package/dist/sessionlog/strategy/common.d.ts.map +1 -0
- package/dist/sessionlog/strategy/common.js +162 -0
- package/dist/sessionlog/strategy/common.js.map +1 -0
- package/dist/sessionlog/strategy/content-overlap.d.ts +33 -0
- package/dist/sessionlog/strategy/content-overlap.d.ts.map +1 -0
- package/dist/sessionlog/strategy/content-overlap.js +168 -0
- package/dist/sessionlog/strategy/content-overlap.js.map +1 -0
- package/dist/sessionlog/strategy/manual-commit.d.ts +35 -0
- package/dist/sessionlog/strategy/manual-commit.d.ts.map +1 -0
- package/dist/sessionlog/strategy/manual-commit.js +732 -0
- package/dist/sessionlog/strategy/manual-commit.js.map +1 -0
- package/dist/sessionlog/strategy/types.d.ts +163 -0
- package/dist/sessionlog/strategy/types.d.ts.map +1 -0
- package/dist/sessionlog/strategy/types.js +49 -0
- package/dist/sessionlog/strategy/types.js.map +1 -0
- package/dist/sessionlog/summarize/claude-generator.d.ts +25 -0
- package/dist/sessionlog/summarize/claude-generator.d.ts.map +1 -0
- package/dist/sessionlog/summarize/claude-generator.js +87 -0
- package/dist/sessionlog/summarize/claude-generator.js.map +1 -0
- package/dist/sessionlog/summarize/summarize.d.ts +52 -0
- package/dist/sessionlog/summarize/summarize.d.ts.map +1 -0
- package/dist/sessionlog/summarize/summarize.js +335 -0
- package/dist/sessionlog/summarize/summarize.js.map +1 -0
- package/dist/sessionlog/types.d.ts +298 -0
- package/dist/sessionlog/types.d.ts.map +1 -0
- package/dist/sessionlog/types.js +104 -0
- package/dist/sessionlog/types.js.map +1 -0
- package/dist/sessionlog/utils/chunk-files.d.ts +25 -0
- package/dist/sessionlog/utils/chunk-files.d.ts.map +1 -0
- package/dist/sessionlog/utils/chunk-files.js +47 -0
- package/dist/sessionlog/utils/chunk-files.js.map +1 -0
- package/dist/sessionlog/utils/commit-message.d.ts +11 -0
- package/dist/sessionlog/utils/commit-message.d.ts.map +1 -0
- package/dist/sessionlog/utils/commit-message.js +54 -0
- package/dist/sessionlog/utils/commit-message.js.map +1 -0
- package/dist/sessionlog/utils/detect-agent.d.ts +19 -0
- package/dist/sessionlog/utils/detect-agent.d.ts.map +1 -0
- package/dist/sessionlog/utils/detect-agent.js +34 -0
- package/dist/sessionlog/utils/detect-agent.js.map +1 -0
- package/dist/sessionlog/utils/hook-managers.d.ts +24 -0
- package/dist/sessionlog/utils/hook-managers.d.ts.map +1 -0
- package/dist/sessionlog/utils/hook-managers.js +87 -0
- package/dist/sessionlog/utils/hook-managers.js.map +1 -0
- package/dist/sessionlog/utils/ide-tags.d.ts +12 -0
- package/dist/sessionlog/utils/ide-tags.d.ts.map +1 -0
- package/dist/sessionlog/utils/ide-tags.js +30 -0
- package/dist/sessionlog/utils/ide-tags.js.map +1 -0
- package/dist/sessionlog/utils/paths.d.ts +32 -0
- package/dist/sessionlog/utils/paths.d.ts.map +1 -0
- package/dist/sessionlog/utils/paths.js +55 -0
- package/dist/sessionlog/utils/paths.js.map +1 -0
- package/dist/sessionlog/utils/preview-rewind.d.ts +23 -0
- package/dist/sessionlog/utils/preview-rewind.d.ts.map +1 -0
- package/dist/sessionlog/utils/preview-rewind.js +63 -0
- package/dist/sessionlog/utils/preview-rewind.js.map +1 -0
- package/dist/sessionlog/utils/rewind-conflict.d.ts +52 -0
- package/dist/sessionlog/utils/rewind-conflict.d.ts.map +1 -0
- package/dist/sessionlog/utils/rewind-conflict.js +79 -0
- package/dist/sessionlog/utils/rewind-conflict.js.map +1 -0
- package/dist/sessionlog/utils/shadow-branch.d.ts +53 -0
- package/dist/sessionlog/utils/shadow-branch.d.ts.map +1 -0
- package/dist/sessionlog/utils/shadow-branch.js +97 -0
- package/dist/sessionlog/utils/shadow-branch.js.map +1 -0
- package/dist/sessionlog/utils/string-utils.d.ts +24 -0
- package/dist/sessionlog/utils/string-utils.d.ts.map +1 -0
- package/dist/sessionlog/utils/string-utils.js +47 -0
- package/dist/sessionlog/utils/string-utils.js.map +1 -0
- package/dist/sessionlog/utils/todo-extract.d.ts +52 -0
- package/dist/sessionlog/utils/todo-extract.d.ts.map +1 -0
- package/dist/sessionlog/utils/todo-extract.js +167 -0
- package/dist/sessionlog/utils/todo-extract.js.map +1 -0
- package/dist/sessionlog/utils/trailers.d.ts +36 -0
- package/dist/sessionlog/utils/trailers.d.ts.map +1 -0
- package/dist/sessionlog/utils/trailers.js +149 -0
- package/dist/sessionlog/utils/trailers.js.map +1 -0
- package/dist/sessionlog/utils/transcript-parse.d.ts +57 -0
- package/dist/sessionlog/utils/transcript-parse.d.ts.map +1 -0
- package/dist/sessionlog/utils/transcript-parse.js +126 -0
- package/dist/sessionlog/utils/transcript-parse.js.map +1 -0
- package/dist/sessionlog/utils/transcript-timestamp.d.ts +22 -0
- package/dist/sessionlog/utils/transcript-timestamp.d.ts.map +1 -0
- package/dist/sessionlog/utils/transcript-timestamp.js +56 -0
- package/dist/sessionlog/utils/transcript-timestamp.js.map +1 -0
- package/dist/sessionlog/utils/tree-ops.d.ts +47 -0
- package/dist/sessionlog/utils/tree-ops.d.ts.map +1 -0
- package/dist/sessionlog/utils/tree-ops.js +145 -0
- package/dist/sessionlog/utils/tree-ops.js.map +1 -0
- package/dist/sessionlog/utils/tty.d.ts +25 -0
- package/dist/sessionlog/utils/tty.d.ts.map +1 -0
- package/dist/sessionlog/utils/tty.js +70 -0
- package/dist/sessionlog/utils/tty.js.map +1 -0
- package/dist/sessionlog/utils/validation.d.ts +31 -0
- package/dist/sessionlog/utils/validation.d.ts.map +1 -0
- package/dist/sessionlog/utils/validation.js +59 -0
- package/dist/sessionlog/utils/validation.js.map +1 -0
- package/dist/sessionlog/utils/worktree.d.ts +16 -0
- package/dist/sessionlog/utils/worktree.d.ts.map +1 -0
- package/dist/sessionlog/utils/worktree.js +50 -0
- package/dist/sessionlog/utils/worktree.js.map +1 -0
- package/dist/storage/__tests__/atomic-write.test.d.ts +5 -0
- package/dist/storage/__tests__/atomic-write.test.d.ts.map +1 -0
- package/dist/storage/__tests__/atomic-write.test.js +170 -0
- package/dist/storage/__tests__/atomic-write.test.js.map +1 -0
- package/dist/storage/__tests__/file-lock.test.d.ts +2 -0
- package/dist/storage/__tests__/file-lock.test.d.ts.map +1 -0
- package/dist/storage/__tests__/file-lock.test.js +89 -0
- package/dist/storage/__tests__/file-lock.test.js.map +1 -0
- package/dist/storage/__tests__/jsonl.test.d.ts +2 -0
- package/dist/storage/__tests__/jsonl.test.d.ts.map +1 -0
- package/dist/storage/__tests__/jsonl.test.js +228 -0
- package/dist/storage/__tests__/jsonl.test.js.map +1 -0
- package/dist/storage/__tests__/locked-writer.test.d.ts +2 -0
- package/dist/storage/__tests__/locked-writer.test.d.ts.map +1 -0
- package/dist/storage/__tests__/locked-writer.test.js +109 -0
- package/dist/storage/__tests__/locked-writer.test.js.map +1 -0
- package/dist/storage/__tests__/sqlite.test.d.ts +2 -0
- package/dist/storage/__tests__/sqlite.test.d.ts.map +1 -0
- package/dist/storage/__tests__/sqlite.test.js +470 -0
- package/dist/storage/__tests__/sqlite.test.js.map +1 -0
- package/dist/storage/sqlite-schema.d.ts.map +1 -1
- package/dist/storage/sqlite-schema.js +2 -0
- package/dist/storage/sqlite-schema.js.map +1 -1
- package/dist/storage/sqlite.d.ts.map +1 -1
- package/dist/storage/sqlite.js +18 -4
- package/dist/storage/sqlite.js.map +1 -1
- package/dist/tools/__tests__/annotate.test.d.ts +5 -0
- package/dist/tools/__tests__/annotate.test.d.ts.map +1 -0
- package/dist/tools/__tests__/annotate.test.js +314 -0
- package/dist/tools/__tests__/annotate.test.js.map +1 -0
- package/dist/tools/__tests__/link.test.d.ts +5 -0
- package/dist/tools/__tests__/link.test.d.ts.map +1 -0
- package/dist/tools/__tests__/link.test.js +245 -0
- package/dist/tools/__tests__/link.test.js.map +1 -0
- package/dist/tools/__tests__/query.test.d.ts +5 -0
- package/dist/tools/__tests__/query.test.d.ts.map +1 -0
- package/dist/tools/__tests__/query.test.js +288 -0
- package/dist/tools/__tests__/query.test.js.map +1 -0
- package/dist/tools/__tests__/task.test.d.ts +5 -0
- package/dist/tools/__tests__/task.test.d.ts.map +1 -0
- package/dist/tools/__tests__/task.test.js +178 -0
- package/dist/tools/__tests__/task.test.js.map +1 -0
- package/dist/tools/index.d.ts +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/query.d.ts +2 -1
- package/dist/tools/query.d.ts.map +1 -1
- package/dist/tools/query.js +217 -7
- package/dist/tools/query.js.map +1 -1
- package/dist/tools/types.d.ts +57 -0
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/types.js.map +1 -1
- package/dist/tracking/claude-task-reconstructor.d.ts +41 -0
- package/dist/tracking/claude-task-reconstructor.d.ts.map +1 -0
- package/dist/tracking/claude-task-reconstructor.js +91 -0
- package/dist/tracking/claude-task-reconstructor.js.map +1 -0
- package/dist/tracking/plan-mode-tracker.d.ts +20 -0
- package/dist/tracking/plan-mode-tracker.d.ts.map +1 -0
- package/dist/tracking/plan-mode-tracker.js +35 -0
- package/dist/tracking/plan-mode-tracker.js.map +1 -0
- package/dist/tracking/transcript-extractor.d.ts +3 -3
- package/dist/tracking/transcript-extractor.d.ts.map +1 -1
- package/dist/tracking/transcript-extractor.js +1 -1
- package/dist/tracking/transcript-extractor.js.map +1 -1
- package/package.json +3 -1
|
@@ -0,0 +1,677 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenTasks MCP Server
|
|
3
|
+
*
|
|
4
|
+
* Exposes the OpenTasks tool interface over Model Context Protocol (MCP).
|
|
5
|
+
* Connects to the daemon via IPC client and routes all operations through
|
|
6
|
+
* the existing provider system — any registered provider (native, beads,
|
|
7
|
+
* sudocode, claude-tasks, etc.) is automatically available.
|
|
8
|
+
*
|
|
9
|
+
* Scopes:
|
|
10
|
+
* - tasks (default): Task CRUD + lifecycle — create, get, update, list
|
|
11
|
+
* - graph: Full graph operations — link, query (all node types, edges, blockers)
|
|
12
|
+
* - annotate: Feedback lifecycle — create, resolve, dismiss, reopen
|
|
13
|
+
* - context: Context/spec CRUD — create, get, update, list
|
|
14
|
+
*/
|
|
15
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
16
|
+
import { z } from 'zod';
|
|
17
|
+
import { OpenTasksClient } from '../client/client.js';
|
|
18
|
+
// ============================================================================
|
|
19
|
+
// Server Factory
|
|
20
|
+
// ============================================================================
|
|
21
|
+
/**
|
|
22
|
+
* Create an MCP server that exposes the OpenTasks tool interface.
|
|
23
|
+
*
|
|
24
|
+
* Default scope (tasks) provides 4 simple CRUD tools:
|
|
25
|
+
* create_task, get_task, update_task, list_tasks
|
|
26
|
+
*
|
|
27
|
+
* Additional scopes can be opted in:
|
|
28
|
+
* --scope tasks,graph,annotate,context
|
|
29
|
+
*/
|
|
30
|
+
export const ALL_SCOPES = ['tasks', 'graph', 'annotate', 'context'];
|
|
31
|
+
export function createMCPServer(options) {
|
|
32
|
+
const client = new OpenTasksClient(options?.clientOptions);
|
|
33
|
+
const scopes = new Set(options?.scopes ?? ['tasks']);
|
|
34
|
+
const server = new McpServer({
|
|
35
|
+
name: 'opentasks',
|
|
36
|
+
version: '0.0.5',
|
|
37
|
+
});
|
|
38
|
+
// Always register tasks scope
|
|
39
|
+
if (scopes.has('tasks')) {
|
|
40
|
+
registerTaskTools(server, client);
|
|
41
|
+
}
|
|
42
|
+
if (scopes.has('graph')) {
|
|
43
|
+
registerGraphTools(server, client);
|
|
44
|
+
}
|
|
45
|
+
if (scopes.has('annotate')) {
|
|
46
|
+
registerAnnotateTools(server, client);
|
|
47
|
+
}
|
|
48
|
+
if (scopes.has('context')) {
|
|
49
|
+
registerContextTools(server, client);
|
|
50
|
+
}
|
|
51
|
+
return server;
|
|
52
|
+
}
|
|
53
|
+
// ============================================================================
|
|
54
|
+
// Scope: tasks (default)
|
|
55
|
+
// ============================================================================
|
|
56
|
+
function registerTaskTools(server, client) {
|
|
57
|
+
server.tool('create_task', 'Create a new task. Supports provider routing via scheme parameter (e.g. beads, sudocode).', {
|
|
58
|
+
title: z.string().describe('Task title'),
|
|
59
|
+
status: z.string().optional().describe('Initial status (default: open)'),
|
|
60
|
+
content: z.string().optional().describe('Markdown description'),
|
|
61
|
+
priority: z.number().optional().describe('Priority 0=highest, 4=lowest'),
|
|
62
|
+
tags: z.array(z.string()).optional().describe('Tags for categorization'),
|
|
63
|
+
assignee: z.string().optional().describe('Assigned user/agent'),
|
|
64
|
+
parent_id: z.string().optional().describe('Parent node ID'),
|
|
65
|
+
metadata: z.record(z.string(), z.unknown()).optional().describe('Additional metadata'),
|
|
66
|
+
scheme: z.string().optional().describe('Provider scheme to route creation to (e.g. beads, sudocode)'),
|
|
67
|
+
}, async (args) => {
|
|
68
|
+
try {
|
|
69
|
+
const { scheme, ...params } = args;
|
|
70
|
+
const result = await client.createNode({ type: 'task', ...params }, scheme ? { scheme } : undefined);
|
|
71
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
return errorResult(error);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
server.tool('get_task', 'Get a task by ID or provider URI (e.g. t-abc1, beads://project/i-123).', {
|
|
78
|
+
id: z.string().describe('Task ID or provider URI'),
|
|
79
|
+
}, async (args) => {
|
|
80
|
+
try {
|
|
81
|
+
const result = await client.getNode(args.id);
|
|
82
|
+
if (!result) {
|
|
83
|
+
return {
|
|
84
|
+
content: [{ type: 'text', text: JSON.stringify({ error: 'Task not found', id: args.id }) }],
|
|
85
|
+
isError: true,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
return errorResult(error);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
server.tool('update_task', `Update a task's fields and/or transition its status. Supports adding/removing blockers.`, {
|
|
95
|
+
id: z.string().describe('Task ID or provider URI'),
|
|
96
|
+
// Field updates
|
|
97
|
+
title: z.string().optional().describe('Update title'),
|
|
98
|
+
content: z.string().optional().describe('Update description'),
|
|
99
|
+
priority: z.number().optional().describe('Update priority'),
|
|
100
|
+
status: z.string().optional().describe('Update status directly'),
|
|
101
|
+
assignee: z.string().optional().describe('Update assignee'),
|
|
102
|
+
tags: z.array(z.string()).optional().describe('Update tags'),
|
|
103
|
+
archived: z.boolean().optional().describe('Archive/unarchive'),
|
|
104
|
+
metadata: z.record(z.string(), z.unknown()).optional().describe('Update metadata (merged)'),
|
|
105
|
+
// Semantic transitions
|
|
106
|
+
transition: z.enum(['start', 'complete', 'block', 'reopen', 'close']).optional()
|
|
107
|
+
.describe('Semantic status transition (alternative to setting status directly)'),
|
|
108
|
+
// Blocker management
|
|
109
|
+
addBlockedBy: z.array(z.string()).optional().describe('Add blocker task IDs (these block this task)'),
|
|
110
|
+
removeBlockedBy: z.array(z.string()).optional().describe('Remove blocker task IDs'),
|
|
111
|
+
addBlocks: z.array(z.string()).optional().describe('Add task IDs that this task blocks'),
|
|
112
|
+
removeBlocks: z.array(z.string()).optional().describe('Remove task IDs that this task blocks'),
|
|
113
|
+
}, async (args) => {
|
|
114
|
+
const results = [];
|
|
115
|
+
const { id, transition, addBlockedBy, removeBlockedBy, addBlocks, removeBlocks, tags, ...fieldUpdates } = args;
|
|
116
|
+
const hasFieldUpdates = Object.values(fieldUpdates).some((v) => v !== undefined);
|
|
117
|
+
// 1. Apply field updates if any
|
|
118
|
+
if (hasFieldUpdates) {
|
|
119
|
+
try {
|
|
120
|
+
const updateResult = await client.updateNode(id, fieldUpdates);
|
|
121
|
+
results.push({ op: 'update', success: true, result: updateResult });
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
results.push({ op: 'update', success: false, error: errorMessage(error) });
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// 2. Apply semantic transition if requested
|
|
128
|
+
if (transition) {
|
|
129
|
+
try {
|
|
130
|
+
const transitionResult = await client.task({ transition: { id, action: transition } });
|
|
131
|
+
if (transitionResult.success) {
|
|
132
|
+
results.push({ op: 'transition', success: true, result: transitionResult });
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
results.push({ op: 'transition', success: false, error: transitionResult.error || 'Transition failed' });
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
results.push({ op: 'transition', success: false, error: errorMessage(error) });
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// 3. Apply blocker changes
|
|
143
|
+
if (addBlockedBy?.length) {
|
|
144
|
+
for (const blockerId of addBlockedBy) {
|
|
145
|
+
try {
|
|
146
|
+
const r = await client.link({ fromId: blockerId, toId: id, type: 'blocks' });
|
|
147
|
+
results.push({ op: 'addBlockedBy', success: r.success, result: r });
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
results.push({ op: 'addBlockedBy', success: false, error: errorMessage(error) });
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (removeBlockedBy?.length) {
|
|
155
|
+
for (const blockerId of removeBlockedBy) {
|
|
156
|
+
try {
|
|
157
|
+
const r = await client.link({ fromId: blockerId, toId: id, type: 'blocks', remove: true });
|
|
158
|
+
results.push({ op: 'removeBlockedBy', success: r.success, result: r });
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
results.push({ op: 'removeBlockedBy', success: false, error: errorMessage(error) });
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
if (addBlocks?.length) {
|
|
166
|
+
for (const blockedId of addBlocks) {
|
|
167
|
+
try {
|
|
168
|
+
const r = await client.link({ fromId: id, toId: blockedId, type: 'blocks' });
|
|
169
|
+
results.push({ op: 'addBlocks', success: r.success, result: r });
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
results.push({ op: 'addBlocks', success: false, error: errorMessage(error) });
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
if (removeBlocks?.length) {
|
|
177
|
+
for (const blockedId of removeBlocks) {
|
|
178
|
+
try {
|
|
179
|
+
const r = await client.link({ fromId: id, toId: blockedId, type: 'blocks', remove: true });
|
|
180
|
+
results.push({ op: 'removeBlocks', success: r.success, result: r });
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
results.push({ op: 'removeBlocks', success: false, error: errorMessage(error) });
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
// Build response
|
|
188
|
+
const anyFailed = results.some((r) => !r.success);
|
|
189
|
+
const output = results.length === 1 ? results[0] : { operations: results };
|
|
190
|
+
return {
|
|
191
|
+
content: [{ type: 'text', text: JSON.stringify(output, null, 2) }],
|
|
192
|
+
isError: anyFailed,
|
|
193
|
+
};
|
|
194
|
+
});
|
|
195
|
+
server.tool('delete_task', 'Delete a task by ID or provider URI. For provider-backed tasks, deletes from both the provider and the local graph.', {
|
|
196
|
+
id: z.string().describe('Task ID or provider URI'),
|
|
197
|
+
}, async (args) => {
|
|
198
|
+
try {
|
|
199
|
+
await client.deleteNode(args.id);
|
|
200
|
+
return { content: [{ type: 'text', text: JSON.stringify({ success: true, id: args.id }) }] };
|
|
201
|
+
}
|
|
202
|
+
catch (error) {
|
|
203
|
+
return errorResult(error);
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
server.tool('list_providers', 'List all registered providers and their capabilities (schemes, status models, supported actions).', {}, async () => {
|
|
207
|
+
try {
|
|
208
|
+
const result = await client.listProviders();
|
|
209
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
210
|
+
}
|
|
211
|
+
catch (error) {
|
|
212
|
+
return errorResult(error);
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
server.tool('reconcile', 'Trigger provider reconciliation. Syncs cached provider-backed nodes with their source providers. Returns a diff summary showing which nodes were updated, unchanged, or unavailable.', {
|
|
216
|
+
providers: z.array(z.string()).optional().describe('Only reconcile these provider names'),
|
|
217
|
+
node_ids: z.array(z.string()).optional().describe('Only reconcile these node IDs'),
|
|
218
|
+
}, async (args) => {
|
|
219
|
+
try {
|
|
220
|
+
const result = await client.reconcileProviders({
|
|
221
|
+
providers: args.providers,
|
|
222
|
+
nodeIds: args.node_ids,
|
|
223
|
+
});
|
|
224
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
225
|
+
}
|
|
226
|
+
catch (error) {
|
|
227
|
+
return errorResult(error);
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
server.tool('list_tasks', 'List and filter tasks. Get ready tasks, find blockers, or query by status/tags/assignee.', {
|
|
231
|
+
// Filter options
|
|
232
|
+
status: z.union([z.string(), z.array(z.string())]).optional().describe('Filter by status(es)'),
|
|
233
|
+
tags: z.array(z.string()).optional().describe('Filter by tags (AND semantics)'),
|
|
234
|
+
assignee: z.string().optional().describe('Filter by assignee'),
|
|
235
|
+
priority: z.union([z.number(), z.object({ min: z.number().optional(), max: z.number().optional() })]).optional()
|
|
236
|
+
.describe('Filter by priority (single value or range)'),
|
|
237
|
+
search: z.string().optional().describe('Text search in title and content'),
|
|
238
|
+
archived: z.boolean().optional().describe('Include archived tasks (default: false)'),
|
|
239
|
+
// Ready query
|
|
240
|
+
ready: z.boolean().optional().describe('Only show tasks ready to work on (no active blockers)'),
|
|
241
|
+
// Blocker queries
|
|
242
|
+
blockersOf: z.string().optional().describe('Get tasks blocking this task ID'),
|
|
243
|
+
blockedBy: z.string().optional().describe('Get tasks blocked by this task ID'),
|
|
244
|
+
// Pagination
|
|
245
|
+
limit: z.number().optional().describe('Maximum results (default: 50)'),
|
|
246
|
+
offset: z.number().optional().describe('Pagination offset'),
|
|
247
|
+
orderBy: z.enum(['created_at', 'updated_at', 'priority', 'title']).optional(),
|
|
248
|
+
orderDirection: z.enum(['asc', 'desc']).optional(),
|
|
249
|
+
// Provider filtering
|
|
250
|
+
providers: z.array(z.string()).optional().describe('Only query these providers (for ready queries)'),
|
|
251
|
+
}, async (args) => {
|
|
252
|
+
try {
|
|
253
|
+
const { ready, blockersOf, blockedBy, providers, ...filters } = args;
|
|
254
|
+
// Ready query — federated across providers
|
|
255
|
+
if (ready) {
|
|
256
|
+
const result = await client.task({
|
|
257
|
+
ready: {
|
|
258
|
+
providers,
|
|
259
|
+
limit: filters.limit,
|
|
260
|
+
tags: filters.tags,
|
|
261
|
+
assignee: filters.assignee,
|
|
262
|
+
priority: typeof filters.priority === 'number' ? filters.priority : undefined,
|
|
263
|
+
},
|
|
264
|
+
});
|
|
265
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
266
|
+
}
|
|
267
|
+
// Blocker queries
|
|
268
|
+
if (blockersOf) {
|
|
269
|
+
const result = await client.query({ blockers: { nodeId: blockersOf } });
|
|
270
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
271
|
+
}
|
|
272
|
+
if (blockedBy) {
|
|
273
|
+
const result = await client.query({ blocking: { nodeId: blockedBy } });
|
|
274
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
275
|
+
}
|
|
276
|
+
// General task list
|
|
277
|
+
const result = await client.query({
|
|
278
|
+
nodes: { type: 'task', ...filters },
|
|
279
|
+
});
|
|
280
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
281
|
+
}
|
|
282
|
+
catch (error) {
|
|
283
|
+
return errorResult(error);
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
// ============================================================================
|
|
288
|
+
// Scope: graph (opt-in)
|
|
289
|
+
// ============================================================================
|
|
290
|
+
function registerGraphTools(server, client) {
|
|
291
|
+
server.tool('link', 'Create or remove an edge between two nodes. Supports local IDs (e.g. t-abc1) and provider URIs (e.g. beads://project/i-123).', {
|
|
292
|
+
fromId: z.string().describe('Source node ID or provider URI'),
|
|
293
|
+
toId: z.string().describe('Target node ID or provider URI'),
|
|
294
|
+
type: z.string().describe('Relationship type: blocks, implements, references, depends-on, related, parent-of, child-of, duplicates, supersedes, discovered-from'),
|
|
295
|
+
remove: z.boolean().optional().describe('Remove the edge instead of creating (default: false)'),
|
|
296
|
+
metadata: z.record(z.string(), z.unknown()).optional().describe('Additional metadata'),
|
|
297
|
+
}, async (args) => {
|
|
298
|
+
try {
|
|
299
|
+
const result = await client.link(args);
|
|
300
|
+
return {
|
|
301
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
302
|
+
isError: !result.success,
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
catch (error) {
|
|
306
|
+
return errorResult(error);
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
server.tool('query', `Query the full task graph. Specify exactly ONE query type:
|
|
310
|
+
- nodes: Filter any node type by status, tags, priority, assignee, search
|
|
311
|
+
- edges: Filter edges by type, from_id, to_id
|
|
312
|
+
- ready: Get unblocked tasks ready to work on
|
|
313
|
+
- blockers/blocking: Dependency traversal
|
|
314
|
+
- feedback/unresolvedFeedback: Feedback queries
|
|
315
|
+
- tasks: Get tasks implementing a context
|
|
316
|
+
- context: Get context nodes a task implements
|
|
317
|
+
- contextSummary: Get breadcrumbs for session continuity (active, blocked, completed tasks, etc.)`, {
|
|
318
|
+
nodes: z.object({
|
|
319
|
+
type: z.union([z.string(), z.array(z.string())]).optional().describe('Node type(s): context, task, feedback, external'),
|
|
320
|
+
status: z.union([z.string(), z.array(z.string())]).optional(),
|
|
321
|
+
tags: z.array(z.string()).optional(),
|
|
322
|
+
parent_id: z.string().optional(),
|
|
323
|
+
archived: z.boolean().nullable().optional(),
|
|
324
|
+
search: z.string().optional(),
|
|
325
|
+
priority: z.union([z.number(), z.object({ min: z.number().optional(), max: z.number().optional() })]).optional(),
|
|
326
|
+
assignee: z.string().optional(),
|
|
327
|
+
limit: z.number().optional(),
|
|
328
|
+
offset: z.number().optional(),
|
|
329
|
+
orderBy: z.enum(['created_at', 'updated_at', 'priority', 'title']).optional(),
|
|
330
|
+
orderDirection: z.enum(['asc', 'desc']).optional(),
|
|
331
|
+
}).optional(),
|
|
332
|
+
edges: z.object({
|
|
333
|
+
type: z.union([z.string(), z.array(z.string())]).optional(),
|
|
334
|
+
from_id: z.string().optional(),
|
|
335
|
+
to_id: z.string().optional(),
|
|
336
|
+
limit: z.number().optional(),
|
|
337
|
+
offset: z.number().optional(),
|
|
338
|
+
}).optional(),
|
|
339
|
+
ready: z.object({
|
|
340
|
+
tags: z.array(z.string()).optional(),
|
|
341
|
+
priority: z.union([z.number(), z.object({ min: z.number().optional(), max: z.number().optional() })]).optional(),
|
|
342
|
+
assignee: z.string().optional(),
|
|
343
|
+
limit: z.number().optional(),
|
|
344
|
+
}).optional(),
|
|
345
|
+
blockers: z.object({
|
|
346
|
+
nodeId: z.string(),
|
|
347
|
+
transitive: z.boolean().optional(),
|
|
348
|
+
activeOnly: z.boolean().optional(),
|
|
349
|
+
}).optional(),
|
|
350
|
+
blocking: z.object({
|
|
351
|
+
nodeId: z.string(),
|
|
352
|
+
transitive: z.boolean().optional(),
|
|
353
|
+
activeOnly: z.boolean().optional(),
|
|
354
|
+
}).optional(),
|
|
355
|
+
feedback: z.object({
|
|
356
|
+
nodeId: z.string(),
|
|
357
|
+
type: z.enum(['comment', 'suggestion', 'request']).optional(),
|
|
358
|
+
resolved: z.boolean().optional(),
|
|
359
|
+
includeDismissed: z.boolean().optional(),
|
|
360
|
+
}).optional(),
|
|
361
|
+
unresolvedFeedback: z.object({
|
|
362
|
+
targetId: z.string().optional(),
|
|
363
|
+
}).optional(),
|
|
364
|
+
tasks: z.object({
|
|
365
|
+
contextId: z.string(),
|
|
366
|
+
}).optional(),
|
|
367
|
+
context: z.object({
|
|
368
|
+
taskId: z.string(),
|
|
369
|
+
}).optional(),
|
|
370
|
+
contextSummary: z.object({
|
|
371
|
+
taskId: z.string().optional().describe('Find context related to a specific task'),
|
|
372
|
+
tags: z.array(z.string()).optional().describe('Filter by tags'),
|
|
373
|
+
branch: z.string().optional().describe('Filter by branch'),
|
|
374
|
+
limit: z.number().optional().describe('Max breadcrumbs per section (default: 10)'),
|
|
375
|
+
}).optional(),
|
|
376
|
+
verbose: z.boolean().optional().describe('Return full objects instead of summaries (default: false)'),
|
|
377
|
+
limit: z.number().optional(),
|
|
378
|
+
offset: z.number().optional(),
|
|
379
|
+
}, async (args) => {
|
|
380
|
+
try {
|
|
381
|
+
const result = await client.query(args);
|
|
382
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
383
|
+
}
|
|
384
|
+
catch (error) {
|
|
385
|
+
return errorResult(error);
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
server.tool('context_summary', 'Get context summary breadcrumbs for session continuity. Returns recently completed tasks, active tasks, blocked tasks, related contexts, and unresolved feedback.', {
|
|
389
|
+
taskId: z.string().optional().describe('Find context related to a specific task'),
|
|
390
|
+
tags: z.array(z.string()).optional().describe('Filter by tags'),
|
|
391
|
+
branch: z.string().optional().describe('Filter by branch'),
|
|
392
|
+
limit: z.number().optional().describe('Max breadcrumbs per section (default: 10)'),
|
|
393
|
+
}, async (args) => {
|
|
394
|
+
try {
|
|
395
|
+
const result = await client.contextSummary(args);
|
|
396
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
397
|
+
}
|
|
398
|
+
catch (error) {
|
|
399
|
+
return errorResult(error);
|
|
400
|
+
}
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
// ============================================================================
|
|
404
|
+
// Scope: annotate (opt-in)
|
|
405
|
+
// ============================================================================
|
|
406
|
+
function registerAnnotateTools(server, client) {
|
|
407
|
+
server.tool('annotate', `Manage feedback on any node. Specify targetId and exactly ONE operation:
|
|
408
|
+
- create: Add new feedback (comment, suggestion, or request)
|
|
409
|
+
- resolve: Mark feedback as resolved
|
|
410
|
+
- dismiss: Dismiss feedback
|
|
411
|
+
- reopen: Reopen resolved/dismissed feedback`, {
|
|
412
|
+
targetId: z.string().describe('Target node ID receiving annotation'),
|
|
413
|
+
create: z.object({
|
|
414
|
+
content: z.string().describe('Feedback content (markdown)'),
|
|
415
|
+
type: z.enum(['comment', 'suggestion', 'request']).optional().describe('Feedback type (default: comment)'),
|
|
416
|
+
anchor: z.object({
|
|
417
|
+
line: z.number().optional().describe('Line number in target content'),
|
|
418
|
+
text: z.string().optional().describe('Text snippet to anchor to'),
|
|
419
|
+
}).optional(),
|
|
420
|
+
}).optional().describe('Create new feedback'),
|
|
421
|
+
resolve: z.string().optional().describe('Feedback ID to resolve'),
|
|
422
|
+
dismiss: z.string().optional().describe('Feedback ID to dismiss'),
|
|
423
|
+
reopen: z.string().optional().describe('Feedback ID to reopen'),
|
|
424
|
+
fromId: z.string().optional().describe('Source node ID (creates discovered-from link)'),
|
|
425
|
+
}, async (args) => {
|
|
426
|
+
try {
|
|
427
|
+
const result = await client.annotate(args);
|
|
428
|
+
return {
|
|
429
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
430
|
+
isError: !result.success,
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
catch (error) {
|
|
434
|
+
return errorResult(error);
|
|
435
|
+
}
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
// ============================================================================
|
|
439
|
+
// Scope: context (opt-in)
|
|
440
|
+
// ============================================================================
|
|
441
|
+
function registerContextTools(server, client) {
|
|
442
|
+
server.tool('create_context', `Create a context node. Contexts capture requirements, specs, design decisions, or references to codebase files.
|
|
443
|
+
|
|
444
|
+
Source types:
|
|
445
|
+
- file: Reference a codebase file (content resolved on access, not stored)
|
|
446
|
+
- inline (default): Content stored directly in the node
|
|
447
|
+
- snippet: Reference specific lines in a file`, {
|
|
448
|
+
title: z.string().optional().describe('Context title (auto-derived from file path if source is file/snippet)'),
|
|
449
|
+
content: z.string().optional().describe('Markdown content (for inline contexts)'),
|
|
450
|
+
priority: z.number().optional().describe('Priority 0=highest, 4=lowest'),
|
|
451
|
+
tags: z.array(z.string()).optional().describe('Tags for categorization'),
|
|
452
|
+
parent_id: z.string().optional().describe('Parent node ID'),
|
|
453
|
+
metadata: z.record(z.string(), z.unknown()).optional().describe('Additional metadata'),
|
|
454
|
+
scheme: z.string().optional().describe('Provider scheme to route creation to'),
|
|
455
|
+
source: z.discriminatedUnion('type', [
|
|
456
|
+
z.object({
|
|
457
|
+
type: z.literal('file'),
|
|
458
|
+
path: z.string().describe('Repo-relative file path'),
|
|
459
|
+
commit: z.string().optional().describe('Pin to specific commit (default: HEAD)'),
|
|
460
|
+
}),
|
|
461
|
+
z.object({
|
|
462
|
+
type: z.literal('snippet'),
|
|
463
|
+
path: z.string().describe('Repo-relative file path'),
|
|
464
|
+
startLine: z.number().describe('Start line number'),
|
|
465
|
+
endLine: z.number().describe('End line number'),
|
|
466
|
+
}),
|
|
467
|
+
]).optional().describe('Content source. Omit for inline content stored in the node.'),
|
|
468
|
+
}, async (args) => {
|
|
469
|
+
try {
|
|
470
|
+
const { scheme, source, ...params } = args;
|
|
471
|
+
// File-backed context — delegate to contextFiles.create
|
|
472
|
+
if (source?.type === 'file') {
|
|
473
|
+
const result = await client.createContextFile({
|
|
474
|
+
filePath: source.path,
|
|
475
|
+
title: params.title,
|
|
476
|
+
tags: params.tags,
|
|
477
|
+
priority: params.priority,
|
|
478
|
+
commit: source.commit,
|
|
479
|
+
});
|
|
480
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
481
|
+
}
|
|
482
|
+
// Snippet context — create as file-backed with line range in metadata
|
|
483
|
+
if (source?.type === 'snippet') {
|
|
484
|
+
const result = await client.createContextFile({
|
|
485
|
+
filePath: source.path,
|
|
486
|
+
title: params.title,
|
|
487
|
+
tags: params.tags,
|
|
488
|
+
priority: params.priority,
|
|
489
|
+
});
|
|
490
|
+
// Update with snippet-specific metadata
|
|
491
|
+
const updated = await client.updateNode(result.id, {
|
|
492
|
+
metadata: {
|
|
493
|
+
...(result.metadata ?? {}),
|
|
494
|
+
context_source: 'snippet',
|
|
495
|
+
context_line_start: source.startLine,
|
|
496
|
+
context_line_end: source.endLine,
|
|
497
|
+
},
|
|
498
|
+
});
|
|
499
|
+
return { content: [{ type: 'text', text: JSON.stringify(updated, null, 2) }] };
|
|
500
|
+
}
|
|
501
|
+
// Inline context — existing behavior
|
|
502
|
+
if (!params.title) {
|
|
503
|
+
return errorResult(new Error('title is required for inline contexts'));
|
|
504
|
+
}
|
|
505
|
+
const result = await client.createNode({ type: 'context', ...params, title: params.title }, scheme ? { scheme } : undefined);
|
|
506
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
507
|
+
}
|
|
508
|
+
catch (error) {
|
|
509
|
+
return errorResult(error);
|
|
510
|
+
}
|
|
511
|
+
});
|
|
512
|
+
server.tool('get_context', `Get a context node by ID. For file-backed contexts, optionally resolve the file content.
|
|
513
|
+
|
|
514
|
+
By default returns the node metadata (lightweight). Use resolve: true to include file content.`, {
|
|
515
|
+
id: z.string().describe('Context ID or provider URI'),
|
|
516
|
+
resolve: z.boolean().optional().describe('Resolve file content for file-backed contexts (default: false)'),
|
|
517
|
+
atCapturedCommit: z.boolean().optional()
|
|
518
|
+
.describe('Resolve at the originally captured commit instead of current worktree (only with resolve: true)'),
|
|
519
|
+
}, async (args) => {
|
|
520
|
+
try {
|
|
521
|
+
const node = await client.getNode(args.id);
|
|
522
|
+
if (!node) {
|
|
523
|
+
return {
|
|
524
|
+
content: [{ type: 'text', text: JSON.stringify({ error: 'Context not found', id: args.id }) }],
|
|
525
|
+
isError: true,
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
// If resolve requested and this is a file-backed context, include content
|
|
529
|
+
if (args.resolve) {
|
|
530
|
+
const metadata = node.metadata;
|
|
531
|
+
if (metadata?.context_file === true) {
|
|
532
|
+
try {
|
|
533
|
+
const resolution = await client.resolveContextFile(args.id, args.atCapturedCommit);
|
|
534
|
+
return {
|
|
535
|
+
content: [{
|
|
536
|
+
type: 'text',
|
|
537
|
+
text: JSON.stringify({ ...node, _resolved: resolution }, null, 2),
|
|
538
|
+
}],
|
|
539
|
+
};
|
|
540
|
+
}
|
|
541
|
+
catch (resolveError) {
|
|
542
|
+
// Return node + resolution error (file may have been deleted)
|
|
543
|
+
return {
|
|
544
|
+
content: [{
|
|
545
|
+
type: 'text',
|
|
546
|
+
text: JSON.stringify({
|
|
547
|
+
...node,
|
|
548
|
+
_resolved: { error: errorMessage(resolveError) },
|
|
549
|
+
}, null, 2),
|
|
550
|
+
}],
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
return { content: [{ type: 'text', text: JSON.stringify(node, null, 2) }] };
|
|
556
|
+
}
|
|
557
|
+
catch (error) {
|
|
558
|
+
return errorResult(error);
|
|
559
|
+
}
|
|
560
|
+
});
|
|
561
|
+
server.tool('update_context', `Update a context node. For file-backed contexts, use sync: true to re-pin to current HEAD.`, {
|
|
562
|
+
id: z.string().describe('Context ID or provider URI'),
|
|
563
|
+
title: z.string().optional(),
|
|
564
|
+
content: z.string().optional(),
|
|
565
|
+
priority: z.number().optional(),
|
|
566
|
+
archived: z.boolean().optional(),
|
|
567
|
+
metadata: z.record(z.string(), z.unknown()).optional().describe('Metadata (merged with existing)'),
|
|
568
|
+
// Context-file specific
|
|
569
|
+
sync: z.boolean().optional().describe('Re-pin file-backed context to current HEAD'),
|
|
570
|
+
force: z.boolean().optional().describe('Force sync even if content hash unchanged (with sync: true)'),
|
|
571
|
+
}, async (args) => {
|
|
572
|
+
try {
|
|
573
|
+
const { id, sync, force, ...updates } = args;
|
|
574
|
+
const results = [];
|
|
575
|
+
// Apply field updates if any
|
|
576
|
+
const hasFieldUpdates = Object.values(updates).some((v) => v !== undefined);
|
|
577
|
+
if (hasFieldUpdates) {
|
|
578
|
+
try {
|
|
579
|
+
const updateResult = await client.updateNode(id, updates);
|
|
580
|
+
results.push({ op: 'update', success: true, result: updateResult });
|
|
581
|
+
}
|
|
582
|
+
catch (error) {
|
|
583
|
+
results.push({ op: 'update', success: false, error: errorMessage(error) });
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
// Sync file-backed context if requested
|
|
587
|
+
if (sync) {
|
|
588
|
+
try {
|
|
589
|
+
const syncResult = await client.syncContextFile(id, { force });
|
|
590
|
+
results.push({ op: 'sync', success: true, result: syncResult });
|
|
591
|
+
}
|
|
592
|
+
catch (error) {
|
|
593
|
+
results.push({ op: 'sync', success: false, error: errorMessage(error) });
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
if (results.length === 0) {
|
|
597
|
+
return { content: [{ type: 'text', text: JSON.stringify({ error: 'No operations specified' }) }], isError: true };
|
|
598
|
+
}
|
|
599
|
+
const anyFailed = results.some((r) => !r.success);
|
|
600
|
+
const output = results.length === 1 ? results[0].result : { operations: results };
|
|
601
|
+
return {
|
|
602
|
+
content: [{ type: 'text', text: JSON.stringify(output, null, 2) }],
|
|
603
|
+
isError: anyFailed,
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
catch (error) {
|
|
607
|
+
return errorResult(error);
|
|
608
|
+
}
|
|
609
|
+
});
|
|
610
|
+
server.tool('list_contexts', `List and filter context nodes. Optionally check drift status for file-backed contexts.`, {
|
|
611
|
+
tags: z.array(z.string()).optional().describe('Filter by tags'),
|
|
612
|
+
search: z.string().optional().describe('Text search in title and content'),
|
|
613
|
+
archived: z.boolean().optional().describe('Include archived (default: false)'),
|
|
614
|
+
limit: z.number().optional().describe('Maximum results (default: 50)'),
|
|
615
|
+
offset: z.number().optional().describe('Pagination offset'),
|
|
616
|
+
// Context-file specific
|
|
617
|
+
filesOnly: z.boolean().optional().describe('Only return file-backed contexts'),
|
|
618
|
+
checkDrift: z.boolean().optional().describe('Include drift status for file-backed contexts'),
|
|
619
|
+
}, async (args) => {
|
|
620
|
+
try {
|
|
621
|
+
const { filesOnly, checkDrift, ...queryArgs } = args;
|
|
622
|
+
const result = await client.query({
|
|
623
|
+
nodes: { type: 'context', ...queryArgs },
|
|
624
|
+
});
|
|
625
|
+
let items = result.items;
|
|
626
|
+
// Filter to file-backed only if requested
|
|
627
|
+
if (filesOnly) {
|
|
628
|
+
items = items.filter((item) => {
|
|
629
|
+
const meta = item.metadata;
|
|
630
|
+
return meta?.context_file === true;
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
// Check drift for file-backed contexts if requested
|
|
634
|
+
if (checkDrift) {
|
|
635
|
+
const fileItems = items.filter((item) => {
|
|
636
|
+
const meta = item.metadata;
|
|
637
|
+
return meta?.context_file === true;
|
|
638
|
+
});
|
|
639
|
+
if (fileItems.length > 0) {
|
|
640
|
+
const ids = fileItems.map((item) => item.id);
|
|
641
|
+
try {
|
|
642
|
+
const driftResults = await client.checkContextFileDriftBatch(ids);
|
|
643
|
+
// Attach drift info to each file-backed item
|
|
644
|
+
for (let i = 0; i < fileItems.length; i++) {
|
|
645
|
+
fileItems[i]._drift = driftResults[i];
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
catch {
|
|
649
|
+
// Best-effort: drift check may fail if files are deleted
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
return {
|
|
654
|
+
content: [{
|
|
655
|
+
type: 'text',
|
|
656
|
+
text: JSON.stringify({ ...result, items }, null, 2),
|
|
657
|
+
}],
|
|
658
|
+
};
|
|
659
|
+
}
|
|
660
|
+
catch (error) {
|
|
661
|
+
return errorResult(error);
|
|
662
|
+
}
|
|
663
|
+
});
|
|
664
|
+
}
|
|
665
|
+
// ============================================================================
|
|
666
|
+
// Helpers
|
|
667
|
+
// ============================================================================
|
|
668
|
+
function errorMessage(error) {
|
|
669
|
+
return error instanceof Error ? error.message : String(error);
|
|
670
|
+
}
|
|
671
|
+
function errorResult(error) {
|
|
672
|
+
return {
|
|
673
|
+
content: [{ type: 'text', text: JSON.stringify({ error: errorMessage(error) }) }],
|
|
674
|
+
isError: true,
|
|
675
|
+
};
|
|
676
|
+
}
|
|
677
|
+
//# sourceMappingURL=server.js.map
|