opentasks 0.0.7 → 0.0.9
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/dist/daemon/entire-linker.d.ts.map +1 -1
- package/dist/daemon/entire-linker.js +42 -48
- package/dist/daemon/entire-linker.js.map +1 -1
- package/dist/daemon/entire-watcher.d.ts +0 -11
- package/dist/daemon/entire-watcher.d.ts.map +1 -1
- package/dist/daemon/entire-watcher.js +1 -32
- package/dist/daemon/entire-watcher.js.map +1 -1
- package/dist/graph/query.js +3 -3
- package/dist/graph/query.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/providers/entire.d.ts +0 -10
- package/dist/providers/entire.d.ts.map +1 -1
- package/dist/providers/entire.js +0 -13
- package/dist/providers/entire.js.map +1 -1
- package/dist/providers/index.d.ts +1 -0
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +2 -0
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/map-connector.d.ts +87 -0
- package/dist/providers/map-connector.d.ts.map +1 -0
- package/dist/providers/map-connector.js +159 -0
- package/dist/providers/map-connector.js.map +1 -0
- package/dist/storage/interface.d.ts +6 -0
- package/dist/storage/interface.d.ts.map +1 -1
- package/dist/storage/interface.js.map +1 -1
- package/dist/storage/sqlite.d.ts +1 -0
- package/dist/storage/sqlite.d.ts.map +1 -1
- package/dist/storage/sqlite.js +11 -0
- package/dist/storage/sqlite.js.map +1 -1
- package/package.json +2 -2
- package/dist/__tests__/cli-tools.test.d.ts +0 -8
- package/dist/__tests__/cli-tools.test.d.ts.map +0 -1
- package/dist/__tests__/cli-tools.test.js +0 -546
- package/dist/__tests__/cli-tools.test.js.map +0 -1
- package/dist/__tests__/cli.test.d.ts +0 -5
- package/dist/__tests__/cli.test.d.ts.map +0 -1
- package/dist/__tests__/cli.test.js +0 -77
- package/dist/__tests__/cli.test.js.map +0 -1
- package/dist/__tests__/p1-p3-gaps.test.d.ts +0 -2
- package/dist/__tests__/p1-p3-gaps.test.d.ts.map +0 -1
- package/dist/__tests__/p1-p3-gaps.test.js +0 -463
- package/dist/__tests__/p1-p3-gaps.test.js.map +0 -1
- package/dist/client/__tests__/client-crud.test.d.ts +0 -7
- package/dist/client/__tests__/client-crud.test.d.ts.map +0 -1
- package/dist/client/__tests__/client-crud.test.js +0 -404
- package/dist/client/__tests__/client-crud.test.js.map +0 -1
- package/dist/client/__tests__/client.test.d.ts +0 -5
- package/dist/client/__tests__/client.test.d.ts.map +0 -1
- package/dist/client/__tests__/client.test.js +0 -518
- package/dist/client/__tests__/client.test.js.map +0 -1
- package/dist/config/__tests__/defaults.test.d.ts +0 -2
- package/dist/config/__tests__/defaults.test.d.ts.map +0 -1
- package/dist/config/__tests__/defaults.test.js +0 -57
- package/dist/config/__tests__/defaults.test.js.map +0 -1
- package/dist/config/__tests__/env.test.d.ts +0 -2
- package/dist/config/__tests__/env.test.d.ts.map +0 -1
- package/dist/config/__tests__/env.test.js +0 -136
- package/dist/config/__tests__/env.test.js.map +0 -1
- package/dist/config/__tests__/index.test.d.ts +0 -2
- package/dist/config/__tests__/index.test.d.ts.map +0 -1
- package/dist/config/__tests__/index.test.js +0 -113
- package/dist/config/__tests__/index.test.js.map +0 -1
- package/dist/config/__tests__/loader.test.d.ts +0 -2
- package/dist/config/__tests__/loader.test.d.ts.map +0 -1
- package/dist/config/__tests__/loader.test.js +0 -128
- package/dist/config/__tests__/loader.test.js.map +0 -1
- package/dist/config/__tests__/merge.test.d.ts +0 -2
- package/dist/config/__tests__/merge.test.d.ts.map +0 -1
- package/dist/config/__tests__/merge.test.js +0 -79
- package/dist/config/__tests__/merge.test.js.map +0 -1
- package/dist/config/__tests__/schema.test.d.ts +0 -2
- package/dist/config/__tests__/schema.test.d.ts.map +0 -1
- package/dist/config/__tests__/schema.test.js +0 -300
- package/dist/config/__tests__/schema.test.js.map +0 -1
- package/dist/core/__tests__/conditional-redirects.test.d.ts +0 -2
- package/dist/core/__tests__/conditional-redirects.test.d.ts.map +0 -1
- package/dist/core/__tests__/conditional-redirects.test.js +0 -83
- package/dist/core/__tests__/conditional-redirects.test.js.map +0 -1
- package/dist/core/__tests__/connections.test.d.ts +0 -2
- package/dist/core/__tests__/connections.test.d.ts.map +0 -1
- package/dist/core/__tests__/connections.test.js +0 -158
- package/dist/core/__tests__/connections.test.js.map +0 -1
- package/dist/core/__tests__/hash.test.d.ts +0 -2
- package/dist/core/__tests__/hash.test.d.ts.map +0 -1
- package/dist/core/__tests__/hash.test.js +0 -139
- package/dist/core/__tests__/hash.test.js.map +0 -1
- package/dist/core/__tests__/id.test.d.ts +0 -2
- package/dist/core/__tests__/id.test.d.ts.map +0 -1
- package/dist/core/__tests__/id.test.js +0 -142
- package/dist/core/__tests__/id.test.js.map +0 -1
- package/dist/core/__tests__/location.test.d.ts +0 -2
- package/dist/core/__tests__/location.test.d.ts.map +0 -1
- package/dist/core/__tests__/location.test.js +0 -77
- package/dist/core/__tests__/location.test.js.map +0 -1
- package/dist/core/__tests__/merge-driver.test.d.ts +0 -2
- package/dist/core/__tests__/merge-driver.test.d.ts.map +0 -1
- package/dist/core/__tests__/merge-driver.test.js +0 -218
- package/dist/core/__tests__/merge-driver.test.js.map +0 -1
- package/dist/core/__tests__/redirects.test.d.ts +0 -2
- package/dist/core/__tests__/redirects.test.d.ts.map +0 -1
- package/dist/core/__tests__/redirects.test.js +0 -123
- package/dist/core/__tests__/redirects.test.js.map +0 -1
- package/dist/core/__tests__/resolve-location-target.test.d.ts +0 -8
- package/dist/core/__tests__/resolve-location-target.test.d.ts.map +0 -1
- package/dist/core/__tests__/resolve-location-target.test.js +0 -303
- package/dist/core/__tests__/resolve-location-target.test.js.map +0 -1
- package/dist/core/__tests__/uri.test.d.ts +0 -2
- package/dist/core/__tests__/uri.test.d.ts.map +0 -1
- package/dist/core/__tests__/uri.test.js +0 -159
- package/dist/core/__tests__/uri.test.js.map +0 -1
- package/dist/core/__tests__/worktree.test.d.ts +0 -2
- package/dist/core/__tests__/worktree.test.d.ts.map +0 -1
- package/dist/core/__tests__/worktree.test.js +0 -120
- package/dist/core/__tests__/worktree.test.js.map +0 -1
- package/dist/daemon/__tests__/flush.test.d.ts +0 -5
- package/dist/daemon/__tests__/flush.test.d.ts.map +0 -1
- package/dist/daemon/__tests__/flush.test.js +0 -213
- package/dist/daemon/__tests__/flush.test.js.map +0 -1
- package/dist/daemon/__tests__/integration.test.d.ts +0 -7
- package/dist/daemon/__tests__/integration.test.d.ts.map +0 -1
- package/dist/daemon/__tests__/integration.test.js +0 -276
- package/dist/daemon/__tests__/integration.test.js.map +0 -1
- package/dist/daemon/__tests__/ipc.test.d.ts +0 -5
- package/dist/daemon/__tests__/ipc.test.d.ts.map +0 -1
- package/dist/daemon/__tests__/ipc.test.js +0 -314
- package/dist/daemon/__tests__/ipc.test.js.map +0 -1
- package/dist/daemon/__tests__/lifecycle.test.d.ts +0 -5
- package/dist/daemon/__tests__/lifecycle.test.d.ts.map +0 -1
- package/dist/daemon/__tests__/lifecycle.test.js +0 -301
- package/dist/daemon/__tests__/lifecycle.test.js.map +0 -1
- package/dist/daemon/__tests__/lock.test.d.ts +0 -5
- package/dist/daemon/__tests__/lock.test.d.ts.map +0 -1
- package/dist/daemon/__tests__/lock.test.js +0 -192
- package/dist/daemon/__tests__/lock.test.js.map +0 -1
- package/dist/daemon/__tests__/methods/graph.test.d.ts +0 -5
- package/dist/daemon/__tests__/methods/graph.test.d.ts.map +0 -1
- package/dist/daemon/__tests__/methods/graph.test.js +0 -309
- package/dist/daemon/__tests__/methods/graph.test.js.map +0 -1
- package/dist/daemon/__tests__/methods/provider.test.d.ts +0 -7
- package/dist/daemon/__tests__/methods/provider.test.d.ts.map +0 -1
- package/dist/daemon/__tests__/methods/provider.test.js +0 -181
- package/dist/daemon/__tests__/methods/provider.test.js.map +0 -1
- package/dist/daemon/__tests__/methods/tools.test.d.ts +0 -5
- package/dist/daemon/__tests__/methods/tools.test.d.ts.map +0 -1
- package/dist/daemon/__tests__/methods/tools.test.js +0 -587
- package/dist/daemon/__tests__/methods/tools.test.js.map +0 -1
- package/dist/daemon/__tests__/multi-location.test.d.ts +0 -8
- package/dist/daemon/__tests__/multi-location.test.d.ts.map +0 -1
- package/dist/daemon/__tests__/multi-location.test.js +0 -669
- package/dist/daemon/__tests__/multi-location.test.js.map +0 -1
- package/dist/daemon/__tests__/registry.test.d.ts +0 -5
- package/dist/daemon/__tests__/registry.test.d.ts.map +0 -1
- package/dist/daemon/__tests__/registry.test.js +0 -208
- package/dist/daemon/__tests__/registry.test.js.map +0 -1
- package/dist/daemon/__tests__/watcher.test.d.ts +0 -5
- package/dist/daemon/__tests__/watcher.test.d.ts.map +0 -1
- package/dist/daemon/__tests__/watcher.test.js +0 -234
- package/dist/daemon/__tests__/watcher.test.js.map +0 -1
- package/dist/daemon/methods/__tests__/graph.test.d.ts +0 -5
- package/dist/daemon/methods/__tests__/graph.test.d.ts.map +0 -1
- package/dist/daemon/methods/__tests__/graph.test.js +0 -274
- package/dist/daemon/methods/__tests__/graph.test.js.map +0 -1
- package/dist/daemon/methods/__tests__/provider.test.d.ts +0 -5
- package/dist/daemon/methods/__tests__/provider.test.d.ts.map +0 -1
- package/dist/daemon/methods/__tests__/provider.test.js +0 -184
- package/dist/daemon/methods/__tests__/provider.test.js.map +0 -1
- package/dist/daemon/methods/__tests__/tools.test.d.ts +0 -5
- package/dist/daemon/methods/__tests__/tools.test.d.ts.map +0 -1
- package/dist/daemon/methods/__tests__/tools.test.js +0 -295
- package/dist/daemon/methods/__tests__/tools.test.js.map +0 -1
- package/dist/entire/agent/agents/claude-code.d.ts +0 -76
- package/dist/entire/agent/agents/claude-code.d.ts.map +0 -1
- package/dist/entire/agent/agents/claude-code.js +0 -759
- package/dist/entire/agent/agents/claude-code.js.map +0 -1
- package/dist/entire/agent/agents/cursor.d.ts +0 -35
- package/dist/entire/agent/agents/cursor.d.ts.map +0 -1
- package/dist/entire/agent/agents/cursor.js +0 -294
- package/dist/entire/agent/agents/cursor.js.map +0 -1
- package/dist/entire/agent/agents/gemini-cli.d.ts +0 -62
- package/dist/entire/agent/agents/gemini-cli.d.ts.map +0 -1
- package/dist/entire/agent/agents/gemini-cli.js +0 -462
- package/dist/entire/agent/agents/gemini-cli.js.map +0 -1
- package/dist/entire/agent/agents/opencode.d.ts +0 -100
- package/dist/entire/agent/agents/opencode.d.ts.map +0 -1
- package/dist/entire/agent/agents/opencode.js +0 -423
- package/dist/entire/agent/agents/opencode.js.map +0 -1
- package/dist/entire/agent/registry.d.ts +0 -54
- package/dist/entire/agent/registry.d.ts.map +0 -1
- package/dist/entire/agent/registry.js +0 -123
- package/dist/entire/agent/registry.js.map +0 -1
- package/dist/entire/agent/session-types.d.ts +0 -45
- package/dist/entire/agent/session-types.d.ts.map +0 -1
- package/dist/entire/agent/session-types.js +0 -50
- package/dist/entire/agent/session-types.js.map +0 -1
- package/dist/entire/agent/types.d.ts +0 -126
- package/dist/entire/agent/types.d.ts.map +0 -1
- package/dist/entire/agent/types.js +0 -39
- package/dist/entire/agent/types.js.map +0 -1
- package/dist/entire/commands/clean.d.ts +0 -30
- package/dist/entire/commands/clean.d.ts.map +0 -1
- package/dist/entire/commands/clean.js +0 -99
- package/dist/entire/commands/clean.js.map +0 -1
- package/dist/entire/commands/disable.d.ts +0 -23
- package/dist/entire/commands/disable.d.ts.map +0 -1
- package/dist/entire/commands/disable.js +0 -57
- package/dist/entire/commands/disable.js.map +0 -1
- package/dist/entire/commands/doctor.d.ts +0 -43
- package/dist/entire/commands/doctor.d.ts.map +0 -1
- package/dist/entire/commands/doctor.js +0 -97
- package/dist/entire/commands/doctor.js.map +0 -1
- package/dist/entire/commands/enable.d.ts +0 -29
- package/dist/entire/commands/enable.d.ts.map +0 -1
- package/dist/entire/commands/enable.js +0 -102
- package/dist/entire/commands/enable.js.map +0 -1
- package/dist/entire/commands/explain.d.ts +0 -68
- package/dist/entire/commands/explain.d.ts.map +0 -1
- package/dist/entire/commands/explain.js +0 -182
- package/dist/entire/commands/explain.js.map +0 -1
- package/dist/entire/commands/reset.d.ts +0 -23
- package/dist/entire/commands/reset.d.ts.map +0 -1
- package/dist/entire/commands/reset.js +0 -68
- package/dist/entire/commands/reset.js.map +0 -1
- package/dist/entire/commands/resume.d.ts +0 -42
- package/dist/entire/commands/resume.d.ts.map +0 -1
- package/dist/entire/commands/resume.js +0 -134
- package/dist/entire/commands/resume.js.map +0 -1
- package/dist/entire/commands/rewind.d.ts +0 -34
- package/dist/entire/commands/rewind.d.ts.map +0 -1
- package/dist/entire/commands/rewind.js +0 -155
- package/dist/entire/commands/rewind.js.map +0 -1
- package/dist/entire/commands/status.d.ts +0 -51
- package/dist/entire/commands/status.d.ts.map +0 -1
- package/dist/entire/commands/status.js +0 -94
- package/dist/entire/commands/status.js.map +0 -1
- package/dist/entire/config.d.ts +0 -40
- package/dist/entire/config.d.ts.map +0 -1
- package/dist/entire/config.js +0 -126
- package/dist/entire/config.js.map +0 -1
- package/dist/entire/git-operations.d.ts +0 -170
- package/dist/entire/git-operations.d.ts.map +0 -1
- package/dist/entire/git-operations.js +0 -395
- package/dist/entire/git-operations.js.map +0 -1
- package/dist/entire/hooks/git-hooks.d.ts +0 -22
- package/dist/entire/hooks/git-hooks.d.ts.map +0 -1
- package/dist/entire/hooks/git-hooks.js +0 -145
- package/dist/entire/hooks/git-hooks.js.map +0 -1
- package/dist/entire/hooks/lifecycle.d.ts +0 -21
- package/dist/entire/hooks/lifecycle.d.ts.map +0 -1
- package/dist/entire/hooks/lifecycle.js +0 -179
- package/dist/entire/hooks/lifecycle.js.map +0 -1
- package/dist/entire/index.d.ts +0 -69
- package/dist/entire/index.d.ts.map +0 -1
- package/dist/entire/index.js +0 -152
- package/dist/entire/index.js.map +0 -1
- package/dist/entire/security/redaction.d.ts +0 -35
- package/dist/entire/security/redaction.d.ts.map +0 -1
- package/dist/entire/security/redaction.js +0 -221
- package/dist/entire/security/redaction.js.map +0 -1
- package/dist/entire/session/state-machine.d.ts +0 -90
- package/dist/entire/session/state-machine.d.ts.map +0 -1
- package/dist/entire/session/state-machine.js +0 -347
- package/dist/entire/session/state-machine.js.map +0 -1
- package/dist/entire/store/checkpoint-store.d.ts +0 -47
- package/dist/entire/store/checkpoint-store.d.ts.map +0 -1
- package/dist/entire/store/checkpoint-store.js +0 -307
- package/dist/entire/store/checkpoint-store.js.map +0 -1
- package/dist/entire/store/native-store.d.ts +0 -14
- package/dist/entire/store/native-store.d.ts.map +0 -1
- package/dist/entire/store/native-store.js +0 -159
- package/dist/entire/store/native-store.js.map +0 -1
- package/dist/entire/store/provider-types.d.ts +0 -78
- package/dist/entire/store/provider-types.d.ts.map +0 -1
- package/dist/entire/store/provider-types.js +0 -12
- package/dist/entire/store/provider-types.js.map +0 -1
- package/dist/entire/store/session-store.d.ts +0 -28
- package/dist/entire/store/session-store.d.ts.map +0 -1
- package/dist/entire/store/session-store.js +0 -187
- package/dist/entire/store/session-store.js.map +0 -1
- package/dist/entire/strategy/attribution.d.ts +0 -39
- package/dist/entire/strategy/attribution.d.ts.map +0 -1
- package/dist/entire/strategy/attribution.js +0 -227
- package/dist/entire/strategy/attribution.js.map +0 -1
- package/dist/entire/strategy/common.d.ts +0 -57
- package/dist/entire/strategy/common.d.ts.map +0 -1
- package/dist/entire/strategy/common.js +0 -156
- package/dist/entire/strategy/common.js.map +0 -1
- package/dist/entire/strategy/content-overlap.d.ts +0 -33
- package/dist/entire/strategy/content-overlap.d.ts.map +0 -1
- package/dist/entire/strategy/content-overlap.js +0 -168
- package/dist/entire/strategy/content-overlap.js.map +0 -1
- package/dist/entire/strategy/manual-commit.d.ts +0 -31
- package/dist/entire/strategy/manual-commit.d.ts.map +0 -1
- package/dist/entire/strategy/manual-commit.js +0 -730
- package/dist/entire/strategy/manual-commit.js.map +0 -1
- package/dist/entire/strategy/types.d.ts +0 -163
- package/dist/entire/strategy/types.d.ts.map +0 -1
- package/dist/entire/strategy/types.js +0 -49
- package/dist/entire/strategy/types.js.map +0 -1
- package/dist/entire/summarize/claude-generator.d.ts +0 -25
- package/dist/entire/summarize/claude-generator.d.ts.map +0 -1
- package/dist/entire/summarize/claude-generator.js +0 -87
- package/dist/entire/summarize/claude-generator.js.map +0 -1
- package/dist/entire/summarize/summarize.d.ts +0 -52
- package/dist/entire/summarize/summarize.d.ts.map +0 -1
- package/dist/entire/summarize/summarize.js +0 -335
- package/dist/entire/summarize/summarize.js.map +0 -1
- package/dist/entire/types.d.ts +0 -288
- package/dist/entire/types.d.ts.map +0 -1
- package/dist/entire/types.js +0 -94
- package/dist/entire/types.js.map +0 -1
- package/dist/entire/utils/chunk-files.d.ts +0 -25
- package/dist/entire/utils/chunk-files.d.ts.map +0 -1
- package/dist/entire/utils/chunk-files.js +0 -47
- package/dist/entire/utils/chunk-files.js.map +0 -1
- package/dist/entire/utils/commit-message.d.ts +0 -11
- package/dist/entire/utils/commit-message.d.ts.map +0 -1
- package/dist/entire/utils/commit-message.js +0 -54
- package/dist/entire/utils/commit-message.js.map +0 -1
- package/dist/entire/utils/detect-agent.d.ts +0 -19
- package/dist/entire/utils/detect-agent.d.ts.map +0 -1
- package/dist/entire/utils/detect-agent.js +0 -34
- package/dist/entire/utils/detect-agent.js.map +0 -1
- package/dist/entire/utils/hook-managers.d.ts +0 -24
- package/dist/entire/utils/hook-managers.d.ts.map +0 -1
- package/dist/entire/utils/hook-managers.js +0 -87
- package/dist/entire/utils/hook-managers.js.map +0 -1
- package/dist/entire/utils/ide-tags.d.ts +0 -12
- package/dist/entire/utils/ide-tags.d.ts.map +0 -1
- package/dist/entire/utils/ide-tags.js +0 -30
- package/dist/entire/utils/ide-tags.js.map +0 -1
- package/dist/entire/utils/paths.d.ts +0 -32
- package/dist/entire/utils/paths.d.ts.map +0 -1
- package/dist/entire/utils/paths.js +0 -55
- package/dist/entire/utils/paths.js.map +0 -1
- package/dist/entire/utils/preview-rewind.d.ts +0 -23
- package/dist/entire/utils/preview-rewind.d.ts.map +0 -1
- package/dist/entire/utils/preview-rewind.js +0 -63
- package/dist/entire/utils/preview-rewind.js.map +0 -1
- package/dist/entire/utils/rewind-conflict.d.ts +0 -52
- package/dist/entire/utils/rewind-conflict.d.ts.map +0 -1
- package/dist/entire/utils/rewind-conflict.js +0 -79
- package/dist/entire/utils/rewind-conflict.js.map +0 -1
- package/dist/entire/utils/shadow-branch.d.ts +0 -44
- package/dist/entire/utils/shadow-branch.d.ts.map +0 -1
- package/dist/entire/utils/shadow-branch.js +0 -93
- package/dist/entire/utils/shadow-branch.js.map +0 -1
- package/dist/entire/utils/string-utils.d.ts +0 -24
- package/dist/entire/utils/string-utils.d.ts.map +0 -1
- package/dist/entire/utils/string-utils.js +0 -47
- package/dist/entire/utils/string-utils.js.map +0 -1
- package/dist/entire/utils/todo-extract.d.ts +0 -52
- package/dist/entire/utils/todo-extract.d.ts.map +0 -1
- package/dist/entire/utils/todo-extract.js +0 -167
- package/dist/entire/utils/todo-extract.js.map +0 -1
- package/dist/entire/utils/trailers.d.ts +0 -36
- package/dist/entire/utils/trailers.d.ts.map +0 -1
- package/dist/entire/utils/trailers.js +0 -149
- package/dist/entire/utils/trailers.js.map +0 -1
- package/dist/entire/utils/transcript-parse.d.ts +0 -57
- package/dist/entire/utils/transcript-parse.d.ts.map +0 -1
- package/dist/entire/utils/transcript-parse.js +0 -126
- package/dist/entire/utils/transcript-parse.js.map +0 -1
- package/dist/entire/utils/transcript-timestamp.d.ts +0 -22
- package/dist/entire/utils/transcript-timestamp.d.ts.map +0 -1
- package/dist/entire/utils/transcript-timestamp.js +0 -56
- package/dist/entire/utils/transcript-timestamp.js.map +0 -1
- package/dist/entire/utils/tree-ops.d.ts +0 -47
- package/dist/entire/utils/tree-ops.d.ts.map +0 -1
- package/dist/entire/utils/tree-ops.js +0 -145
- package/dist/entire/utils/tree-ops.js.map +0 -1
- package/dist/entire/utils/tty.d.ts +0 -25
- package/dist/entire/utils/tty.d.ts.map +0 -1
- package/dist/entire/utils/tty.js +0 -70
- package/dist/entire/utils/tty.js.map +0 -1
- package/dist/entire/utils/validation.d.ts +0 -31
- package/dist/entire/utils/validation.d.ts.map +0 -1
- package/dist/entire/utils/validation.js +0 -59
- package/dist/entire/utils/validation.js.map +0 -1
- package/dist/entire/utils/worktree.d.ts +0 -16
- package/dist/entire/utils/worktree.d.ts.map +0 -1
- package/dist/entire/utils/worktree.js +0 -50
- package/dist/entire/utils/worktree.js.map +0 -1
- package/dist/graph/__tests__/EdgeTypeRegistry.test.d.ts +0 -2
- package/dist/graph/__tests__/EdgeTypeRegistry.test.d.ts.map +0 -1
- package/dist/graph/__tests__/EdgeTypeRegistry.test.js +0 -212
- package/dist/graph/__tests__/EdgeTypeRegistry.test.js.map +0 -1
- package/dist/graph/__tests__/FederatedGraph.test.d.ts +0 -2
- package/dist/graph/__tests__/FederatedGraph.test.d.ts.map +0 -1
- package/dist/graph/__tests__/FederatedGraph.test.js +0 -661
- package/dist/graph/__tests__/FederatedGraph.test.js.map +0 -1
- package/dist/graph/__tests__/GraphologyAdapter.test.d.ts +0 -2
- package/dist/graph/__tests__/GraphologyAdapter.test.d.ts.map +0 -1
- package/dist/graph/__tests__/GraphologyAdapter.test.js +0 -326
- package/dist/graph/__tests__/GraphologyAdapter.test.js.map +0 -1
- package/dist/graph/__tests__/HydratingFederatedGraph.test.d.ts +0 -2
- package/dist/graph/__tests__/HydratingFederatedGraph.test.d.ts.map +0 -1
- package/dist/graph/__tests__/HydratingFederatedGraph.test.js +0 -587
- package/dist/graph/__tests__/HydratingFederatedGraph.test.js.map +0 -1
- package/dist/graph/__tests__/debounce.test.d.ts +0 -5
- package/dist/graph/__tests__/debounce.test.d.ts.map +0 -1
- package/dist/graph/__tests__/debounce.test.js +0 -195
- package/dist/graph/__tests__/debounce.test.js.map +0 -1
- package/dist/graph/__tests__/edge-cases.test.d.ts +0 -8
- package/dist/graph/__tests__/edge-cases.test.d.ts.map +0 -1
- package/dist/graph/__tests__/edge-cases.test.js +0 -472
- package/dist/graph/__tests__/edge-cases.test.js.map +0 -1
- package/dist/graph/__tests__/expansion.test.d.ts +0 -2
- package/dist/graph/__tests__/expansion.test.d.ts.map +0 -1
- package/dist/graph/__tests__/expansion.test.js +0 -105
- package/dist/graph/__tests__/expansion.test.js.map +0 -1
- package/dist/graph/__tests__/provider-store.test.d.ts +0 -5
- package/dist/graph/__tests__/provider-store.test.d.ts.map +0 -1
- package/dist/graph/__tests__/provider-store.test.js +0 -791
- package/dist/graph/__tests__/provider-store.test.js.map +0 -1
- package/dist/graph/__tests__/query.test.d.ts +0 -5
- package/dist/graph/__tests__/query.test.d.ts.map +0 -1
- package/dist/graph/__tests__/query.test.js +0 -774
- package/dist/graph/__tests__/query.test.js.map +0 -1
- package/dist/graph/__tests__/store.test.d.ts +0 -5
- package/dist/graph/__tests__/store.test.d.ts.map +0 -1
- package/dist/graph/__tests__/store.test.js +0 -489
- package/dist/graph/__tests__/store.test.js.map +0 -1
- package/dist/graph/__tests__/sync.test.d.ts +0 -5
- package/dist/graph/__tests__/sync.test.d.ts.map +0 -1
- package/dist/graph/__tests__/sync.test.js +0 -129
- package/dist/graph/__tests__/sync.test.js.map +0 -1
- package/dist/graph/__tests__/validation.test.d.ts +0 -2
- package/dist/graph/__tests__/validation.test.d.ts.map +0 -1
- package/dist/graph/__tests__/validation.test.js +0 -521
- package/dist/graph/__tests__/validation.test.js.map +0 -1
- package/dist/providers/__tests__/beads.test.d.ts +0 -5
- package/dist/providers/__tests__/beads.test.d.ts.map +0 -1
- package/dist/providers/__tests__/beads.test.js +0 -591
- package/dist/providers/__tests__/beads.test.js.map +0 -1
- package/dist/providers/__tests__/claude-tasks.test.d.ts +0 -5
- package/dist/providers/__tests__/claude-tasks.test.d.ts.map +0 -1
- package/dist/providers/__tests__/claude-tasks.test.js +0 -392
- package/dist/providers/__tests__/claude-tasks.test.js.map +0 -1
- package/dist/providers/__tests__/from-config.test.d.ts +0 -5
- package/dist/providers/__tests__/from-config.test.d.ts.map +0 -1
- package/dist/providers/__tests__/from-config.test.js +0 -152
- package/dist/providers/__tests__/from-config.test.js.map +0 -1
- package/dist/providers/__tests__/materialization.test.d.ts +0 -5
- package/dist/providers/__tests__/materialization.test.d.ts.map +0 -1
- package/dist/providers/__tests__/materialization.test.js +0 -407
- package/dist/providers/__tests__/materialization.test.js.map +0 -1
- package/dist/providers/__tests__/native.test.d.ts +0 -5
- package/dist/providers/__tests__/native.test.d.ts.map +0 -1
- package/dist/providers/__tests__/native.test.js +0 -566
- package/dist/providers/__tests__/native.test.js.map +0 -1
- package/dist/providers/__tests__/registry.test.d.ts +0 -5
- package/dist/providers/__tests__/registry.test.d.ts.map +0 -1
- package/dist/providers/__tests__/registry.test.js +0 -183
- package/dist/providers/__tests__/registry.test.js.map +0 -1
- package/dist/providers/traits/__tests__/RelationshipQueryable.test.d.ts +0 -2
- package/dist/providers/traits/__tests__/RelationshipQueryable.test.d.ts.map +0 -1
- package/dist/providers/traits/__tests__/RelationshipQueryable.test.js +0 -169
- package/dist/providers/traits/__tests__/RelationshipQueryable.test.js.map +0 -1
- package/dist/providers/traits/__tests__/TaskManageable.test.d.ts +0 -2
- package/dist/providers/traits/__tests__/TaskManageable.test.d.ts.map +0 -1
- package/dist/providers/traits/__tests__/TaskManageable.test.js +0 -172
- package/dist/providers/traits/__tests__/TaskManageable.test.js.map +0 -1
- package/dist/schema/__tests__/validation.test.d.ts +0 -2
- package/dist/schema/__tests__/validation.test.d.ts.map +0 -1
- package/dist/schema/__tests__/validation.test.js +0 -241
- package/dist/schema/__tests__/validation.test.js.map +0 -1
- package/dist/storage/__tests__/atomic-write.test.d.ts +0 -5
- package/dist/storage/__tests__/atomic-write.test.d.ts.map +0 -1
- package/dist/storage/__tests__/atomic-write.test.js +0 -170
- package/dist/storage/__tests__/atomic-write.test.js.map +0 -1
- package/dist/storage/__tests__/file-lock.test.d.ts +0 -2
- package/dist/storage/__tests__/file-lock.test.d.ts.map +0 -1
- package/dist/storage/__tests__/file-lock.test.js +0 -89
- package/dist/storage/__tests__/file-lock.test.js.map +0 -1
- package/dist/storage/__tests__/jsonl.test.d.ts +0 -2
- package/dist/storage/__tests__/jsonl.test.d.ts.map +0 -1
- package/dist/storage/__tests__/jsonl.test.js +0 -228
- package/dist/storage/__tests__/jsonl.test.js.map +0 -1
- package/dist/storage/__tests__/locked-writer.test.d.ts +0 -2
- package/dist/storage/__tests__/locked-writer.test.d.ts.map +0 -1
- package/dist/storage/__tests__/locked-writer.test.js +0 -109
- package/dist/storage/__tests__/locked-writer.test.js.map +0 -1
- package/dist/storage/__tests__/sqlite.test.d.ts +0 -2
- package/dist/storage/__tests__/sqlite.test.d.ts.map +0 -1
- package/dist/storage/__tests__/sqlite.test.js +0 -470
- package/dist/storage/__tests__/sqlite.test.js.map +0 -1
- package/dist/tools/__tests__/annotate.test.d.ts +0 -5
- package/dist/tools/__tests__/annotate.test.d.ts.map +0 -1
- package/dist/tools/__tests__/annotate.test.js +0 -314
- package/dist/tools/__tests__/annotate.test.js.map +0 -1
- package/dist/tools/__tests__/link.test.d.ts +0 -5
- package/dist/tools/__tests__/link.test.d.ts.map +0 -1
- package/dist/tools/__tests__/link.test.js +0 -245
- package/dist/tools/__tests__/link.test.js.map +0 -1
- package/dist/tools/__tests__/query.test.d.ts +0 -5
- package/dist/tools/__tests__/query.test.d.ts.map +0 -1
- package/dist/tools/__tests__/query.test.js +0 -288
- package/dist/tools/__tests__/query.test.js.map +0 -1
- package/dist/tools/__tests__/task.test.d.ts +0 -5
- package/dist/tools/__tests__/task.test.d.ts.map +0 -1
- package/dist/tools/__tests__/task.test.js +0 -178
- package/dist/tools/__tests__/task.test.js.map +0 -1
|
@@ -1,791 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for Provider-Aware Graph Store
|
|
3
|
-
*/
|
|
4
|
-
import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest';
|
|
5
|
-
import { createProviderAwareStore, } from '../provider-store.js';
|
|
6
|
-
import { createProviderRegistry } from '../../providers/registry.js';
|
|
7
|
-
describe('ProviderAwareStore', () => {
|
|
8
|
-
let baseStore;
|
|
9
|
-
let providerStore;
|
|
10
|
-
let mockBeadsProvider;
|
|
11
|
-
// Mock nodes
|
|
12
|
-
const mockSpec = {
|
|
13
|
-
id: 's-abc1',
|
|
14
|
-
uuid: 'uuid-1',
|
|
15
|
-
type: 'spec',
|
|
16
|
-
title: 'Test Spec',
|
|
17
|
-
content: 'Spec content',
|
|
18
|
-
created_at: '2024-01-01T00:00:00.000Z',
|
|
19
|
-
updated_at: '2024-01-01T00:00:00.000Z',
|
|
20
|
-
};
|
|
21
|
-
const mockExternalNode = {
|
|
22
|
-
id: 'x-ext1',
|
|
23
|
-
uuid: 'uuid-ext-1',
|
|
24
|
-
type: 'external',
|
|
25
|
-
title: 'External Issue',
|
|
26
|
-
uri: 'beads://./bd-123',
|
|
27
|
-
source: 'beads',
|
|
28
|
-
materialized: true,
|
|
29
|
-
cached_at: new Date().toISOString(),
|
|
30
|
-
created_at: '2024-01-01T00:00:00.000Z',
|
|
31
|
-
updated_at: '2024-01-01T00:00:00.000Z',
|
|
32
|
-
};
|
|
33
|
-
const mockProviderNode = {
|
|
34
|
-
id: 'bd-123',
|
|
35
|
-
uri: 'beads://./bd-123',
|
|
36
|
-
type: 'issue',
|
|
37
|
-
title: 'Beads Issue',
|
|
38
|
-
content: 'Issue content',
|
|
39
|
-
status: 'open',
|
|
40
|
-
priority: 2,
|
|
41
|
-
rawData: { custom: 'data' },
|
|
42
|
-
fetchedAt: '2024-01-01T00:00:00.000Z',
|
|
43
|
-
};
|
|
44
|
-
beforeEach(() => {
|
|
45
|
-
vi.useFakeTimers();
|
|
46
|
-
// Create mock base store
|
|
47
|
-
baseStore = {
|
|
48
|
-
getNode: vi.fn(),
|
|
49
|
-
createNode: vi.fn(),
|
|
50
|
-
updateNode: vi.fn(),
|
|
51
|
-
deleteNode: vi.fn(),
|
|
52
|
-
query: {
|
|
53
|
-
nodes: vi.fn().mockResolvedValue([]),
|
|
54
|
-
edges: vi.fn(),
|
|
55
|
-
blockers: vi.fn(),
|
|
56
|
-
blocking: vi.fn(),
|
|
57
|
-
ready: vi.fn(),
|
|
58
|
-
children: vi.fn(),
|
|
59
|
-
descendants: vi.fn(),
|
|
60
|
-
ancestors: vi.fn(),
|
|
61
|
-
feedback: vi.fn(),
|
|
62
|
-
},
|
|
63
|
-
initialize: vi.fn(),
|
|
64
|
-
close: vi.fn(),
|
|
65
|
-
flush: vi.fn(),
|
|
66
|
-
createEdge: vi.fn(),
|
|
67
|
-
getEdge: vi.fn(),
|
|
68
|
-
deleteEdge: vi.fn(),
|
|
69
|
-
restoreNode: vi.fn(),
|
|
70
|
-
addTags: vi.fn(),
|
|
71
|
-
removeTags: vi.fn(),
|
|
72
|
-
setTags: vi.fn(),
|
|
73
|
-
transaction: vi.fn(),
|
|
74
|
-
};
|
|
75
|
-
// Create mock beads provider
|
|
76
|
-
mockBeadsProvider = {
|
|
77
|
-
name: 'beads',
|
|
78
|
-
schemes: ['beads', 'bd'],
|
|
79
|
-
capabilities: { read: true, write: true, search: true, watch: false, mount: true, feedback: false },
|
|
80
|
-
parseUri: vi.fn((uri) => {
|
|
81
|
-
if (uri.startsWith('beads://') || uri.startsWith('bd://')) {
|
|
82
|
-
const id = uri.split('/').pop() || '';
|
|
83
|
-
return { scheme: 'beads', id, isRelative: uri.includes('/.') };
|
|
84
|
-
}
|
|
85
|
-
return null;
|
|
86
|
-
}),
|
|
87
|
-
buildUri: vi.fn((id) => `beads://./${id}`),
|
|
88
|
-
isValidUri: vi.fn((uri) => uri.startsWith('beads://') || uri.startsWith('bd://')),
|
|
89
|
-
get: vi.fn().mockResolvedValue(mockProviderNode),
|
|
90
|
-
list: vi.fn(),
|
|
91
|
-
create: vi.fn(),
|
|
92
|
-
update: vi.fn(),
|
|
93
|
-
delete: vi.fn(),
|
|
94
|
-
};
|
|
95
|
-
// Create provider store
|
|
96
|
-
providerStore = createProviderAwareStore(baseStore);
|
|
97
|
-
});
|
|
98
|
-
afterEach(() => {
|
|
99
|
-
providerStore.stopBackgroundSync();
|
|
100
|
-
vi.useRealTimers();
|
|
101
|
-
});
|
|
102
|
-
describe('initialization', () => {
|
|
103
|
-
it('should have providers registry', () => {
|
|
104
|
-
expect(providerStore.providers).toBeDefined();
|
|
105
|
-
expect(providerStore.providers.list).toBeDefined();
|
|
106
|
-
});
|
|
107
|
-
it('should have materialization manager', () => {
|
|
108
|
-
expect(providerStore.materialization).toBeDefined();
|
|
109
|
-
expect(providerStore.materialization.config).toBeDefined();
|
|
110
|
-
});
|
|
111
|
-
it('should auto-register native provider', () => {
|
|
112
|
-
const nativeProvider = providerStore.providers.get('native');
|
|
113
|
-
expect(nativeProvider).toBeDefined();
|
|
114
|
-
expect(nativeProvider?.name).toBe('native');
|
|
115
|
-
});
|
|
116
|
-
it('should not auto-register native provider when disabled', () => {
|
|
117
|
-
const storeWithoutNative = createProviderAwareStore(baseStore, {
|
|
118
|
-
autoRegisterNative: false,
|
|
119
|
-
});
|
|
120
|
-
expect(storeWithoutNative.providers.get('native')).toBeUndefined();
|
|
121
|
-
});
|
|
122
|
-
it('should use provided registry', () => {
|
|
123
|
-
const customRegistry = createProviderRegistry();
|
|
124
|
-
customRegistry.register(mockBeadsProvider);
|
|
125
|
-
const storeWithCustomRegistry = createProviderAwareStore(baseStore, {
|
|
126
|
-
registry: customRegistry,
|
|
127
|
-
autoRegisterNative: false,
|
|
128
|
-
});
|
|
129
|
-
expect(storeWithCustomRegistry.providers.get('beads')).toBe(mockBeadsProvider);
|
|
130
|
-
});
|
|
131
|
-
});
|
|
132
|
-
describe('resolveNode', () => {
|
|
133
|
-
describe('local IDs', () => {
|
|
134
|
-
it('should resolve local IDs via getNode', async () => {
|
|
135
|
-
vi.mocked(baseStore.getNode).mockResolvedValue(mockSpec);
|
|
136
|
-
const result = await providerStore.resolveNode('s-abc1');
|
|
137
|
-
expect(baseStore.getNode).toHaveBeenCalledWith('s-abc1');
|
|
138
|
-
expect(result).toBe(mockSpec);
|
|
139
|
-
});
|
|
140
|
-
it('should return null for non-existent local node', async () => {
|
|
141
|
-
vi.mocked(baseStore.getNode).mockResolvedValue(null);
|
|
142
|
-
const result = await providerStore.resolveNode('s-notfound');
|
|
143
|
-
expect(result).toBeNull();
|
|
144
|
-
});
|
|
145
|
-
it('should handle all local ID prefixes', async () => {
|
|
146
|
-
vi.mocked(baseStore.getNode).mockResolvedValue(mockSpec);
|
|
147
|
-
for (const prefix of ['s-', 'i-', 'f-', 'e-', 'x-']) {
|
|
148
|
-
await providerStore.resolveNode(`${prefix}abc1`);
|
|
149
|
-
expect(baseStore.getNode).toHaveBeenCalledWith(`${prefix}abc1`);
|
|
150
|
-
}
|
|
151
|
-
});
|
|
152
|
-
});
|
|
153
|
-
describe('external URIs', () => {
|
|
154
|
-
beforeEach(() => {
|
|
155
|
-
providerStore.providers.register(mockBeadsProvider);
|
|
156
|
-
});
|
|
157
|
-
it('should resolve URIs via provider', async () => {
|
|
158
|
-
vi.mocked(baseStore.query.nodes).mockResolvedValue([]);
|
|
159
|
-
const result = await providerStore.resolveNode('beads://./bd-123');
|
|
160
|
-
expect(mockBeadsProvider.get).toHaveBeenCalledWith('bd-123', undefined);
|
|
161
|
-
expect(result).toBeDefined();
|
|
162
|
-
});
|
|
163
|
-
it('should return null for unknown schemes', async () => {
|
|
164
|
-
const result = await providerStore.resolveNode('unknown://./something');
|
|
165
|
-
expect(result).toBeNull();
|
|
166
|
-
});
|
|
167
|
-
it('should use cached node when not stale', async () => {
|
|
168
|
-
const freshNode = {
|
|
169
|
-
...mockExternalNode,
|
|
170
|
-
cached_at: new Date().toISOString(),
|
|
171
|
-
};
|
|
172
|
-
vi.mocked(baseStore.query.nodes).mockResolvedValue([freshNode]);
|
|
173
|
-
const result = await providerStore.resolveNode('beads://./bd-123');
|
|
174
|
-
expect(mockBeadsProvider.get).not.toHaveBeenCalled();
|
|
175
|
-
expect(result).toEqual(freshNode);
|
|
176
|
-
});
|
|
177
|
-
it('should bypass cache when refresh=true', async () => {
|
|
178
|
-
const freshNode = {
|
|
179
|
-
...mockExternalNode,
|
|
180
|
-
cached_at: new Date().toISOString(),
|
|
181
|
-
};
|
|
182
|
-
vi.mocked(baseStore.query.nodes).mockResolvedValue([freshNode]);
|
|
183
|
-
await providerStore.resolveNode('beads://./bd-123', { refresh: true });
|
|
184
|
-
expect(mockBeadsProvider.get).toHaveBeenCalled();
|
|
185
|
-
});
|
|
186
|
-
it('should materialize when explicitly requested', async () => {
|
|
187
|
-
vi.mocked(baseStore.query.nodes).mockResolvedValue([]);
|
|
188
|
-
vi.mocked(baseStore.createNode).mockResolvedValue(mockExternalNode);
|
|
189
|
-
const result = await providerStore.resolveNode('beads://./bd-123', {
|
|
190
|
-
materialize: true,
|
|
191
|
-
});
|
|
192
|
-
expect(baseStore.createNode).toHaveBeenCalledWith(expect.objectContaining({
|
|
193
|
-
type: 'external',
|
|
194
|
-
uri: 'beads://./bd-123',
|
|
195
|
-
}));
|
|
196
|
-
});
|
|
197
|
-
it('should return provider node directly when not materializing', async () => {
|
|
198
|
-
vi.mocked(baseStore.query.nodes).mockResolvedValue([]);
|
|
199
|
-
const result = await providerStore.resolveNode('beads://./bd-123');
|
|
200
|
-
// With on-demand strategy (default), should not materialize without explicit flag
|
|
201
|
-
expect(baseStore.createNode).not.toHaveBeenCalled();
|
|
202
|
-
});
|
|
203
|
-
});
|
|
204
|
-
});
|
|
205
|
-
describe('materializeNode', () => {
|
|
206
|
-
beforeEach(() => {
|
|
207
|
-
providerStore.providers.register(mockBeadsProvider);
|
|
208
|
-
});
|
|
209
|
-
it('should create external node from provider data', async () => {
|
|
210
|
-
vi.mocked(baseStore.query.nodes).mockResolvedValue([]);
|
|
211
|
-
vi.mocked(baseStore.createNode).mockResolvedValue(mockExternalNode);
|
|
212
|
-
const result = await providerStore.materializeNode('beads://./bd-123');
|
|
213
|
-
expect(mockBeadsProvider.get).toHaveBeenCalledWith('bd-123');
|
|
214
|
-
expect(baseStore.createNode).toHaveBeenCalledWith(expect.objectContaining({
|
|
215
|
-
type: 'external',
|
|
216
|
-
uri: 'beads://./bd-123',
|
|
217
|
-
source: 'beads',
|
|
218
|
-
title: 'Beads Issue',
|
|
219
|
-
}));
|
|
220
|
-
});
|
|
221
|
-
it('should throw for unknown URI scheme', async () => {
|
|
222
|
-
await expect(providerStore.materializeNode('unknown://./something')).rejects.toThrow('No provider found');
|
|
223
|
-
});
|
|
224
|
-
it('should throw if node not found in provider', async () => {
|
|
225
|
-
vi.mocked(mockBeadsProvider.get).mockResolvedValue(null);
|
|
226
|
-
await expect(providerStore.materializeNode('beads://./bd-notfound')).rejects.toThrow('Node not found');
|
|
227
|
-
});
|
|
228
|
-
it('should update existing node if already materialized', async () => {
|
|
229
|
-
vi.mocked(baseStore.query.nodes).mockResolvedValue([mockExternalNode]);
|
|
230
|
-
vi.mocked(baseStore.updateNode).mockResolvedValue(mockExternalNode);
|
|
231
|
-
await providerStore.materializeNode('beads://./bd-123');
|
|
232
|
-
expect(baseStore.updateNode).toHaveBeenCalled();
|
|
233
|
-
expect(baseStore.createNode).not.toHaveBeenCalled();
|
|
234
|
-
});
|
|
235
|
-
});
|
|
236
|
-
describe('refreshNode', () => {
|
|
237
|
-
beforeEach(() => {
|
|
238
|
-
providerStore.providers.register(mockBeadsProvider);
|
|
239
|
-
});
|
|
240
|
-
it('should refresh an external node', async () => {
|
|
241
|
-
vi.mocked(baseStore.getNode).mockResolvedValue(mockExternalNode);
|
|
242
|
-
vi.mocked(baseStore.query.nodes).mockResolvedValue([mockExternalNode]);
|
|
243
|
-
vi.mocked(baseStore.updateNode).mockResolvedValue(mockExternalNode);
|
|
244
|
-
const result = await providerStore.refreshNode('x-ext1');
|
|
245
|
-
expect(mockBeadsProvider.get).toHaveBeenCalledWith('beads://./bd-123', undefined);
|
|
246
|
-
expect(baseStore.updateNode).toHaveBeenCalled();
|
|
247
|
-
});
|
|
248
|
-
it('should throw for non-external node', async () => {
|
|
249
|
-
vi.mocked(baseStore.getNode).mockResolvedValue(mockSpec);
|
|
250
|
-
await expect(providerStore.refreshNode('s-abc1')).rejects.toThrow('not external');
|
|
251
|
-
});
|
|
252
|
-
it('should throw for non-existent node', async () => {
|
|
253
|
-
vi.mocked(baseStore.getNode).mockResolvedValue(null);
|
|
254
|
-
await expect(providerStore.refreshNode('x-notfound')).rejects.toThrow('Node not found');
|
|
255
|
-
});
|
|
256
|
-
});
|
|
257
|
-
describe('background sync', () => {
|
|
258
|
-
it('should start and stop background sync', () => {
|
|
259
|
-
providerStore = createProviderAwareStore(baseStore, {
|
|
260
|
-
materialization: {
|
|
261
|
-
backgroundSyncInterval: 1000,
|
|
262
|
-
},
|
|
263
|
-
});
|
|
264
|
-
expect(providerStore.isBackgroundSyncRunning()).toBe(false);
|
|
265
|
-
providerStore.startBackgroundSync();
|
|
266
|
-
expect(providerStore.isBackgroundSyncRunning()).toBe(true);
|
|
267
|
-
providerStore.stopBackgroundSync();
|
|
268
|
-
expect(providerStore.isBackgroundSyncRunning()).toBe(false);
|
|
269
|
-
});
|
|
270
|
-
it('should not start if interval is 0', () => {
|
|
271
|
-
providerStore = createProviderAwareStore(baseStore, {
|
|
272
|
-
materialization: {
|
|
273
|
-
backgroundSyncInterval: 0,
|
|
274
|
-
},
|
|
275
|
-
});
|
|
276
|
-
providerStore.startBackgroundSync();
|
|
277
|
-
expect(providerStore.isBackgroundSyncRunning()).toBe(false);
|
|
278
|
-
});
|
|
279
|
-
});
|
|
280
|
-
describe('provider registration', () => {
|
|
281
|
-
it('should allow registering additional providers', () => {
|
|
282
|
-
providerStore.providers.register(mockBeadsProvider);
|
|
283
|
-
expect(providerStore.providers.get('beads')).toBe(mockBeadsProvider);
|
|
284
|
-
expect(providerStore.providers.canResolve('beads://./bd-123')).toBe(true);
|
|
285
|
-
});
|
|
286
|
-
it('should allow unregistering providers', () => {
|
|
287
|
-
providerStore.providers.register(mockBeadsProvider);
|
|
288
|
-
providerStore.providers.unregister('beads');
|
|
289
|
-
expect(providerStore.providers.get('beads')).toBeUndefined();
|
|
290
|
-
});
|
|
291
|
-
});
|
|
292
|
-
describe('base store methods', () => {
|
|
293
|
-
it('should pass through getNode to base store', async () => {
|
|
294
|
-
vi.mocked(baseStore.getNode).mockResolvedValue(mockSpec);
|
|
295
|
-
const result = await providerStore.getNode('s-abc1');
|
|
296
|
-
expect(baseStore.getNode).toHaveBeenCalledWith('s-abc1');
|
|
297
|
-
expect(result).toBe(mockSpec);
|
|
298
|
-
});
|
|
299
|
-
it('should pass through createNode to base store', async () => {
|
|
300
|
-
vi.mocked(baseStore.createNode).mockResolvedValue(mockSpec);
|
|
301
|
-
const result = await providerStore.createNode({
|
|
302
|
-
type: 'spec',
|
|
303
|
-
title: 'New Spec',
|
|
304
|
-
});
|
|
305
|
-
expect(baseStore.createNode).toHaveBeenCalled();
|
|
306
|
-
expect(result).toBe(mockSpec);
|
|
307
|
-
});
|
|
308
|
-
it('should pass through query to base store', async () => {
|
|
309
|
-
vi.mocked(baseStore.query.nodes).mockResolvedValue([mockSpec]);
|
|
310
|
-
const result = await providerStore.query.nodes({ type: 'spec' });
|
|
311
|
-
expect(baseStore.query.nodes).toHaveBeenCalledWith({ type: 'spec' });
|
|
312
|
-
expect(result).toEqual([mockSpec]);
|
|
313
|
-
});
|
|
314
|
-
});
|
|
315
|
-
describe('materialization strategies', () => {
|
|
316
|
-
beforeEach(() => {
|
|
317
|
-
providerStore.providers.register(mockBeadsProvider);
|
|
318
|
-
});
|
|
319
|
-
it('should materialize with lazy strategy on resolve', async () => {
|
|
320
|
-
const lazyStore = createProviderAwareStore(baseStore, {
|
|
321
|
-
materialization: { default: 'lazy' },
|
|
322
|
-
});
|
|
323
|
-
lazyStore.providers.register(mockBeadsProvider);
|
|
324
|
-
vi.mocked(baseStore.query.nodes).mockResolvedValue([]);
|
|
325
|
-
vi.mocked(baseStore.createNode).mockResolvedValue(mockExternalNode);
|
|
326
|
-
await lazyStore.resolveNode('beads://./bd-123');
|
|
327
|
-
expect(baseStore.createNode).toHaveBeenCalled();
|
|
328
|
-
});
|
|
329
|
-
it('should materialize with eager strategy always', async () => {
|
|
330
|
-
const eagerStore = createProviderAwareStore(baseStore, {
|
|
331
|
-
materialization: { default: 'eager' },
|
|
332
|
-
});
|
|
333
|
-
eagerStore.providers.register(mockBeadsProvider);
|
|
334
|
-
vi.mocked(baseStore.query.nodes).mockResolvedValue([]);
|
|
335
|
-
vi.mocked(baseStore.createNode).mockResolvedValue(mockExternalNode);
|
|
336
|
-
await eagerStore.resolveNode('beads://./bd-123');
|
|
337
|
-
expect(baseStore.createNode).toHaveBeenCalled();
|
|
338
|
-
});
|
|
339
|
-
it('should not materialize with none strategy', async () => {
|
|
340
|
-
const noneStore = createProviderAwareStore(baseStore, {
|
|
341
|
-
materialization: { default: 'none' },
|
|
342
|
-
});
|
|
343
|
-
noneStore.providers.register(mockBeadsProvider);
|
|
344
|
-
vi.mocked(baseStore.query.nodes).mockResolvedValue([]);
|
|
345
|
-
await noneStore.resolveNode('beads://./bd-123', { materialize: true });
|
|
346
|
-
// Even with explicit flag, 'none' should not materialize
|
|
347
|
-
expect(baseStore.createNode).not.toHaveBeenCalled();
|
|
348
|
-
});
|
|
349
|
-
});
|
|
350
|
-
// ===========================================================================
|
|
351
|
-
// Provider-Routed CRUD (Unified Interface)
|
|
352
|
-
// ===========================================================================
|
|
353
|
-
describe('providerCreate', () => {
|
|
354
|
-
it('should create locally when defaultProvider is native', async () => {
|
|
355
|
-
const store = createProviderAwareStore(baseStore, {
|
|
356
|
-
defaultProvider: 'native',
|
|
357
|
-
});
|
|
358
|
-
const mockNode = { ...mockSpec };
|
|
359
|
-
vi.mocked(baseStore.createNode).mockResolvedValue(mockNode);
|
|
360
|
-
const result = await store.providerCreate({
|
|
361
|
-
type: 'spec',
|
|
362
|
-
title: 'Test Spec',
|
|
363
|
-
});
|
|
364
|
-
expect(result.provider).toBe('native');
|
|
365
|
-
expect(result.uri).toBeUndefined();
|
|
366
|
-
expect(baseStore.createNode).toHaveBeenCalledWith({
|
|
367
|
-
type: 'spec',
|
|
368
|
-
title: 'Test Spec',
|
|
369
|
-
});
|
|
370
|
-
});
|
|
371
|
-
it('should route to external provider via scheme param', async () => {
|
|
372
|
-
const store = createProviderAwareStore(baseStore, {
|
|
373
|
-
defaultProvider: 'native',
|
|
374
|
-
});
|
|
375
|
-
store.providers.register(mockBeadsProvider);
|
|
376
|
-
const createdProviderNode = {
|
|
377
|
-
id: 'bd-new1',
|
|
378
|
-
uri: 'beads://./bd-new1',
|
|
379
|
-
type: 'issue',
|
|
380
|
-
title: 'New Issue',
|
|
381
|
-
fetchedAt: new Date().toISOString(),
|
|
382
|
-
};
|
|
383
|
-
vi.mocked(mockBeadsProvider.create).mockResolvedValue(createdProviderNode);
|
|
384
|
-
vi.mocked(baseStore.query.nodes).mockResolvedValue([]);
|
|
385
|
-
vi.mocked(baseStore.createNode).mockResolvedValue({
|
|
386
|
-
...mockExternalNode,
|
|
387
|
-
id: 'x-new1',
|
|
388
|
-
title: 'New Issue',
|
|
389
|
-
uri: 'beads://./bd-new1',
|
|
390
|
-
});
|
|
391
|
-
const result = await store.providerCreate({ type: 'issue', title: 'New Issue' }, { scheme: 'beads' });
|
|
392
|
-
expect(result.provider).toBe('beads');
|
|
393
|
-
expect(result.uri).toBe('beads://./bd-new1');
|
|
394
|
-
expect(mockBeadsProvider.create).toHaveBeenCalledWith({
|
|
395
|
-
type: 'issue',
|
|
396
|
-
title: 'New Issue',
|
|
397
|
-
content: undefined,
|
|
398
|
-
status: undefined,
|
|
399
|
-
priority: undefined,
|
|
400
|
-
metadata: undefined,
|
|
401
|
-
}, undefined);
|
|
402
|
-
// Should materialize the node locally
|
|
403
|
-
expect(baseStore.createNode).toHaveBeenCalled();
|
|
404
|
-
});
|
|
405
|
-
it('should use defaultProvider when no scheme specified', async () => {
|
|
406
|
-
const store = createProviderAwareStore(baseStore, {
|
|
407
|
-
defaultProvider: 'beads',
|
|
408
|
-
});
|
|
409
|
-
store.providers.register(mockBeadsProvider);
|
|
410
|
-
const createdProviderNode = {
|
|
411
|
-
id: 'bd-new2',
|
|
412
|
-
uri: 'beads://./bd-new2',
|
|
413
|
-
type: 'issue',
|
|
414
|
-
title: 'Default Provider Issue',
|
|
415
|
-
fetchedAt: new Date().toISOString(),
|
|
416
|
-
};
|
|
417
|
-
vi.mocked(mockBeadsProvider.create).mockResolvedValue(createdProviderNode);
|
|
418
|
-
vi.mocked(baseStore.query.nodes).mockResolvedValue([]);
|
|
419
|
-
vi.mocked(baseStore.createNode).mockResolvedValue({
|
|
420
|
-
...mockExternalNode,
|
|
421
|
-
id: 'x-new2',
|
|
422
|
-
});
|
|
423
|
-
const result = await store.providerCreate({
|
|
424
|
-
type: 'issue',
|
|
425
|
-
title: 'Default Provider Issue',
|
|
426
|
-
});
|
|
427
|
-
// Should route to beads since it's the defaultProvider
|
|
428
|
-
expect(result.provider).toBe('beads');
|
|
429
|
-
expect(mockBeadsProvider.create).toHaveBeenCalled();
|
|
430
|
-
});
|
|
431
|
-
it('should throw for unknown provider', async () => {
|
|
432
|
-
const store = createProviderAwareStore(baseStore);
|
|
433
|
-
await expect(store.providerCreate({ type: 'issue', title: 'Test' }, { scheme: 'nonexistent' })).rejects.toThrow('Unknown provider: nonexistent');
|
|
434
|
-
});
|
|
435
|
-
it('should throw for read-only provider', async () => {
|
|
436
|
-
const readOnlyProvider = {
|
|
437
|
-
...mockBeadsProvider,
|
|
438
|
-
name: 'readonly',
|
|
439
|
-
schemes: ['readonly'],
|
|
440
|
-
capabilities: { read: true, write: false, search: false, watch: false, mount: false, feedback: false },
|
|
441
|
-
};
|
|
442
|
-
const store = createProviderAwareStore(baseStore);
|
|
443
|
-
store.providers.register(readOnlyProvider);
|
|
444
|
-
await expect(store.providerCreate({ type: 'issue', title: 'Test' }, { scheme: 'readonly' })).rejects.toThrow('read-only');
|
|
445
|
-
});
|
|
446
|
-
it('should throw for non-mountable provider', async () => {
|
|
447
|
-
const nonMountable = {
|
|
448
|
-
...mockBeadsProvider,
|
|
449
|
-
name: 'nomount',
|
|
450
|
-
schemes: ['nomount'],
|
|
451
|
-
capabilities: { read: true, write: true, search: false, watch: false, mount: false, feedback: false },
|
|
452
|
-
};
|
|
453
|
-
const store = createProviderAwareStore(baseStore);
|
|
454
|
-
store.providers.register(nonMountable);
|
|
455
|
-
await expect(store.providerCreate({ type: 'issue', title: 'Test' }, { scheme: 'nomount' })).rejects.toThrow('does not support mounting');
|
|
456
|
-
});
|
|
457
|
-
});
|
|
458
|
-
describe('providerGet', () => {
|
|
459
|
-
it('should get local node directly', async () => {
|
|
460
|
-
vi.mocked(baseStore.getNode).mockResolvedValue(mockSpec);
|
|
461
|
-
const result = await providerStore.providerGet('s-abc1');
|
|
462
|
-
expect(baseStore.getNode).toHaveBeenCalledWith('s-abc1');
|
|
463
|
-
expect(result).toEqual(mockSpec);
|
|
464
|
-
});
|
|
465
|
-
it('should refresh stale external node', async () => {
|
|
466
|
-
const staleNode = {
|
|
467
|
-
...mockExternalNode,
|
|
468
|
-
cached_at: '2020-01-01T00:00:00.000Z', // very old
|
|
469
|
-
};
|
|
470
|
-
vi.mocked(baseStore.getNode).mockResolvedValue(staleNode);
|
|
471
|
-
providerStore.providers.register(mockBeadsProvider);
|
|
472
|
-
// Mock the refresh path: query for existing, then update
|
|
473
|
-
vi.mocked(baseStore.query.nodes).mockResolvedValue([staleNode]);
|
|
474
|
-
vi.mocked(baseStore.updateNode).mockResolvedValue({
|
|
475
|
-
...staleNode,
|
|
476
|
-
title: 'Beads Issue',
|
|
477
|
-
cached_at: new Date().toISOString(),
|
|
478
|
-
});
|
|
479
|
-
const result = await providerStore.providerGet('x-ext1');
|
|
480
|
-
expect(mockBeadsProvider.get).toHaveBeenCalled();
|
|
481
|
-
});
|
|
482
|
-
it('should resolve provider URI and materialize', async () => {
|
|
483
|
-
providerStore.providers.register(mockBeadsProvider);
|
|
484
|
-
vi.mocked(baseStore.query.nodes).mockResolvedValue([]);
|
|
485
|
-
vi.mocked(baseStore.createNode).mockResolvedValue(mockExternalNode);
|
|
486
|
-
const result = await providerStore.providerGet('beads://./bd-123');
|
|
487
|
-
expect(mockBeadsProvider.get).toHaveBeenCalled();
|
|
488
|
-
});
|
|
489
|
-
it('should return null for nonexistent local node', async () => {
|
|
490
|
-
vi.mocked(baseStore.getNode).mockResolvedValue(null);
|
|
491
|
-
const result = await providerStore.providerGet('s-nonexist');
|
|
492
|
-
expect(result).toBeNull();
|
|
493
|
-
});
|
|
494
|
-
});
|
|
495
|
-
describe('providerUpdate', () => {
|
|
496
|
-
it('should update local node directly', async () => {
|
|
497
|
-
const updatedNode = { ...mockSpec, title: 'Updated' };
|
|
498
|
-
vi.mocked(baseStore.getNode).mockResolvedValue(mockSpec);
|
|
499
|
-
vi.mocked(baseStore.updateNode).mockResolvedValue(updatedNode);
|
|
500
|
-
const result = await providerStore.providerUpdate('s-abc1', { title: 'Updated' });
|
|
501
|
-
expect(baseStore.updateNode).toHaveBeenCalledWith('s-abc1', { title: 'Updated' });
|
|
502
|
-
expect(result.title).toBe('Updated');
|
|
503
|
-
});
|
|
504
|
-
it('should route update to external provider for materialized node', async () => {
|
|
505
|
-
providerStore.providers.register(mockBeadsProvider);
|
|
506
|
-
vi.mocked(baseStore.getNode).mockResolvedValue(mockExternalNode);
|
|
507
|
-
const updatedProviderNode = {
|
|
508
|
-
...mockProviderNode,
|
|
509
|
-
title: 'Updated in Beads',
|
|
510
|
-
};
|
|
511
|
-
vi.mocked(mockBeadsProvider.update).mockResolvedValue(updatedProviderNode);
|
|
512
|
-
// Mock materialization (find existing, then update)
|
|
513
|
-
vi.mocked(baseStore.query.nodes).mockResolvedValue([mockExternalNode]);
|
|
514
|
-
vi.mocked(baseStore.updateNode).mockResolvedValue({
|
|
515
|
-
...mockExternalNode,
|
|
516
|
-
title: 'Updated in Beads',
|
|
517
|
-
});
|
|
518
|
-
const result = await providerStore.providerUpdate('x-ext1', { title: 'Updated in Beads' });
|
|
519
|
-
expect(mockBeadsProvider.update).toHaveBeenCalledWith('bd-123', {
|
|
520
|
-
title: 'Updated in Beads',
|
|
521
|
-
content: undefined,
|
|
522
|
-
status: undefined,
|
|
523
|
-
priority: undefined,
|
|
524
|
-
metadata: undefined,
|
|
525
|
-
}, undefined);
|
|
526
|
-
});
|
|
527
|
-
it('should route update via provider URI', async () => {
|
|
528
|
-
providerStore.providers.register(mockBeadsProvider);
|
|
529
|
-
// No existing materialized copy
|
|
530
|
-
vi.mocked(baseStore.query.nodes).mockResolvedValue([]);
|
|
531
|
-
// Mock fetching the node for materialization
|
|
532
|
-
vi.mocked(baseStore.createNode).mockResolvedValue(mockExternalNode);
|
|
533
|
-
const updatedProviderNode = {
|
|
534
|
-
...mockProviderNode,
|
|
535
|
-
title: 'Updated via URI',
|
|
536
|
-
};
|
|
537
|
-
vi.mocked(mockBeadsProvider.update).mockResolvedValue(updatedProviderNode);
|
|
538
|
-
// After materialization, the update path will re-materialize
|
|
539
|
-
vi.mocked(baseStore.updateNode).mockResolvedValue({
|
|
540
|
-
...mockExternalNode,
|
|
541
|
-
title: 'Updated via URI',
|
|
542
|
-
});
|
|
543
|
-
const result = await providerStore.providerUpdate('beads://./bd-123', { title: 'Updated via URI' });
|
|
544
|
-
expect(mockBeadsProvider.update).toHaveBeenCalled();
|
|
545
|
-
});
|
|
546
|
-
it('should throw for nonexistent node', async () => {
|
|
547
|
-
vi.mocked(baseStore.getNode).mockResolvedValue(null);
|
|
548
|
-
await expect(providerStore.providerUpdate('s-nonexist', { title: 'Test' })).rejects.toThrow('not found');
|
|
549
|
-
});
|
|
550
|
-
it('should throw when external node provider is not registered', async () => {
|
|
551
|
-
// External node exists but its provider (beads) is NOT registered
|
|
552
|
-
vi.mocked(baseStore.getNode).mockResolvedValue(mockExternalNode);
|
|
553
|
-
await expect(providerStore.providerUpdate('x-ext1', { title: 'Update' })).rejects.toThrow('Provider not registered');
|
|
554
|
-
});
|
|
555
|
-
});
|
|
556
|
-
describe('providerDelete', () => {
|
|
557
|
-
it('should delete local node directly', async () => {
|
|
558
|
-
vi.mocked(baseStore.getNode).mockResolvedValue(mockSpec);
|
|
559
|
-
vi.mocked(baseStore.deleteNode).mockResolvedValue(undefined);
|
|
560
|
-
await providerStore.providerDelete('s-abc1');
|
|
561
|
-
expect(baseStore.deleteNode).toHaveBeenCalledWith('s-abc1', undefined);
|
|
562
|
-
});
|
|
563
|
-
it('should route delete to external provider and remove local copy', async () => {
|
|
564
|
-
providerStore.providers.register(mockBeadsProvider);
|
|
565
|
-
vi.mocked(baseStore.getNode).mockResolvedValue(mockExternalNode);
|
|
566
|
-
vi.mocked(mockBeadsProvider.delete).mockResolvedValue(undefined);
|
|
567
|
-
vi.mocked(baseStore.deleteNode).mockResolvedValue(undefined);
|
|
568
|
-
await providerStore.providerDelete('x-ext1');
|
|
569
|
-
// Should delete in provider
|
|
570
|
-
expect(mockBeadsProvider.delete).toHaveBeenCalledWith('bd-123', undefined);
|
|
571
|
-
// Should hard-delete local materialized copy
|
|
572
|
-
expect(baseStore.deleteNode).toHaveBeenCalledWith('x-ext1', { hard: true });
|
|
573
|
-
});
|
|
574
|
-
it('should throw for nonexistent node', async () => {
|
|
575
|
-
vi.mocked(baseStore.getNode).mockResolvedValue(null);
|
|
576
|
-
await expect(providerStore.providerDelete('s-nonexist')).rejects.toThrow('not found');
|
|
577
|
-
});
|
|
578
|
-
it('should throw when external node provider is not registered', async () => {
|
|
579
|
-
// External node exists but its provider (beads) is NOT registered
|
|
580
|
-
vi.mocked(baseStore.getNode).mockResolvedValue(mockExternalNode);
|
|
581
|
-
await expect(providerStore.providerDelete('x-ext1')).rejects.toThrow('Provider not registered');
|
|
582
|
-
});
|
|
583
|
-
});
|
|
584
|
-
describe('defaultProvider', () => {
|
|
585
|
-
it('should default to native', () => {
|
|
586
|
-
const store = createProviderAwareStore(baseStore);
|
|
587
|
-
expect(store.defaultProvider).toBe('native');
|
|
588
|
-
});
|
|
589
|
-
it('should respect config', () => {
|
|
590
|
-
const store = createProviderAwareStore(baseStore, {
|
|
591
|
-
defaultProvider: 'sudocode',
|
|
592
|
-
});
|
|
593
|
-
expect(store.defaultProvider).toBe('sudocode');
|
|
594
|
-
});
|
|
595
|
-
});
|
|
596
|
-
// =========================================================================
|
|
597
|
-
// Task Lifecycle (TaskManageable)
|
|
598
|
-
// =========================================================================
|
|
599
|
-
describe('task lifecycle', () => {
|
|
600
|
-
let mockTaskProvider;
|
|
601
|
-
const mockTaskProviderNode = {
|
|
602
|
-
id: 'task-1',
|
|
603
|
-
uri: 'taskprov://task-1',
|
|
604
|
-
type: 'issue',
|
|
605
|
-
title: 'Task One',
|
|
606
|
-
status: 'in_progress',
|
|
607
|
-
fetchedAt: new Date().toISOString(),
|
|
608
|
-
};
|
|
609
|
-
const mockTaskExternalNode = {
|
|
610
|
-
id: 'x-task1',
|
|
611
|
-
uuid: 'uuid-task-1',
|
|
612
|
-
type: 'external',
|
|
613
|
-
title: 'Task One',
|
|
614
|
-
uri: 'taskprov://task-1',
|
|
615
|
-
source: 'taskprov',
|
|
616
|
-
materialized: true,
|
|
617
|
-
cached_at: new Date().toISOString(),
|
|
618
|
-
created_at: '2024-01-01T00:00:00.000Z',
|
|
619
|
-
updated_at: '2024-01-01T00:00:00.000Z',
|
|
620
|
-
};
|
|
621
|
-
beforeEach(() => {
|
|
622
|
-
mockTaskProvider = {
|
|
623
|
-
name: 'taskprov',
|
|
624
|
-
schemes: ['taskprov'],
|
|
625
|
-
capabilities: { read: true, write: true, search: false, watch: false, mount: true, feedback: false },
|
|
626
|
-
parseUri: vi.fn((uri) => {
|
|
627
|
-
if (uri.startsWith('taskprov://')) {
|
|
628
|
-
const id = uri.slice('taskprov://'.length);
|
|
629
|
-
return { scheme: 'taskprov', id, isRelative: false };
|
|
630
|
-
}
|
|
631
|
-
return null;
|
|
632
|
-
}),
|
|
633
|
-
buildUri: vi.fn((id) => `taskprov://${id}`),
|
|
634
|
-
isValidUri: vi.fn((uri) => uri.startsWith('taskprov://')),
|
|
635
|
-
get: vi.fn().mockResolvedValue(mockTaskProviderNode),
|
|
636
|
-
list: vi.fn().mockResolvedValue([]),
|
|
637
|
-
create: vi.fn(),
|
|
638
|
-
update: vi.fn(),
|
|
639
|
-
delete: vi.fn(),
|
|
640
|
-
taskCapabilities: {
|
|
641
|
-
actions: ['start', 'complete', 'block', 'reopen'],
|
|
642
|
-
supportsAssignment: true,
|
|
643
|
-
supportsReadyQuery: true,
|
|
644
|
-
statusModel: ['open', 'in_progress', 'blocked', 'done'],
|
|
645
|
-
},
|
|
646
|
-
transitionTask: vi.fn().mockResolvedValue(mockTaskProviderNode),
|
|
647
|
-
readyTasks: vi.fn().mockResolvedValue([mockTaskProviderNode]),
|
|
648
|
-
assignTask: vi.fn().mockResolvedValue(mockTaskProviderNode),
|
|
649
|
-
validActions: vi.fn().mockResolvedValue(['start', 'close']),
|
|
650
|
-
};
|
|
651
|
-
});
|
|
652
|
-
describe('taskTransition', () => {
|
|
653
|
-
it('should transition a task via provider URI', async () => {
|
|
654
|
-
providerStore.providers.register(mockTaskProvider);
|
|
655
|
-
// Mock materialization: no existing node, so create one
|
|
656
|
-
vi.mocked(baseStore.query.nodes).mockResolvedValue([]);
|
|
657
|
-
vi.mocked(baseStore.createNode).mockResolvedValue(mockTaskExternalNode);
|
|
658
|
-
const result = await providerStore.taskTransition('taskprov://task-1', 'start');
|
|
659
|
-
expect(mockTaskProvider.transitionTask).toHaveBeenCalledWith('task-1', 'start', undefined);
|
|
660
|
-
expect(result.action).toBe('start');
|
|
661
|
-
expect(result.provider).toBe('taskprov');
|
|
662
|
-
expect(result.node).toBeDefined();
|
|
663
|
-
});
|
|
664
|
-
it('should transition a task via local external node ID', async () => {
|
|
665
|
-
providerStore.providers.register(mockTaskProvider);
|
|
666
|
-
vi.mocked(baseStore.getNode).mockResolvedValue(mockTaskExternalNode);
|
|
667
|
-
vi.mocked(baseStore.query.nodes).mockResolvedValue([mockTaskExternalNode]);
|
|
668
|
-
vi.mocked(baseStore.updateNode).mockResolvedValue(mockTaskExternalNode);
|
|
669
|
-
const result = await providerStore.taskTransition('x-task1', 'complete');
|
|
670
|
-
expect(mockTaskProvider.transitionTask).toHaveBeenCalledWith('task-1', 'complete', undefined);
|
|
671
|
-
expect(result.action).toBe('complete');
|
|
672
|
-
});
|
|
673
|
-
it('should throw for provider that does not support tasks', async () => {
|
|
674
|
-
providerStore.providers.register(mockBeadsProvider);
|
|
675
|
-
await expect(providerStore.taskTransition('beads://./bd-123', 'start')).rejects.toThrow('does not support task operations');
|
|
676
|
-
});
|
|
677
|
-
it('should throw for nonexistent node', async () => {
|
|
678
|
-
vi.mocked(baseStore.getNode).mockResolvedValue(null);
|
|
679
|
-
await expect(providerStore.taskTransition('s-nonexist', 'start')).rejects.toThrow('not found');
|
|
680
|
-
});
|
|
681
|
-
it('should forward context to provider', async () => {
|
|
682
|
-
providerStore.providers.register(mockTaskProvider);
|
|
683
|
-
vi.mocked(baseStore.query.nodes).mockResolvedValue([]);
|
|
684
|
-
vi.mocked(baseStore.createNode).mockResolvedValue(mockTaskExternalNode);
|
|
685
|
-
const ctx = { cwd: '/other/dir', timeout: 5000 };
|
|
686
|
-
await providerStore.taskTransition('taskprov://task-1', 'start', { context: ctx });
|
|
687
|
-
expect(mockTaskProvider.transitionTask).toHaveBeenCalledWith('task-1', 'start', ctx);
|
|
688
|
-
});
|
|
689
|
-
});
|
|
690
|
-
describe('taskReady', () => {
|
|
691
|
-
it('should aggregate ready tasks across task-capable providers', async () => {
|
|
692
|
-
providerStore.providers.register(mockTaskProvider);
|
|
693
|
-
// Mock materialization for each ready task
|
|
694
|
-
vi.mocked(baseStore.query.nodes).mockResolvedValue([]);
|
|
695
|
-
vi.mocked(baseStore.createNode).mockResolvedValue(mockTaskExternalNode);
|
|
696
|
-
const ready = await providerStore.taskReady();
|
|
697
|
-
expect(mockTaskProvider.readyTasks).toHaveBeenCalled();
|
|
698
|
-
expect(ready.length).toBeGreaterThanOrEqual(1);
|
|
699
|
-
});
|
|
700
|
-
it('should skip non-task-capable providers', async () => {
|
|
701
|
-
providerStore.providers.register(mockBeadsProvider);
|
|
702
|
-
providerStore.providers.register(mockTaskProvider);
|
|
703
|
-
vi.mocked(baseStore.query.nodes).mockResolvedValue([]);
|
|
704
|
-
vi.mocked(baseStore.createNode).mockResolvedValue(mockTaskExternalNode);
|
|
705
|
-
await providerStore.taskReady();
|
|
706
|
-
// Only taskprov should be queried
|
|
707
|
-
expect(mockTaskProvider.readyTasks).toHaveBeenCalled();
|
|
708
|
-
});
|
|
709
|
-
it('should filter by provider name', async () => {
|
|
710
|
-
providerStore.providers.register(mockTaskProvider);
|
|
711
|
-
await providerStore.taskReady({ providers: ['other-provider'] });
|
|
712
|
-
// taskprov should NOT be queried because it wasn't in the filter
|
|
713
|
-
expect(mockTaskProvider.readyTasks).not.toHaveBeenCalled();
|
|
714
|
-
});
|
|
715
|
-
it('should return existing materialized nodes when available', async () => {
|
|
716
|
-
providerStore.providers.register(mockTaskProvider);
|
|
717
|
-
// Mock: existing materialized node found
|
|
718
|
-
vi.mocked(baseStore.query.nodes).mockResolvedValue([mockTaskExternalNode]);
|
|
719
|
-
const ready = await providerStore.taskReady();
|
|
720
|
-
expect(ready[0]).toEqual(mockTaskExternalNode);
|
|
721
|
-
});
|
|
722
|
-
it('should forward options to provider', async () => {
|
|
723
|
-
providerStore.providers.register(mockTaskProvider);
|
|
724
|
-
vi.mocked(baseStore.query.nodes).mockResolvedValue([]);
|
|
725
|
-
vi.mocked(baseStore.createNode).mockResolvedValue(mockTaskExternalNode);
|
|
726
|
-
await providerStore.taskReady({ limit: 5, tags: ['urgent'], assignee: 'alice' });
|
|
727
|
-
expect(mockTaskProvider.readyTasks).toHaveBeenCalledWith({ limit: 5, tags: ['urgent'], priority: undefined, assignee: 'alice' }, undefined);
|
|
728
|
-
});
|
|
729
|
-
});
|
|
730
|
-
describe('taskAssign', () => {
|
|
731
|
-
it('should assign a task via provider', async () => {
|
|
732
|
-
providerStore.providers.register(mockTaskProvider);
|
|
733
|
-
vi.mocked(baseStore.query.nodes).mockResolvedValue([]);
|
|
734
|
-
vi.mocked(baseStore.createNode).mockResolvedValue(mockTaskExternalNode);
|
|
735
|
-
const result = await providerStore.taskAssign('taskprov://task-1', 'alice');
|
|
736
|
-
expect(mockTaskProvider.assignTask).toHaveBeenCalledWith('task-1', 'alice', undefined);
|
|
737
|
-
expect(result).toBeDefined();
|
|
738
|
-
});
|
|
739
|
-
it('should throw for provider that does not support assignment', async () => {
|
|
740
|
-
const noAssignProvider = {
|
|
741
|
-
...mockTaskProvider,
|
|
742
|
-
name: 'noassign',
|
|
743
|
-
schemes: ['noassign'],
|
|
744
|
-
parseUri: vi.fn((uri) => {
|
|
745
|
-
if (uri.startsWith('noassign://')) {
|
|
746
|
-
return { scheme: 'noassign', id: uri.slice('noassign://'.length), isRelative: false };
|
|
747
|
-
}
|
|
748
|
-
return null;
|
|
749
|
-
}),
|
|
750
|
-
buildUri: vi.fn((id) => `noassign://${id}`),
|
|
751
|
-
isValidUri: vi.fn((uri) => uri.startsWith('noassign://')),
|
|
752
|
-
taskCapabilities: {
|
|
753
|
-
...mockTaskProvider.taskCapabilities,
|
|
754
|
-
supportsAssignment: false,
|
|
755
|
-
},
|
|
756
|
-
assignTask: undefined,
|
|
757
|
-
};
|
|
758
|
-
providerStore.providers.register(noAssignProvider);
|
|
759
|
-
await expect(providerStore.taskAssign('noassign://task-1', 'alice')).rejects.toThrow('does not support task assignment');
|
|
760
|
-
});
|
|
761
|
-
});
|
|
762
|
-
describe('taskValidActions', () => {
|
|
763
|
-
it('should return valid actions from provider', async () => {
|
|
764
|
-
providerStore.providers.register(mockTaskProvider);
|
|
765
|
-
const actions = await providerStore.taskValidActions('taskprov://task-1');
|
|
766
|
-
expect(mockTaskProvider.validActions).toHaveBeenCalledWith('task-1');
|
|
767
|
-
expect(actions).toEqual(['start', 'close']);
|
|
768
|
-
});
|
|
769
|
-
it('should fall back to taskCapabilities.actions when validActions not implemented', async () => {
|
|
770
|
-
const noValidActionsProvider = {
|
|
771
|
-
...mockTaskProvider,
|
|
772
|
-
name: 'novalid',
|
|
773
|
-
schemes: ['novalid'],
|
|
774
|
-
parseUri: vi.fn((uri) => {
|
|
775
|
-
if (uri.startsWith('novalid://')) {
|
|
776
|
-
return { scheme: 'novalid', id: uri.slice('novalid://'.length), isRelative: false };
|
|
777
|
-
}
|
|
778
|
-
return null;
|
|
779
|
-
}),
|
|
780
|
-
buildUri: vi.fn((id) => `novalid://${id}`),
|
|
781
|
-
isValidUri: vi.fn((uri) => uri.startsWith('novalid://')),
|
|
782
|
-
validActions: undefined,
|
|
783
|
-
};
|
|
784
|
-
providerStore.providers.register(noValidActionsProvider);
|
|
785
|
-
const actions = await providerStore.taskValidActions('novalid://task-1');
|
|
786
|
-
expect(actions).toEqual(['start', 'complete', 'block', 'reopen']);
|
|
787
|
-
});
|
|
788
|
-
});
|
|
789
|
-
});
|
|
790
|
-
});
|
|
791
|
-
//# sourceMappingURL=provider-store.test.js.map
|