opentasks 0.0.7 → 0.0.8
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/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/package.json +1 -1
- 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,669 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for Multi-Location Daemon (Phase B)
|
|
3
|
-
*
|
|
4
|
-
* Tests the multi-location daemon mode where a single daemon
|
|
5
|
-
* manages multiple worktree locations under one git repo.
|
|
6
|
-
*/
|
|
7
|
-
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
8
|
-
import * as fs from 'node:fs/promises';
|
|
9
|
-
import * as path from 'node:path';
|
|
10
|
-
import * as os from 'node:os';
|
|
11
|
-
import { createDaemon, } from '../lifecycle.js';
|
|
12
|
-
import { createIPCClient } from '../ipc.js';
|
|
13
|
-
import { DaemonError } from '../types.js';
|
|
14
|
-
import { createSingleLocationResolver, createMultiLocationResolver, } from '../location-state.js';
|
|
15
|
-
// ============================================================================
|
|
16
|
-
// Mock Helpers
|
|
17
|
-
// ============================================================================
|
|
18
|
-
function createMockStore() {
|
|
19
|
-
const nodes = new Map();
|
|
20
|
-
return {
|
|
21
|
-
initialize: vi.fn().mockResolvedValue(undefined),
|
|
22
|
-
close: vi.fn().mockResolvedValue(undefined),
|
|
23
|
-
flush: vi.fn().mockResolvedValue(undefined),
|
|
24
|
-
createNode: vi.fn().mockImplementation(async (input) => {
|
|
25
|
-
const node = {
|
|
26
|
-
id: `i-${Date.now().toString(36)}${Math.random().toString(36).slice(2, 5)}`,
|
|
27
|
-
uuid: '550e8400-e29b-41d4-a716-446655440000',
|
|
28
|
-
type: input.type || 'issue',
|
|
29
|
-
title: input.title,
|
|
30
|
-
status: input.status || 'open',
|
|
31
|
-
created_at: new Date().toISOString(),
|
|
32
|
-
updated_at: new Date().toISOString(),
|
|
33
|
-
...input,
|
|
34
|
-
};
|
|
35
|
-
nodes.set(node.id, node);
|
|
36
|
-
return node;
|
|
37
|
-
}),
|
|
38
|
-
getNode: vi.fn().mockImplementation(async (id) => {
|
|
39
|
-
return nodes.get(id) ?? null;
|
|
40
|
-
}),
|
|
41
|
-
updateNode: vi.fn().mockImplementation(async (id, updates) => {
|
|
42
|
-
const node = nodes.get(id);
|
|
43
|
-
if (!node)
|
|
44
|
-
throw new Error(`Node not found: ${id}`);
|
|
45
|
-
const updated = { ...node, ...updates, updated_at: new Date().toISOString() };
|
|
46
|
-
nodes.set(id, updated);
|
|
47
|
-
return updated;
|
|
48
|
-
}),
|
|
49
|
-
deleteNode: vi.fn().mockResolvedValue(undefined),
|
|
50
|
-
restoreNode: vi.fn(),
|
|
51
|
-
createEdge: vi.fn().mockImplementation(async (input) => {
|
|
52
|
-
const edge = {
|
|
53
|
-
id: `x-${Date.now().toString(36)}`,
|
|
54
|
-
uuid: '550e8400-e29b-41d4-a716-446655440001',
|
|
55
|
-
from_id: input.from_id,
|
|
56
|
-
to_id: input.to_id,
|
|
57
|
-
type: input.type || 'blocks',
|
|
58
|
-
created_at: new Date().toISOString(),
|
|
59
|
-
};
|
|
60
|
-
return edge;
|
|
61
|
-
}),
|
|
62
|
-
getEdge: vi.fn().mockResolvedValue(null),
|
|
63
|
-
deleteEdge: vi.fn().mockResolvedValue(undefined),
|
|
64
|
-
addTags: vi.fn(),
|
|
65
|
-
removeTags: vi.fn(),
|
|
66
|
-
setTags: vi.fn(),
|
|
67
|
-
query: {
|
|
68
|
-
nodes: vi.fn().mockResolvedValue([]),
|
|
69
|
-
edges: vi.fn().mockResolvedValue([]),
|
|
70
|
-
edgesFrom: vi.fn().mockResolvedValue([]),
|
|
71
|
-
edgesTo: vi.fn().mockResolvedValue([]),
|
|
72
|
-
edgesFor: vi.fn().mockResolvedValue([]),
|
|
73
|
-
blockers: vi.fn().mockResolvedValue([]),
|
|
74
|
-
blocking: vi.fn().mockResolvedValue([]),
|
|
75
|
-
isBlocking: vi.fn().mockResolvedValue(false),
|
|
76
|
-
implementers: vi.fn().mockResolvedValue([]),
|
|
77
|
-
specs: vi.fn().mockResolvedValue([]),
|
|
78
|
-
children: vi.fn().mockResolvedValue([]),
|
|
79
|
-
parent: vi.fn().mockResolvedValue(null),
|
|
80
|
-
ancestors: vi.fn().mockResolvedValue([]),
|
|
81
|
-
descendants: vi.fn().mockResolvedValue([]),
|
|
82
|
-
ready: vi.fn().mockResolvedValue([]),
|
|
83
|
-
feedback: vi.fn().mockResolvedValue([]),
|
|
84
|
-
unresolvedFeedback: vi.fn().mockResolvedValue([]),
|
|
85
|
-
},
|
|
86
|
-
transaction: vi.fn(),
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
function createMockFlushManager() {
|
|
90
|
-
return {
|
|
91
|
-
markDirty: vi.fn(),
|
|
92
|
-
schedule: vi.fn(),
|
|
93
|
-
flush: vi.fn().mockResolvedValue(undefined),
|
|
94
|
-
pause: vi.fn(),
|
|
95
|
-
resume: vi.fn(),
|
|
96
|
-
finalFlush: vi.fn().mockResolvedValue(undefined),
|
|
97
|
-
hasPendingChanges: vi.fn().mockReturnValue(false),
|
|
98
|
-
getDirtyNodes: vi.fn().mockReturnValue([]),
|
|
99
|
-
paused: false,
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
function createMockWatcher() {
|
|
103
|
-
return {
|
|
104
|
-
start: vi.fn().mockResolvedValue(undefined),
|
|
105
|
-
stop: vi.fn().mockResolvedValue(undefined),
|
|
106
|
-
pause: vi.fn(),
|
|
107
|
-
resume: vi.fn(),
|
|
108
|
-
onchange: vi.fn(),
|
|
109
|
-
paused: false,
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
function createMockLocationState(hash, opentasksPath, primary = false) {
|
|
113
|
-
return {
|
|
114
|
-
hash,
|
|
115
|
-
opentasksPath,
|
|
116
|
-
store: createMockStore(),
|
|
117
|
-
flushManager: createMockFlushManager(),
|
|
118
|
-
watcher: createMockWatcher(),
|
|
119
|
-
primary,
|
|
120
|
-
healthy: true,
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
// ============================================================================
|
|
124
|
-
// LocationResolver Unit Tests
|
|
125
|
-
// ============================================================================
|
|
126
|
-
describe('LocationResolver', () => {
|
|
127
|
-
describe('createSingleLocationResolver', () => {
|
|
128
|
-
it('should resolve any hash to the single state', () => {
|
|
129
|
-
const state = createMockLocationState('abc12345', '/tmp/.opentasks', true);
|
|
130
|
-
const resolver = createSingleLocationResolver(state);
|
|
131
|
-
expect(resolver.resolve()).toBe(state);
|
|
132
|
-
expect(resolver.resolve('abc12345')).toBe(state);
|
|
133
|
-
expect(resolver.resolve('anything')).toBe(state);
|
|
134
|
-
});
|
|
135
|
-
it('should return state as default', () => {
|
|
136
|
-
const state = createMockLocationState('abc12345', '/tmp/.opentasks', true);
|
|
137
|
-
const resolver = createSingleLocationResolver(state);
|
|
138
|
-
expect(resolver.getDefault()).toBe(state);
|
|
139
|
-
});
|
|
140
|
-
it('should list single location', () => {
|
|
141
|
-
const state = createMockLocationState('abc12345', '/tmp/.opentasks', true);
|
|
142
|
-
const resolver = createSingleLocationResolver(state);
|
|
143
|
-
const list = resolver.list();
|
|
144
|
-
expect(list).toHaveLength(1);
|
|
145
|
-
expect(list[0].hash).toBe('abc12345');
|
|
146
|
-
expect(list[0].primary).toBe(true);
|
|
147
|
-
expect(list[0].healthy).toBe(true);
|
|
148
|
-
});
|
|
149
|
-
it('should reject add in single-location mode', () => {
|
|
150
|
-
const state = createMockLocationState('abc12345', '/tmp/.opentasks', true);
|
|
151
|
-
const resolver = createSingleLocationResolver(state);
|
|
152
|
-
const newState = createMockLocationState('def67890', '/tmp2/.opentasks');
|
|
153
|
-
expect(() => resolver.add(newState)).toThrow('Cannot add locations');
|
|
154
|
-
});
|
|
155
|
-
it('should reject remove in single-location mode', async () => {
|
|
156
|
-
const state = createMockLocationState('abc12345', '/tmp/.opentasks', true);
|
|
157
|
-
const resolver = createSingleLocationResolver(state);
|
|
158
|
-
await expect(resolver.remove('abc12345')).rejects.toThrow('Cannot remove locations');
|
|
159
|
-
});
|
|
160
|
-
});
|
|
161
|
-
describe('createMultiLocationResolver', () => {
|
|
162
|
-
it('should resolve primary hash as default', () => {
|
|
163
|
-
const resolver = createMultiLocationResolver('primary1');
|
|
164
|
-
const state = createMockLocationState('primary1', '/repo/.opentasks', true);
|
|
165
|
-
resolver.add(state);
|
|
166
|
-
expect(resolver.resolve()).toBe(state);
|
|
167
|
-
expect(resolver.getDefault()).toBe(state);
|
|
168
|
-
});
|
|
169
|
-
it('should resolve specific location by hash', () => {
|
|
170
|
-
const resolver = createMultiLocationResolver('primary1');
|
|
171
|
-
const state1 = createMockLocationState('primary1', '/repo/.opentasks', true);
|
|
172
|
-
const state2 = createMockLocationState('worktree', '/wt/.opentasks');
|
|
173
|
-
resolver.add(state1);
|
|
174
|
-
resolver.add(state2);
|
|
175
|
-
expect(resolver.resolve('primary1')).toBe(state1);
|
|
176
|
-
expect(resolver.resolve('worktree')).toBe(state2);
|
|
177
|
-
});
|
|
178
|
-
it('should throw LOCATION_NOT_FOUND for unknown hash', () => {
|
|
179
|
-
const resolver = createMultiLocationResolver('primary1');
|
|
180
|
-
const state = createMockLocationState('primary1', '/repo/.opentasks', true);
|
|
181
|
-
resolver.add(state);
|
|
182
|
-
expect(() => resolver.resolve('unknown')).toThrow(DaemonError);
|
|
183
|
-
expect(() => resolver.resolve('unknown')).toThrow('Location not found');
|
|
184
|
-
});
|
|
185
|
-
it('should list all locations', () => {
|
|
186
|
-
const resolver = createMultiLocationResolver('primary1');
|
|
187
|
-
resolver.add(createMockLocationState('primary1', '/repo/.opentasks', true));
|
|
188
|
-
resolver.add(createMockLocationState('wt1', '/wt1/.opentasks'));
|
|
189
|
-
resolver.add(createMockLocationState('wt2', '/wt2/.opentasks'));
|
|
190
|
-
const list = resolver.list();
|
|
191
|
-
expect(list).toHaveLength(3);
|
|
192
|
-
expect(list.map(l => l.hash).sort()).toEqual(['primary1', 'wt1', 'wt2']);
|
|
193
|
-
});
|
|
194
|
-
it('should check has()', () => {
|
|
195
|
-
const resolver = createMultiLocationResolver('primary1');
|
|
196
|
-
resolver.add(createMockLocationState('primary1', '/repo/.opentasks', true));
|
|
197
|
-
expect(resolver.has('primary1')).toBe(true);
|
|
198
|
-
expect(resolver.has('unknown')).toBe(false);
|
|
199
|
-
});
|
|
200
|
-
it('should add and remove locations', async () => {
|
|
201
|
-
const resolver = createMultiLocationResolver('primary1');
|
|
202
|
-
resolver.add(createMockLocationState('primary1', '/repo/.opentasks', true));
|
|
203
|
-
const wt = createMockLocationState('wt1', '/wt1/.opentasks');
|
|
204
|
-
resolver.add(wt);
|
|
205
|
-
expect(resolver.list()).toHaveLength(2);
|
|
206
|
-
await resolver.remove('wt1');
|
|
207
|
-
expect(resolver.list()).toHaveLength(1);
|
|
208
|
-
expect(resolver.has('wt1')).toBe(false);
|
|
209
|
-
});
|
|
210
|
-
it('should call teardown on remove', async () => {
|
|
211
|
-
const resolver = createMultiLocationResolver('primary1');
|
|
212
|
-
const wt = createMockLocationState('wt1', '/wt1/.opentasks');
|
|
213
|
-
resolver.add(wt);
|
|
214
|
-
await resolver.remove('wt1');
|
|
215
|
-
// Watcher stop should have been called
|
|
216
|
-
expect(wt.watcher.stop).toHaveBeenCalled();
|
|
217
|
-
// Final flush should have been called
|
|
218
|
-
expect(wt.flushManager.finalFlush).toHaveBeenCalled();
|
|
219
|
-
// Store close should have been called
|
|
220
|
-
expect(wt.store.close).toHaveBeenCalled();
|
|
221
|
-
});
|
|
222
|
-
it('should fallback to first location if primary not found', () => {
|
|
223
|
-
const resolver = createMultiLocationResolver('missing');
|
|
224
|
-
const state = createMockLocationState('fallback', '/fb/.opentasks');
|
|
225
|
-
resolver.add(state);
|
|
226
|
-
expect(resolver.getDefault()).toBe(state);
|
|
227
|
-
});
|
|
228
|
-
it('should throw when no locations available', () => {
|
|
229
|
-
const resolver = createMultiLocationResolver('primary1');
|
|
230
|
-
expect(() => resolver.resolve()).toThrow('No locations available');
|
|
231
|
-
});
|
|
232
|
-
it('should be idempotent on remove of non-existent hash', async () => {
|
|
233
|
-
const resolver = createMultiLocationResolver('primary1');
|
|
234
|
-
// Should not throw
|
|
235
|
-
await resolver.remove('nonexistent');
|
|
236
|
-
});
|
|
237
|
-
});
|
|
238
|
-
});
|
|
239
|
-
// ============================================================================
|
|
240
|
-
// Multi-Location Daemon Integration Tests
|
|
241
|
-
// ============================================================================
|
|
242
|
-
describe('Multi-Location Daemon', () => {
|
|
243
|
-
let tempDir;
|
|
244
|
-
let gitCommonDir;
|
|
245
|
-
let primaryPath;
|
|
246
|
-
let worktreePath;
|
|
247
|
-
let registryPath;
|
|
248
|
-
let daemon;
|
|
249
|
-
let client;
|
|
250
|
-
/**
|
|
251
|
-
* Setup a simulated git repo structure with multiple worktree locations.
|
|
252
|
-
*/
|
|
253
|
-
async function setupGitRepoStructure() {
|
|
254
|
-
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'opentasks-multi-loc-'));
|
|
255
|
-
// Simulated repo structure:
|
|
256
|
-
// tempDir/repo/.git/ ← gitCommonDir
|
|
257
|
-
// tempDir/repo/.git/opentasks/worktrees.json
|
|
258
|
-
// tempDir/repo/.opentasks/ ← primary location
|
|
259
|
-
// tempDir/worktree1/.opentasks/ ← secondary location
|
|
260
|
-
gitCommonDir = path.join(tempDir, 'repo', '.git');
|
|
261
|
-
primaryPath = path.join(tempDir, 'repo', '.opentasks');
|
|
262
|
-
worktreePath = path.join(tempDir, 'worktree1', '.opentasks');
|
|
263
|
-
registryPath = path.join(tempDir, 'registry', 'registry.json');
|
|
264
|
-
// Create directories
|
|
265
|
-
await fs.mkdir(gitCommonDir, { recursive: true });
|
|
266
|
-
await fs.mkdir(path.join(gitCommonDir, 'opentasks'), { recursive: true });
|
|
267
|
-
await fs.mkdir(primaryPath, { recursive: true });
|
|
268
|
-
await fs.mkdir(worktreePath, { recursive: true });
|
|
269
|
-
// Create empty graph.jsonl files
|
|
270
|
-
await fs.writeFile(path.join(primaryPath, 'graph.jsonl'), '', 'utf-8');
|
|
271
|
-
await fs.writeFile(path.join(worktreePath, 'graph.jsonl'), '', 'utf-8');
|
|
272
|
-
// Create worktree registry
|
|
273
|
-
const worktreeRegistry = {
|
|
274
|
-
worktrees: [
|
|
275
|
-
{
|
|
276
|
-
path: path.join(tempDir, 'repo'),
|
|
277
|
-
opentasksPath: primaryPath,
|
|
278
|
-
hash: 'pr1m4ry1',
|
|
279
|
-
role: 'manager',
|
|
280
|
-
},
|
|
281
|
-
{
|
|
282
|
-
path: path.join(tempDir, 'worktree1'),
|
|
283
|
-
opentasksPath: worktreePath,
|
|
284
|
-
hash: 'w0rktrs1',
|
|
285
|
-
role: 'worker',
|
|
286
|
-
redirectTarget: 'pr1m4ry1',
|
|
287
|
-
},
|
|
288
|
-
],
|
|
289
|
-
};
|
|
290
|
-
await fs.writeFile(path.join(gitCommonDir, 'opentasks', 'worktrees.json'), JSON.stringify(worktreeRegistry, null, 2), 'utf-8');
|
|
291
|
-
}
|
|
292
|
-
function createMultiConfig(overrides = {}) {
|
|
293
|
-
return {
|
|
294
|
-
gitCommonDir,
|
|
295
|
-
version: '1.0.0-test',
|
|
296
|
-
registryPath,
|
|
297
|
-
shutdownTimeoutMs: 3000,
|
|
298
|
-
primaryLocationPath: primaryPath,
|
|
299
|
-
...overrides,
|
|
300
|
-
};
|
|
301
|
-
}
|
|
302
|
-
beforeEach(async () => {
|
|
303
|
-
await setupGitRepoStructure();
|
|
304
|
-
daemon = null;
|
|
305
|
-
client = null;
|
|
306
|
-
});
|
|
307
|
-
afterEach(async () => {
|
|
308
|
-
if (client?.connected) {
|
|
309
|
-
client.disconnect();
|
|
310
|
-
client = null;
|
|
311
|
-
}
|
|
312
|
-
if (daemon) {
|
|
313
|
-
try {
|
|
314
|
-
await daemon.stop();
|
|
315
|
-
}
|
|
316
|
-
catch { /* ignore */ }
|
|
317
|
-
daemon = null;
|
|
318
|
-
}
|
|
319
|
-
try {
|
|
320
|
-
await fs.rm(tempDir, { recursive: true, force: true });
|
|
321
|
-
}
|
|
322
|
-
catch { /* ignore */ }
|
|
323
|
-
});
|
|
324
|
-
describe('creation', () => {
|
|
325
|
-
it('should create multi-location daemon with correct paths', () => {
|
|
326
|
-
daemon = createDaemon(createMultiConfig());
|
|
327
|
-
const expectedSocketPath = path.join(gitCommonDir, 'opentasks', 'daemon.sock');
|
|
328
|
-
expect(daemon.socketPath).toBe(expectedSocketPath);
|
|
329
|
-
expect(daemon.locationPath).toBe(path.join(gitCommonDir, 'opentasks'));
|
|
330
|
-
});
|
|
331
|
-
it('should start in stopped state', () => {
|
|
332
|
-
daemon = createDaemon(createMultiConfig());
|
|
333
|
-
const status = daemon.getStatus();
|
|
334
|
-
expect(status.state).toBe('stopped');
|
|
335
|
-
});
|
|
336
|
-
});
|
|
337
|
-
describe('start and stop', () => {
|
|
338
|
-
it('should start and initialize locations', async () => {
|
|
339
|
-
daemon = createDaemon(createMultiConfig());
|
|
340
|
-
await daemon.start();
|
|
341
|
-
const status = daemon.getStatus();
|
|
342
|
-
expect(status.state).toBe('running');
|
|
343
|
-
expect(status.locationCount).toBeGreaterThanOrEqual(1);
|
|
344
|
-
});
|
|
345
|
-
it('should stop cleanly', async () => {
|
|
346
|
-
daemon = createDaemon(createMultiConfig());
|
|
347
|
-
await daemon.start();
|
|
348
|
-
await daemon.stop();
|
|
349
|
-
const status = daemon.getStatus();
|
|
350
|
-
expect(status.state).toBe('stopped');
|
|
351
|
-
});
|
|
352
|
-
it('should reject double start', async () => {
|
|
353
|
-
daemon = createDaemon(createMultiConfig());
|
|
354
|
-
await daemon.start();
|
|
355
|
-
await expect(daemon.start()).rejects.toThrow(DaemonError);
|
|
356
|
-
});
|
|
357
|
-
it('should be idempotent on stop', async () => {
|
|
358
|
-
daemon = createDaemon(createMultiConfig());
|
|
359
|
-
await daemon.start();
|
|
360
|
-
await daemon.stop();
|
|
361
|
-
await daemon.stop();
|
|
362
|
-
await daemon.stop();
|
|
363
|
-
expect(daemon.getStatus().state).toBe('stopped');
|
|
364
|
-
});
|
|
365
|
-
});
|
|
366
|
-
describe('IPC operations', () => {
|
|
367
|
-
it('should accept IPC connections', async () => {
|
|
368
|
-
daemon = createDaemon(createMultiConfig());
|
|
369
|
-
await daemon.start();
|
|
370
|
-
client = createIPCClient(daemon.socketPath);
|
|
371
|
-
await client.connect();
|
|
372
|
-
const result = await client.request('ping');
|
|
373
|
-
expect(result.pong).toBe(true);
|
|
374
|
-
});
|
|
375
|
-
it('should report location count in status', async () => {
|
|
376
|
-
daemon = createDaemon(createMultiConfig());
|
|
377
|
-
await daemon.start();
|
|
378
|
-
client = createIPCClient(daemon.socketPath);
|
|
379
|
-
await client.connect();
|
|
380
|
-
const status = await client.request('status');
|
|
381
|
-
expect(status.state).toBe('running');
|
|
382
|
-
expect(status.locationCount).toBeGreaterThanOrEqual(1);
|
|
383
|
-
});
|
|
384
|
-
it('should report healthy status when all locations are up', async () => {
|
|
385
|
-
daemon = createDaemon(createMultiConfig());
|
|
386
|
-
await daemon.start();
|
|
387
|
-
client = createIPCClient(daemon.socketPath);
|
|
388
|
-
await client.connect();
|
|
389
|
-
const health = await client.request('health');
|
|
390
|
-
expect(health.status).toBe('healthy');
|
|
391
|
-
});
|
|
392
|
-
it('should handle graph.create on default location', async () => {
|
|
393
|
-
daemon = createDaemon(createMultiConfig());
|
|
394
|
-
await daemon.start();
|
|
395
|
-
client = createIPCClient(daemon.socketPath);
|
|
396
|
-
await client.connect();
|
|
397
|
-
const node = await client.request('graph.create', {
|
|
398
|
-
type: 'issue',
|
|
399
|
-
title: 'Test Issue',
|
|
400
|
-
status: 'open',
|
|
401
|
-
});
|
|
402
|
-
expect(node.title).toBe('Test Issue');
|
|
403
|
-
expect(node.id).toBeTruthy();
|
|
404
|
-
});
|
|
405
|
-
it('should handle graph.create with explicit location', async () => {
|
|
406
|
-
daemon = createDaemon(createMultiConfig());
|
|
407
|
-
await daemon.start();
|
|
408
|
-
client = createIPCClient(daemon.socketPath);
|
|
409
|
-
await client.connect();
|
|
410
|
-
// Create on primary location explicitly
|
|
411
|
-
const node = await client.request('graph.create', {
|
|
412
|
-
type: 'issue',
|
|
413
|
-
title: 'Primary Issue',
|
|
414
|
-
status: 'open',
|
|
415
|
-
location: 'pr1m4ry1',
|
|
416
|
-
});
|
|
417
|
-
expect(node.title).toBe('Primary Issue');
|
|
418
|
-
});
|
|
419
|
-
it('should route graph operations to specific worktree', async () => {
|
|
420
|
-
daemon = createDaemon(createMultiConfig());
|
|
421
|
-
await daemon.start();
|
|
422
|
-
client = createIPCClient(daemon.socketPath);
|
|
423
|
-
await client.connect();
|
|
424
|
-
// Create on worktree location
|
|
425
|
-
const node = await client.request('graph.create', {
|
|
426
|
-
type: 'issue',
|
|
427
|
-
title: 'Worktree Issue',
|
|
428
|
-
status: 'open',
|
|
429
|
-
location: 'w0rktrs1',
|
|
430
|
-
});
|
|
431
|
-
expect(node.title).toBe('Worktree Issue');
|
|
432
|
-
});
|
|
433
|
-
it('should return error for unknown location', async () => {
|
|
434
|
-
daemon = createDaemon(createMultiConfig());
|
|
435
|
-
await daemon.start();
|
|
436
|
-
client = createIPCClient(daemon.socketPath);
|
|
437
|
-
await client.connect();
|
|
438
|
-
// The IPC server wraps DaemonError as JSON-RPC Internal error
|
|
439
|
-
await expect(client.request('graph.create', {
|
|
440
|
-
type: 'issue',
|
|
441
|
-
title: 'Bad Location',
|
|
442
|
-
status: 'open',
|
|
443
|
-
location: 'unknown1',
|
|
444
|
-
})).rejects.toThrow('Internal error');
|
|
445
|
-
});
|
|
446
|
-
});
|
|
447
|
-
describe('location IPC methods', () => {
|
|
448
|
-
it('should list locations', async () => {
|
|
449
|
-
daemon = createDaemon(createMultiConfig());
|
|
450
|
-
await daemon.start();
|
|
451
|
-
client = createIPCClient(daemon.socketPath);
|
|
452
|
-
await client.connect();
|
|
453
|
-
const locations = await client.request('location.list');
|
|
454
|
-
expect(locations.length).toBeGreaterThanOrEqual(1);
|
|
455
|
-
// Primary should be in the list
|
|
456
|
-
const primary = locations.find(l => l.primary);
|
|
457
|
-
expect(primary).toBeTruthy();
|
|
458
|
-
});
|
|
459
|
-
it('should list all registered worktrees', async () => {
|
|
460
|
-
daemon = createDaemon(createMultiConfig());
|
|
461
|
-
await daemon.start();
|
|
462
|
-
client = createIPCClient(daemon.socketPath);
|
|
463
|
-
await client.connect();
|
|
464
|
-
const locations = await client.request('location.list');
|
|
465
|
-
const hashes = locations.map(l => l.hash);
|
|
466
|
-
// Should have both primary and worktree
|
|
467
|
-
expect(hashes).toContain('pr1m4ry1');
|
|
468
|
-
expect(hashes).toContain('w0rktrs1');
|
|
469
|
-
});
|
|
470
|
-
it('should unregister a location', async () => {
|
|
471
|
-
daemon = createDaemon(createMultiConfig());
|
|
472
|
-
await daemon.start();
|
|
473
|
-
client = createIPCClient(daemon.socketPath);
|
|
474
|
-
await client.connect();
|
|
475
|
-
// Unregister worktree
|
|
476
|
-
const result = await client.request('location.unregister', {
|
|
477
|
-
hash: 'w0rktrs1',
|
|
478
|
-
});
|
|
479
|
-
expect(result.success).toBe(true);
|
|
480
|
-
// Verify it's gone
|
|
481
|
-
const locations = await client.request('location.list');
|
|
482
|
-
const hashes = locations.map(l => l.hash);
|
|
483
|
-
expect(hashes).not.toContain('w0rktrs1');
|
|
484
|
-
});
|
|
485
|
-
it('should dynamically register a new location', async () => {
|
|
486
|
-
daemon = createDaemon(createMultiConfig());
|
|
487
|
-
await daemon.start();
|
|
488
|
-
client = createIPCClient(daemon.socketPath);
|
|
489
|
-
await client.connect();
|
|
490
|
-
// Create a new worktree location
|
|
491
|
-
const newWorktrePath = path.join(tempDir, 'worktree2', '.opentasks');
|
|
492
|
-
await fs.mkdir(newWorktrePath, { recursive: true });
|
|
493
|
-
await fs.writeFile(path.join(newWorktrePath, 'graph.jsonl'), '', 'utf-8');
|
|
494
|
-
// Register it
|
|
495
|
-
const result = await client.request('location.register', {
|
|
496
|
-
hash: 'n3wloc01',
|
|
497
|
-
opentasksPath: newWorktrePath,
|
|
498
|
-
});
|
|
499
|
-
expect(result.success).toBe(true);
|
|
500
|
-
// Verify it's in the list
|
|
501
|
-
const locations = await client.request('location.list');
|
|
502
|
-
const hashes = locations.map(l => l.hash);
|
|
503
|
-
expect(hashes).toContain('n3wloc01');
|
|
504
|
-
});
|
|
505
|
-
it('should fail to register invalid location path', async () => {
|
|
506
|
-
daemon = createDaemon(createMultiConfig());
|
|
507
|
-
await daemon.start();
|
|
508
|
-
client = createIPCClient(daemon.socketPath);
|
|
509
|
-
await client.connect();
|
|
510
|
-
// Try to register a path that doesn't exist
|
|
511
|
-
await expect(client.request('location.register', {
|
|
512
|
-
hash: 'bad1loc1',
|
|
513
|
-
opentasksPath: '/nonexistent/path/.opentasks',
|
|
514
|
-
})).rejects.toThrow();
|
|
515
|
-
});
|
|
516
|
-
it('should be idempotent for already-registered location', async () => {
|
|
517
|
-
daemon = createDaemon(createMultiConfig());
|
|
518
|
-
await daemon.start();
|
|
519
|
-
client = createIPCClient(daemon.socketPath);
|
|
520
|
-
await client.connect();
|
|
521
|
-
// Re-register an existing location
|
|
522
|
-
const result = await client.request('location.register', {
|
|
523
|
-
hash: 'pr1m4ry1',
|
|
524
|
-
opentasksPath: primaryPath,
|
|
525
|
-
});
|
|
526
|
-
expect(result.success).toBe(true);
|
|
527
|
-
});
|
|
528
|
-
});
|
|
529
|
-
describe('graceful degradation', () => {
|
|
530
|
-
it('should start even if secondary location is unreachable', async () => {
|
|
531
|
-
// Remove the worktree .opentasks dir to make it fail
|
|
532
|
-
await fs.rm(worktreePath, { recursive: true, force: true });
|
|
533
|
-
daemon = createDaemon(createMultiConfig());
|
|
534
|
-
await daemon.start();
|
|
535
|
-
const status = daemon.getStatus();
|
|
536
|
-
expect(status.state).toBe('running');
|
|
537
|
-
// At least primary should be initialized
|
|
538
|
-
expect(status.locationCount).toBeGreaterThanOrEqual(1);
|
|
539
|
-
});
|
|
540
|
-
it('should fail if no locations can be initialized', async () => {
|
|
541
|
-
// Remove both locations
|
|
542
|
-
await fs.rm(primaryPath, { recursive: true, force: true });
|
|
543
|
-
await fs.rm(worktreePath, { recursive: true, force: true });
|
|
544
|
-
daemon = createDaemon(createMultiConfig());
|
|
545
|
-
await expect(daemon.start()).rejects.toThrow('No locations could be initialized');
|
|
546
|
-
expect(daemon.getStatus().state).toBe('stopped');
|
|
547
|
-
});
|
|
548
|
-
});
|
|
549
|
-
describe('flush operations', () => {
|
|
550
|
-
it('should flush specific location', async () => {
|
|
551
|
-
daemon = createDaemon(createMultiConfig());
|
|
552
|
-
await daemon.start();
|
|
553
|
-
client = createIPCClient(daemon.socketPath);
|
|
554
|
-
await client.connect();
|
|
555
|
-
const result = await client.request('flush', {
|
|
556
|
-
location: 'pr1m4ry1',
|
|
557
|
-
});
|
|
558
|
-
expect(result.success).toBe(true);
|
|
559
|
-
});
|
|
560
|
-
it('should flush default location when no location specified', async () => {
|
|
561
|
-
daemon = createDaemon(createMultiConfig());
|
|
562
|
-
await daemon.start();
|
|
563
|
-
client = createIPCClient(daemon.socketPath);
|
|
564
|
-
await client.connect();
|
|
565
|
-
const result = await client.request('flush');
|
|
566
|
-
expect(result.success).toBe(true);
|
|
567
|
-
});
|
|
568
|
-
});
|
|
569
|
-
describe('shutdown via IPC', () => {
|
|
570
|
-
it('should shutdown multi-location daemon via IPC', async () => {
|
|
571
|
-
daemon = createDaemon(createMultiConfig());
|
|
572
|
-
await daemon.start();
|
|
573
|
-
client = createIPCClient(daemon.socketPath);
|
|
574
|
-
await client.connect();
|
|
575
|
-
const result = await client.request('shutdown');
|
|
576
|
-
expect(result.success).toBe(true);
|
|
577
|
-
client.disconnect();
|
|
578
|
-
client = null;
|
|
579
|
-
// Wait for shutdown
|
|
580
|
-
await new Promise((r) => setTimeout(r, 300));
|
|
581
|
-
expect(daemon.getStatus().state).toBe('stopped');
|
|
582
|
-
});
|
|
583
|
-
});
|
|
584
|
-
});
|
|
585
|
-
// ============================================================================
|
|
586
|
-
// Backward Compatibility Tests
|
|
587
|
-
// ============================================================================
|
|
588
|
-
describe('Backward Compatibility', () => {
|
|
589
|
-
let tempDir;
|
|
590
|
-
let locationPath;
|
|
591
|
-
let registryPath;
|
|
592
|
-
let daemon;
|
|
593
|
-
let client;
|
|
594
|
-
beforeEach(async () => {
|
|
595
|
-
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'opentasks-compat-'));
|
|
596
|
-
locationPath = path.join(tempDir, '.opentasks');
|
|
597
|
-
registryPath = path.join(tempDir, 'registry', 'registry.json');
|
|
598
|
-
await fs.mkdir(locationPath, { recursive: true });
|
|
599
|
-
daemon = null;
|
|
600
|
-
client = null;
|
|
601
|
-
});
|
|
602
|
-
afterEach(async () => {
|
|
603
|
-
if (client?.connected) {
|
|
604
|
-
client.disconnect();
|
|
605
|
-
client = null;
|
|
606
|
-
}
|
|
607
|
-
if (daemon) {
|
|
608
|
-
try {
|
|
609
|
-
await daemon.stop();
|
|
610
|
-
}
|
|
611
|
-
catch { /* ignore */ }
|
|
612
|
-
daemon = null;
|
|
613
|
-
}
|
|
614
|
-
try {
|
|
615
|
-
await fs.rm(tempDir, { recursive: true, force: true });
|
|
616
|
-
}
|
|
617
|
-
catch { /* ignore */ }
|
|
618
|
-
});
|
|
619
|
-
it('should still work with single-location config (no gitCommonDir)', async () => {
|
|
620
|
-
const store = createMockStore();
|
|
621
|
-
daemon = createDaemon({
|
|
622
|
-
locationPath,
|
|
623
|
-
version: '1.0.0-test',
|
|
624
|
-
store,
|
|
625
|
-
registryPath,
|
|
626
|
-
shutdownTimeoutMs: 2000,
|
|
627
|
-
});
|
|
628
|
-
await daemon.start();
|
|
629
|
-
client = createIPCClient(daemon.socketPath);
|
|
630
|
-
await client.connect();
|
|
631
|
-
const result = await client.request('ping');
|
|
632
|
-
expect(result.pong).toBe(true);
|
|
633
|
-
const node = await client.request('graph.create', {
|
|
634
|
-
type: 'issue',
|
|
635
|
-
title: 'Compat Test',
|
|
636
|
-
status: 'open',
|
|
637
|
-
});
|
|
638
|
-
expect(node.title).toBe('Compat Test');
|
|
639
|
-
expect(store.createNode).toHaveBeenCalledOnce();
|
|
640
|
-
client.disconnect();
|
|
641
|
-
client = null;
|
|
642
|
-
await daemon.stop();
|
|
643
|
-
expect(daemon.getStatus().state).toBe('stopped');
|
|
644
|
-
expect(store.close).toHaveBeenCalledOnce();
|
|
645
|
-
});
|
|
646
|
-
it('single-location config should ignore location param', async () => {
|
|
647
|
-
const store = createMockStore();
|
|
648
|
-
daemon = createDaemon({
|
|
649
|
-
locationPath,
|
|
650
|
-
version: '1.0.0-test',
|
|
651
|
-
store,
|
|
652
|
-
registryPath,
|
|
653
|
-
shutdownTimeoutMs: 2000,
|
|
654
|
-
});
|
|
655
|
-
await daemon.start();
|
|
656
|
-
client = createIPCClient(daemon.socketPath);
|
|
657
|
-
await client.connect();
|
|
658
|
-
// Even with a location param, single-location resolves to the only store
|
|
659
|
-
const node = await client.request('graph.create', {
|
|
660
|
-
type: 'issue',
|
|
661
|
-
title: 'With Location',
|
|
662
|
-
status: 'open',
|
|
663
|
-
location: 'anyhash1',
|
|
664
|
-
});
|
|
665
|
-
expect(node.title).toBe('With Location');
|
|
666
|
-
expect(store.createNode).toHaveBeenCalledOnce();
|
|
667
|
-
});
|
|
668
|
-
});
|
|
669
|
-
//# sourceMappingURL=multi-location.test.js.map
|