@quolu/lattice 0.70.0 → 0.71.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/lattice.mjs +21 -0
- package/package.json +1 -1
- package/sensor/dist/bin/lattice-sensor.js +746 -323
- package/sensor/dist/bin/viewer-gate.d.ts +17 -0
- package/sensor/dist/bin/viewer-gate.d.ts.map +1 -0
- package/sensor/dist/bin/viewer-gate.js +31 -0
- package/sensor/dist/bin/viewer-gate.js.map +1 -0
- package/sensor/dist/context/formatter.d.ts +7 -1
- package/sensor/dist/context/formatter.d.ts.map +1 -1
- package/sensor/dist/context/formatter.js +12 -6
- package/sensor/dist/context/formatter.js.map +1 -1
- package/sensor/dist/context/index.d.ts +12 -0
- package/sensor/dist/context/index.d.ts.map +1 -1
- package/sensor/dist/context/index.js +103 -16
- package/sensor/dist/context/index.js.map +1 -1
- package/sensor/dist/db/index.d.ts +23 -2
- package/sensor/dist/db/index.d.ts.map +1 -1
- package/sensor/dist/db/index.js +109 -31
- package/sensor/dist/db/index.js.map +1 -1
- package/sensor/dist/db/migrations.d.ts +1 -1
- package/sensor/dist/db/migrations.d.ts.map +1 -1
- package/sensor/dist/db/migrations.js +68 -1
- package/sensor/dist/db/migrations.js.map +1 -1
- package/sensor/dist/db/queries.d.ts +583 -6
- package/sensor/dist/db/queries.d.ts.map +1 -1
- package/sensor/dist/db/queries.js +1425 -57
- package/sensor/dist/db/queries.js.map +1 -1
- package/sensor/dist/db/schema.sql +27 -4
- package/sensor/dist/db/sqlite-adapter.d.ts +2 -0
- package/sensor/dist/db/sqlite-adapter.d.ts.map +1 -1
- package/sensor/dist/db/sqlite-adapter.js +56 -7
- package/sensor/dist/db/sqlite-adapter.js.map +1 -1
- package/sensor/dist/db/synthesis-stage.d.ts +12 -0
- package/sensor/dist/db/synthesis-stage.d.ts.map +1 -0
- package/sensor/dist/db/synthesis-stage.js +93 -0
- package/sensor/dist/db/synthesis-stage.js.map +1 -0
- package/sensor/dist/db/wal-valve.d.ts +32 -12
- package/sensor/dist/db/wal-valve.d.ts.map +1 -1
- package/sensor/dist/db/wal-valve.js +65 -22
- package/sensor/dist/db/wal-valve.js.map +1 -1
- package/sensor/dist/db/wsl-shared-index.d.ts +53 -0
- package/sensor/dist/db/wsl-shared-index.d.ts.map +1 -0
- package/sensor/dist/db/wsl-shared-index.js +121 -0
- package/sensor/dist/db/wsl-shared-index.js.map +1 -0
- package/sensor/dist/directory.d.ts +126 -2
- package/sensor/dist/directory.d.ts.map +1 -1
- package/sensor/dist/directory.js +285 -16
- package/sensor/dist/directory.js.map +1 -1
- package/sensor/dist/errors.d.ts +14 -0
- package/sensor/dist/errors.d.ts.map +1 -1
- package/sensor/dist/errors.js +16 -1
- package/sensor/dist/errors.js.map +1 -1
- package/sensor/dist/extraction/cfml-extractor.d.ts +1 -0
- package/sensor/dist/extraction/cfml-extractor.d.ts.map +1 -1
- package/sensor/dist/extraction/cfml-extractor.js +15 -3
- package/sensor/dist/extraction/cfml-extractor.js.map +1 -1
- package/sensor/dist/extraction/dfm-extractor.d.ts.map +1 -1
- package/sensor/dist/extraction/dfm-extractor.js +14 -10
- package/sensor/dist/extraction/dfm-extractor.js.map +1 -1
- package/sensor/dist/extraction/extraction-version.d.ts +1 -1
- package/sensor/dist/extraction/extraction-version.d.ts.map +1 -1
- package/sensor/dist/extraction/extraction-version.js +3 -1
- package/sensor/dist/extraction/extraction-version.js.map +1 -1
- package/sensor/dist/extraction/function-ref.d.ts +6 -4
- package/sensor/dist/extraction/function-ref.d.ts.map +1 -1
- package/sensor/dist/extraction/function-ref.js +35 -14
- package/sensor/dist/extraction/function-ref.js.map +1 -1
- package/sensor/dist/extraction/generated-detection.d.ts +48 -12
- package/sensor/dist/extraction/generated-detection.d.ts.map +1 -1
- package/sensor/dist/extraction/generated-detection.js +176 -11
- package/sensor/dist/extraction/generated-detection.js.map +1 -1
- package/sensor/dist/extraction/grammars.d.ts +38 -0
- package/sensor/dist/extraction/grammars.d.ts.map +1 -1
- package/sensor/dist/extraction/grammars.js +115 -3
- package/sensor/dist/extraction/grammars.js.map +1 -1
- package/sensor/dist/extraction/index.d.ts +218 -14
- package/sensor/dist/extraction/index.d.ts.map +1 -1
- package/sensor/dist/extraction/index.js +887 -175
- package/sensor/dist/extraction/index.js.map +1 -1
- package/sensor/dist/extraction/languages/c-cpp.d.ts +58 -0
- package/sensor/dist/extraction/languages/c-cpp.d.ts.map +1 -1
- package/sensor/dist/extraction/languages/c-cpp.js +310 -19
- package/sensor/dist/extraction/languages/c-cpp.js.map +1 -1
- package/sensor/dist/extraction/languages/dart.d.ts.map +1 -1
- package/sensor/dist/extraction/languages/dart.js +8 -3
- package/sensor/dist/extraction/languages/dart.js.map +1 -1
- package/sensor/dist/extraction/languages/erlang.d.ts.map +1 -1
- package/sensor/dist/extraction/languages/erlang.js +58 -22
- package/sensor/dist/extraction/languages/erlang.js.map +1 -1
- package/sensor/dist/extraction/languages/javascript.js +1 -1
- package/sensor/dist/extraction/languages/javascript.js.map +1 -1
- package/sensor/dist/extraction/languages/kotlin.d.ts.map +1 -1
- package/sensor/dist/extraction/languages/kotlin.js +169 -36
- package/sensor/dist/extraction/languages/kotlin.js.map +1 -1
- package/sensor/dist/extraction/languages/lua.d.ts.map +1 -1
- package/sensor/dist/extraction/languages/lua.js +4 -1
- package/sensor/dist/extraction/languages/lua.js.map +1 -1
- package/sensor/dist/extraction/languages/objc.d.ts.map +1 -1
- package/sensor/dist/extraction/languages/objc.js +4 -0
- package/sensor/dist/extraction/languages/objc.js.map +1 -1
- package/sensor/dist/extraction/languages/python.d.ts.map +1 -1
- package/sensor/dist/extraction/languages/python.js +71 -0
- package/sensor/dist/extraction/languages/python.js.map +1 -1
- package/sensor/dist/extraction/languages/rust.d.ts +20 -0
- package/sensor/dist/extraction/languages/rust.d.ts.map +1 -1
- package/sensor/dist/extraction/languages/rust.js +50 -20
- package/sensor/dist/extraction/languages/rust.js.map +1 -1
- package/sensor/dist/extraction/languages/scala.d.ts.map +1 -1
- package/sensor/dist/extraction/languages/scala.js +18 -3
- package/sensor/dist/extraction/languages/scala.js.map +1 -1
- package/sensor/dist/extraction/languages/swift.d.ts +15 -0
- package/sensor/dist/extraction/languages/swift.d.ts.map +1 -1
- package/sensor/dist/extraction/languages/swift.js +50 -0
- package/sensor/dist/extraction/languages/swift.js.map +1 -1
- package/sensor/dist/extraction/languages/typescript.d.ts.map +1 -1
- package/sensor/dist/extraction/languages/typescript.js +9 -2
- package/sensor/dist/extraction/languages/typescript.js.map +1 -1
- package/sensor/dist/extraction/liquid-extractor.d.ts +18 -0
- package/sensor/dist/extraction/liquid-extractor.d.ts.map +1 -1
- package/sensor/dist/extraction/liquid-extractor.js +98 -22
- package/sensor/dist/extraction/liquid-extractor.js.map +1 -1
- package/sensor/dist/extraction/mybatis-extractor.d.ts.map +1 -1
- package/sensor/dist/extraction/mybatis-extractor.js +6 -4
- package/sensor/dist/extraction/mybatis-extractor.js.map +1 -1
- package/sensor/dist/extraction/parse-pool.d.ts +7 -0
- package/sensor/dist/extraction/parse-pool.d.ts.map +1 -1
- package/sensor/dist/extraction/parse-pool.js +20 -1
- package/sensor/dist/extraction/parse-pool.js.map +1 -1
- package/sensor/dist/extraction/syntax-tokens.d.ts +103 -0
- package/sensor/dist/extraction/syntax-tokens.d.ts.map +1 -0
- package/sensor/dist/extraction/syntax-tokens.js +381 -0
- package/sensor/dist/extraction/syntax-tokens.js.map +1 -0
- package/sensor/dist/extraction/tree-sitter-helpers.d.ts +5 -0
- package/sensor/dist/extraction/tree-sitter-helpers.d.ts.map +1 -1
- package/sensor/dist/extraction/tree-sitter-helpers.js +17 -0
- package/sensor/dist/extraction/tree-sitter-helpers.js.map +1 -1
- package/sensor/dist/extraction/tree-sitter-types.d.ts +31 -3
- package/sensor/dist/extraction/tree-sitter-types.d.ts.map +1 -1
- package/sensor/dist/extraction/tree-sitter.d.ts +101 -18
- package/sensor/dist/extraction/tree-sitter.d.ts.map +1 -1
- package/sensor/dist/extraction/tree-sitter.js +928 -134
- package/sensor/dist/extraction/tree-sitter.js.map +1 -1
- package/sensor/dist/extraction/wasm/tree-sitter-scala.wasm +0 -0
- package/sensor/dist/file-limits.d.ts +40 -0
- package/sensor/dist/file-limits.d.ts.map +1 -0
- package/sensor/dist/file-limits.js +147 -0
- package/sensor/dist/file-limits.js.map +1 -0
- package/sensor/dist/graph/branch-guards.d.ts +265 -0
- package/sensor/dist/graph/branch-guards.d.ts.map +1 -0
- package/sensor/dist/graph/branch-guards.js +2325 -0
- package/sensor/dist/graph/branch-guards.js.map +1 -0
- package/sensor/dist/graph/dead-code.d.ts +251 -0
- package/sensor/dist/graph/dead-code.d.ts.map +1 -0
- package/sensor/dist/graph/dead-code.js +776 -0
- package/sensor/dist/graph/dead-code.js.map +1 -0
- package/sensor/dist/graph/dynamic-boundary-report.d.ts +121 -0
- package/sensor/dist/graph/dynamic-boundary-report.d.ts.map +1 -0
- package/sensor/dist/graph/dynamic-boundary-report.js +283 -0
- package/sensor/dist/graph/dynamic-boundary-report.js.map +1 -0
- package/sensor/dist/graph/index.d.ts +4 -0
- package/sensor/dist/graph/index.d.ts.map +1 -1
- package/sensor/dist/graph/index.js +16 -1
- package/sensor/dist/graph/index.js.map +1 -1
- package/sensor/dist/graph/named-symbol-flow.d.ts +125 -0
- package/sensor/dist/graph/named-symbol-flow.d.ts.map +1 -0
- package/sensor/dist/graph/named-symbol-flow.js +552 -0
- package/sensor/dist/graph/named-symbol-flow.js.map +1 -0
- package/sensor/dist/graph/queries.d.ts.map +1 -1
- package/sensor/dist/graph/queries.js +2 -0
- package/sensor/dist/graph/queries.js.map +1 -1
- package/sensor/dist/graph/symbol-lookup.d.ts +83 -0
- package/sensor/dist/graph/symbol-lookup.d.ts.map +1 -0
- package/sensor/dist/graph/symbol-lookup.js +181 -0
- package/sensor/dist/graph/symbol-lookup.js.map +1 -0
- package/sensor/dist/graph/traversal.d.ts +9 -0
- package/sensor/dist/graph/traversal.d.ts.map +1 -1
- package/sensor/dist/graph/traversal.js +62 -36
- package/sensor/dist/graph/traversal.js.map +1 -1
- package/sensor/dist/graph/type-hierarchy.d.ts +155 -0
- package/sensor/dist/graph/type-hierarchy.d.ts.map +1 -0
- package/sensor/dist/graph/type-hierarchy.js +382 -0
- package/sensor/dist/graph/type-hierarchy.js.map +1 -0
- package/sensor/dist/index.d.ts +272 -10
- package/sensor/dist/index.d.ts.map +1 -1
- package/sensor/dist/index.js +510 -34
- package/sensor/dist/index.js.map +1 -1
- package/sensor/dist/mcp/answer-freshness.d.ts +10 -0
- package/sensor/dist/mcp/answer-freshness.d.ts.map +1 -0
- package/sensor/dist/mcp/answer-freshness.js +68 -0
- package/sensor/dist/mcp/answer-freshness.js.map +1 -0
- package/sensor/dist/mcp/daemon-manager.d.ts +1 -1
- package/sensor/dist/mcp/daemon-manager.d.ts.map +1 -1
- package/sensor/dist/mcp/daemon-manager.js +17 -1
- package/sensor/dist/mcp/daemon-manager.js.map +1 -1
- package/sensor/dist/mcp/daemon-paths.d.ts +8 -0
- package/sensor/dist/mcp/daemon-paths.d.ts.map +1 -1
- package/sensor/dist/mcp/daemon-paths.js +65 -2
- package/sensor/dist/mcp/daemon-paths.js.map +1 -1
- package/sensor/dist/mcp/daemon-registry.d.ts +17 -4
- package/sensor/dist/mcp/daemon-registry.d.ts.map +1 -1
- package/sensor/dist/mcp/daemon-registry.js +133 -23
- package/sensor/dist/mcp/daemon-registry.js.map +1 -1
- package/sensor/dist/mcp/daemon.d.ts +26 -13
- package/sensor/dist/mcp/daemon.d.ts.map +1 -1
- package/sensor/dist/mcp/daemon.js +126 -32
- package/sensor/dist/mcp/daemon.js.map +1 -1
- package/sensor/dist/mcp/dynamic-boundaries.d.ts +1 -10
- package/sensor/dist/mcp/dynamic-boundaries.d.ts.map +1 -1
- package/sensor/dist/mcp/dynamic-boundaries.js +46 -42
- package/sensor/dist/mcp/dynamic-boundaries.js.map +1 -1
- package/sensor/dist/mcp/engine.d.ts +31 -9
- package/sensor/dist/mcp/engine.d.ts.map +1 -1
- package/sensor/dist/mcp/engine.js +190 -79
- package/sensor/dist/mcp/engine.js.map +1 -1
- package/sensor/dist/mcp/explore-dedup.d.ts +140 -0
- package/sensor/dist/mcp/explore-dedup.d.ts.map +1 -0
- package/sensor/dist/mcp/explore-dedup.js +239 -0
- package/sensor/dist/mcp/explore-dedup.js.map +1 -0
- package/sensor/dist/mcp/explore-diagnostics.d.ts +289 -0
- package/sensor/dist/mcp/explore-diagnostics.d.ts.map +1 -0
- package/sensor/dist/mcp/explore-diagnostics.js +558 -0
- package/sensor/dist/mcp/explore-diagnostics.js.map +1 -0
- package/sensor/dist/mcp/explore-session-state.d.ts +217 -0
- package/sensor/dist/mcp/explore-session-state.d.ts.map +1 -0
- package/sensor/dist/mcp/explore-session-state.js +322 -0
- package/sensor/dist/mcp/explore-session-state.js.map +1 -0
- package/sensor/dist/mcp/index-freshness-worker.d.ts +2 -0
- package/sensor/dist/mcp/index-freshness-worker.d.ts.map +1 -0
- package/sensor/dist/mcp/index-freshness-worker.js +30 -0
- package/sensor/dist/mcp/index-freshness-worker.js.map +1 -0
- package/sensor/dist/mcp/index-freshness.d.ts +7 -0
- package/sensor/dist/mcp/index-freshness.d.ts.map +1 -0
- package/sensor/dist/mcp/index-freshness.js +94 -0
- package/sensor/dist/mcp/index-freshness.js.map +1 -0
- package/sensor/dist/mcp/index.d.ts +3 -1
- package/sensor/dist/mcp/index.d.ts.map +1 -1
- package/sensor/dist/mcp/index.js +109 -12
- package/sensor/dist/mcp/index.js.map +1 -1
- package/sensor/dist/mcp/liveness-watchdog.d.ts +4 -1
- package/sensor/dist/mcp/liveness-watchdog.d.ts.map +1 -1
- package/sensor/dist/mcp/liveness-watchdog.js +11 -2
- package/sensor/dist/mcp/liveness-watchdog.js.map +1 -1
- package/sensor/dist/mcp/project-lifecycle.d.ts +9 -0
- package/sensor/dist/mcp/project-lifecycle.d.ts.map +1 -0
- package/sensor/dist/mcp/project-lifecycle.js +182 -0
- package/sensor/dist/mcp/project-lifecycle.js.map +1 -0
- package/sensor/dist/mcp/proxy.d.ts.map +1 -1
- package/sensor/dist/mcp/proxy.js +15 -1
- package/sensor/dist/mcp/proxy.js.map +1 -1
- package/sensor/dist/mcp/query-pool.d.ts +2 -2
- package/sensor/dist/mcp/query-pool.d.ts.map +1 -1
- package/sensor/dist/mcp/query-pool.js +9 -7
- package/sensor/dist/mcp/query-pool.js.map +1 -1
- package/sensor/dist/mcp/query-worker.js +2 -2
- package/sensor/dist/mcp/query-worker.js.map +1 -1
- package/sensor/dist/mcp/server-instructions.d.ts +2 -2
- package/sensor/dist/mcp/server-instructions.d.ts.map +1 -1
- package/sensor/dist/mcp/server-instructions.js +13 -6
- package/sensor/dist/mcp/server-instructions.js.map +1 -1
- package/sensor/dist/mcp/session.d.ts +16 -0
- package/sensor/dist/mcp/session.d.ts.map +1 -1
- package/sensor/dist/mcp/session.js +36 -13
- package/sensor/dist/mcp/session.js.map +1 -1
- package/sensor/dist/mcp/startup-handshake.d.ts +3 -1
- package/sensor/dist/mcp/startup-handshake.d.ts.map +1 -1
- package/sensor/dist/mcp/startup-handshake.js +10 -2
- package/sensor/dist/mcp/startup-handshake.js.map +1 -1
- package/sensor/dist/mcp/tools.d.ts +496 -38
- package/sensor/dist/mcp/tools.d.ts.map +1 -1
- package/sensor/dist/mcp/tools.js +4021 -772
- package/sensor/dist/mcp/tools.js.map +1 -1
- package/sensor/dist/mcp/writer-lock.d.ts +61 -0
- package/sensor/dist/mcp/writer-lock.d.ts.map +1 -0
- package/sensor/dist/mcp/writer-lock.js +260 -0
- package/sensor/dist/mcp/writer-lock.js.map +1 -0
- package/sensor/dist/project-config.d.ts +23 -0
- package/sensor/dist/project-config.d.ts.map +1 -1
- package/sensor/dist/project-config.js +39 -2
- package/sensor/dist/project-config.js.map +1 -1
- package/sensor/dist/resolution/alias-binding.d.ts +56 -0
- package/sensor/dist/resolution/alias-binding.d.ts.map +1 -0
- package/sensor/dist/resolution/alias-binding.js +127 -0
- package/sensor/dist/resolution/alias-binding.js.map +1 -0
- package/sensor/dist/resolution/c-fnptr-synthesizer.d.ts.map +1 -1
- package/sensor/dist/resolution/c-fnptr-synthesizer.js +21 -19
- package/sensor/dist/resolution/c-fnptr-synthesizer.js.map +1 -1
- package/sensor/dist/resolution/callback-synthesizer.d.ts +23 -1
- package/sensor/dist/resolution/callback-synthesizer.d.ts.map +1 -1
- package/sensor/dist/resolution/callback-synthesizer.js +356 -155
- package/sensor/dist/resolution/callback-synthesizer.js.map +1 -1
- package/sensor/dist/resolution/cpp-constructor.d.ts +4 -0
- package/sensor/dist/resolution/cpp-constructor.d.ts.map +1 -0
- package/sensor/dist/resolution/cpp-constructor.js +123 -0
- package/sensor/dist/resolution/cpp-constructor.js.map +1 -0
- package/sensor/dist/resolution/cpp-macro-visibility.d.ts +12 -0
- package/sensor/dist/resolution/cpp-macro-visibility.d.ts.map +1 -0
- package/sensor/dist/resolution/cpp-macro-visibility.js +342 -0
- package/sensor/dist/resolution/cpp-macro-visibility.js.map +1 -0
- package/sensor/dist/resolution/expo-router-synthesizer.d.ts +32 -0
- package/sensor/dist/resolution/expo-router-synthesizer.d.ts.map +1 -0
- package/sensor/dist/resolution/expo-router-synthesizer.js +189 -0
- package/sensor/dist/resolution/expo-router-synthesizer.js.map +1 -0
- package/sensor/dist/resolution/frameworks/csharp.d.ts.map +1 -1
- package/sensor/dist/resolution/frameworks/csharp.js +96 -2
- package/sensor/dist/resolution/frameworks/csharp.js.map +1 -1
- package/sensor/dist/resolution/frameworks/expo-router.d.ts +189 -0
- package/sensor/dist/resolution/frameworks/expo-router.d.ts.map +1 -0
- package/sensor/dist/resolution/frameworks/expo-router.js +785 -0
- package/sensor/dist/resolution/frameworks/expo-router.js.map +1 -0
- package/sensor/dist/resolution/frameworks/express.d.ts.map +1 -1
- package/sensor/dist/resolution/frameworks/express.js +251 -16
- package/sensor/dist/resolution/frameworks/express.js.map +1 -1
- package/sensor/dist/resolution/frameworks/index.d.ts +5 -0
- package/sensor/dist/resolution/frameworks/index.d.ts.map +1 -1
- package/sensor/dist/resolution/frameworks/index.js +29 -1
- package/sensor/dist/resolution/frameworks/index.js.map +1 -1
- package/sensor/dist/resolution/frameworks/java.d.ts.map +1 -1
- package/sensor/dist/resolution/frameworks/java.js +79 -47
- package/sensor/dist/resolution/frameworks/java.js.map +1 -1
- package/sensor/dist/resolution/frameworks/laravel.d.ts.map +1 -1
- package/sensor/dist/resolution/frameworks/laravel.js +294 -4
- package/sensor/dist/resolution/frameworks/laravel.js.map +1 -1
- package/sensor/dist/resolution/frameworks/nestjs.d.ts.map +1 -1
- package/sensor/dist/resolution/frameworks/nestjs.js +6 -14
- package/sensor/dist/resolution/frameworks/nestjs.js.map +1 -1
- package/sensor/dist/resolution/frameworks/nextjs.d.ts +76 -0
- package/sensor/dist/resolution/frameworks/nextjs.d.ts.map +1 -0
- package/sensor/dist/resolution/frameworks/nextjs.js +328 -0
- package/sensor/dist/resolution/frameworks/nextjs.js.map +1 -0
- package/sensor/dist/resolution/frameworks/object-literal.d.ts +32 -0
- package/sensor/dist/resolution/frameworks/object-literal.d.ts.map +1 -0
- package/sensor/dist/resolution/frameworks/object-literal.js +139 -0
- package/sensor/dist/resolution/frameworks/object-literal.js.map +1 -0
- package/sensor/dist/resolution/frameworks/package-deps.d.ts +14 -0
- package/sensor/dist/resolution/frameworks/package-deps.d.ts.map +1 -0
- package/sensor/dist/resolution/frameworks/package-deps.js +78 -0
- package/sensor/dist/resolution/frameworks/package-deps.js.map +1 -0
- package/sensor/dist/resolution/frameworks/python.d.ts.map +1 -1
- package/sensor/dist/resolution/frameworks/python.js +166 -0
- package/sensor/dist/resolution/frameworks/python.js.map +1 -1
- package/sensor/dist/resolution/frameworks/react-native.d.ts +26 -0
- package/sensor/dist/resolution/frameworks/react-native.d.ts.map +1 -1
- package/sensor/dist/resolution/frameworks/react-native.js +153 -14
- package/sensor/dist/resolution/frameworks/react-native.js.map +1 -1
- package/sensor/dist/resolution/frameworks/react-router.d.ts +46 -0
- package/sensor/dist/resolution/frameworks/react-router.d.ts.map +1 -0
- package/sensor/dist/resolution/frameworks/react-router.js +187 -0
- package/sensor/dist/resolution/frameworks/react-router.js.map +1 -0
- package/sensor/dist/resolution/frameworks/react.d.ts +2 -1
- package/sensor/dist/resolution/frameworks/react.d.ts.map +1 -1
- package/sensor/dist/resolution/frameworks/react.js +188 -139
- package/sensor/dist/resolution/frameworks/react.js.map +1 -1
- package/sensor/dist/resolution/frameworks/svelte.d.ts.map +1 -1
- package/sensor/dist/resolution/frameworks/svelte.js +6 -1
- package/sensor/dist/resolution/frameworks/svelte.js.map +1 -1
- package/sensor/dist/resolution/frameworks/sveltekit-router.d.ts +36 -0
- package/sensor/dist/resolution/frameworks/sveltekit-router.d.ts.map +1 -0
- package/sensor/dist/resolution/frameworks/sveltekit-router.js +156 -0
- package/sensor/dist/resolution/frameworks/sveltekit-router.js.map +1 -0
- package/sensor/dist/resolution/frameworks/swift.d.ts.map +1 -1
- package/sensor/dist/resolution/frameworks/swift.js +140 -99
- package/sensor/dist/resolution/frameworks/swift.js.map +1 -1
- package/sensor/dist/resolution/frameworks/tanstack-router.d.ts +84 -0
- package/sensor/dist/resolution/frameworks/tanstack-router.d.ts.map +1 -0
- package/sensor/dist/resolution/frameworks/tanstack-router.js +437 -0
- package/sensor/dist/resolution/frameworks/tanstack-router.js.map +1 -0
- package/sensor/dist/resolution/frameworks/vue-router.d.ts +82 -0
- package/sensor/dist/resolution/frameworks/vue-router.d.ts.map +1 -0
- package/sensor/dist/resolution/frameworks/vue-router.js +377 -0
- package/sensor/dist/resolution/frameworks/vue-router.js.map +1 -0
- package/sensor/dist/resolution/import-resolver.d.ts +38 -0
- package/sensor/dist/resolution/import-resolver.d.ts.map +1 -1
- package/sensor/dist/resolution/import-resolver.js +394 -28
- package/sensor/dist/resolution/import-resolver.js.map +1 -1
- package/sensor/dist/resolution/index.d.ts +89 -25
- package/sensor/dist/resolution/index.d.ts.map +1 -1
- package/sensor/dist/resolution/index.js +573 -148
- package/sensor/dist/resolution/index.js.map +1 -1
- package/sensor/dist/resolution/js-builtins.d.ts +13 -0
- package/sensor/dist/resolution/js-builtins.d.ts.map +1 -0
- package/sensor/dist/resolution/js-builtins.js +46 -0
- package/sensor/dist/resolution/js-builtins.js.map +1 -0
- package/sensor/dist/resolution/name-matcher.d.ts +99 -22
- package/sensor/dist/resolution/name-matcher.d.ts.map +1 -1
- package/sensor/dist/resolution/name-matcher.js +2220 -86
- package/sensor/dist/resolution/name-matcher.js.map +1 -1
- package/sensor/dist/resolution/next-router-synthesizer.d.ts +27 -0
- package/sensor/dist/resolution/next-router-synthesizer.d.ts.map +1 -0
- package/sensor/dist/resolution/next-router-synthesizer.js +113 -0
- package/sensor/dist/resolution/next-router-synthesizer.js.map +1 -0
- package/sensor/dist/resolution/path-aliases.d.ts +6 -4
- package/sensor/dist/resolution/path-aliases.d.ts.map +1 -1
- package/sensor/dist/resolution/path-aliases.js +125 -17
- package/sensor/dist/resolution/path-aliases.js.map +1 -1
- package/sensor/dist/resolution/react-router-synthesizer.d.ts +33 -0
- package/sensor/dist/resolution/react-router-synthesizer.d.ts.map +1 -0
- package/sensor/dist/resolution/react-router-synthesizer.js +126 -0
- package/sensor/dist/resolution/react-router-synthesizer.js.map +1 -0
- package/sensor/dist/resolution/resolver-pool.d.ts +2 -0
- package/sensor/dist/resolution/resolver-pool.d.ts.map +1 -1
- package/sensor/dist/resolution/resolver-pool.js +4 -0
- package/sensor/dist/resolution/resolver-pool.js.map +1 -1
- package/sensor/dist/resolution/strip-comments.d.ts +6 -0
- package/sensor/dist/resolution/strip-comments.d.ts.map +1 -1
- package/sensor/dist/resolution/strip-comments.js +58 -0
- package/sensor/dist/resolution/strip-comments.js.map +1 -1
- package/sensor/dist/resolution/sveltekit-synthesizer.d.ts +58 -0
- package/sensor/dist/resolution/sveltekit-synthesizer.d.ts.map +1 -0
- package/sensor/dist/resolution/sveltekit-synthesizer.js +173 -0
- package/sensor/dist/resolution/sveltekit-synthesizer.js.map +1 -0
- package/sensor/dist/resolution/swift-type-visibility.d.ts +52 -0
- package/sensor/dist/resolution/swift-type-visibility.d.ts.map +1 -0
- package/sensor/dist/resolution/swift-type-visibility.js +328 -0
- package/sensor/dist/resolution/swift-type-visibility.js.map +1 -0
- package/sensor/dist/resolution/synth-utils.d.ts +26 -0
- package/sensor/dist/resolution/synth-utils.d.ts.map +1 -0
- package/sensor/dist/resolution/synth-utils.js +75 -0
- package/sensor/dist/resolution/synth-utils.js.map +1 -0
- package/sensor/dist/resolution/tanstack-router-synthesizer.d.ts +31 -0
- package/sensor/dist/resolution/tanstack-router-synthesizer.d.ts.map +1 -0
- package/sensor/dist/resolution/tanstack-router-synthesizer.js +114 -0
- package/sensor/dist/resolution/tanstack-router-synthesizer.js.map +1 -0
- package/sensor/dist/resolution/tier-synthesizer.d.ts +54 -0
- package/sensor/dist/resolution/tier-synthesizer.d.ts.map +1 -0
- package/sensor/dist/resolution/tier-synthesizer.js +1294 -0
- package/sensor/dist/resolution/tier-synthesizer.js.map +1 -0
- package/sensor/dist/resolution/types.d.ts +78 -2
- package/sensor/dist/resolution/types.d.ts.map +1 -1
- package/sensor/dist/resolution/types.js +64 -0
- package/sensor/dist/resolution/types.js.map +1 -1
- package/sensor/dist/resolution/vue-router-synthesizer.d.ts +30 -0
- package/sensor/dist/resolution/vue-router-synthesizer.d.ts.map +1 -0
- package/sensor/dist/resolution/vue-router-synthesizer.js +115 -0
- package/sensor/dist/resolution/vue-router-synthesizer.js.map +1 -0
- package/sensor/dist/search/identifier-segments.d.ts +10 -0
- package/sensor/dist/search/identifier-segments.d.ts.map +1 -1
- package/sensor/dist/search/identifier-segments.js +29 -0
- package/sensor/dist/search/identifier-segments.js.map +1 -1
- package/sensor/dist/search/query-paths.d.ts +106 -0
- package/sensor/dist/search/query-paths.d.ts.map +1 -0
- package/sensor/dist/search/query-paths.js +513 -0
- package/sensor/dist/search/query-paths.js.map +1 -0
- package/sensor/dist/search/query-utils.d.ts +22 -2
- package/sensor/dist/search/query-utils.d.ts.map +1 -1
- package/sensor/dist/search/query-utils.js +56 -16
- package/sensor/dist/search/query-utils.js.map +1 -1
- package/sensor/dist/sync/watch-policy.d.ts +14 -0
- package/sensor/dist/sync/watch-policy.d.ts.map +1 -1
- package/sensor/dist/sync/watch-policy.js +19 -0
- package/sensor/dist/sync/watch-policy.js.map +1 -1
- package/sensor/dist/sync/watcher.d.ts +74 -35
- package/sensor/dist/sync/watcher.d.ts.map +1 -1
- package/sensor/dist/sync/watcher.js +281 -99
- package/sensor/dist/sync/watcher.js.map +1 -1
- package/sensor/dist/telemetry/index.d.ts +4 -2
- package/sensor/dist/telemetry/index.d.ts.map +1 -1
- package/sensor/dist/telemetry/index.js +92 -41
- package/sensor/dist/telemetry/index.js.map +1 -1
- package/sensor/dist/types.d.ts +18 -2
- package/sensor/dist/types.d.ts.map +1 -1
- package/sensor/dist/types.js +2 -0
- package/sensor/dist/types.js.map +1 -1
- package/sensor/dist/ui-server/api/deadcode.d.ts +84 -0
- package/sensor/dist/ui-server/api/deadcode.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/deadcode.js +136 -0
- package/sensor/dist/ui-server/api/deadcode.js.map +1 -0
- package/sensor/dist/ui-server/api/effects.d.ts +94 -0
- package/sensor/dist/ui-server/api/effects.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/effects.js +527 -0
- package/sensor/dist/ui-server/api/effects.js.map +1 -0
- package/sensor/dist/ui-server/api/entrypoints.d.ts +92 -0
- package/sensor/dist/ui-server/api/entrypoints.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/entrypoints.js +361 -0
- package/sensor/dist/ui-server/api/entrypoints.js.map +1 -0
- package/sensor/dist/ui-server/api/events.d.ts +183 -0
- package/sensor/dist/ui-server/api/events.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/events.js +430 -0
- package/sensor/dist/ui-server/api/events.js.map +1 -0
- package/sensor/dist/ui-server/api/file.d.ts +66 -0
- package/sensor/dist/ui-server/api/file.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/file.js +235 -0
- package/sensor/dist/ui-server/api/file.js.map +1 -0
- package/sensor/dist/ui-server/api/filecode.d.ts +126 -0
- package/sensor/dist/ui-server/api/filecode.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/filecode.js +205 -0
- package/sensor/dist/ui-server/api/filecode.js.map +1 -0
- package/sensor/dist/ui-server/api/flow.d.ts +226 -0
- package/sensor/dist/ui-server/api/flow.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/flow.js +612 -0
- package/sensor/dist/ui-server/api/flow.js.map +1 -0
- package/sensor/dist/ui-server/api/hierarchy.d.ts +81 -0
- package/sensor/dist/ui-server/api/hierarchy.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/hierarchy.js +92 -0
- package/sensor/dist/ui-server/api/hierarchy.js.map +1 -0
- package/sensor/dist/ui-server/api/index.d.ts +90 -0
- package/sensor/dist/ui-server/api/index.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/index.js +332 -0
- package/sensor/dist/ui-server/api/index.js.map +1 -0
- package/sensor/dist/ui-server/api/map.d.ts +256 -0
- package/sensor/dist/ui-server/api/map.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/map.js +760 -0
- package/sensor/dist/ui-server/api/map.js.map +1 -0
- package/sensor/dist/ui-server/api/node.d.ts +81 -0
- package/sensor/dist/ui-server/api/node.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/node.js +388 -0
- package/sensor/dist/ui-server/api/node.js.map +1 -0
- package/sensor/dist/ui-server/api/nodes.d.ts +25 -0
- package/sensor/dist/ui-server/api/nodes.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/nodes.js +45 -0
- package/sensor/dist/ui-server/api/nodes.js.map +1 -0
- package/sensor/dist/ui-server/api/program.d.ts +139 -0
- package/sensor/dist/ui-server/api/program.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/program.js +315 -0
- package/sensor/dist/ui-server/api/program.js.map +1 -0
- package/sensor/dist/ui-server/api/respond.d.ts +76 -0
- package/sensor/dist/ui-server/api/respond.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/respond.js +186 -0
- package/sensor/dist/ui-server/api/respond.js.map +1 -0
- package/sensor/dist/ui-server/api/route-roots.d.ts +39 -0
- package/sensor/dist/ui-server/api/route-roots.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/route-roots.js +96 -0
- package/sensor/dist/ui-server/api/route-roots.js.map +1 -0
- package/sensor/dist/ui-server/api/routes.d.ts +59 -0
- package/sensor/dist/ui-server/api/routes.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/routes.js +108 -0
- package/sensor/dist/ui-server/api/routes.js.map +1 -0
- package/sensor/dist/ui-server/api/screens.d.ts +117 -0
- package/sensor/dist/ui-server/api/screens.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/screens.js +611 -0
- package/sensor/dist/ui-server/api/screens.js.map +1 -0
- package/sensor/dist/ui-server/api/search.d.ts +29 -0
- package/sensor/dist/ui-server/api/search.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/search.js +232 -0
- package/sensor/dist/ui-server/api/search.js.map +1 -0
- package/sensor/dist/ui-server/api/session.d.ts +52 -0
- package/sensor/dist/ui-server/api/session.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/session.js +196 -0
- package/sensor/dist/ui-server/api/session.js.map +1 -0
- package/sensor/dist/ui-server/api/source.d.ts +200 -0
- package/sensor/dist/ui-server/api/source.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/source.js +422 -0
- package/sensor/dist/ui-server/api/source.js.map +1 -0
- package/sensor/dist/ui-server/api/stats.d.ts +27 -0
- package/sensor/dist/ui-server/api/stats.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/stats.js +164 -0
- package/sensor/dist/ui-server/api/stats.js.map +1 -0
- package/sensor/dist/ui-server/api/steps.d.ts +274 -0
- package/sensor/dist/ui-server/api/steps.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/steps.js +1544 -0
- package/sensor/dist/ui-server/api/steps.js.map +1 -0
- package/sensor/dist/ui-server/api/trail-store.d.ts +142 -0
- package/sensor/dist/ui-server/api/trail-store.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/trail-store.js +325 -0
- package/sensor/dist/ui-server/api/trail-store.js.map +1 -0
- package/sensor/dist/ui-server/api/trails.d.ts +163 -0
- package/sensor/dist/ui-server/api/trails.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/trails.js +369 -0
- package/sensor/dist/ui-server/api/trails.js.map +1 -0
- package/sensor/dist/ui-server/api/when.d.ts +133 -0
- package/sensor/dist/ui-server/api/when.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/when.js +275 -0
- package/sensor/dist/ui-server/api/when.js.map +1 -0
- package/sensor/dist/ui-server/api/wire.d.ts +179 -0
- package/sensor/dist/ui-server/api/wire.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/wire.js +231 -0
- package/sensor/dist/ui-server/api/wire.js.map +1 -0
- package/sensor/dist/ui-server/assets.d.ts +40 -0
- package/sensor/dist/ui-server/assets.d.ts.map +1 -0
- package/sensor/dist/ui-server/assets.js +110 -0
- package/sensor/dist/ui-server/assets.js.map +1 -0
- package/sensor/dist/ui-server/constants.d.ts +32 -0
- package/sensor/dist/ui-server/constants.d.ts.map +1 -0
- package/sensor/dist/ui-server/constants.js +35 -0
- package/sensor/dist/ui-server/constants.js.map +1 -0
- package/sensor/dist/ui-server/highlight/index.d.ts +113 -0
- package/sensor/dist/ui-server/highlight/index.d.ts.map +1 -0
- package/sensor/dist/ui-server/highlight/index.js +307 -0
- package/sensor/dist/ui-server/highlight/index.js.map +1 -0
- package/sensor/dist/ui-server/highlight/languages.d.ts +36 -0
- package/sensor/dist/ui-server/highlight/languages.d.ts.map +1 -0
- package/sensor/dist/ui-server/highlight/languages.js +50 -0
- package/sensor/dist/ui-server/highlight/languages.js.map +1 -0
- package/sensor/dist/ui-server/index.d.ts +92 -0
- package/sensor/dist/ui-server/index.d.ts.map +1 -0
- package/sensor/dist/ui-server/index.js +399 -0
- package/sensor/dist/ui-server/index.js.map +1 -0
- package/sensor/dist/ui-server/open-browser.d.ts +31 -0
- package/sensor/dist/ui-server/open-browser.d.ts.map +1 -0
- package/sensor/dist/ui-server/open-browser.js +79 -0
- package/sensor/dist/ui-server/open-browser.js.map +1 -0
- package/sensor/dist/ui-server/security.d.ts +127 -0
- package/sensor/dist/ui-server/security.d.ts.map +1 -0
- package/sensor/dist/ui-server/security.js +332 -0
- package/sensor/dist/ui-server/security.js.map +1 -0
- package/sensor/dist/ui-server/static.d.ts +45 -0
- package/sensor/dist/ui-server/static.d.ts.map +1 -0
- package/sensor/dist/ui-server/static.js +165 -0
- package/sensor/dist/ui-server/static.js.map +1 -0
- package/sensor/dist/utils.d.ts +14 -2
- package/sensor/dist/utils.d.ts.map +1 -1
- package/sensor/dist/utils.js +25 -10
- package/sensor/dist/utils.js.map +1 -1
- package/src/sensor-adapter.mjs +5 -1
|
@@ -38,6 +38,8 @@ exports.isProcessAlive = isProcessAlive;
|
|
|
38
38
|
exports.registerDaemon = registerDaemon;
|
|
39
39
|
exports.deregisterDaemon = deregisterDaemon;
|
|
40
40
|
exports.listDaemons = listDaemons;
|
|
41
|
+
exports.listVerifiedDaemons = listVerifiedDaemons;
|
|
42
|
+
exports.clearStaleDaemonArtifacts = clearStaleDaemonArtifacts;
|
|
41
43
|
exports.stopDaemonAt = stopDaemonAt;
|
|
42
44
|
exports.stopAllDaemons = stopAllDaemons;
|
|
43
45
|
/**
|
|
@@ -66,6 +68,7 @@ const os = __importStar(require("os"));
|
|
|
66
68
|
const path = __importStar(require("path"));
|
|
67
69
|
const crypto = __importStar(require("crypto"));
|
|
68
70
|
const daemon_paths_1 = require("./daemon-paths");
|
|
71
|
+
const writer_lock_1 = require("./writer-lock");
|
|
69
72
|
/**
|
|
70
73
|
* `~/.lattice/sensor/daemons` — GLOBAL, keyed off the home dir. (The per-project
|
|
71
74
|
* index dir is fixed at `.lattice/sensor` and has no env override — see
|
|
@@ -174,24 +177,97 @@ function listDaemons(opts = {}) {
|
|
|
174
177
|
}
|
|
175
178
|
return live.sort((a, b) => b.startedAt - a.startedAt);
|
|
176
179
|
}
|
|
177
|
-
/**
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
180
|
+
/**
|
|
181
|
+
* Registry entries whose socket hello proves the recorded process is the
|
|
182
|
+
* daemon. Used by every user-facing list/stop-all path so a reused PID cannot
|
|
183
|
+
* appear as a phantom running daemon (#1553).
|
|
184
|
+
*/
|
|
185
|
+
async function listVerifiedDaemons(opts = {}) {
|
|
186
|
+
const prune = opts.prune ?? true;
|
|
187
|
+
const candidates = listDaemons({ prune });
|
|
188
|
+
const checks = await Promise.all(candidates.map(async (rec) => ({
|
|
189
|
+
rec,
|
|
190
|
+
verified: await (0, daemon_paths_1.probeDaemonIdentity)(rec),
|
|
191
|
+
})));
|
|
192
|
+
const verified = [];
|
|
193
|
+
for (const check of checks) {
|
|
194
|
+
if (check.verified)
|
|
195
|
+
verified.push(check.rec);
|
|
196
|
+
else if (prune)
|
|
197
|
+
deregisterDaemon(check.rec.root);
|
|
181
198
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
199
|
+
return verified;
|
|
200
|
+
}
|
|
201
|
+
/** Remove stale artifacts while holding the project writer slot exclusively. */
|
|
202
|
+
function cleanupDaemonArtifacts(root, expectedLockContents) {
|
|
203
|
+
const pidPath = (0, daemon_paths_1.getDaemonPidPath)(root);
|
|
204
|
+
// A daemon owns writer.pid before binding or relocating its socket. Claiming
|
|
205
|
+
// the writer slot therefore freezes every legitimate daemon artifact writer
|
|
206
|
+
// while we compare the inspected lock snapshot and clean it up.
|
|
207
|
+
if ((0, writer_lock_1.readWriterLock)(root)?.pid === process.pid)
|
|
208
|
+
return false;
|
|
209
|
+
const claim = (0, writer_lock_1.tryAcquireWriterLock)(root, 'cleanup');
|
|
210
|
+
if (claim.kind === 'taken')
|
|
211
|
+
return false;
|
|
212
|
+
try {
|
|
213
|
+
if (expectedLockContents === null) {
|
|
214
|
+
if (fs.existsSync(pidPath))
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
188
218
|
try {
|
|
189
|
-
fs.
|
|
219
|
+
if (fs.readFileSync(pidPath, 'utf8') !== expectedLockContents)
|
|
220
|
+
return false;
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
// POSIX sockets are real files; Windows named pipes vanish with the process.
|
|
227
|
+
// Sweep every candidate before releasing daemon.pid, so no successor can
|
|
228
|
+
// acquire the lock and bind a socket that this cleanup then removes.
|
|
229
|
+
if (process.platform !== 'win32') {
|
|
230
|
+
for (const candidate of (0, daemon_paths_1.getDaemonSocketCandidates)(root)) {
|
|
231
|
+
try {
|
|
232
|
+
fs.unlinkSync(candidate);
|
|
233
|
+
}
|
|
234
|
+
catch { /* gone */ }
|
|
190
235
|
}
|
|
191
|
-
catch { /* gone */ }
|
|
192
236
|
}
|
|
237
|
+
deregisterDaemon(root);
|
|
238
|
+
try {
|
|
239
|
+
fs.unlinkSync(pidPath);
|
|
240
|
+
}
|
|
241
|
+
catch (err) {
|
|
242
|
+
if (err.code !== 'ENOENT')
|
|
243
|
+
return false;
|
|
244
|
+
}
|
|
245
|
+
return true;
|
|
193
246
|
}
|
|
194
|
-
|
|
247
|
+
finally {
|
|
248
|
+
(0, writer_lock_1.releaseWriterLock)(root);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
/** Remove daemon artifacts only when no matching daemon answers the socket hello. */
|
|
252
|
+
async function clearStaleDaemonArtifacts(root) {
|
|
253
|
+
const pidPath = (0, daemon_paths_1.getDaemonPidPath)(root);
|
|
254
|
+
const hadArtifacts = fs.existsSync(pidPath) || (process.platform !== 'win32' && (0, daemon_paths_1.getDaemonSocketCandidates)(root).some((p) => fs.existsSync(p)));
|
|
255
|
+
if (!hadArtifacts)
|
|
256
|
+
return false;
|
|
257
|
+
let info = null;
|
|
258
|
+
let lockContents = null;
|
|
259
|
+
try {
|
|
260
|
+
lockContents = fs.readFileSync(pidPath, 'utf8');
|
|
261
|
+
info = (0, daemon_paths_1.decodeLockInfo)(lockContents);
|
|
262
|
+
}
|
|
263
|
+
catch { /* missing/corrupt */ }
|
|
264
|
+
if (info && isProcessAlive(info.pid)) {
|
|
265
|
+
// A live legacy holder has no socket path to probe. That is inconclusive,
|
|
266
|
+
// not proof of PID reuse, so preserve its lock rather than risk two writers.
|
|
267
|
+
if (!(0, daemon_paths_1.canProbeDaemonIdentity)(info) || await (0, daemon_paths_1.probeDaemonIdentity)(info))
|
|
268
|
+
return false;
|
|
269
|
+
}
|
|
270
|
+
return cleanupDaemonArtifacts(root, lockContents);
|
|
195
271
|
}
|
|
196
272
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
197
273
|
async function waitForDeath(pid, timeoutMs) {
|
|
@@ -207,13 +283,17 @@ async function waitForDeath(pid, timeoutMs) {
|
|
|
207
283
|
* Stop the daemon serving `root`: SIGTERM, wait, then SIGKILL if it won't go,
|
|
208
284
|
* then sweep its artifacts. `root` must be realpath'd (match how the daemon
|
|
209
285
|
* keys its socket/lockfile). Resolves the pid from the authoritative lockfile,
|
|
210
|
-
* falling back to the registry.
|
|
286
|
+
* falling back to the registry. Rebuild callers preserve unverified live locks
|
|
287
|
+
* instead of interpreting a failed probe as permission to discard the database.
|
|
211
288
|
*/
|
|
212
|
-
async function stopDaemonAt(root) {
|
|
289
|
+
async function stopDaemonAt(root, options = {}) {
|
|
213
290
|
let pid = null;
|
|
291
|
+
let identity = null;
|
|
292
|
+
let lockContents = null;
|
|
214
293
|
try {
|
|
215
|
-
|
|
216
|
-
|
|
294
|
+
lockContents = fs.readFileSync((0, daemon_paths_1.getDaemonPidPath)(root), 'utf8');
|
|
295
|
+
identity = (0, daemon_paths_1.decodeLockInfo)(lockContents);
|
|
296
|
+
pid = identity?.pid ?? null;
|
|
217
297
|
}
|
|
218
298
|
catch {
|
|
219
299
|
/* no lockfile */
|
|
@@ -221,15 +301,39 @@ async function stopDaemonAt(root) {
|
|
|
221
301
|
if (pid == null) {
|
|
222
302
|
const rec = listDaemons({ prune: false }).find((r) => path.resolve(r.root) === path.resolve(root));
|
|
223
303
|
pid = rec?.pid ?? null;
|
|
304
|
+
if (rec)
|
|
305
|
+
identity = rec;
|
|
224
306
|
}
|
|
225
307
|
if (pid == null) {
|
|
226
|
-
cleanupDaemonArtifacts(root);
|
|
308
|
+
cleanupDaemonArtifacts(root, lockContents);
|
|
227
309
|
return { root, pid: null, outcome: 'no-daemon' };
|
|
228
310
|
}
|
|
229
311
|
if (!isProcessAlive(pid)) {
|
|
230
|
-
cleanupDaemonArtifacts(root);
|
|
231
|
-
return { root, pid, outcome: 'not-running' };
|
|
312
|
+
const removed = cleanupDaemonArtifacts(root, lockContents);
|
|
313
|
+
return { root, pid, outcome: removed ? 'not-running' : 'unverified' };
|
|
314
|
+
}
|
|
315
|
+
// Never signal a process merely because it reused a stale daemon PID. The
|
|
316
|
+
// daemon's immediate hello is the process-identity proof (#1553).
|
|
317
|
+
if (!identity || !(0, daemon_paths_1.canProbeDaemonIdentity)(identity)) {
|
|
318
|
+
return { root, pid, outcome: 'unverified' };
|
|
319
|
+
}
|
|
320
|
+
if (!await (0, daemon_paths_1.probeDaemonIdentity)(identity)) {
|
|
321
|
+
if (options.preserveUnverified)
|
|
322
|
+
return { root, pid, outcome: 'unverified' };
|
|
323
|
+
const removed = cleanupDaemonArtifacts(root, lockContents);
|
|
324
|
+
return { root, pid, outcome: removed ? 'not-running' : 'unverified' };
|
|
232
325
|
}
|
|
326
|
+
// Identity probing awaits I/O: never act on a superseded ownership record.
|
|
327
|
+
const sameLock = () => {
|
|
328
|
+
try {
|
|
329
|
+
return fs.readFileSync((0, daemon_paths_1.getDaemonPidPath)(root), 'utf8') === lockContents;
|
|
330
|
+
}
|
|
331
|
+
catch {
|
|
332
|
+
return lockContents === null;
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
if (!sameLock())
|
|
336
|
+
return { root, pid, outcome: 'unverified' };
|
|
233
337
|
// POSIX: SIGTERM runs the daemon's graceful shutdown. Windows: TerminateProcess
|
|
234
338
|
// (no graceful path), so we always sweep artifacts ourselves below.
|
|
235
339
|
try {
|
|
@@ -238,20 +342,26 @@ async function stopDaemonAt(root) {
|
|
|
238
342
|
catch { /* raced to exit */ }
|
|
239
343
|
let outcome = 'term';
|
|
240
344
|
if (!(await waitForDeath(pid, 3000))) {
|
|
345
|
+
// Re-prove identity before escalating; the old PID may have been reused.
|
|
346
|
+
if (!sameLock() || !await (0, daemon_paths_1.probeDaemonIdentity)(identity) || !sameLock()) {
|
|
347
|
+
return { root, pid, outcome: 'still-running' };
|
|
348
|
+
}
|
|
241
349
|
try {
|
|
242
350
|
process.kill(pid, 'SIGKILL');
|
|
243
351
|
}
|
|
244
352
|
catch { /* raced to exit */ }
|
|
245
|
-
await waitForDeath(pid, 2000)
|
|
353
|
+
if (!(await waitForDeath(pid, 2000))) {
|
|
354
|
+
return { root, pid, outcome: 'still-running' };
|
|
355
|
+
}
|
|
246
356
|
outcome = 'kill';
|
|
247
357
|
}
|
|
248
|
-
cleanupDaemonArtifacts(root);
|
|
358
|
+
cleanupDaemonArtifacts(root, lockContents);
|
|
249
359
|
return { root, pid, outcome };
|
|
250
360
|
}
|
|
251
361
|
/** Stop every registered, live daemon. */
|
|
252
362
|
async function stopAllDaemons() {
|
|
253
363
|
const results = [];
|
|
254
|
-
for (const rec of
|
|
364
|
+
for (const rec of await listVerifiedDaemons()) {
|
|
255
365
|
results.push(await stopDaemonAt(rec.root));
|
|
256
366
|
}
|
|
257
367
|
return results;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon-registry.js","sourceRoot":"","sources":["../../src/mcp/daemon-registry.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"daemon-registry.js","sourceRoot":"","sources":["../../src/mcp/daemon-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -92,13 +92,13 @@ export interface DaemonStartResult {
|
|
|
92
92
|
*
|
|
93
93
|
* Race-safe: callers must first call `tryAcquireDaemonLock(projectRoot)` and
|
|
94
94
|
* only construct a Daemon if they got the lock (`kind: 'acquired'`). The atomic
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
* daemons.
|
|
95
|
+
* create/link inside the acquire helper elects one candidate. The project
|
|
96
|
+
* writer lock then fences bind/ownership refresh against stale-artifact cleanup.
|
|
98
97
|
*/
|
|
99
98
|
export declare class Daemon {
|
|
100
99
|
private projectRoot;
|
|
101
100
|
private server;
|
|
101
|
+
private acceptedSockets;
|
|
102
102
|
private clients;
|
|
103
103
|
/** Per-client peer pids from the optional client-hello, for the liveness sweep. */
|
|
104
104
|
private clientPeers;
|
|
@@ -117,10 +117,9 @@ export declare class Daemon {
|
|
|
117
117
|
maxIdleMs?: number;
|
|
118
118
|
});
|
|
119
119
|
/**
|
|
120
|
-
* Bind the socket, kick off engine init, and
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
* listening — the daemon then sticks around until idle/shutdown.
|
|
120
|
+
* Bind the socket, refresh the ownership record, kick off engine init, and
|
|
121
|
+
* register signal handlers. The promise resolves once the server is listening
|
|
122
|
+
* — the daemon then sticks around until idle/shutdown.
|
|
124
123
|
*/
|
|
125
124
|
start(): Promise<DaemonStartResult>;
|
|
126
125
|
/** Currently-connected client count. Exposed for tests / status output. */
|
|
@@ -177,6 +176,14 @@ export declare class Daemon {
|
|
|
177
176
|
reapDeadClients(isAlive: (pid: number) => boolean): number;
|
|
178
177
|
private cleanupLockfile;
|
|
179
178
|
}
|
|
179
|
+
/**
|
|
180
|
+
* Publish the bound socket without abandoning a live daemon on a transient
|
|
181
|
+
* Windows sharing violation. Keep this startup step synchronous: accepting a
|
|
182
|
+
* client before ownership is refreshed could initialize an engine too early.
|
|
183
|
+
* Retries wait per {@link LOCK_REFRESH_RETRY_DELAYS_MS}; permanent failures
|
|
184
|
+
* still abort startup.
|
|
185
|
+
*/
|
|
186
|
+
export declare function refreshDaemonLock(pidPath: string, initialContents: string, lock: DaemonLockInfo, platform?: NodeJS.Platform): void;
|
|
180
187
|
/**
|
|
181
188
|
* Result of `tryAcquireDaemonLock`. Either we got the lockfile (caller becomes
|
|
182
189
|
* the daemon), or it already existed (caller should connect to the existing
|
|
@@ -189,6 +196,8 @@ export type AcquireResult = {
|
|
|
189
196
|
} | {
|
|
190
197
|
kind: 'taken';
|
|
191
198
|
existing: DaemonLockInfo | null;
|
|
199
|
+
/** Exact record read after losing acquisition; null when it was unreadable. */
|
|
200
|
+
lockContents: string | null;
|
|
192
201
|
pidPath: string;
|
|
193
202
|
};
|
|
194
203
|
/**
|
|
@@ -234,17 +243,21 @@ export declare function tryAcquireDaemonLock(projectRoot: string): AcquireResult
|
|
|
234
243
|
*/
|
|
235
244
|
export declare function acquireLockViaExclusiveOpen(pidPath: string, info: DaemonLockInfo): boolean;
|
|
236
245
|
/**
|
|
237
|
-
* Remove a stale pidfile
|
|
238
|
-
*
|
|
239
|
-
* daemon (re)acquired in the meantime.
|
|
246
|
+
* Remove a stale pidfile. Re-reads the file immediately before unlinking so a
|
|
247
|
+
* different daemon that acquired the lock in the meantime is never disturbed.
|
|
240
248
|
*
|
|
241
249
|
* must-fix 1 (issue #411 review): the original unconditionally `unlink`'d,
|
|
242
250
|
* which let a racing candidate delete a healthy daemon's lock. Passing
|
|
243
251
|
* `expectedDeadPid` (the pid the caller believed was dead) makes the clear a
|
|
244
|
-
* compare-and-delete: bail if the file now holds a different pid
|
|
245
|
-
* pid
|
|
252
|
+
* compare-and-delete: bail if the file now holds a different pid. By default a
|
|
253
|
+
* live pid is also preserved; `allowLivePid` is reserved for callers that have
|
|
254
|
+
* already disproved daemon identity with the socket hello (#1553). Returns true
|
|
255
|
+
* when the stale lock is gone (or was already gone).
|
|
246
256
|
*/
|
|
247
|
-
export declare function clearStaleDaemonLock(pidPath: string, expectedDeadPid?: number
|
|
257
|
+
export declare function clearStaleDaemonLock(pidPath: string, expectedDeadPid?: number, opts?: {
|
|
258
|
+
allowLivePid?: boolean;
|
|
259
|
+
expectedLockContents?: string;
|
|
260
|
+
}): boolean;
|
|
248
261
|
/**
|
|
249
262
|
* Probe whether `pid` is currently alive (signal-0). Treats EPERM as alive on
|
|
250
263
|
* every platform (the process exists, it's just not ours to signal) so we never
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../src/mcp/daemon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAGH,OAAO,KAAK,GAAG,MAAM,KAAK,CAAC;AAK3B,OAAO,EACL,cAAc,EAMf,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../src/mcp/daemon.ts"],"names":[],"mappings":"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"}
|
|
@@ -76,6 +76,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
76
76
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
77
77
|
exports.MAX_HELLO_LINE_BYTES = exports.Daemon = void 0;
|
|
78
78
|
exports.finalizeDaemonExit = finalizeDaemonExit;
|
|
79
|
+
exports.refreshDaemonLock = refreshDaemonLock;
|
|
79
80
|
exports.tryAcquireDaemonLock = tryAcquireDaemonLock;
|
|
80
81
|
exports.acquireLockViaExclusiveOpen = acquireLockViaExclusiveOpen;
|
|
81
82
|
exports.clearStaleDaemonLock = clearStaleDaemonLock;
|
|
@@ -91,6 +92,7 @@ const session_1 = require("./session");
|
|
|
91
92
|
const transport_1 = require("./transport");
|
|
92
93
|
const daemon_paths_1 = require("./daemon-paths");
|
|
93
94
|
const version_1 = require("./version");
|
|
95
|
+
const writer_lock_1 = require("./writer-lock");
|
|
94
96
|
const daemon_registry_1 = require("./daemon-registry");
|
|
95
97
|
/** Default idle linger after the last client disconnects. */
|
|
96
98
|
const DEFAULT_IDLE_TIMEOUT_MS = 300_000;
|
|
@@ -151,13 +153,15 @@ exports.MAX_HELLO_LINE_BYTES = MAX_HELLO_LINE_BYTES;
|
|
|
151
153
|
*
|
|
152
154
|
* Race-safe: callers must first call `tryAcquireDaemonLock(projectRoot)` and
|
|
153
155
|
* only construct a Daemon if they got the lock (`kind: 'acquired'`). The atomic
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
* daemons.
|
|
156
|
+
* create/link inside the acquire helper elects one candidate. The project
|
|
157
|
+
* writer lock then fences bind/ownership refresh against stale-artifact cleanup.
|
|
157
158
|
*/
|
|
158
159
|
class Daemon {
|
|
159
160
|
projectRoot;
|
|
160
161
|
server = null;
|
|
162
|
+
// Includes sockets waiting for the optional client hello, before a session
|
|
163
|
+
// exists. server.close() waits for these too, so stop must destroy them.
|
|
164
|
+
acceptedSockets = new Set();
|
|
161
165
|
clients = new Set();
|
|
162
166
|
/** Per-client peer pids from the optional client-hello, for the liveness sweep. */
|
|
163
167
|
clientPeers = new Map();
|
|
@@ -191,16 +195,32 @@ class Daemon {
|
|
|
191
195
|
this.engine.setExecutionMode('daemon', 'daemon');
|
|
192
196
|
}
|
|
193
197
|
/**
|
|
194
|
-
* Bind the socket, kick off engine init, and
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
* listening — the daemon then sticks around until idle/shutdown.
|
|
198
|
+
* Bind the socket, refresh the ownership record, kick off engine init, and
|
|
199
|
+
* register signal handlers. The promise resolves once the server is listening
|
|
200
|
+
* — the daemon then sticks around until idle/shutdown.
|
|
198
201
|
*/
|
|
199
202
|
async start() {
|
|
200
|
-
//
|
|
201
|
-
//
|
|
202
|
-
|
|
203
|
-
|
|
203
|
+
// #1740: claim the project writer lock before opening/watching so a
|
|
204
|
+
// concurrent direct-mode serve --mcp cannot start a second watcher.
|
|
205
|
+
(0, writer_lock_1.assertNoRebuild)(this.projectRoot);
|
|
206
|
+
const writer = (0, writer_lock_1.tryAcquireWriterLock)(this.projectRoot, 'daemon');
|
|
207
|
+
if (writer.kind === 'taken') {
|
|
208
|
+
const msg = (0, writer_lock_1.writerLockHeldMessage)(writer.existing, writer.pidPath);
|
|
209
|
+
process.stderr.write(`[LatticeSensor daemon] ${msg}\n`);
|
|
210
|
+
this.cleanupLockfile();
|
|
211
|
+
throw new Error(msg);
|
|
212
|
+
}
|
|
213
|
+
let initialLockContents;
|
|
214
|
+
try {
|
|
215
|
+
initialLockContents = fs.readFileSync(this.pidPath, 'utf8');
|
|
216
|
+
if ((0, daemon_paths_1.decodeLockInfo)(initialLockContents)?.pid !== process.pid) {
|
|
217
|
+
throw new Error('daemon lock belongs to another process');
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
catch {
|
|
221
|
+
(0, writer_lock_1.releaseWriterLock)(this.projectRoot);
|
|
222
|
+
throw new Error('Lost daemon lock ownership before startup.');
|
|
223
|
+
}
|
|
204
224
|
// Walk the ordered socket candidates and bind the first that works. The
|
|
205
225
|
// in-project path comes first; the deterministic tmpdir path is the fallback
|
|
206
226
|
// for a filesystem that can't host an AF_UNIX node at all (ExFAT/FAT external
|
|
@@ -265,19 +285,24 @@ class Daemon {
|
|
|
265
285
|
socketPath: this.socketPath,
|
|
266
286
|
startedAt: Date.now(),
|
|
267
287
|
};
|
|
268
|
-
//
|
|
269
|
-
//
|
|
270
|
-
//
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
288
|
+
// Refresh the lock on every successful bind, not only relocation. The
|
|
289
|
+
// writer lock prevents stale-artifact cleanup from racing this ownership
|
|
290
|
+
// check, and the exact snapshot prevents overwriting a replacement record.
|
|
291
|
+
try {
|
|
292
|
+
refreshDaemonLock(this.pidPath, initialLockContents, lock);
|
|
293
|
+
}
|
|
294
|
+
catch (err) {
|
|
274
295
|
try {
|
|
275
|
-
|
|
276
|
-
fs.writeFileSync(tmpPid, (0, daemon_paths_1.encodeLockInfo)(lock), { mode: 0o600 });
|
|
277
|
-
fs.renameSync(tmpPid, this.pidPath);
|
|
296
|
+
bound.server.close();
|
|
278
297
|
}
|
|
279
|
-
catch { /* best-effort
|
|
298
|
+
catch { /* best-effort */ }
|
|
299
|
+
this.cleanupLockfile();
|
|
300
|
+
throw err;
|
|
280
301
|
}
|
|
302
|
+
// Engine init is deliberately backgrounded — see #172. It starts only
|
|
303
|
+
// after bind and ownership refresh, so a delayed daemon that lost election
|
|
304
|
+
// can never open a second watcher or writer.
|
|
305
|
+
void this.engine.ensureInitialized(this.projectRoot);
|
|
281
306
|
// Drop a discovery record so `lattice sensor list` / `stop --all` can find us.
|
|
282
307
|
// Best-effort; a missing record only means list's liveness prune covers it.
|
|
283
308
|
(0, daemon_registry_1.registerDaemon)({ root: this.projectRoot, ...lock });
|
|
@@ -324,11 +349,14 @@ class Daemon {
|
|
|
324
349
|
catch { /* best-effort */ }
|
|
325
350
|
}
|
|
326
351
|
this.clients.clear();
|
|
352
|
+
for (const socket of this.acceptedSockets)
|
|
353
|
+
socket.destroy();
|
|
354
|
+
this.acceptedSockets.clear();
|
|
327
355
|
if (this.server) {
|
|
328
356
|
await new Promise((resolve) => this.server.close(() => resolve()));
|
|
329
357
|
this.server = null;
|
|
330
358
|
}
|
|
331
|
-
this.engine.stop();
|
|
359
|
+
await this.engine.stop();
|
|
332
360
|
this.cleanupLockfile();
|
|
333
361
|
(0, daemon_registry_1.deregisterDaemon)(this.projectRoot);
|
|
334
362
|
if (process.platform !== 'win32') {
|
|
@@ -343,6 +371,12 @@ class Daemon {
|
|
|
343
371
|
finalizeDaemonExit(process.platform, (code) => process.exit(code));
|
|
344
372
|
}
|
|
345
373
|
handleConnection(socket) {
|
|
374
|
+
if (this.stopping) {
|
|
375
|
+
socket.destroy();
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
this.acceptedSockets.add(socket);
|
|
379
|
+
socket.once('close', () => this.acceptedSockets.delete(socket));
|
|
346
380
|
// Hello first so the proxy can verify versions before piping any
|
|
347
381
|
// application bytes. The proxy reads exactly one line, then forwards.
|
|
348
382
|
const hello = {
|
|
@@ -357,6 +391,10 @@ class Daemon {
|
|
|
357
391
|
// timeout, a non-hello first line, an early close — yields null pids and we
|
|
358
392
|
// fall back to the socket-close lifecycle exactly as before (#692).
|
|
359
393
|
void readClientHello(socket).then((peers) => {
|
|
394
|
+
if (this.stopping || socket.destroyed) {
|
|
395
|
+
socket.destroy();
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
360
398
|
const transport = new transport_1.SocketTransport(socket);
|
|
361
399
|
const session = new session_1.MCPSession(transport, this.engine, {
|
|
362
400
|
explicitProjectPath: this.projectRoot,
|
|
@@ -493,6 +531,7 @@ class Daemon {
|
|
|
493
531
|
return reaped;
|
|
494
532
|
}
|
|
495
533
|
cleanupLockfile() {
|
|
534
|
+
(0, writer_lock_1.releaseWriterLock)(this.projectRoot);
|
|
496
535
|
try {
|
|
497
536
|
if (fs.existsSync(this.pidPath)) {
|
|
498
537
|
// Only remove if it still belongs to us — another daemon may have
|
|
@@ -508,6 +547,52 @@ class Daemon {
|
|
|
508
547
|
}
|
|
509
548
|
}
|
|
510
549
|
exports.Daemon = Daemon;
|
|
550
|
+
/**
|
|
551
|
+
* Waits between retries of the pid-file replace on Windows, doubling to a cap:
|
|
552
|
+
* eight attempts wait about 1.6s in all. Windows refuses to replace a file
|
|
553
|
+
* while any handle to it is open, so an antivirus scan, an indexer, or another
|
|
554
|
+
* session reading the lock can each hold it for a moment, and for longer on a
|
|
555
|
+
* loaded machine (#1773). The total stays well inside a launcher's ~6s connect
|
|
556
|
+
* window.
|
|
557
|
+
*/
|
|
558
|
+
const LOCK_REFRESH_RETRY_DELAYS_MS = [25, 50, 100, 200, 400, 400, 400];
|
|
559
|
+
/**
|
|
560
|
+
* Publish the bound socket without abandoning a live daemon on a transient
|
|
561
|
+
* Windows sharing violation. Keep this startup step synchronous: accepting a
|
|
562
|
+
* client before ownership is refreshed could initialize an engine too early.
|
|
563
|
+
* Retries wait per {@link LOCK_REFRESH_RETRY_DELAYS_MS}; permanent failures
|
|
564
|
+
* still abort startup.
|
|
565
|
+
*/
|
|
566
|
+
function refreshDaemonLock(pidPath, initialContents, lock, platform = process.platform) {
|
|
567
|
+
const tmpPid = `${pidPath}.${process.pid}.bound`;
|
|
568
|
+
try {
|
|
569
|
+
fs.writeFileSync(tmpPid, (0, daemon_paths_1.encodeLockInfo)(lock), { mode: 0o600 });
|
|
570
|
+
for (let attempt = 0;; attempt++) {
|
|
571
|
+
// A retry must never replace a record whose owner changed while waiting.
|
|
572
|
+
if (fs.readFileSync(pidPath, 'utf8') !== initialContents) {
|
|
573
|
+
throw new Error('Lost daemon lock ownership after binding.');
|
|
574
|
+
}
|
|
575
|
+
try {
|
|
576
|
+
fs.renameSync(tmpPid, pidPath);
|
|
577
|
+
return;
|
|
578
|
+
}
|
|
579
|
+
catch (error) {
|
|
580
|
+
const code = error.code;
|
|
581
|
+
const delay = LOCK_REFRESH_RETRY_DELAYS_MS[attempt];
|
|
582
|
+
if (platform !== 'win32' || !['EPERM', 'EACCES', 'EBUSY'].includes(code ?? '') || delay === undefined) {
|
|
583
|
+
throw error;
|
|
584
|
+
}
|
|
585
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, delay);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
finally {
|
|
590
|
+
try {
|
|
591
|
+
fs.unlinkSync(tmpPid);
|
|
592
|
+
}
|
|
593
|
+
catch { /* renamed, or best-effort cleanup */ }
|
|
594
|
+
}
|
|
595
|
+
}
|
|
511
596
|
/**
|
|
512
597
|
* Atomically create the daemon pidfile with its full record already in place.
|
|
513
598
|
* Returns either an `acquired` result (the caller is the daemon-elect and may
|
|
@@ -587,11 +672,13 @@ function tryAcquireDaemonLock(projectRoot) {
|
|
|
587
672
|
// record — `existing` is null only for a genuinely corrupt leftover, never a
|
|
588
673
|
// mid-write race.
|
|
589
674
|
let existing = null;
|
|
675
|
+
let lockContents = null;
|
|
590
676
|
try {
|
|
591
|
-
|
|
677
|
+
lockContents = fs.readFileSync(pidPath, 'utf8');
|
|
678
|
+
existing = (0, daemon_paths_1.decodeLockInfo)(lockContents);
|
|
592
679
|
}
|
|
593
680
|
catch { /* unreadable lockfile — treat as malformed */ }
|
|
594
|
-
return { kind: 'taken', existing, pidPath };
|
|
681
|
+
return { kind: 'taken', existing, lockContents, pidPath };
|
|
595
682
|
}
|
|
596
683
|
/**
|
|
597
684
|
* Exclusive-create the pidfile (O_CREAT|O_EXCL via the `wx` flag) and write the
|
|
@@ -621,26 +708,33 @@ function acquireLockViaExclusiveOpen(pidPath, info) {
|
|
|
621
708
|
return true;
|
|
622
709
|
}
|
|
623
710
|
/**
|
|
624
|
-
* Remove a stale pidfile
|
|
625
|
-
*
|
|
626
|
-
* daemon (re)acquired in the meantime.
|
|
711
|
+
* Remove a stale pidfile. Re-reads the file immediately before unlinking so a
|
|
712
|
+
* different daemon that acquired the lock in the meantime is never disturbed.
|
|
627
713
|
*
|
|
628
714
|
* must-fix 1 (issue #411 review): the original unconditionally `unlink`'d,
|
|
629
715
|
* which let a racing candidate delete a healthy daemon's lock. Passing
|
|
630
716
|
* `expectedDeadPid` (the pid the caller believed was dead) makes the clear a
|
|
631
|
-
* compare-and-delete: bail if the file now holds a different pid
|
|
632
|
-
* pid
|
|
717
|
+
* compare-and-delete: bail if the file now holds a different pid. By default a
|
|
718
|
+
* live pid is also preserved; `allowLivePid` is reserved for callers that have
|
|
719
|
+
* already disproved daemon identity with the socket hello (#1553). Returns true
|
|
720
|
+
* when the stale lock is gone (or was already gone).
|
|
633
721
|
*/
|
|
634
|
-
function clearStaleDaemonLock(pidPath, expectedDeadPid) {
|
|
722
|
+
function clearStaleDaemonLock(pidPath, expectedDeadPid, opts = {}) {
|
|
635
723
|
try {
|
|
636
724
|
const raw = fs.readFileSync(pidPath, 'utf8');
|
|
725
|
+
// The identity record changed after the caller inspected it. Even the same
|
|
726
|
+
// PID may now advertise a newly-bound socket, so this snapshot was never
|
|
727
|
+
// disproved and must not be deleted.
|
|
728
|
+
if (opts.expectedLockContents !== undefined && raw !== opts.expectedLockContents)
|
|
729
|
+
return false;
|
|
637
730
|
const info = (0, daemon_paths_1.decodeLockInfo)(raw);
|
|
638
731
|
if (info) {
|
|
639
732
|
// A different pid took over since we read it — not ours to clear.
|
|
640
733
|
if (expectedDeadPid !== undefined && info.pid !== expectedDeadPid)
|
|
641
734
|
return false;
|
|
642
|
-
//
|
|
643
|
-
|
|
735
|
+
// PID liveness is normally sufficient. The takeover caller may override
|
|
736
|
+
// it only after a failed identity handshake proves PID reuse.
|
|
737
|
+
if (!opts.allowLivePid && info.pid > 0 && isProcessAlive(info.pid))
|
|
644
738
|
return false;
|
|
645
739
|
}
|
|
646
740
|
fs.unlinkSync(pidPath);
|