opentasks 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +344 -1
- package/dist/__tests__/cli-tools.test.d.ts +8 -0
- package/dist/__tests__/cli-tools.test.d.ts.map +1 -0
- package/dist/__tests__/cli-tools.test.js +546 -0
- package/dist/__tests__/cli-tools.test.js.map +1 -0
- package/dist/__tests__/cli.test.d.ts +5 -0
- package/dist/__tests__/cli.test.d.ts.map +1 -0
- package/dist/__tests__/cli.test.js +77 -0
- package/dist/__tests__/cli.test.js.map +1 -0
- package/dist/__tests__/p1-p3-gaps.test.d.ts +2 -0
- package/dist/__tests__/p1-p3-gaps.test.d.ts.map +1 -0
- package/dist/__tests__/p1-p3-gaps.test.js +463 -0
- package/dist/__tests__/p1-p3-gaps.test.js.map +1 -0
- package/dist/cli.d.ts +19 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +702 -23
- package/dist/cli.js.map +1 -1
- package/dist/client/__tests__/client-crud.test.d.ts +7 -0
- package/dist/client/__tests__/client-crud.test.d.ts.map +1 -0
- package/dist/client/__tests__/client-crud.test.js +404 -0
- package/dist/client/__tests__/client-crud.test.js.map +1 -0
- package/dist/client/__tests__/client.test.d.ts +5 -0
- package/dist/client/__tests__/client.test.d.ts.map +1 -0
- package/dist/client/__tests__/client.test.js +518 -0
- package/dist/client/__tests__/client.test.js.map +1 -0
- package/dist/client/client.d.ts +228 -0
- package/dist/client/client.d.ts.map +1 -0
- package/dist/client/client.js +393 -0
- package/dist/client/client.js.map +1 -0
- package/dist/client/index.d.ts +11 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +9 -0
- package/dist/client/index.js.map +1 -0
- package/dist/config/__tests__/defaults.test.d.ts +2 -0
- package/dist/config/__tests__/defaults.test.d.ts.map +1 -0
- package/dist/config/__tests__/defaults.test.js +57 -0
- package/dist/config/__tests__/defaults.test.js.map +1 -0
- package/dist/config/__tests__/env.test.d.ts +2 -0
- package/dist/config/__tests__/env.test.d.ts.map +1 -0
- package/dist/config/__tests__/env.test.js +136 -0
- package/dist/config/__tests__/env.test.js.map +1 -0
- package/dist/config/__tests__/index.test.d.ts +2 -0
- package/dist/config/__tests__/index.test.d.ts.map +1 -0
- package/dist/config/__tests__/index.test.js +113 -0
- package/dist/config/__tests__/index.test.js.map +1 -0
- package/dist/config/__tests__/loader.test.d.ts +2 -0
- package/dist/config/__tests__/loader.test.d.ts.map +1 -0
- package/dist/config/__tests__/loader.test.js +128 -0
- package/dist/config/__tests__/loader.test.js.map +1 -0
- package/dist/config/__tests__/merge.test.d.ts +2 -0
- package/dist/config/__tests__/merge.test.d.ts.map +1 -0
- package/dist/config/__tests__/merge.test.js +79 -0
- package/dist/config/__tests__/merge.test.js.map +1 -0
- package/dist/config/__tests__/schema.test.d.ts +2 -0
- package/dist/config/__tests__/schema.test.d.ts.map +1 -0
- package/dist/config/__tests__/schema.test.js +300 -0
- package/dist/config/__tests__/schema.test.js.map +1 -0
- package/dist/config/defaults.d.ts +13 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +15 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/env.d.ts +14 -0
- package/dist/config/env.d.ts.map +1 -0
- package/dist/config/env.js +130 -0
- package/dist/config/env.js.map +1 -0
- package/dist/config/errors.d.ts +21 -0
- package/dist/config/errors.d.ts.map +1 -0
- package/dist/config/errors.js +30 -0
- package/dist/config/errors.js.map +1 -0
- package/dist/config/index.d.ts +21 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +41 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/loader.d.ts +8 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +87 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/merge.d.ts +12 -0
- package/dist/config/merge.d.ts.map +1 -0
- package/dist/config/merge.js +54 -0
- package/dist/config/merge.js.map +1 -0
- package/dist/config/schema.d.ts +644 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +491 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/core/__tests__/conditional-redirects.test.d.ts +2 -0
- package/dist/core/__tests__/conditional-redirects.test.d.ts.map +1 -0
- package/dist/core/__tests__/conditional-redirects.test.js +83 -0
- package/dist/core/__tests__/conditional-redirects.test.js.map +1 -0
- package/dist/core/__tests__/connections.test.d.ts +2 -0
- package/dist/core/__tests__/connections.test.d.ts.map +1 -0
- package/dist/core/__tests__/connections.test.js +158 -0
- package/dist/core/__tests__/connections.test.js.map +1 -0
- package/dist/core/__tests__/hash.test.d.ts +2 -0
- package/dist/core/__tests__/hash.test.d.ts.map +1 -0
- package/dist/core/__tests__/hash.test.js +139 -0
- package/dist/core/__tests__/hash.test.js.map +1 -0
- package/dist/core/__tests__/id.test.d.ts +2 -0
- package/dist/core/__tests__/id.test.d.ts.map +1 -0
- package/dist/core/__tests__/id.test.js +142 -0
- package/dist/core/__tests__/id.test.js.map +1 -0
- package/dist/core/__tests__/location.test.d.ts +2 -0
- package/dist/core/__tests__/location.test.d.ts.map +1 -0
- package/dist/core/__tests__/location.test.js +77 -0
- package/dist/core/__tests__/location.test.js.map +1 -0
- package/dist/core/__tests__/merge-driver.test.d.ts +2 -0
- package/dist/core/__tests__/merge-driver.test.d.ts.map +1 -0
- package/dist/core/__tests__/merge-driver.test.js +218 -0
- package/dist/core/__tests__/merge-driver.test.js.map +1 -0
- package/dist/core/__tests__/redirects.test.d.ts +2 -0
- package/dist/core/__tests__/redirects.test.d.ts.map +1 -0
- package/dist/core/__tests__/redirects.test.js +123 -0
- package/dist/core/__tests__/redirects.test.js.map +1 -0
- package/dist/core/__tests__/resolve-location-target.test.d.ts +8 -0
- package/dist/core/__tests__/resolve-location-target.test.d.ts.map +1 -0
- package/dist/core/__tests__/resolve-location-target.test.js +303 -0
- package/dist/core/__tests__/resolve-location-target.test.js.map +1 -0
- package/dist/core/__tests__/uri.test.d.ts +2 -0
- package/dist/core/__tests__/uri.test.d.ts.map +1 -0
- package/dist/core/__tests__/uri.test.js +159 -0
- package/dist/core/__tests__/uri.test.js.map +1 -0
- package/dist/core/__tests__/worktree.test.d.ts +2 -0
- package/dist/core/__tests__/worktree.test.d.ts.map +1 -0
- package/dist/core/__tests__/worktree.test.js +120 -0
- package/dist/core/__tests__/worktree.test.js.map +1 -0
- package/dist/core/conditional-redirects.d.ts +42 -0
- package/dist/core/conditional-redirects.d.ts.map +1 -0
- package/dist/core/conditional-redirects.js +59 -0
- package/dist/core/conditional-redirects.js.map +1 -0
- package/dist/core/connections.d.ts +87 -0
- package/dist/core/connections.d.ts.map +1 -0
- package/dist/core/connections.js +160 -0
- package/dist/core/connections.js.map +1 -0
- package/dist/core/discover.d.ts +39 -0
- package/dist/core/discover.d.ts.map +1 -0
- package/dist/core/discover.js +136 -0
- package/dist/core/discover.js.map +1 -0
- package/dist/core/hash.d.ts +25 -0
- package/dist/core/hash.d.ts.map +1 -0
- package/dist/core/hash.js +62 -0
- package/dist/core/hash.js.map +1 -0
- package/dist/core/id.d.ts +79 -0
- package/dist/core/id.d.ts.map +1 -0
- package/dist/core/id.js +141 -0
- package/dist/core/id.js.map +1 -0
- package/dist/core/index.d.ts +15 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +24 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/location.d.ts +70 -0
- package/dist/core/location.d.ts.map +1 -0
- package/dist/core/location.js +121 -0
- package/dist/core/location.js.map +1 -0
- package/dist/core/merge-driver.d.ts +50 -0
- package/dist/core/merge-driver.d.ts.map +1 -0
- package/dist/core/merge-driver.js +258 -0
- package/dist/core/merge-driver.js.map +1 -0
- package/dist/core/redirects.d.ts +91 -0
- package/dist/core/redirects.d.ts.map +1 -0
- package/dist/core/redirects.js +113 -0
- package/dist/core/redirects.js.map +1 -0
- package/dist/core/uri.d.ts +105 -0
- package/dist/core/uri.d.ts.map +1 -0
- package/dist/core/uri.js +190 -0
- package/dist/core/uri.js.map +1 -0
- package/dist/core/worktree.d.ts +106 -0
- package/dist/core/worktree.d.ts.map +1 -0
- package/dist/core/worktree.js +394 -0
- package/dist/core/worktree.js.map +1 -0
- package/dist/daemon/__tests__/flush.test.d.ts +5 -0
- package/dist/daemon/__tests__/flush.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/flush.test.js +213 -0
- package/dist/daemon/__tests__/flush.test.js.map +1 -0
- package/dist/daemon/__tests__/integration.test.d.ts +7 -0
- package/dist/daemon/__tests__/integration.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/integration.test.js +276 -0
- package/dist/daemon/__tests__/integration.test.js.map +1 -0
- package/dist/daemon/__tests__/ipc.test.d.ts +5 -0
- package/dist/daemon/__tests__/ipc.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/ipc.test.js +314 -0
- package/dist/daemon/__tests__/ipc.test.js.map +1 -0
- package/dist/daemon/__tests__/lifecycle.test.d.ts +5 -0
- package/dist/daemon/__tests__/lifecycle.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/lifecycle.test.js +301 -0
- package/dist/daemon/__tests__/lifecycle.test.js.map +1 -0
- package/dist/daemon/__tests__/lock.test.d.ts +5 -0
- package/dist/daemon/__tests__/lock.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/lock.test.js +192 -0
- package/dist/daemon/__tests__/lock.test.js.map +1 -0
- package/dist/daemon/__tests__/methods/graph.test.d.ts +5 -0
- package/dist/daemon/__tests__/methods/graph.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/methods/graph.test.js +309 -0
- package/dist/daemon/__tests__/methods/graph.test.js.map +1 -0
- package/dist/daemon/__tests__/methods/provider.test.d.ts +7 -0
- package/dist/daemon/__tests__/methods/provider.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/methods/provider.test.js +181 -0
- package/dist/daemon/__tests__/methods/provider.test.js.map +1 -0
- package/dist/daemon/__tests__/methods/tools.test.d.ts +5 -0
- package/dist/daemon/__tests__/methods/tools.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/methods/tools.test.js +587 -0
- package/dist/daemon/__tests__/methods/tools.test.js.map +1 -0
- package/dist/daemon/__tests__/multi-location.test.d.ts +8 -0
- package/dist/daemon/__tests__/multi-location.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/multi-location.test.js +669 -0
- package/dist/daemon/__tests__/multi-location.test.js.map +1 -0
- package/dist/daemon/__tests__/registry.test.d.ts +5 -0
- package/dist/daemon/__tests__/registry.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/registry.test.js +208 -0
- package/dist/daemon/__tests__/registry.test.js.map +1 -0
- package/dist/daemon/__tests__/watcher.test.d.ts +5 -0
- package/dist/daemon/__tests__/watcher.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/watcher.test.js +234 -0
- package/dist/daemon/__tests__/watcher.test.js.map +1 -0
- package/dist/daemon/entire-linker.d.ts +68 -0
- package/dist/daemon/entire-linker.d.ts.map +1 -0
- package/dist/daemon/entire-linker.js +439 -0
- package/dist/daemon/entire-linker.js.map +1 -0
- package/dist/daemon/entire-watcher.d.ts +66 -0
- package/dist/daemon/entire-watcher.d.ts.map +1 -0
- package/dist/daemon/entire-watcher.js +258 -0
- package/dist/daemon/entire-watcher.js.map +1 -0
- package/dist/daemon/factory.d.ts +59 -0
- package/dist/daemon/factory.d.ts.map +1 -0
- package/dist/daemon/factory.js +72 -0
- package/dist/daemon/factory.js.map +1 -0
- package/dist/daemon/flush.d.ts +51 -0
- package/dist/daemon/flush.d.ts.map +1 -0
- package/dist/daemon/flush.js +89 -0
- package/dist/daemon/flush.js.map +1 -0
- package/dist/daemon/index.d.ts +39 -0
- package/dist/daemon/index.d.ts.map +1 -0
- package/dist/daemon/index.js +24 -0
- package/dist/daemon/index.js.map +1 -0
- package/dist/daemon/ipc.d.ts +97 -0
- package/dist/daemon/ipc.d.ts.map +1 -0
- package/dist/daemon/ipc.js +304 -0
- package/dist/daemon/ipc.js.map +1 -0
- package/dist/daemon/lifecycle.d.ts +85 -0
- package/dist/daemon/lifecycle.d.ts.map +1 -0
- package/dist/daemon/lifecycle.js +754 -0
- package/dist/daemon/lifecycle.js.map +1 -0
- package/dist/daemon/location-state.d.ts +85 -0
- package/dist/daemon/location-state.d.ts.map +1 -0
- package/dist/daemon/location-state.js +291 -0
- package/dist/daemon/location-state.js.map +1 -0
- package/dist/daemon/lock.d.ts +29 -0
- package/dist/daemon/lock.d.ts.map +1 -0
- package/dist/daemon/lock.js +131 -0
- package/dist/daemon/lock.js.map +1 -0
- package/dist/daemon/methods/__tests__/graph.test.d.ts +5 -0
- package/dist/daemon/methods/__tests__/graph.test.d.ts.map +1 -0
- package/dist/daemon/methods/__tests__/graph.test.js +274 -0
- package/dist/daemon/methods/__tests__/graph.test.js.map +1 -0
- package/dist/daemon/methods/__tests__/provider.test.d.ts +5 -0
- package/dist/daemon/methods/__tests__/provider.test.d.ts.map +1 -0
- package/dist/daemon/methods/__tests__/provider.test.js +184 -0
- package/dist/daemon/methods/__tests__/provider.test.js.map +1 -0
- package/dist/daemon/methods/__tests__/tools.test.d.ts +5 -0
- package/dist/daemon/methods/__tests__/tools.test.d.ts.map +1 -0
- package/dist/daemon/methods/__tests__/tools.test.js +295 -0
- package/dist/daemon/methods/__tests__/tools.test.js.map +1 -0
- package/dist/daemon/methods/archive.d.ts +22 -0
- package/dist/daemon/methods/archive.d.ts.map +1 -0
- package/dist/daemon/methods/archive.js +107 -0
- package/dist/daemon/methods/archive.js.map +1 -0
- package/dist/daemon/methods/graph.d.ts +26 -0
- package/dist/daemon/methods/graph.d.ts.map +1 -0
- package/dist/daemon/methods/graph.js +157 -0
- package/dist/daemon/methods/graph.js.map +1 -0
- package/dist/daemon/methods/lifecycle.d.ts +54 -0
- package/dist/daemon/methods/lifecycle.d.ts.map +1 -0
- package/dist/daemon/methods/lifecycle.js +46 -0
- package/dist/daemon/methods/lifecycle.js.map +1 -0
- package/dist/daemon/methods/location.d.ts +24 -0
- package/dist/daemon/methods/location.d.ts.map +1 -0
- package/dist/daemon/methods/location.js +72 -0
- package/dist/daemon/methods/location.js.map +1 -0
- package/dist/daemon/methods/provider.d.ts +22 -0
- package/dist/daemon/methods/provider.d.ts.map +1 -0
- package/dist/daemon/methods/provider.js +72 -0
- package/dist/daemon/methods/provider.js.map +1 -0
- package/dist/daemon/methods/tools.d.ts +23 -0
- package/dist/daemon/methods/tools.d.ts.map +1 -0
- package/dist/daemon/methods/tools.js +111 -0
- package/dist/daemon/methods/tools.js.map +1 -0
- package/dist/daemon/registry.d.ts +35 -0
- package/dist/daemon/registry.d.ts.map +1 -0
- package/dist/daemon/registry.js +189 -0
- package/dist/daemon/registry.js.map +1 -0
- package/dist/daemon/types.d.ts +101 -0
- package/dist/daemon/types.d.ts.map +1 -0
- package/dist/daemon/types.js +19 -0
- package/dist/daemon/types.js.map +1 -0
- package/dist/daemon/watcher.d.ts +62 -0
- package/dist/daemon/watcher.d.ts.map +1 -0
- package/dist/daemon/watcher.js +142 -0
- package/dist/daemon/watcher.js.map +1 -0
- package/dist/graph/EdgeTypeRegistry.d.ts +134 -0
- package/dist/graph/EdgeTypeRegistry.d.ts.map +1 -0
- package/dist/graph/EdgeTypeRegistry.js +255 -0
- package/dist/graph/EdgeTypeRegistry.js.map +1 -0
- package/dist/graph/FederatedGraph.d.ts +296 -0
- package/dist/graph/FederatedGraph.d.ts.map +1 -0
- package/dist/graph/FederatedGraph.js +406 -0
- package/dist/graph/FederatedGraph.js.map +1 -0
- package/dist/graph/GraphologyAdapter.d.ts +151 -0
- package/dist/graph/GraphologyAdapter.d.ts.map +1 -0
- package/dist/graph/GraphologyAdapter.js +209 -0
- package/dist/graph/GraphologyAdapter.js.map +1 -0
- package/dist/graph/HydratingFederatedGraph.d.ts +151 -0
- package/dist/graph/HydratingFederatedGraph.d.ts.map +1 -0
- package/dist/graph/HydratingFederatedGraph.js +327 -0
- package/dist/graph/HydratingFederatedGraph.js.map +1 -0
- package/dist/graph/__tests__/EdgeTypeRegistry.test.d.ts +2 -0
- package/dist/graph/__tests__/EdgeTypeRegistry.test.d.ts.map +1 -0
- package/dist/graph/__tests__/EdgeTypeRegistry.test.js +212 -0
- package/dist/graph/__tests__/EdgeTypeRegistry.test.js.map +1 -0
- package/dist/graph/__tests__/FederatedGraph.test.d.ts +2 -0
- package/dist/graph/__tests__/FederatedGraph.test.d.ts.map +1 -0
- package/dist/graph/__tests__/FederatedGraph.test.js +661 -0
- package/dist/graph/__tests__/FederatedGraph.test.js.map +1 -0
- package/dist/graph/__tests__/GraphologyAdapter.test.d.ts +2 -0
- package/dist/graph/__tests__/GraphologyAdapter.test.d.ts.map +1 -0
- package/dist/graph/__tests__/GraphologyAdapter.test.js +326 -0
- package/dist/graph/__tests__/GraphologyAdapter.test.js.map +1 -0
- package/dist/graph/__tests__/HydratingFederatedGraph.test.d.ts +2 -0
- package/dist/graph/__tests__/HydratingFederatedGraph.test.d.ts.map +1 -0
- package/dist/graph/__tests__/HydratingFederatedGraph.test.js +587 -0
- package/dist/graph/__tests__/HydratingFederatedGraph.test.js.map +1 -0
- package/dist/graph/__tests__/debounce.test.d.ts +5 -0
- package/dist/graph/__tests__/debounce.test.d.ts.map +1 -0
- package/dist/graph/__tests__/debounce.test.js +195 -0
- package/dist/graph/__tests__/debounce.test.js.map +1 -0
- package/dist/graph/__tests__/edge-cases.test.d.ts +8 -0
- package/dist/graph/__tests__/edge-cases.test.d.ts.map +1 -0
- package/dist/graph/__tests__/edge-cases.test.js +472 -0
- package/dist/graph/__tests__/edge-cases.test.js.map +1 -0
- package/dist/graph/__tests__/expansion.test.d.ts +2 -0
- package/dist/graph/__tests__/expansion.test.d.ts.map +1 -0
- package/dist/graph/__tests__/expansion.test.js +105 -0
- package/dist/graph/__tests__/expansion.test.js.map +1 -0
- package/dist/graph/__tests__/provider-store.test.d.ts +5 -0
- package/dist/graph/__tests__/provider-store.test.d.ts.map +1 -0
- package/dist/graph/__tests__/provider-store.test.js +791 -0
- package/dist/graph/__tests__/provider-store.test.js.map +1 -0
- package/dist/graph/__tests__/query.test.d.ts +5 -0
- package/dist/graph/__tests__/query.test.d.ts.map +1 -0
- package/dist/graph/__tests__/query.test.js +774 -0
- package/dist/graph/__tests__/query.test.js.map +1 -0
- package/dist/graph/__tests__/store.test.d.ts +5 -0
- package/dist/graph/__tests__/store.test.d.ts.map +1 -0
- package/dist/graph/__tests__/store.test.js +489 -0
- package/dist/graph/__tests__/store.test.js.map +1 -0
- package/dist/graph/__tests__/sync.test.d.ts +5 -0
- package/dist/graph/__tests__/sync.test.d.ts.map +1 -0
- package/dist/graph/__tests__/sync.test.js +129 -0
- package/dist/graph/__tests__/sync.test.js.map +1 -0
- package/dist/graph/__tests__/validation.test.d.ts +2 -0
- package/dist/graph/__tests__/validation.test.d.ts.map +1 -0
- package/dist/graph/__tests__/validation.test.js +521 -0
- package/dist/graph/__tests__/validation.test.js.map +1 -0
- package/dist/graph/coordination.d.ts +190 -0
- package/dist/graph/coordination.d.ts.map +1 -0
- package/dist/graph/coordination.js +180 -0
- package/dist/graph/coordination.js.map +1 -0
- package/dist/graph/debounce.d.ts +47 -0
- package/dist/graph/debounce.d.ts.map +1 -0
- package/dist/graph/debounce.js +95 -0
- package/dist/graph/debounce.js.map +1 -0
- package/dist/graph/expansion.d.ts +64 -0
- package/dist/graph/expansion.d.ts.map +1 -0
- package/dist/graph/expansion.js +205 -0
- package/dist/graph/expansion.js.map +1 -0
- package/dist/graph/history.d.ts +186 -0
- package/dist/graph/history.d.ts.map +1 -0
- package/dist/graph/history.js +155 -0
- package/dist/graph/history.js.map +1 -0
- package/dist/graph/index.d.ts +35 -0
- package/dist/graph/index.d.ts.map +1 -0
- package/dist/graph/index.js +22 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph/provider-store.d.ts +211 -0
- package/dist/graph/provider-store.d.ts.map +1 -0
- package/dist/graph/provider-store.js +568 -0
- package/dist/graph/provider-store.js.map +1 -0
- package/dist/graph/query.d.ts +90 -0
- package/dist/graph/query.d.ts.map +1 -0
- package/dist/graph/query.js +463 -0
- package/dist/graph/query.js.map +1 -0
- package/dist/graph/store.d.ts +71 -0
- package/dist/graph/store.d.ts.map +1 -0
- package/dist/graph/store.js +530 -0
- package/dist/graph/store.js.map +1 -0
- package/dist/graph/sync.d.ts +48 -0
- package/dist/graph/sync.d.ts.map +1 -0
- package/dist/graph/sync.js +60 -0
- package/dist/graph/sync.js.map +1 -0
- package/dist/graph/types.d.ts +289 -0
- package/dist/graph/types.d.ts.map +1 -0
- package/dist/graph/types.js +19 -0
- package/dist/graph/types.js.map +1 -0
- package/dist/graph/validation.d.ts +26 -0
- package/dist/graph/validation.d.ts.map +1 -0
- package/dist/graph/validation.js +338 -0
- package/dist/graph/validation.js.map +1 -0
- package/dist/index.d.ts +25 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -25
- package/dist/index.js.map +1 -1
- package/dist/materialization/archiver.d.ts +12 -0
- package/dist/materialization/archiver.d.ts.map +1 -0
- package/dist/materialization/archiver.js +273 -0
- package/dist/materialization/archiver.js.map +1 -0
- package/dist/materialization/git-archive-store.d.ts +17 -0
- package/dist/materialization/git-archive-store.d.ts.map +1 -0
- package/dist/materialization/git-archive-store.js +509 -0
- package/dist/materialization/git-archive-store.js.map +1 -0
- package/dist/materialization/git-remote-store.d.ts +22 -0
- package/dist/materialization/git-remote-store.d.ts.map +1 -0
- package/dist/materialization/git-remote-store.js +448 -0
- package/dist/materialization/git-remote-store.js.map +1 -0
- package/dist/materialization/graph-id.d.ts +53 -0
- package/dist/materialization/graph-id.d.ts.map +1 -0
- package/dist/materialization/graph-id.js +163 -0
- package/dist/materialization/graph-id.js.map +1 -0
- package/dist/materialization/http-remote-store.d.ts +12 -0
- package/dist/materialization/http-remote-store.d.ts.map +1 -0
- package/dist/materialization/http-remote-store.js +143 -0
- package/dist/materialization/http-remote-store.js.map +1 -0
- package/dist/materialization/index.d.ts +15 -0
- package/dist/materialization/index.d.ts.map +1 -0
- package/dist/materialization/index.js +17 -0
- package/dist/materialization/index.js.map +1 -0
- package/dist/materialization/remote-store-factory.d.ts +17 -0
- package/dist/materialization/remote-store-factory.d.ts.map +1 -0
- package/dist/materialization/remote-store-factory.js +46 -0
- package/dist/materialization/remote-store-factory.js.map +1 -0
- package/dist/materialization/snapshot.d.ts +34 -0
- package/dist/materialization/snapshot.d.ts.map +1 -0
- package/dist/materialization/snapshot.js +177 -0
- package/dist/materialization/snapshot.js.map +1 -0
- package/dist/materialization/types.d.ts +300 -0
- package/dist/materialization/types.d.ts.map +1 -0
- package/dist/materialization/types.js +17 -0
- package/dist/materialization/types.js.map +1 -0
- package/dist/providers/__tests__/beads.test.d.ts +5 -0
- package/dist/providers/__tests__/beads.test.d.ts.map +1 -0
- package/dist/providers/__tests__/beads.test.js +591 -0
- package/dist/providers/__tests__/beads.test.js.map +1 -0
- package/dist/providers/__tests__/claude-tasks.test.d.ts +5 -0
- package/dist/providers/__tests__/claude-tasks.test.d.ts.map +1 -0
- package/dist/providers/__tests__/claude-tasks.test.js +392 -0
- package/dist/providers/__tests__/claude-tasks.test.js.map +1 -0
- package/dist/providers/__tests__/from-config.test.d.ts +5 -0
- package/dist/providers/__tests__/from-config.test.d.ts.map +1 -0
- package/dist/providers/__tests__/from-config.test.js +152 -0
- package/dist/providers/__tests__/from-config.test.js.map +1 -0
- package/dist/providers/__tests__/materialization.test.d.ts +5 -0
- package/dist/providers/__tests__/materialization.test.d.ts.map +1 -0
- package/dist/providers/__tests__/materialization.test.js +407 -0
- package/dist/providers/__tests__/materialization.test.js.map +1 -0
- package/dist/providers/__tests__/native.test.d.ts +5 -0
- package/dist/providers/__tests__/native.test.d.ts.map +1 -0
- package/dist/providers/__tests__/native.test.js +566 -0
- package/dist/providers/__tests__/native.test.js.map +1 -0
- package/dist/providers/__tests__/registry.test.d.ts +5 -0
- package/dist/providers/__tests__/registry.test.d.ts.map +1 -0
- package/dist/providers/__tests__/registry.test.js +183 -0
- package/dist/providers/__tests__/registry.test.js.map +1 -0
- package/dist/providers/beads.d.ts +46 -0
- package/dist/providers/beads.d.ts.map +1 -0
- package/dist/providers/beads.js +865 -0
- package/dist/providers/beads.js.map +1 -0
- package/dist/providers/claude-tasks.d.ts +56 -0
- package/dist/providers/claude-tasks.d.ts.map +1 -0
- package/dist/providers/claude-tasks.js +282 -0
- package/dist/providers/claude-tasks.js.map +1 -0
- package/dist/providers/entire.d.ts +88 -0
- package/dist/providers/entire.d.ts.map +1 -0
- package/dist/providers/entire.js +409 -0
- package/dist/providers/entire.js.map +1 -0
- package/dist/providers/from-config.d.ts +47 -0
- package/dist/providers/from-config.d.ts.map +1 -0
- package/dist/providers/from-config.js +150 -0
- package/dist/providers/from-config.js.map +1 -0
- package/dist/providers/index.d.ts +26 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +29 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/location.d.ts +44 -0
- package/dist/providers/location.d.ts.map +1 -0
- package/dist/providers/location.js +157 -0
- package/dist/providers/location.js.map +1 -0
- package/dist/providers/materialization.d.ts +46 -0
- package/dist/providers/materialization.d.ts.map +1 -0
- package/dist/providers/materialization.js +237 -0
- package/dist/providers/materialization.js.map +1 -0
- package/dist/providers/native.d.ts +32 -0
- package/dist/providers/native.d.ts.map +1 -0
- package/dist/providers/native.js +552 -0
- package/dist/providers/native.js.map +1 -0
- package/dist/providers/registry.d.ts +11 -0
- package/dist/providers/registry.d.ts.map +1 -0
- package/dist/providers/registry.js +97 -0
- package/dist/providers/registry.js.map +1 -0
- package/dist/providers/sudocode.d.ts +49 -0
- package/dist/providers/sudocode.d.ts.map +1 -0
- package/dist/providers/sudocode.js +945 -0
- package/dist/providers/sudocode.js.map +1 -0
- package/dist/providers/sync.d.ts +299 -0
- package/dist/providers/sync.d.ts.map +1 -0
- package/dist/providers/sync.js +93 -0
- package/dist/providers/sync.js.map +1 -0
- package/dist/providers/traits/RelationshipQueryable.d.ts +129 -0
- package/dist/providers/traits/RelationshipQueryable.d.ts.map +1 -0
- package/dist/providers/traits/RelationshipQueryable.js +68 -0
- package/dist/providers/traits/RelationshipQueryable.js.map +1 -0
- package/dist/providers/traits/TaskManageable.d.ts +157 -0
- package/dist/providers/traits/TaskManageable.d.ts.map +1 -0
- package/dist/providers/traits/TaskManageable.js +37 -0
- package/dist/providers/traits/TaskManageable.js.map +1 -0
- package/dist/providers/traits/Watchable.d.ts +216 -0
- package/dist/providers/traits/Watchable.d.ts.map +1 -0
- package/dist/providers/traits/Watchable.js +37 -0
- package/dist/providers/traits/Watchable.js.map +1 -0
- package/dist/providers/traits/__tests__/RelationshipQueryable.test.d.ts +2 -0
- package/dist/providers/traits/__tests__/RelationshipQueryable.test.d.ts.map +1 -0
- package/dist/providers/traits/__tests__/RelationshipQueryable.test.js +169 -0
- package/dist/providers/traits/__tests__/RelationshipQueryable.test.js.map +1 -0
- package/dist/providers/traits/__tests__/TaskManageable.test.d.ts +2 -0
- package/dist/providers/traits/__tests__/TaskManageable.test.d.ts.map +1 -0
- package/dist/providers/traits/__tests__/TaskManageable.test.js +172 -0
- package/dist/providers/traits/__tests__/TaskManageable.test.js.map +1 -0
- package/dist/providers/traits/index.d.ts +13 -0
- package/dist/providers/traits/index.d.ts.map +1 -0
- package/dist/providers/traits/index.js +10 -0
- package/dist/providers/traits/index.js.map +1 -0
- package/dist/providers/types.d.ts +284 -0
- package/dist/providers/types.d.ts.map +1 -0
- package/dist/providers/types.js +30 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/schema/__tests__/validation.test.d.ts +2 -0
- package/dist/schema/__tests__/validation.test.d.ts.map +1 -0
- package/dist/schema/__tests__/validation.test.js +241 -0
- package/dist/schema/__tests__/validation.test.js.map +1 -0
- package/dist/schema/base.d.ts +68 -0
- package/dist/schema/base.d.ts.map +1 -0
- package/dist/schema/base.js +5 -0
- package/dist/schema/base.js.map +1 -0
- package/dist/schema/edges.d.ts +49 -0
- package/dist/schema/edges.d.ts.map +1 -0
- package/dist/schema/edges.js +9 -0
- package/dist/schema/edges.js.map +1 -0
- package/dist/schema/index.d.ts +11 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +8 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/schema/nodes.d.ts +97 -0
- package/dist/schema/nodes.d.ts.map +1 -0
- package/dist/schema/nodes.js +5 -0
- package/dist/schema/nodes.js.map +1 -0
- package/dist/schema/storage.d.ts +107 -0
- package/dist/schema/storage.d.ts.map +1 -0
- package/dist/schema/storage.js +10 -0
- package/dist/schema/storage.js.map +1 -0
- package/dist/schema/validation.d.ts +61 -0
- package/dist/schema/validation.d.ts.map +1 -0
- package/dist/schema/validation.js +170 -0
- package/dist/schema/validation.js.map +1 -0
- package/dist/storage/__tests__/atomic-write.test.d.ts +5 -0
- package/dist/storage/__tests__/atomic-write.test.d.ts.map +1 -0
- package/dist/storage/__tests__/atomic-write.test.js +170 -0
- package/dist/storage/__tests__/atomic-write.test.js.map +1 -0
- package/dist/storage/__tests__/file-lock.test.d.ts +2 -0
- package/dist/storage/__tests__/file-lock.test.d.ts.map +1 -0
- package/dist/storage/__tests__/file-lock.test.js +89 -0
- package/dist/storage/__tests__/file-lock.test.js.map +1 -0
- package/dist/storage/__tests__/jsonl.test.d.ts +2 -0
- package/dist/storage/__tests__/jsonl.test.d.ts.map +1 -0
- package/dist/storage/__tests__/jsonl.test.js +228 -0
- package/dist/storage/__tests__/jsonl.test.js.map +1 -0
- package/dist/storage/__tests__/locked-writer.test.d.ts +2 -0
- package/dist/storage/__tests__/locked-writer.test.d.ts.map +1 -0
- package/dist/storage/__tests__/locked-writer.test.js +109 -0
- package/dist/storage/__tests__/locked-writer.test.js.map +1 -0
- package/dist/storage/__tests__/sqlite.test.d.ts +2 -0
- package/dist/storage/__tests__/sqlite.test.d.ts.map +1 -0
- package/dist/storage/__tests__/sqlite.test.js +470 -0
- package/dist/storage/__tests__/sqlite.test.js.map +1 -0
- package/dist/storage/atomic-write.d.ts +38 -0
- package/dist/storage/atomic-write.d.ts.map +1 -0
- package/dist/storage/atomic-write.js +83 -0
- package/dist/storage/atomic-write.js.map +1 -0
- package/dist/storage/file-lock.d.ts +66 -0
- package/dist/storage/file-lock.d.ts.map +1 -0
- package/dist/storage/file-lock.js +176 -0
- package/dist/storage/file-lock.js.map +1 -0
- package/dist/storage/index.d.ts +11 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +13 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/interface.d.ts +219 -0
- package/dist/storage/interface.d.ts.map +1 -0
- package/dist/storage/interface.js +22 -0
- package/dist/storage/interface.js.map +1 -0
- package/dist/storage/jsonl.d.ts +106 -0
- package/dist/storage/jsonl.d.ts.map +1 -0
- package/dist/storage/jsonl.js +218 -0
- package/dist/storage/jsonl.js.map +1 -0
- package/dist/storage/locked-writer.d.ts +67 -0
- package/dist/storage/locked-writer.d.ts.map +1 -0
- package/dist/storage/locked-writer.js +105 -0
- package/dist/storage/locked-writer.js.map +1 -0
- package/dist/storage/sqlite-schema.d.ts +48 -0
- package/dist/storage/sqlite-schema.d.ts.map +1 -0
- package/dist/storage/sqlite-schema.js +169 -0
- package/dist/storage/sqlite-schema.js.map +1 -0
- package/dist/storage/sqlite.d.ts +73 -0
- package/dist/storage/sqlite.d.ts.map +1 -0
- package/dist/storage/sqlite.js +698 -0
- package/dist/storage/sqlite.js.map +1 -0
- package/dist/tools/__tests__/annotate.test.d.ts +5 -0
- package/dist/tools/__tests__/annotate.test.d.ts.map +1 -0
- package/dist/tools/__tests__/annotate.test.js +314 -0
- package/dist/tools/__tests__/annotate.test.js.map +1 -0
- package/dist/tools/__tests__/link.test.d.ts +5 -0
- package/dist/tools/__tests__/link.test.d.ts.map +1 -0
- package/dist/tools/__tests__/link.test.js +245 -0
- package/dist/tools/__tests__/link.test.js.map +1 -0
- package/dist/tools/__tests__/query.test.d.ts +5 -0
- package/dist/tools/__tests__/query.test.d.ts.map +1 -0
- package/dist/tools/__tests__/query.test.js +288 -0
- package/dist/tools/__tests__/query.test.js.map +1 -0
- package/dist/tools/__tests__/task.test.d.ts +5 -0
- package/dist/tools/__tests__/task.test.d.ts.map +1 -0
- package/dist/tools/__tests__/task.test.js +178 -0
- package/dist/tools/__tests__/task.test.js.map +1 -0
- package/dist/tools/annotate.d.ts +17 -0
- package/dist/tools/annotate.d.ts.map +1 -0
- package/dist/tools/annotate.js +218 -0
- package/dist/tools/annotate.js.map +1 -0
- package/dist/tools/index.d.ts +14 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +14 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/link.d.ts +17 -0
- package/dist/tools/link.d.ts.map +1 -0
- package/dist/tools/link.js +127 -0
- package/dist/tools/link.js.map +1 -0
- package/dist/tools/query.d.ts +17 -0
- package/dist/tools/query.d.ts.map +1 -0
- package/dist/tools/query.js +342 -0
- package/dist/tools/query.js.map +1 -0
- package/dist/tools/task.d.ts +20 -0
- package/dist/tools/task.d.ts.map +1 -0
- package/dist/tools/task.js +161 -0
- package/dist/tools/task.js.map +1 -0
- package/dist/tools/types.d.ts +334 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +19 -0
- package/dist/tools/types.js.map +1 -0
- package/package.json +40 -5
|
@@ -0,0 +1,754 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Daemon Lifecycle Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages the start/stop lifecycle of an OpenTasks daemon.
|
|
5
|
+
* Supports two modes via unified createDaemon():
|
|
6
|
+
* - Single-location: one store, one location (backward compatible)
|
|
7
|
+
* - Multi-location: multiple worktrees under one git repo
|
|
8
|
+
*/
|
|
9
|
+
import * as fs from 'node:fs/promises';
|
|
10
|
+
import * as path from 'node:path';
|
|
11
|
+
import { createLockManager } from './lock.js';
|
|
12
|
+
import { createRegistryManager } from './registry.js';
|
|
13
|
+
import { DaemonError } from './types.js';
|
|
14
|
+
import { createIPCServer } from './ipc.js';
|
|
15
|
+
import { createFileWatcher } from './watcher.js';
|
|
16
|
+
import { createDaemonFlushManager } from './flush.js';
|
|
17
|
+
import { createEntireWatcher } from './entire-watcher.js';
|
|
18
|
+
import { createEntireAutoLinker } from './entire-linker.js';
|
|
19
|
+
import { registerLifecycleMethods } from './methods/lifecycle.js';
|
|
20
|
+
import { registerGraphMethods } from './methods/graph.js';
|
|
21
|
+
import { registerToolsMethods } from './methods/tools.js';
|
|
22
|
+
import { registerLocationMethods } from './methods/location.js';
|
|
23
|
+
import { createProviderAwareStore } from '../graph/provider-store.js';
|
|
24
|
+
import { registerProviderMethods } from './methods/provider.js';
|
|
25
|
+
import { registerArchiveMethods } from './methods/archive.js';
|
|
26
|
+
import { loadConfigFile } from '../config/loader.js';
|
|
27
|
+
import { createBeadsProvider } from '../providers/beads.js';
|
|
28
|
+
import { createSudocodeProvider } from '../providers/sudocode.js';
|
|
29
|
+
import { createClaudeTasksProvider } from '../providers/claude-tasks.js';
|
|
30
|
+
import { createLocationState, createSingleLocationResolver, createMultiLocationResolver, } from './location-state.js';
|
|
31
|
+
import { readWorktreeRegistry } from '../core/worktree.js';
|
|
32
|
+
// ============================================================================
|
|
33
|
+
// Constants
|
|
34
|
+
// ============================================================================
|
|
35
|
+
const DEFAULT_SHUTDOWN_TIMEOUT_MS = 2000;
|
|
36
|
+
// ============================================================================
|
|
37
|
+
// Type Guards
|
|
38
|
+
// ============================================================================
|
|
39
|
+
/**
|
|
40
|
+
* Check if config is for multi-location mode
|
|
41
|
+
*/
|
|
42
|
+
function isMultiLocationConfig(config) {
|
|
43
|
+
return 'gitCommonDir' in config;
|
|
44
|
+
}
|
|
45
|
+
// ============================================================================
|
|
46
|
+
// Provider Registration
|
|
47
|
+
// ============================================================================
|
|
48
|
+
/**
|
|
49
|
+
* Register external providers on a ProviderAwareStore based on config.
|
|
50
|
+
* Reads the `providers` section of the OpenTasks config and instantiates
|
|
51
|
+
* enabled providers, registering them with the store's provider registry.
|
|
52
|
+
*/
|
|
53
|
+
function registerConfiguredProviders(providerStore, config) {
|
|
54
|
+
const providersConfig = config?.providers;
|
|
55
|
+
if (!providersConfig)
|
|
56
|
+
return;
|
|
57
|
+
// Register Beads provider if enabled
|
|
58
|
+
if (providersConfig.beads?.enabled !== false) {
|
|
59
|
+
try {
|
|
60
|
+
const beads = createBeadsProvider({
|
|
61
|
+
executable: providersConfig.beads?.executable,
|
|
62
|
+
timeout: providersConfig.beads?.timeout,
|
|
63
|
+
});
|
|
64
|
+
providerStore.providers.register(beads);
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
// Graceful degradation: skip provider if creation fails
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// Register Sudocode provider if enabled
|
|
71
|
+
if (providersConfig.sudocode?.enabled !== false) {
|
|
72
|
+
try {
|
|
73
|
+
const sudocode = createSudocodeProvider({
|
|
74
|
+
executable: providersConfig.sudocode?.executable,
|
|
75
|
+
timeout: providersConfig.sudocode?.timeout,
|
|
76
|
+
});
|
|
77
|
+
providerStore.providers.register(sudocode);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
// Graceful degradation: skip provider if creation fails
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// Register Claude Tasks provider if enabled
|
|
84
|
+
if (providersConfig.claudeTasks?.enabled !== false) {
|
|
85
|
+
try {
|
|
86
|
+
const claudeTasks = createClaudeTasksProvider();
|
|
87
|
+
providerStore.providers.register(claudeTasks);
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
// Graceful degradation: skip provider if creation fails
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// ============================================================================
|
|
95
|
+
// Shared Helpers
|
|
96
|
+
// ============================================================================
|
|
97
|
+
/**
|
|
98
|
+
* Check if a daemon is already running for a location
|
|
99
|
+
*/
|
|
100
|
+
export async function checkExistingDaemon(locationPath) {
|
|
101
|
+
const lockManager = createLockManager(locationPath);
|
|
102
|
+
const isHeld = await lockManager.isHeld();
|
|
103
|
+
if (!isHeld) {
|
|
104
|
+
return { running: false };
|
|
105
|
+
}
|
|
106
|
+
const lock = await lockManager.read();
|
|
107
|
+
if (!lock) {
|
|
108
|
+
return { running: false };
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
running: true,
|
|
112
|
+
socketPath: lock.socketPath,
|
|
113
|
+
pid: lock.pid,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
// ============================================================================
|
|
117
|
+
// Unified Factory
|
|
118
|
+
// ============================================================================
|
|
119
|
+
/**
|
|
120
|
+
* Create a daemon, supporting both single-location and multi-location modes.
|
|
121
|
+
*
|
|
122
|
+
* - If config has `locationPath` + `store`: single-location mode (backward compatible)
|
|
123
|
+
* - If config has `gitCommonDir`: multi-location mode (manages all worktrees)
|
|
124
|
+
*/
|
|
125
|
+
export function createDaemon(config) {
|
|
126
|
+
if (isMultiLocationConfig(config)) {
|
|
127
|
+
return createMultiLocationDaemon(config);
|
|
128
|
+
}
|
|
129
|
+
return createSingleLocationDaemon(config);
|
|
130
|
+
}
|
|
131
|
+
// ============================================================================
|
|
132
|
+
// Single-Location Daemon
|
|
133
|
+
// ============================================================================
|
|
134
|
+
function createSingleLocationDaemon(config) {
|
|
135
|
+
const { locationPath, version, store, shutdownTimeoutMs = DEFAULT_SHUTDOWN_TIMEOUT_MS, registryPath, openTasksConfig, } = config;
|
|
136
|
+
// Use config values for paths, falling back to defaults
|
|
137
|
+
const socketFileName = openTasksConfig?.daemon?.socketPath ?? 'daemon.sock';
|
|
138
|
+
const databaseFileName = openTasksConfig?.storage?.sqlitePath ?? 'cache.db';
|
|
139
|
+
const socketPath = path.join(locationPath, socketFileName);
|
|
140
|
+
const databasePath = path.join(locationPath, databaseFileName);
|
|
141
|
+
// State
|
|
142
|
+
let state = 'stopped';
|
|
143
|
+
let startedAt = null;
|
|
144
|
+
// Managers
|
|
145
|
+
const lockManager = createLockManager(locationPath);
|
|
146
|
+
const registryManager = createRegistryManager(registryPath);
|
|
147
|
+
// Components (initialized in start(), torn down in stop())
|
|
148
|
+
let ipcServer = null;
|
|
149
|
+
let fileWatcher = null;
|
|
150
|
+
let flushManager = null;
|
|
151
|
+
let activeProviderStore = null;
|
|
152
|
+
let entireWatcher = null;
|
|
153
|
+
let entireLinker = null;
|
|
154
|
+
// Signal handlers (stored for cleanup)
|
|
155
|
+
let signalHandlers = [];
|
|
156
|
+
function setupSignalHandlers(daemon) {
|
|
157
|
+
const handler = () => {
|
|
158
|
+
void daemon.stop();
|
|
159
|
+
};
|
|
160
|
+
const signals = ['SIGTERM', 'SIGINT'];
|
|
161
|
+
for (const signal of signals) {
|
|
162
|
+
process.on(signal, handler);
|
|
163
|
+
signalHandlers.push({ signal, handler });
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
function removeSignalHandlers() {
|
|
167
|
+
for (const { signal, handler } of signalHandlers) {
|
|
168
|
+
process.off(signal, handler);
|
|
169
|
+
}
|
|
170
|
+
signalHandlers = [];
|
|
171
|
+
}
|
|
172
|
+
async function removeSocketFile() {
|
|
173
|
+
try {
|
|
174
|
+
await fs.unlink(socketPath);
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
if (error.code !== 'ENOENT') {
|
|
178
|
+
throw error;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
const daemon = {
|
|
183
|
+
socketPath,
|
|
184
|
+
locationPath,
|
|
185
|
+
async start() {
|
|
186
|
+
if (state !== 'stopped') {
|
|
187
|
+
throw new DaemonError('DAEMON_ALREADY_RUNNING', `Daemon is already ${state}`);
|
|
188
|
+
}
|
|
189
|
+
state = 'starting';
|
|
190
|
+
try {
|
|
191
|
+
// 1. Check for existing daemon
|
|
192
|
+
const existing = await checkExistingDaemon(locationPath);
|
|
193
|
+
if (existing.running) {
|
|
194
|
+
state = 'stopped';
|
|
195
|
+
throw new DaemonError('DAEMON_ALREADY_RUNNING', `Daemon already running (PID ${existing.pid}) at ${existing.socketPath}`);
|
|
196
|
+
}
|
|
197
|
+
// 2. Acquire lock
|
|
198
|
+
await lockManager.acquire({
|
|
199
|
+
version,
|
|
200
|
+
socketPath,
|
|
201
|
+
databasePath,
|
|
202
|
+
});
|
|
203
|
+
// 3. Remove stale socket file
|
|
204
|
+
await removeSocketFile();
|
|
205
|
+
// 4. Register in global registry
|
|
206
|
+
startedAt = new Date().toISOString();
|
|
207
|
+
const entry = {
|
|
208
|
+
locationPath,
|
|
209
|
+
socketPath,
|
|
210
|
+
pid: process.pid,
|
|
211
|
+
version,
|
|
212
|
+
startedAt,
|
|
213
|
+
lastActivity: startedAt,
|
|
214
|
+
};
|
|
215
|
+
await registryManager.register(entry);
|
|
216
|
+
// 5. Setup signal handlers
|
|
217
|
+
setupSignalHandlers(daemon);
|
|
218
|
+
// 6. Create flush manager
|
|
219
|
+
flushManager = createDaemonFlushManager({ debounceMs: 5000, maxDelayMs: 30000 }, async (_dirtyNodeIds) => {
|
|
220
|
+
fileWatcher?.pause();
|
|
221
|
+
try {
|
|
222
|
+
await store.flush();
|
|
223
|
+
}
|
|
224
|
+
finally {
|
|
225
|
+
fileWatcher?.resume();
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
// 7. Create IPC server
|
|
229
|
+
ipcServer = createIPCServer(socketPath);
|
|
230
|
+
// 8. Create single-location resolver wrapping store + flushManager
|
|
231
|
+
const defaultProvider = openTasksConfig?.defaultProvider ?? 'native';
|
|
232
|
+
const providerStore = createProviderAwareStore(store, {
|
|
233
|
+
defaultProvider,
|
|
234
|
+
});
|
|
235
|
+
// Register external providers from config
|
|
236
|
+
registerConfiguredProviders(providerStore, openTasksConfig);
|
|
237
|
+
activeProviderStore = providerStore;
|
|
238
|
+
const locationState = {
|
|
239
|
+
hash: 'primary',
|
|
240
|
+
opentasksPath: locationPath,
|
|
241
|
+
store,
|
|
242
|
+
providerStore,
|
|
243
|
+
flushManager,
|
|
244
|
+
watcher: null, // watcher managed separately
|
|
245
|
+
primary: true,
|
|
246
|
+
healthy: true,
|
|
247
|
+
};
|
|
248
|
+
const locationResolver = createSingleLocationResolver(locationState);
|
|
249
|
+
// 9. Register method handlers
|
|
250
|
+
registerLifecycleMethods({
|
|
251
|
+
server: ipcServer,
|
|
252
|
+
getStatus: () => daemon.getStatus(),
|
|
253
|
+
shutdown: () => daemon.stop(),
|
|
254
|
+
version,
|
|
255
|
+
startedAt: new Date(startedAt),
|
|
256
|
+
});
|
|
257
|
+
registerGraphMethods({
|
|
258
|
+
server: ipcServer,
|
|
259
|
+
locationResolver,
|
|
260
|
+
});
|
|
261
|
+
registerToolsMethods({
|
|
262
|
+
server: ipcServer,
|
|
263
|
+
locationResolver,
|
|
264
|
+
});
|
|
265
|
+
registerProviderMethods({
|
|
266
|
+
server: ipcServer,
|
|
267
|
+
locationResolver,
|
|
268
|
+
});
|
|
269
|
+
registerArchiveMethods({
|
|
270
|
+
server: ipcServer,
|
|
271
|
+
locationResolver,
|
|
272
|
+
});
|
|
273
|
+
// 10. Start IPC server (begin listening)
|
|
274
|
+
await ipcServer.start();
|
|
275
|
+
// 11. Create and start file watcher
|
|
276
|
+
fileWatcher = createFileWatcher({ locationPath });
|
|
277
|
+
fileWatcher.onchange((_event) => {
|
|
278
|
+
// External changes detected. Full reload deferred.
|
|
279
|
+
});
|
|
280
|
+
await fileWatcher.start();
|
|
281
|
+
// Update the location state's watcher reference
|
|
282
|
+
locationState.watcher = fileWatcher;
|
|
283
|
+
// 12. Start provider watching for watchable providers
|
|
284
|
+
providerStore.startProviderWatching();
|
|
285
|
+
// 13. Initialize Entire watcher + auto-linker (optional)
|
|
286
|
+
try {
|
|
287
|
+
entireWatcher = createEntireWatcher({ locationPath });
|
|
288
|
+
entireLinker = createEntireAutoLinker({
|
|
289
|
+
store,
|
|
290
|
+
flushManager,
|
|
291
|
+
});
|
|
292
|
+
entireWatcher.onSessionEvent((event) => {
|
|
293
|
+
void entireLinker.handleSessionEvent(event);
|
|
294
|
+
});
|
|
295
|
+
await entireWatcher.start();
|
|
296
|
+
}
|
|
297
|
+
catch {
|
|
298
|
+
// Entire integration is optional — continue without it
|
|
299
|
+
entireWatcher = null;
|
|
300
|
+
entireLinker = null;
|
|
301
|
+
}
|
|
302
|
+
// 13. Mark as running
|
|
303
|
+
state = 'running';
|
|
304
|
+
}
|
|
305
|
+
catch (error) {
|
|
306
|
+
// Cleanup on failure
|
|
307
|
+
state = 'stopped';
|
|
308
|
+
startedAt = null;
|
|
309
|
+
if (entireWatcher) {
|
|
310
|
+
try {
|
|
311
|
+
await entireWatcher.stop();
|
|
312
|
+
}
|
|
313
|
+
catch {
|
|
314
|
+
/* ignore */
|
|
315
|
+
}
|
|
316
|
+
entireWatcher = null;
|
|
317
|
+
entireLinker = null;
|
|
318
|
+
}
|
|
319
|
+
if (fileWatcher) {
|
|
320
|
+
try {
|
|
321
|
+
await fileWatcher.stop();
|
|
322
|
+
}
|
|
323
|
+
catch {
|
|
324
|
+
/* ignore */
|
|
325
|
+
}
|
|
326
|
+
fileWatcher = null;
|
|
327
|
+
}
|
|
328
|
+
if (ipcServer) {
|
|
329
|
+
try {
|
|
330
|
+
await ipcServer.stop();
|
|
331
|
+
}
|
|
332
|
+
catch {
|
|
333
|
+
/* ignore */
|
|
334
|
+
}
|
|
335
|
+
ipcServer = null;
|
|
336
|
+
}
|
|
337
|
+
flushManager = null;
|
|
338
|
+
try {
|
|
339
|
+
await lockManager.release();
|
|
340
|
+
}
|
|
341
|
+
catch {
|
|
342
|
+
// Ignore release errors during cleanup
|
|
343
|
+
}
|
|
344
|
+
throw error;
|
|
345
|
+
}
|
|
346
|
+
},
|
|
347
|
+
async stop() {
|
|
348
|
+
if (state === 'stopped' || state === 'stopping') {
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
if (state === 'starting') {
|
|
352
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
353
|
+
if (state === 'starting') {
|
|
354
|
+
throw new DaemonError('SHUTDOWN_TIMEOUT', 'Cannot stop daemon while starting');
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
state = 'stopping';
|
|
358
|
+
const shutdownPromise = (async () => {
|
|
359
|
+
try {
|
|
360
|
+
removeSignalHandlers();
|
|
361
|
+
if (ipcServer) {
|
|
362
|
+
await ipcServer.stop();
|
|
363
|
+
ipcServer = null;
|
|
364
|
+
}
|
|
365
|
+
// Stop Entire watcher before file watcher
|
|
366
|
+
if (entireWatcher) {
|
|
367
|
+
await entireWatcher.stop();
|
|
368
|
+
entireWatcher = null;
|
|
369
|
+
entireLinker = null;
|
|
370
|
+
}
|
|
371
|
+
// Stop provider watching before tearing down file watcher and store
|
|
372
|
+
if (activeProviderStore) {
|
|
373
|
+
activeProviderStore.stopProviderWatching();
|
|
374
|
+
activeProviderStore.stopBackgroundSync();
|
|
375
|
+
activeProviderStore = null;
|
|
376
|
+
}
|
|
377
|
+
if (fileWatcher) {
|
|
378
|
+
await fileWatcher.stop();
|
|
379
|
+
fileWatcher = null;
|
|
380
|
+
}
|
|
381
|
+
if (flushManager) {
|
|
382
|
+
await flushManager.finalFlush();
|
|
383
|
+
flushManager = null;
|
|
384
|
+
}
|
|
385
|
+
await store.close();
|
|
386
|
+
await registryManager.unregister(locationPath);
|
|
387
|
+
await removeSocketFile();
|
|
388
|
+
await lockManager.release();
|
|
389
|
+
}
|
|
390
|
+
finally {
|
|
391
|
+
state = 'stopped';
|
|
392
|
+
startedAt = null;
|
|
393
|
+
}
|
|
394
|
+
})();
|
|
395
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
396
|
+
setTimeout(() => {
|
|
397
|
+
reject(new DaemonError('SHUTDOWN_TIMEOUT', 'Shutdown timed out'));
|
|
398
|
+
}, shutdownTimeoutMs);
|
|
399
|
+
});
|
|
400
|
+
try {
|
|
401
|
+
await Promise.race([shutdownPromise, timeoutPromise]);
|
|
402
|
+
}
|
|
403
|
+
catch (error) {
|
|
404
|
+
state = 'stopped';
|
|
405
|
+
startedAt = null;
|
|
406
|
+
removeSignalHandlers();
|
|
407
|
+
throw error;
|
|
408
|
+
}
|
|
409
|
+
},
|
|
410
|
+
getStatus() {
|
|
411
|
+
return {
|
|
412
|
+
state,
|
|
413
|
+
startedAt,
|
|
414
|
+
pid: process.pid,
|
|
415
|
+
socketPath,
|
|
416
|
+
pendingFlush: flushManager?.hasPendingChanges() ?? false,
|
|
417
|
+
connectionCount: ipcServer?.getConnectionCount() ?? 0,
|
|
418
|
+
};
|
|
419
|
+
},
|
|
420
|
+
};
|
|
421
|
+
return daemon;
|
|
422
|
+
}
|
|
423
|
+
// ============================================================================
|
|
424
|
+
// Multi-Location Daemon
|
|
425
|
+
// ============================================================================
|
|
426
|
+
function createMultiLocationDaemon(config) {
|
|
427
|
+
const { gitCommonDir, version, shutdownTimeoutMs = DEFAULT_SHUTDOWN_TIMEOUT_MS, registryPath, primaryLocationPath: primaryOverride, } = config;
|
|
428
|
+
// Daemon home is .git/opentasks/
|
|
429
|
+
const daemonHomePath = path.join(gitCommonDir, 'opentasks');
|
|
430
|
+
const socketPath = path.join(daemonHomePath, 'daemon.sock');
|
|
431
|
+
const databasePath = path.join(daemonHomePath, 'cache.db');
|
|
432
|
+
// Primary location: override or auto-detect (git root's .opentasks/)
|
|
433
|
+
const gitRoot = path.dirname(gitCommonDir); // /repo/.git → /repo
|
|
434
|
+
const defaultPrimaryPath = path.join(gitRoot, '.opentasks');
|
|
435
|
+
const primaryPath = primaryOverride ?? defaultPrimaryPath;
|
|
436
|
+
// State
|
|
437
|
+
let state = 'stopped';
|
|
438
|
+
let startedAt = null;
|
|
439
|
+
// Managers
|
|
440
|
+
const lockManager = createLockManager(daemonHomePath);
|
|
441
|
+
const registryManager = createRegistryManager(registryPath);
|
|
442
|
+
// Components
|
|
443
|
+
let ipcServer = null;
|
|
444
|
+
let locationResolver = null;
|
|
445
|
+
// Signal handlers
|
|
446
|
+
let signalHandlers = [];
|
|
447
|
+
function setupSignalHandlers(daemon) {
|
|
448
|
+
const handler = () => {
|
|
449
|
+
void daemon.stop();
|
|
450
|
+
};
|
|
451
|
+
const signals = ['SIGTERM', 'SIGINT'];
|
|
452
|
+
for (const signal of signals) {
|
|
453
|
+
process.on(signal, handler);
|
|
454
|
+
signalHandlers.push({ signal, handler });
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
function removeSignalHandlers() {
|
|
458
|
+
for (const { signal, handler } of signalHandlers) {
|
|
459
|
+
process.off(signal, handler);
|
|
460
|
+
}
|
|
461
|
+
signalHandlers = [];
|
|
462
|
+
}
|
|
463
|
+
async function removeSocketFile() {
|
|
464
|
+
try {
|
|
465
|
+
await fs.unlink(socketPath);
|
|
466
|
+
}
|
|
467
|
+
catch (error) {
|
|
468
|
+
if (error.code !== 'ENOENT') {
|
|
469
|
+
throw error;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Initialize a location, returning its state. Returns null on failure (degraded mode).
|
|
475
|
+
*/
|
|
476
|
+
async function initLocation(opentasksPath, hash, isPrimary, locationConfig) {
|
|
477
|
+
try {
|
|
478
|
+
const locState = await createLocationState(opentasksPath, hash, isPrimary);
|
|
479
|
+
// Wrap store with provider-aware dispatch
|
|
480
|
+
const defaultProvider = locationConfig?.defaultProvider ?? 'native';
|
|
481
|
+
locState.providerStore = createProviderAwareStore(locState.store, {
|
|
482
|
+
defaultProvider,
|
|
483
|
+
});
|
|
484
|
+
// Register external providers from config
|
|
485
|
+
registerConfiguredProviders(locState.providerStore, locationConfig);
|
|
486
|
+
await locState.watcher.start();
|
|
487
|
+
// Start provider watching for watchable providers
|
|
488
|
+
locState.providerStore.startProviderWatching();
|
|
489
|
+
return locState;
|
|
490
|
+
}
|
|
491
|
+
catch {
|
|
492
|
+
// Graceful degradation: skip failed locations
|
|
493
|
+
return null;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Read worktree entries from the registry. Returns empty array if no registry.
|
|
498
|
+
*/
|
|
499
|
+
function getWorktreeEntries() {
|
|
500
|
+
try {
|
|
501
|
+
const registry = readWorktreeRegistry(gitCommonDir);
|
|
502
|
+
return registry.worktrees;
|
|
503
|
+
}
|
|
504
|
+
catch {
|
|
505
|
+
return [];
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* Determine primary hash from config or worktree registry
|
|
510
|
+
*/
|
|
511
|
+
function determinePrimaryHash(entries) {
|
|
512
|
+
// If primary path matches a registered worktree, use its hash
|
|
513
|
+
const primaryEntry = entries.find((e) => path.resolve(e.opentasksPath) === path.resolve(primaryPath));
|
|
514
|
+
if (primaryEntry) {
|
|
515
|
+
return primaryEntry.hash;
|
|
516
|
+
}
|
|
517
|
+
// Fallback: use 'primary' as the hash
|
|
518
|
+
return 'primary';
|
|
519
|
+
}
|
|
520
|
+
const daemon = {
|
|
521
|
+
socketPath,
|
|
522
|
+
locationPath: daemonHomePath,
|
|
523
|
+
async start() {
|
|
524
|
+
if (state !== 'stopped') {
|
|
525
|
+
throw new DaemonError('DAEMON_ALREADY_RUNNING', `Daemon is already ${state}`);
|
|
526
|
+
}
|
|
527
|
+
state = 'starting';
|
|
528
|
+
try {
|
|
529
|
+
// 1. Ensure daemon home directory exists
|
|
530
|
+
await fs.mkdir(daemonHomePath, { recursive: true });
|
|
531
|
+
// 2. Check for existing daemon
|
|
532
|
+
const existing = await checkExistingDaemon(daemonHomePath);
|
|
533
|
+
if (existing.running) {
|
|
534
|
+
state = 'stopped';
|
|
535
|
+
throw new DaemonError('DAEMON_ALREADY_RUNNING', `Daemon already running (PID ${existing.pid}) at ${existing.socketPath}`);
|
|
536
|
+
}
|
|
537
|
+
// 3. Acquire lock
|
|
538
|
+
await lockManager.acquire({
|
|
539
|
+
version,
|
|
540
|
+
socketPath,
|
|
541
|
+
databasePath,
|
|
542
|
+
});
|
|
543
|
+
// 4. Remove stale socket file
|
|
544
|
+
await removeSocketFile();
|
|
545
|
+
// 5. Register in global registry
|
|
546
|
+
startedAt = new Date().toISOString();
|
|
547
|
+
const entry = {
|
|
548
|
+
locationPath: daemonHomePath,
|
|
549
|
+
socketPath,
|
|
550
|
+
pid: process.pid,
|
|
551
|
+
version,
|
|
552
|
+
startedAt,
|
|
553
|
+
lastActivity: startedAt,
|
|
554
|
+
};
|
|
555
|
+
await registryManager.register(entry);
|
|
556
|
+
// 6. Setup signal handlers
|
|
557
|
+
setupSignalHandlers(daemon);
|
|
558
|
+
// 7. Read worktree registry and determine primary hash
|
|
559
|
+
const worktreeEntries = getWorktreeEntries();
|
|
560
|
+
const primaryHash = determinePrimaryHash(worktreeEntries);
|
|
561
|
+
// 8. Create multi-location resolver
|
|
562
|
+
locationResolver = createMultiLocationResolver(primaryHash);
|
|
563
|
+
// 9. Initialize primary location (load config from .opentasks/config.json)
|
|
564
|
+
let primaryConfig = null;
|
|
565
|
+
try {
|
|
566
|
+
primaryConfig = await loadConfigFile(path.dirname(primaryPath));
|
|
567
|
+
}
|
|
568
|
+
catch {
|
|
569
|
+
// Config load failure is non-fatal; defaults will be used
|
|
570
|
+
}
|
|
571
|
+
const primaryState = await initLocation(primaryPath, primaryHash, true, primaryConfig ?? undefined);
|
|
572
|
+
if (primaryState) {
|
|
573
|
+
locationResolver.add(primaryState);
|
|
574
|
+
}
|
|
575
|
+
// 10. Initialize worktree locations (graceful degradation)
|
|
576
|
+
for (const wt of worktreeEntries) {
|
|
577
|
+
// Skip if already added as primary
|
|
578
|
+
if (locationResolver.has(wt.hash))
|
|
579
|
+
continue;
|
|
580
|
+
let wtConfig = null;
|
|
581
|
+
try {
|
|
582
|
+
wtConfig = await loadConfigFile(path.dirname(wt.opentasksPath));
|
|
583
|
+
}
|
|
584
|
+
catch {
|
|
585
|
+
// Config load failure is non-fatal
|
|
586
|
+
}
|
|
587
|
+
const wtState = await initLocation(wt.opentasksPath, wt.hash, false, wtConfig ?? undefined);
|
|
588
|
+
if (wtState) {
|
|
589
|
+
locationResolver.add(wtState);
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
// 11. Verify at least one location initialized
|
|
593
|
+
if (locationResolver.list().length === 0) {
|
|
594
|
+
throw new DaemonError('LOCATION_INIT_FAILED', 'No locations could be initialized');
|
|
595
|
+
}
|
|
596
|
+
// 12. Create IPC server
|
|
597
|
+
ipcServer = createIPCServer(socketPath);
|
|
598
|
+
// 13. Register method handlers
|
|
599
|
+
registerLifecycleMethods({
|
|
600
|
+
server: ipcServer,
|
|
601
|
+
getStatus: () => daemon.getStatus(),
|
|
602
|
+
shutdown: () => daemon.stop(),
|
|
603
|
+
version,
|
|
604
|
+
startedAt: new Date(startedAt),
|
|
605
|
+
checkHealth: () => {
|
|
606
|
+
const locations = locationResolver.list();
|
|
607
|
+
if (locations.length === 0)
|
|
608
|
+
return 'unhealthy';
|
|
609
|
+
const unhealthy = locations.filter((l) => !l.healthy);
|
|
610
|
+
if (unhealthy.length === locations.length)
|
|
611
|
+
return 'unhealthy';
|
|
612
|
+
if (unhealthy.length > 0)
|
|
613
|
+
return 'degraded';
|
|
614
|
+
return 'healthy';
|
|
615
|
+
},
|
|
616
|
+
});
|
|
617
|
+
registerGraphMethods({
|
|
618
|
+
server: ipcServer,
|
|
619
|
+
locationResolver,
|
|
620
|
+
});
|
|
621
|
+
registerToolsMethods({
|
|
622
|
+
server: ipcServer,
|
|
623
|
+
locationResolver,
|
|
624
|
+
});
|
|
625
|
+
registerProviderMethods({
|
|
626
|
+
server: ipcServer,
|
|
627
|
+
locationResolver,
|
|
628
|
+
});
|
|
629
|
+
registerLocationMethods({
|
|
630
|
+
server: ipcServer,
|
|
631
|
+
locationResolver,
|
|
632
|
+
gitCommonDir,
|
|
633
|
+
});
|
|
634
|
+
// 14. Start IPC server
|
|
635
|
+
await ipcServer.start();
|
|
636
|
+
// 15. Mark as running
|
|
637
|
+
state = 'running';
|
|
638
|
+
}
|
|
639
|
+
catch (error) {
|
|
640
|
+
// Cleanup on failure
|
|
641
|
+
state = 'stopped';
|
|
642
|
+
startedAt = null;
|
|
643
|
+
if (ipcServer) {
|
|
644
|
+
try {
|
|
645
|
+
await ipcServer.stop();
|
|
646
|
+
}
|
|
647
|
+
catch {
|
|
648
|
+
/* ignore */
|
|
649
|
+
}
|
|
650
|
+
ipcServer = null;
|
|
651
|
+
}
|
|
652
|
+
// Tear down all initialized locations
|
|
653
|
+
if (locationResolver) {
|
|
654
|
+
for (const info of locationResolver.list()) {
|
|
655
|
+
try {
|
|
656
|
+
await locationResolver.remove(info.hash);
|
|
657
|
+
}
|
|
658
|
+
catch {
|
|
659
|
+
/* ignore */
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
locationResolver = null;
|
|
663
|
+
}
|
|
664
|
+
try {
|
|
665
|
+
await lockManager.release();
|
|
666
|
+
}
|
|
667
|
+
catch {
|
|
668
|
+
// Ignore release errors during cleanup
|
|
669
|
+
}
|
|
670
|
+
throw error;
|
|
671
|
+
}
|
|
672
|
+
},
|
|
673
|
+
async stop() {
|
|
674
|
+
if (state === 'stopped' || state === 'stopping') {
|
|
675
|
+
return;
|
|
676
|
+
}
|
|
677
|
+
if (state === 'starting') {
|
|
678
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
679
|
+
if (state === 'starting') {
|
|
680
|
+
throw new DaemonError('SHUTDOWN_TIMEOUT', 'Cannot stop daemon while starting');
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
state = 'stopping';
|
|
684
|
+
const shutdownPromise = (async () => {
|
|
685
|
+
try {
|
|
686
|
+
removeSignalHandlers();
|
|
687
|
+
// Stop IPC server
|
|
688
|
+
if (ipcServer) {
|
|
689
|
+
await ipcServer.stop();
|
|
690
|
+
ipcServer = null;
|
|
691
|
+
}
|
|
692
|
+
// Tear down all locations (stop watchers, flush, close stores)
|
|
693
|
+
if (locationResolver) {
|
|
694
|
+
const locations = locationResolver.list();
|
|
695
|
+
for (const info of locations) {
|
|
696
|
+
try {
|
|
697
|
+
await locationResolver.remove(info.hash);
|
|
698
|
+
}
|
|
699
|
+
catch {
|
|
700
|
+
/* ignore during shutdown */
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
locationResolver = null;
|
|
704
|
+
}
|
|
705
|
+
// Unregister, remove socket, release lock
|
|
706
|
+
await registryManager.unregister(daemonHomePath);
|
|
707
|
+
await removeSocketFile();
|
|
708
|
+
await lockManager.release();
|
|
709
|
+
}
|
|
710
|
+
finally {
|
|
711
|
+
state = 'stopped';
|
|
712
|
+
startedAt = null;
|
|
713
|
+
}
|
|
714
|
+
})();
|
|
715
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
716
|
+
setTimeout(() => {
|
|
717
|
+
reject(new DaemonError('SHUTDOWN_TIMEOUT', 'Shutdown timed out'));
|
|
718
|
+
}, shutdownTimeoutMs);
|
|
719
|
+
});
|
|
720
|
+
try {
|
|
721
|
+
await Promise.race([shutdownPromise, timeoutPromise]);
|
|
722
|
+
}
|
|
723
|
+
catch (error) {
|
|
724
|
+
state = 'stopped';
|
|
725
|
+
startedAt = null;
|
|
726
|
+
removeSignalHandlers();
|
|
727
|
+
throw error;
|
|
728
|
+
}
|
|
729
|
+
},
|
|
730
|
+
getStatus() {
|
|
731
|
+
const locations = locationResolver?.list() ?? [];
|
|
732
|
+
const hasPendingFlush = locations.some((info) => {
|
|
733
|
+
try {
|
|
734
|
+
const locState = locationResolver?.resolve(info.hash);
|
|
735
|
+
return locState?.flushManager.hasPendingChanges() ?? false;
|
|
736
|
+
}
|
|
737
|
+
catch {
|
|
738
|
+
return false;
|
|
739
|
+
}
|
|
740
|
+
});
|
|
741
|
+
return {
|
|
742
|
+
state,
|
|
743
|
+
startedAt,
|
|
744
|
+
pid: process.pid,
|
|
745
|
+
socketPath,
|
|
746
|
+
pendingFlush: hasPendingFlush,
|
|
747
|
+
connectionCount: ipcServer?.getConnectionCount() ?? 0,
|
|
748
|
+
locationCount: locations.length,
|
|
749
|
+
};
|
|
750
|
+
},
|
|
751
|
+
};
|
|
752
|
+
return daemon;
|
|
753
|
+
}
|
|
754
|
+
//# sourceMappingURL=lifecycle.js.map
|