@legioncodeinc/nectar 0.0.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/LICENSE.md +662 -0
- package/README.md +307 -0
- package/dist/api/daemon-api-wiring.d.ts +72 -0
- package/dist/api/daemon-api-wiring.d.ts.map +1 -0
- package/dist/api/daemon-api-wiring.js +150 -0
- package/dist/api/daemon-api-wiring.js.map +1 -0
- package/dist/api/hive-graph-api.d.ts +136 -0
- package/dist/api/hive-graph-api.d.ts.map +1 -0
- package/dist/api/hive-graph-api.js +234 -0
- package/dist/api/hive-graph-api.js.map +1 -0
- package/dist/api/loopback-client.d.ts +27 -0
- package/dist/api/loopback-client.d.ts.map +1 -0
- package/dist/api/loopback-client.js +87 -0
- package/dist/api/loopback-client.js.map +1 -0
- package/dist/api/router.d.ts +172 -0
- package/dist/api/router.d.ts.map +1 -0
- package/dist/api/router.js +212 -0
- package/dist/api/router.js.map +1 -0
- package/dist/api/status-query.d.ts +49 -0
- package/dist/api/status-query.d.ts.map +1 -0
- package/dist/api/status-query.js +103 -0
- package/dist/api/status-query.js.map +1 -0
- package/dist/brood-guard.d.ts +24 -0
- package/dist/brood-guard.d.ts.map +1 -0
- package/dist/brood-guard.js +19 -0
- package/dist/brood-guard.js.map +1 -0
- package/dist/brood-prereqs.d.ts +62 -0
- package/dist/brood-prereqs.d.ts.map +1 -0
- package/dist/brood-prereqs.js +87 -0
- package/dist/brood-prereqs.js.map +1 -0
- package/dist/brooding/bucketing.d.ts +68 -0
- package/dist/brooding/bucketing.d.ts.map +1 -0
- package/dist/brooding/bucketing.js +122 -0
- package/dist/brooding/bucketing.js.map +1 -0
- package/dist/brooding/cli.d.ts +78 -0
- package/dist/brooding/cli.d.ts.map +1 -0
- package/dist/brooding/cli.js +140 -0
- package/dist/brooding/cli.js.map +1 -0
- package/dist/brooding/constants.d.ts +75 -0
- package/dist/brooding/constants.d.ts.map +1 -0
- package/dist/brooding/constants.js +91 -0
- package/dist/brooding/constants.js.map +1 -0
- package/dist/brooding/cost.d.ts +110 -0
- package/dist/brooding/cost.d.ts.map +1 -0
- package/dist/brooding/cost.js +96 -0
- package/dist/brooding/cost.js.map +1 -0
- package/dist/brooding/describe.d.ts +152 -0
- package/dist/brooding/describe.d.ts.map +1 -0
- package/dist/brooding/describe.js +281 -0
- package/dist/brooding/describe.js.map +1 -0
- package/dist/brooding/discovery.d.ts +116 -0
- package/dist/brooding/discovery.d.ts.map +1 -0
- package/dist/brooding/discovery.js +179 -0
- package/dist/brooding/discovery.js.map +1 -0
- package/dist/brooding/index.d.ts +23 -0
- package/dist/brooding/index.d.ts.map +1 -0
- package/dist/brooding/index.js +33 -0
- package/dist/brooding/index.js.map +1 -0
- package/dist/brooding/pipeline-async.d.ts +97 -0
- package/dist/brooding/pipeline-async.d.ts.map +1 -0
- package/dist/brooding/pipeline-async.js +364 -0
- package/dist/brooding/pipeline-async.js.map +1 -0
- package/dist/brooding/pipeline.d.ts +198 -0
- package/dist/brooding/pipeline.d.ts.map +1 -0
- package/dist/brooding/pipeline.js +454 -0
- package/dist/brooding/pipeline.js.map +1 -0
- package/dist/brooding/precheck.d.ts +52 -0
- package/dist/brooding/precheck.d.ts.map +1 -0
- package/dist/brooding/precheck.js +143 -0
- package/dist/brooding/precheck.js.map +1 -0
- package/dist/brooding/resumability.d.ts +57 -0
- package/dist/brooding/resumability.d.ts.map +1 -0
- package/dist/brooding/resumability.js +46 -0
- package/dist/brooding/resumability.js.map +1 -0
- package/dist/cli.d.ts +139 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +912 -0
- package/dist/cli.js.map +1 -0
- package/dist/config-file.d.ts +52 -0
- package/dist/config-file.d.ts.map +1 -0
- package/dist/config-file.js +130 -0
- package/dist/config-file.js.map +1 -0
- package/dist/config.d.ts +49 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +98 -0
- package/dist/config.js.map +1 -0
- package/dist/daemon.d.ts +265 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +664 -0
- package/dist/daemon.js.map +1 -0
- package/dist/doctor-registry.d.ts +134 -0
- package/dist/doctor-registry.d.ts.map +1 -0
- package/dist/doctor-registry.js +173 -0
- package/dist/doctor-registry.js.map +1 -0
- package/dist/embeddings/cohere-portkey.d.ts +67 -0
- package/dist/embeddings/cohere-portkey.d.ts.map +1 -0
- package/dist/embeddings/cohere-portkey.js +171 -0
- package/dist/embeddings/cohere-portkey.js.map +1 -0
- package/dist/embeddings/config.d.ts +74 -0
- package/dist/embeddings/config.d.ts.map +1 -0
- package/dist/embeddings/config.js +131 -0
- package/dist/embeddings/config.js.map +1 -0
- package/dist/embeddings/guard.d.ts +34 -0
- package/dist/embeddings/guard.d.ts.map +1 -0
- package/dist/embeddings/guard.js +67 -0
- package/dist/embeddings/guard.js.map +1 -0
- package/dist/embeddings/hosted-portkey.d.ts +73 -0
- package/dist/embeddings/hosted-portkey.d.ts.map +1 -0
- package/dist/embeddings/hosted-portkey.js +179 -0
- package/dist/embeddings/hosted-portkey.js.map +1 -0
- package/dist/embeddings/http.d.ts +33 -0
- package/dist/embeddings/http.d.ts.map +1 -0
- package/dist/embeddings/http.js +19 -0
- package/dist/embeddings/http.js.map +1 -0
- package/dist/embeddings/index.d.ts +17 -0
- package/dist/embeddings/index.d.ts.map +1 -0
- package/dist/embeddings/index.js +17 -0
- package/dist/embeddings/index.js.map +1 -0
- package/dist/embeddings/local-nomic.d.ts +78 -0
- package/dist/embeddings/local-nomic.d.ts.map +1 -0
- package/dist/embeddings/local-nomic.js +126 -0
- package/dist/embeddings/local-nomic.js.map +1 -0
- package/dist/embeddings/provider.d.ts +79 -0
- package/dist/embeddings/provider.d.ts.map +1 -0
- package/dist/embeddings/provider.js +50 -0
- package/dist/embeddings/provider.js.map +1 -0
- package/dist/enricher/config.d.ts +43 -0
- package/dist/enricher/config.d.ts.map +1 -0
- package/dist/enricher/config.js +34 -0
- package/dist/enricher/config.js.map +1 -0
- package/dist/enricher/content-cache.d.ts +29 -0
- package/dist/enricher/content-cache.d.ts.map +1 -0
- package/dist/enricher/content-cache.js +24 -0
- package/dist/enricher/content-cache.js.map +1 -0
- package/dist/enricher/cycle.d.ts +71 -0
- package/dist/enricher/cycle.d.ts.map +1 -0
- package/dist/enricher/cycle.js +319 -0
- package/dist/enricher/cycle.js.map +1 -0
- package/dist/enricher/describe.d.ts +61 -0
- package/dist/enricher/describe.d.ts.map +1 -0
- package/dist/enricher/describe.js +175 -0
- package/dist/enricher/describe.js.map +1 -0
- package/dist/enricher/failure.d.ts +25 -0
- package/dist/enricher/failure.d.ts.map +1 -0
- package/dist/enricher/failure.js +46 -0
- package/dist/enricher/failure.js.map +1 -0
- package/dist/enricher/index.d.ts +22 -0
- package/dist/enricher/index.d.ts.map +1 -0
- package/dist/enricher/index.js +22 -0
- package/dist/enricher/index.js.map +1 -0
- package/dist/enricher/jaccard.d.ts +11 -0
- package/dist/enricher/jaccard.d.ts.map +1 -0
- package/dist/enricher/jaccard.js +29 -0
- package/dist/enricher/jaccard.js.map +1 -0
- package/dist/enricher/loop.d.ts +22 -0
- package/dist/enricher/loop.d.ts.map +1 -0
- package/dist/enricher/loop.js +34 -0
- package/dist/enricher/loop.js.map +1 -0
- package/dist/enricher/meaningful-change.d.ts +28 -0
- package/dist/enricher/meaningful-change.d.ts.map +1 -0
- package/dist/enricher/meaningful-change.js +41 -0
- package/dist/enricher/meaningful-change.js.map +1 -0
- package/dist/enricher/observability.d.ts +22 -0
- package/dist/enricher/observability.d.ts.map +1 -0
- package/dist/enricher/observability.js +55 -0
- package/dist/enricher/observability.js.map +1 -0
- package/dist/enricher/pending-query.d.ts +35 -0
- package/dist/enricher/pending-query.d.ts.map +1 -0
- package/dist/enricher/pending-query.js +54 -0
- package/dist/enricher/pending-query.js.map +1 -0
- package/dist/enricher/sql-update.d.ts +7 -0
- package/dist/enricher/sql-update.d.ts.map +1 -0
- package/dist/enricher/sql-update.js +22 -0
- package/dist/enricher/sql-update.js.map +1 -0
- package/dist/enricher/store-adapter.d.ts +98 -0
- package/dist/enricher/store-adapter.d.ts.map +1 -0
- package/dist/enricher/store-adapter.js +129 -0
- package/dist/enricher/store-adapter.js.map +1 -0
- package/dist/enricher/store.d.ts +58 -0
- package/dist/enricher/store.d.ts.map +1 -0
- package/dist/enricher/store.js +126 -0
- package/dist/enricher/store.js.map +1 -0
- package/dist/enricher/tokenize.d.ts +10 -0
- package/dist/enricher/tokenize.d.ts.map +1 -0
- package/dist/enricher/tokenize.js +28 -0
- package/dist/enricher/tokenize.js.map +1 -0
- package/dist/errors.d.ts +41 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +56 -0
- package/dist/errors.js.map +1 -0
- package/dist/health.d.ts +147 -0
- package/dist/health.d.ts.map +1 -0
- package/dist/health.js +168 -0
- package/dist/health.js.map +1 -0
- package/dist/hive-graph/deeplake-credentials.d.ts +68 -0
- package/dist/hive-graph/deeplake-credentials.d.ts.map +1 -0
- package/dist/hive-graph/deeplake-credentials.js +135 -0
- package/dist/hive-graph/deeplake-credentials.js.map +1 -0
- package/dist/hive-graph/deeplake-heal.d.ts +63 -0
- package/dist/hive-graph/deeplake-heal.d.ts.map +1 -0
- package/dist/hive-graph/deeplake-heal.js +118 -0
- package/dist/hive-graph/deeplake-heal.js.map +1 -0
- package/dist/hive-graph/deeplake-store.d.ts +199 -0
- package/dist/hive-graph/deeplake-store.d.ts.map +1 -0
- package/dist/hive-graph/deeplake-store.js +541 -0
- package/dist/hive-graph/deeplake-store.js.map +1 -0
- package/dist/hive-graph/deeplake-transport.d.ts +89 -0
- package/dist/hive-graph/deeplake-transport.d.ts.map +1 -0
- package/dist/hive-graph/deeplake-transport.js +145 -0
- package/dist/hive-graph/deeplake-transport.js.map +1 -0
- package/dist/hive-graph/hash.d.ts +3 -0
- package/dist/hive-graph/hash.d.ts.map +1 -0
- package/dist/hive-graph/hash.js +12 -0
- package/dist/hive-graph/hash.js.map +1 -0
- package/dist/hive-graph/memory-store.d.ts +39 -0
- package/dist/hive-graph/memory-store.d.ts.map +1 -0
- package/dist/hive-graph/memory-store.js +125 -0
- package/dist/hive-graph/memory-store.js.map +1 -0
- package/dist/hive-graph/model.d.ts +109 -0
- package/dist/hive-graph/model.d.ts.map +1 -0
- package/dist/hive-graph/model.js +36 -0
- package/dist/hive-graph/model.js.map +1 -0
- package/dist/hive-graph/paths.d.ts +7 -0
- package/dist/hive-graph/paths.d.ts.map +1 -0
- package/dist/hive-graph/paths.js +26 -0
- package/dist/hive-graph/paths.js.map +1 -0
- package/dist/hive-graph/project-scope.d.ts +99 -0
- package/dist/hive-graph/project-scope.d.ts.map +1 -0
- package/dist/hive-graph/project-scope.js +286 -0
- package/dist/hive-graph/project-scope.js.map +1 -0
- package/dist/hive-graph/schema.d.ts +53 -0
- package/dist/hive-graph/schema.d.ts.map +1 -0
- package/dist/hive-graph/schema.js +139 -0
- package/dist/hive-graph/schema.js.map +1 -0
- package/dist/hive-graph/search-types.d.ts +82 -0
- package/dist/hive-graph/search-types.d.ts.map +1 -0
- package/dist/hive-graph/search-types.js +2 -0
- package/dist/hive-graph/search-types.js.map +1 -0
- package/dist/hive-graph/search.d.ts +51 -0
- package/dist/hive-graph/search.d.ts.map +1 -0
- package/dist/hive-graph/search.js +417 -0
- package/dist/hive-graph/search.js.map +1 -0
- package/dist/hive-graph/sql-guards.d.ts +99 -0
- package/dist/hive-graph/sql-guards.d.ts.map +1 -0
- package/dist/hive-graph/sql-guards.js +129 -0
- package/dist/hive-graph/sql-guards.js.map +1 -0
- package/dist/hive-graph/store.d.ts +151 -0
- package/dist/hive-graph/store.d.ts.map +1 -0
- package/dist/hive-graph/store.js +2 -0
- package/dist/hive-graph/store.js.map +1 -0
- package/dist/hive-graph/ulid.d.ts +14 -0
- package/dist/hive-graph/ulid.d.ts.map +1 -0
- package/dist/hive-graph/ulid.js +109 -0
- package/dist/hive-graph/ulid.js.map +1 -0
- package/dist/hivedoctor-registry.d.ts +111 -0
- package/dist/hivedoctor-registry.d.ts.map +1 -0
- package/dist/hivedoctor-registry.js +143 -0
- package/dist/hivedoctor-registry.js.map +1 -0
- package/dist/index.d.ts +106 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +78 -0
- package/dist/index.js.map +1 -0
- package/dist/lock.d.ts +66 -0
- package/dist/lock.d.ts.map +1 -0
- package/dist/lock.js +282 -0
- package/dist/lock.js.map +1 -0
- package/dist/poll-loop.d.ts +71 -0
- package/dist/poll-loop.d.ts.map +1 -0
- package/dist/poll-loop.js +130 -0
- package/dist/poll-loop.js.map +1 -0
- package/dist/portkey/config.d.ts +46 -0
- package/dist/portkey/config.d.ts.map +1 -0
- package/dist/portkey/config.js +68 -0
- package/dist/portkey/config.js.map +1 -0
- package/dist/portkey/describe-model.d.ts +53 -0
- package/dist/portkey/describe-model.d.ts.map +1 -0
- package/dist/portkey/describe-model.js +56 -0
- package/dist/portkey/describe-model.js.map +1 -0
- package/dist/portkey/headers.d.ts +31 -0
- package/dist/portkey/headers.d.ts.map +1 -0
- package/dist/portkey/headers.js +37 -0
- package/dist/portkey/headers.js.map +1 -0
- package/dist/portkey/transport.d.ts +89 -0
- package/dist/portkey/transport.d.ts.map +1 -0
- package/dist/portkey/transport.js +167 -0
- package/dist/portkey/transport.js.map +1 -0
- package/dist/projection/format.d.ts +51 -0
- package/dist/projection/format.d.ts.map +1 -0
- package/dist/projection/format.js +81 -0
- package/dist/projection/format.js.map +1 -0
- package/dist/projection/generate.d.ts +31 -0
- package/dist/projection/generate.d.ts.map +1 -0
- package/dist/projection/generate.js +83 -0
- package/dist/projection/generate.js.map +1 -0
- package/dist/projection/inherit.d.ts +27 -0
- package/dist/projection/inherit.d.ts.map +1 -0
- package/dist/projection/inherit.js +128 -0
- package/dist/projection/inherit.js.map +1 -0
- package/dist/projection/load.d.ts +47 -0
- package/dist/projection/load.d.ts.map +1 -0
- package/dist/projection/load.js +258 -0
- package/dist/projection/load.js.map +1 -0
- package/dist/projection/store-adapter.d.ts +42 -0
- package/dist/projection/store-adapter.d.ts.map +1 -0
- package/dist/projection/store-adapter.js +42 -0
- package/dist/projection/store-adapter.js.map +1 -0
- package/dist/projection/write.d.ts +79 -0
- package/dist/projection/write.d.ts.map +1 -0
- package/dist/projection/write.js +122 -0
- package/dist/projection/write.js.map +1 -0
- package/dist/registration/classify.d.ts +33 -0
- package/dist/registration/classify.d.ts.map +1 -0
- package/dist/registration/classify.js +32 -0
- package/dist/registration/classify.js.map +1 -0
- package/dist/registration/copy-detect.d.ts +22 -0
- package/dist/registration/copy-detect.d.ts.map +1 -0
- package/dist/registration/copy-detect.js +12 -0
- package/dist/registration/copy-detect.js.map +1 -0
- package/dist/registration/disk-fs.d.ts +41 -0
- package/dist/registration/disk-fs.d.ts.map +1 -0
- package/dist/registration/disk-fs.js +175 -0
- package/dist/registration/disk-fs.js.map +1 -0
- package/dist/registration/fs-watch.d.ts +114 -0
- package/dist/registration/fs-watch.d.ts.map +1 -0
- package/dist/registration/fs-watch.js +266 -0
- package/dist/registration/fs-watch.js.map +1 -0
- package/dist/registration/ignore.d.ts +77 -0
- package/dist/registration/ignore.d.ts.map +1 -0
- package/dist/registration/ignore.js +249 -0
- package/dist/registration/ignore.js.map +1 -0
- package/dist/registration/ladder.d.ts +211 -0
- package/dist/registration/ladder.d.ts.map +1 -0
- package/dist/registration/ladder.js +378 -0
- package/dist/registration/ladder.js.map +1 -0
- package/dist/registration/paths-safe.d.ts +21 -0
- package/dist/registration/paths-safe.d.ts.map +1 -0
- package/dist/registration/paths-safe.js +88 -0
- package/dist/registration/paths-safe.js.map +1 -0
- package/dist/registration/prune-cli.d.ts +48 -0
- package/dist/registration/prune-cli.d.ts.map +1 -0
- package/dist/registration/prune-cli.js +57 -0
- package/dist/registration/prune-cli.js.map +1 -0
- package/dist/registration/review-cli.d.ts +42 -0
- package/dist/registration/review-cli.d.ts.map +1 -0
- package/dist/registration/review-cli.js +110 -0
- package/dist/registration/review-cli.js.map +1 -0
- package/dist/registration/review-store.d.ts +73 -0
- package/dist/registration/review-store.d.ts.map +1 -0
- package/dist/registration/review-store.js +243 -0
- package/dist/registration/review-store.js.map +1 -0
- package/dist/registration/service.d.ts +196 -0
- package/dist/registration/service.d.ts.map +1 -0
- package/dist/registration/service.js +384 -0
- package/dist/registration/service.js.map +1 -0
- package/dist/registration/store-bridge.d.ts +133 -0
- package/dist/registration/store-bridge.d.ts.map +1 -0
- package/dist/registration/store-bridge.js +159 -0
- package/dist/registration/store-bridge.js.map +1 -0
- package/dist/registration/tlsh.d.ts +125 -0
- package/dist/registration/tlsh.d.ts.map +1 -0
- package/dist/registration/tlsh.js +274 -0
- package/dist/registration/tlsh.js.map +1 -0
- package/dist/server.d.ts +26 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +156 -0
- package/dist/server.js.map +1 -0
- package/dist/service/argv.d.ts +52 -0
- package/dist/service/argv.d.ts.map +1 -0
- package/dist/service/argv.js +127 -0
- package/dist/service/argv.js.map +1 -0
- package/dist/service/command-runner.d.ts +54 -0
- package/dist/service/command-runner.d.ts.map +1 -0
- package/dist/service/command-runner.js +55 -0
- package/dist/service/command-runner.js.map +1 -0
- package/dist/service/index.d.ts +83 -0
- package/dist/service/index.d.ts.map +1 -0
- package/dist/service/index.js +270 -0
- package/dist/service/index.js.map +1 -0
- package/dist/service/platform.d.ts +110 -0
- package/dist/service/platform.d.ts.map +1 -0
- package/dist/service/platform.js +157 -0
- package/dist/service/platform.js.map +1 -0
- package/dist/service/templates.d.ts +88 -0
- package/dist/service/templates.d.ts.map +1 -0
- package/dist/service/templates.js +212 -0
- package/dist/service/templates.js.map +1 -0
- package/dist/source-graph/deeplake-credentials.d.ts +57 -0
- package/dist/source-graph/deeplake-credentials.d.ts.map +1 -0
- package/dist/source-graph/deeplake-credentials.js +109 -0
- package/dist/source-graph/deeplake-credentials.js.map +1 -0
- package/dist/source-graph/deeplake-heal.d.ts +53 -0
- package/dist/source-graph/deeplake-heal.d.ts.map +1 -0
- package/dist/source-graph/deeplake-heal.js +41 -0
- package/dist/source-graph/deeplake-heal.js.map +1 -0
- package/dist/source-graph/deeplake-store.d.ts +151 -0
- package/dist/source-graph/deeplake-store.d.ts.map +1 -0
- package/dist/source-graph/deeplake-store.js +389 -0
- package/dist/source-graph/deeplake-store.js.map +1 -0
- package/dist/source-graph/deeplake-transport.d.ts +74 -0
- package/dist/source-graph/deeplake-transport.d.ts.map +1 -0
- package/dist/source-graph/deeplake-transport.js +107 -0
- package/dist/source-graph/deeplake-transport.js.map +1 -0
- package/dist/source-graph/hash.d.ts +3 -0
- package/dist/source-graph/hash.d.ts.map +1 -0
- package/dist/source-graph/hash.js +12 -0
- package/dist/source-graph/hash.js.map +1 -0
- package/dist/source-graph/memory-store.d.ts +32 -0
- package/dist/source-graph/memory-store.d.ts.map +1 -0
- package/dist/source-graph/memory-store.js +81 -0
- package/dist/source-graph/memory-store.js.map +1 -0
- package/dist/source-graph/model.d.ts +102 -0
- package/dist/source-graph/model.d.ts.map +1 -0
- package/dist/source-graph/model.js +36 -0
- package/dist/source-graph/model.js.map +1 -0
- package/dist/source-graph/paths.d.ts +7 -0
- package/dist/source-graph/paths.d.ts.map +1 -0
- package/dist/source-graph/paths.js +26 -0
- package/dist/source-graph/paths.js.map +1 -0
- package/dist/source-graph/schema.d.ts +44 -0
- package/dist/source-graph/schema.d.ts.map +1 -0
- package/dist/source-graph/schema.js +123 -0
- package/dist/source-graph/schema.js.map +1 -0
- package/dist/source-graph/sql-guards.d.ts +99 -0
- package/dist/source-graph/sql-guards.d.ts.map +1 -0
- package/dist/source-graph/sql-guards.js +129 -0
- package/dist/source-graph/sql-guards.js.map +1 -0
- package/dist/source-graph/store.d.ts +101 -0
- package/dist/source-graph/store.d.ts.map +1 -0
- package/dist/source-graph/store.js +2 -0
- package/dist/source-graph/store.js.map +1 -0
- package/dist/source-graph/ulid.d.ts +9 -0
- package/dist/source-graph/ulid.d.ts.map +1 -0
- package/dist/source-graph/ulid.js +61 -0
- package/dist/source-graph/ulid.js.map +1 -0
- package/dist/telemetry/checkin.d.ts +66 -0
- package/dist/telemetry/checkin.d.ts.map +1 -0
- package/dist/telemetry/checkin.js +142 -0
- package/dist/telemetry/checkin.js.map +1 -0
- package/dist/telemetry/db.d.ts +34 -0
- package/dist/telemetry/db.d.ts.map +1 -0
- package/dist/telemetry/db.js +122 -0
- package/dist/telemetry/db.js.map +1 -0
- package/dist/telemetry/index.d.ts +76 -0
- package/dist/telemetry/index.d.ts.map +1 -0
- package/dist/telemetry/index.js +98 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/telemetry/logs.d.ts +83 -0
- package/dist/telemetry/logs.d.ts.map +1 -0
- package/dist/telemetry/logs.js +110 -0
- package/dist/telemetry/logs.js.map +1 -0
- package/dist/telemetry/metrics.d.ts +82 -0
- package/dist/telemetry/metrics.d.ts.map +1 -0
- package/dist/telemetry/metrics.js +148 -0
- package/dist/telemetry/metrics.js.map +1 -0
- package/dist/telemetry-usage/emit.d.ts +105 -0
- package/dist/telemetry-usage/emit.d.ts.map +1 -0
- package/dist/telemetry-usage/emit.js +267 -0
- package/dist/telemetry-usage/emit.js.map +1 -0
- package/dist/telemetry-usage/posthog-key.d.ts +22 -0
- package/dist/telemetry-usage/posthog-key.d.ts.map +1 -0
- package/dist/telemetry-usage/posthog-key.js +22 -0
- package/dist/telemetry-usage/posthog-key.js.map +1 -0
- package/dist/worker.d.ts +69 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +91 -0
- package/dist/worker.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
import { inTenancy } from "../hive-graph/model.js";
|
|
2
|
+
import { mintNectar, nectarCreatedAt } from "../hive-graph/ulid.js";
|
|
3
|
+
import { sha256Hex } from "../hive-graph/hash.js";
|
|
4
|
+
import { filenameOf, extOf } from "../hive-graph/paths.js";
|
|
5
|
+
import { classifyNewFile } from "./copy-detect.js";
|
|
6
|
+
// Value import; tlsh's back-edge to this module is `import type` (erased), so there is no runtime cycle.
|
|
7
|
+
import { computeFingerprint } from "./tlsh.js";
|
|
8
|
+
/** A simple `Map`-backed {@link StatCache}. One instance persists for the lifetime of a `RegistrationService` (across cycles, not across a daemon restart - a restart re-warms via the store's own version-row stat, just without the touch optimization until the next touch). */
|
|
9
|
+
export function createInMemoryStatCache() {
|
|
10
|
+
const map = new Map();
|
|
11
|
+
return {
|
|
12
|
+
get: (relPath) => map.get(relPath),
|
|
13
|
+
set: (relPath, stat) => {
|
|
14
|
+
map.set(relPath, { mtimeObserved: stat.mtimeObserved, sizeBytes: stat.sizeBytes });
|
|
15
|
+
},
|
|
16
|
+
delete: (relPath) => {
|
|
17
|
+
map.delete(relPath);
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/** Run the ladder for one observed file. Returns which step fired and the nectar it resolved to. */
|
|
22
|
+
export function reassociate(file, deps) {
|
|
23
|
+
const { store, tenancy } = deps;
|
|
24
|
+
const byPath = store.latestVersionByPath(tenancy, file.relPath);
|
|
25
|
+
// Step 1: (path, mtime, size) exact -> unchanged, no read, no hash. A
|
|
26
|
+
// fast-path cache hit (NEC-035 / AC-018c.9) takes precedence over the
|
|
27
|
+
// stored version row's own stat: it is the freshest stat the ladder has
|
|
28
|
+
// ever observed for this path since the content last actually changed.
|
|
29
|
+
const cachedStat = deps.statCache?.get(file.relPath);
|
|
30
|
+
const effectiveMtime = cachedStat?.mtimeObserved ?? byPath?.version.mtimeObserved;
|
|
31
|
+
const effectiveSize = cachedStat?.sizeBytes ?? byPath?.version.sizeBytes;
|
|
32
|
+
if (byPath !== undefined && effectiveMtime === file.mtimeObserved && effectiveSize === file.sizeBytes) {
|
|
33
|
+
return { step: 1, action: "noop", nectar: byPath.identity.nectar };
|
|
34
|
+
}
|
|
35
|
+
// Anything past step 1 requires the content hash (and the persisted fingerprint).
|
|
36
|
+
const content = file.readContent();
|
|
37
|
+
const hash = sha256Hex(content);
|
|
38
|
+
const fingerprint = computeFingerprint(content);
|
|
39
|
+
// Step 2: path is known; compare content.
|
|
40
|
+
if (byPath !== undefined) {
|
|
41
|
+
if (byPath.version.contentHash === hash) {
|
|
42
|
+
// Content identical (mtime/size changed, e.g. `touch`): still a no-op,
|
|
43
|
+
// but remember the fresh stat (NEC-035) so the NEXT observation of this
|
|
44
|
+
// unchanged file takes the step-1 fast path instead of re-hashing.
|
|
45
|
+
deps.statCache?.set(file.relPath, { mtimeObserved: file.mtimeObserved, sizeBytes: file.sizeBytes });
|
|
46
|
+
return { step: 2, action: "noop", nectar: byPath.identity.nectar };
|
|
47
|
+
}
|
|
48
|
+
// Real content change: the fresh version row already carries the correct
|
|
49
|
+
// stat, so any stale cache entry from a prior touch must not shadow it.
|
|
50
|
+
deps.statCache?.delete(file.relPath);
|
|
51
|
+
appendEditVersion(deps, byPath, file, hash, fingerprint);
|
|
52
|
+
deps.onEnrichQueued?.(byPath.identity.nectar);
|
|
53
|
+
return { step: 2, action: "append-version", nectar: byPath.identity.nectar };
|
|
54
|
+
}
|
|
55
|
+
// Path is NOT known. Look for an exact content-hash match to another nectar.
|
|
56
|
+
const byHash = store.latestVersionByHash(tenancy, hash);
|
|
57
|
+
if (byHash !== undefined) {
|
|
58
|
+
const sourcePath = byHash.version.path;
|
|
59
|
+
// NEC-034 / AC-018c.8: on a case-insensitive filesystem, a case-only
|
|
60
|
+
// rename (`Foo.ts` -> `foo.ts`) leaves `existsOnDisk(sourcePath)` true
|
|
61
|
+
// (the OS resolves either casing to the same file), which would
|
|
62
|
+
// misclassify the rename as a copy. `file.relPath` is the TRUE on-disk
|
|
63
|
+
// casing of the just-observed path (from `fs.watch`/`readdir`, never
|
|
64
|
+
// user-typed), so a source that case-folds equal but differs in exact
|
|
65
|
+
// casing is unambiguously the same file, renamed - no filesystem
|
|
66
|
+
// existence check needed for that specific determination.
|
|
67
|
+
const caseOnlyRename = deps.caseInsensitive === true &&
|
|
68
|
+
sourcePath !== file.relPath &&
|
|
69
|
+
sourcePath.toLowerCase() === file.relPath.toLowerCase();
|
|
70
|
+
if (sourcePath !== file.relPath && (caseOnlyRename || !deps.existsOnDisk(sourcePath))) {
|
|
71
|
+
// Step 3: the source path is gone (or case-only renamed) -> this is a
|
|
72
|
+
// move. Carry the nectar, inherit the description (content unchanged),
|
|
73
|
+
// enqueue no enrich. The carry is refused (falls through to mint) if
|
|
74
|
+
// the source is out of tenancy. `file.relPath` (the fresh casing) is
|
|
75
|
+
// what gets written, so stored rows preserve on-disk casing.
|
|
76
|
+
if (writeCarriedRow(store, tenancy, deps.now(), byHash, file, hash, null, fingerprint)) {
|
|
77
|
+
deps.statCache?.delete(sourcePath);
|
|
78
|
+
return { step: 3, action: "carry-nectar", nectar: byHash.identity.nectar };
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// Source still on disk -> a copy. Mint with provenance (step 5).
|
|
82
|
+
return mintOrCopy(deps, file, hash, fingerprint);
|
|
83
|
+
}
|
|
84
|
+
// Step 4: fuzzy match to a missing file (only if an injected fuzzy step exists).
|
|
85
|
+
// Candidates read the missing nectar's PERSISTED fingerprint column, so the
|
|
86
|
+
// match survives a daemon restart (no in-process cache).
|
|
87
|
+
let review = null;
|
|
88
|
+
if (deps.fuzzy !== undefined) {
|
|
89
|
+
const candidates = missingCandidates(deps, file.relPath).map((lv) => ({
|
|
90
|
+
...lv,
|
|
91
|
+
fingerprint: lv.version.fingerprint ?? null,
|
|
92
|
+
}));
|
|
93
|
+
const outcome = deps.fuzzy.match(content, candidates);
|
|
94
|
+
switch (outcome.kind) {
|
|
95
|
+
case "match": {
|
|
96
|
+
const carried = store.latestVersion(outcome.nectar);
|
|
97
|
+
const identity = store.getIdentity(outcome.nectar);
|
|
98
|
+
if (carried !== undefined &&
|
|
99
|
+
identity !== undefined &&
|
|
100
|
+
writeCarriedRow(store, tenancy, deps.now(), { identity, version: carried }, file, hash, outcome.confidence, fingerprint)) {
|
|
101
|
+
// High-confidence carry: content changed, so (re)describe (PRD-006d AC step-4 high band).
|
|
102
|
+
deps.onEnrichQueued?.(outcome.nectar);
|
|
103
|
+
return { step: 4, action: "carry-nectar", nectar: outcome.nectar };
|
|
104
|
+
}
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
case "review": {
|
|
108
|
+
review = { nectar: outcome.nectar, confidence: outcome.confidence, distance: outcome.distance ?? null };
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
case "none":
|
|
112
|
+
break;
|
|
113
|
+
default: {
|
|
114
|
+
const _exhaustive = outcome;
|
|
115
|
+
return _exhaustive;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// Step 5: mint (or copy, with provenance). A below-high fuzzy candidate is
|
|
120
|
+
// surfaced for review AFTER the fresh mint so the record can name the minted
|
|
121
|
+
// nectar; accepting it later re-associates the missing nectar onto this path.
|
|
122
|
+
const result = mintOrCopy(deps, file, hash, fingerprint);
|
|
123
|
+
if (review !== null) {
|
|
124
|
+
deps.onReviewNeeded?.({
|
|
125
|
+
nectar: review.nectar,
|
|
126
|
+
relPath: file.relPath,
|
|
127
|
+
confidence: review.confidence,
|
|
128
|
+
distance: review.distance,
|
|
129
|
+
contentHash: hash,
|
|
130
|
+
sizeBytes: file.sizeBytes,
|
|
131
|
+
mtimeObserved: file.mtimeObserved,
|
|
132
|
+
mintedNectar: result.nectar,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
return result;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Missing candidates: known latest versions whose current path is gone from
|
|
139
|
+
* disk (and is not this file's path). PRD-018c EX-4 (change-detection review
|
|
140
|
+
* M7): when the caller supplies `deps.missingPaths` (computed ONCE per
|
|
141
|
+
* settle/resync cycle in `service.ts`'s `runCycle`), this is an O(1) set
|
|
142
|
+
* lookup per known version instead of an `existsOnDisk` stat - eliminating the
|
|
143
|
+
* O(known-files) stat-per-new-file cost the review flagged. Falls back to the
|
|
144
|
+
* pre-018c per-candidate `existsOnDisk` stat when `missingPaths` is omitted
|
|
145
|
+
* (unit tests calling `reassociate` directly need no change).
|
|
146
|
+
*/
|
|
147
|
+
function missingCandidates(deps, selfPath) {
|
|
148
|
+
const missing = deps.missingPaths;
|
|
149
|
+
if (missing !== undefined) {
|
|
150
|
+
return deps.store
|
|
151
|
+
.listLatestVersions(deps.tenancy)
|
|
152
|
+
.filter((lv) => lv.version.path !== selfPath && missing.has(lv.version.path));
|
|
153
|
+
}
|
|
154
|
+
return deps.store
|
|
155
|
+
.listLatestVersions(deps.tenancy)
|
|
156
|
+
.filter((lv) => lv.version.path !== selfPath && !deps.existsOnDisk(lv.version.path));
|
|
157
|
+
}
|
|
158
|
+
function baseVersion(tenancy, now, file, hash, seq, fingerprint) {
|
|
159
|
+
return {
|
|
160
|
+
nectar: "",
|
|
161
|
+
contentHash: hash,
|
|
162
|
+
seq,
|
|
163
|
+
path: file.relPath,
|
|
164
|
+
filename: filenameOf(file.relPath),
|
|
165
|
+
ext: extOf(file.relPath),
|
|
166
|
+
sizeBytes: file.sizeBytes,
|
|
167
|
+
mtimeObserved: file.mtimeObserved,
|
|
168
|
+
title: "",
|
|
169
|
+
description: "",
|
|
170
|
+
concepts: "[]",
|
|
171
|
+
embedding: null,
|
|
172
|
+
confidence: null,
|
|
173
|
+
fingerprint,
|
|
174
|
+
describedAt: "",
|
|
175
|
+
describeModel: "",
|
|
176
|
+
describeStatus: "pending",
|
|
177
|
+
observedAt: now,
|
|
178
|
+
orgId: tenancy.orgId,
|
|
179
|
+
workspaceId: tenancy.workspaceId,
|
|
180
|
+
projectId: tenancy.projectId,
|
|
181
|
+
lastUpdateDate: now,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
/** Step 2: append an edited version (new content, pending description). Persists the content fingerprint. */
|
|
185
|
+
function appendEditVersion(deps, prev, file, hash, fingerprint) {
|
|
186
|
+
const seq = deps.store.nextSeq(prev.identity.nectar);
|
|
187
|
+
const row = baseVersion(deps.tenancy, deps.now(), file, hash, seq, fingerprint);
|
|
188
|
+
row.nectar = prev.identity.nectar;
|
|
189
|
+
deps.store.appendVersion(row);
|
|
190
|
+
deps.store.touchIdentity(prev.identity.nectar, deps.now());
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Step 3/4 carry: append a version row that carries `source`'s nectar to a new
|
|
194
|
+
* path, inheriting the prior description (content is identical for an exact
|
|
195
|
+
* step-3 move; a fuzzy carry keeps provenance and can be re-described later).
|
|
196
|
+
* Shared by the ladder and by `review-matches` accept.
|
|
197
|
+
*
|
|
198
|
+
* Returns false (and writes nothing) when `source.identity` is outside
|
|
199
|
+
* `tenancy`: a carry must never move a nectar minted under another project onto
|
|
200
|
+
* a path in this one (AC-20). Callers treat false as "no carry" and fall through
|
|
201
|
+
* to a fresh mint.
|
|
202
|
+
*/
|
|
203
|
+
function writeCarriedRow(store, tenancy, now, source, file, hash, confidence, fingerprint) {
|
|
204
|
+
if (!inTenancy(source.identity, tenancy))
|
|
205
|
+
return false; // refuse a cross-project carry
|
|
206
|
+
const seq = store.nextSeq(source.identity.nectar);
|
|
207
|
+
const row = baseVersion(tenancy, now, file, hash, seq, fingerprint);
|
|
208
|
+
row.nectar = source.identity.nectar;
|
|
209
|
+
row.title = source.version.title;
|
|
210
|
+
row.description = source.version.description;
|
|
211
|
+
row.concepts = source.version.concepts;
|
|
212
|
+
row.embedding = source.version.embedding;
|
|
213
|
+
row.describedAt = source.version.describedAt;
|
|
214
|
+
row.describeModel = source.version.describeModel;
|
|
215
|
+
row.describeStatus = source.version.describeStatus;
|
|
216
|
+
row.confidence = confidence;
|
|
217
|
+
store.appendVersion(row);
|
|
218
|
+
store.touchIdentity(source.identity.nectar, now);
|
|
219
|
+
return true;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Carry an existing nectar onto a new path (the `review-matches` accept path,
|
|
223
|
+
* AC-18): append a carried version row for `sourceNectar` at `target`. Returns
|
|
224
|
+
* false if the source nectar no longer exists. This is exactly what a
|
|
225
|
+
* high-confidence step 4 does, applied on human confirmation instead.
|
|
226
|
+
*
|
|
227
|
+
* The carried row's `fingerprint` is left NULL here: the accept path works from
|
|
228
|
+
* the persisted pending-candidate metadata (hash/size/mtime), not the file
|
|
229
|
+
* content, so there is nothing to fingerprint. It self-heals on the next
|
|
230
|
+
* observation of the file (a step-2 edit persists a fresh fingerprint), per the
|
|
231
|
+
* nullable-column contract.
|
|
232
|
+
*/
|
|
233
|
+
export function carryNectar(store, tenancy, now, sourceNectar, target, confidence) {
|
|
234
|
+
const version = store.latestVersion(sourceNectar);
|
|
235
|
+
const identity = store.getIdentity(sourceNectar);
|
|
236
|
+
if (version === undefined || identity === undefined)
|
|
237
|
+
return false;
|
|
238
|
+
// writeCarriedRow enforces the tenancy guard and returns false on a cross-project source.
|
|
239
|
+
return writeCarriedRow(store, tenancy, now, { identity, version }, { relPath: target.relPath, sizeBytes: target.sizeBytes, mtimeObserved: target.mtimeObserved }, target.contentHash, confidence, null);
|
|
240
|
+
}
|
|
241
|
+
/** Step 5: mint a fresh nectar, or record a copy with provenance. Persists the content fingerprint. */
|
|
242
|
+
function mintOrCopy(deps, file, hash, fingerprint) {
|
|
243
|
+
const decision = classifyNewFile(deps.store, deps.tenancy, hash);
|
|
244
|
+
const nectar = mintNectar();
|
|
245
|
+
const now = deps.now();
|
|
246
|
+
const identity = {
|
|
247
|
+
nectar,
|
|
248
|
+
kind: "file",
|
|
249
|
+
createdAt: nectarCreatedAt(nectar),
|
|
250
|
+
derivedFromNectar: decision.action === "copy" ? decision.sourceNectar : "",
|
|
251
|
+
forkContentHash: decision.action === "copy" ? decision.forkContentHash : "",
|
|
252
|
+
orgId: deps.tenancy.orgId,
|
|
253
|
+
workspaceId: deps.tenancy.workspaceId,
|
|
254
|
+
projectId: deps.tenancy.projectId,
|
|
255
|
+
lastUpdateDate: now,
|
|
256
|
+
};
|
|
257
|
+
deps.store.insertIdentity(identity);
|
|
258
|
+
const row = baseVersion(deps.tenancy, now, file, hash, 0, fingerprint);
|
|
259
|
+
row.nectar = nectar;
|
|
260
|
+
deps.store.appendVersion(row);
|
|
261
|
+
deps.onEnrichQueued?.(nectar);
|
|
262
|
+
return { step: 5, action: decision.action === "copy" ? "copy" : "mint", nectar };
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* PRD-018d (NEC-036): the idempotent crash-repair sweep for the ladder's
|
|
266
|
+
* multi-write actions.
|
|
267
|
+
*
|
|
268
|
+
* Every ladder action that mutates the store is a SEQUENCE of two writes
|
|
269
|
+
* (mint = `insertIdentity` + `appendVersion`; edit/carry = `appendVersion` +
|
|
270
|
+
* `touchIdentity`; review-accept = carry + `deleteNectar` of the placeholder,
|
|
271
|
+
* `review-cli.ts`), with no atomicity across a crash between them (the
|
|
272
|
+
* sync/async store bridge that would let these be one transaction is
|
|
273
|
+
* PRD-018b's construction, a Non-Goal here). This sweep heals the three
|
|
274
|
+
* resulting invariant violations instead, and is idempotent: running it again
|
|
275
|
+
* on an already-healed store finds nothing to do.
|
|
276
|
+
*
|
|
277
|
+
* 1. An orphan identity (a mint that crashed after `insertIdentity`, before
|
|
278
|
+
* `appendVersion`): zero version rows. There is no content to construct a
|
|
279
|
+
* version from, so the only sound repair is deleting the orphan (the same
|
|
280
|
+
* `deleteNectar` review-accept already uses to retire a placeholder -
|
|
281
|
+
* this sweep is not a new deletion path, just a new caller of the
|
|
282
|
+
* existing one). Requires the OPTIONAL `store.listIdentities` (skipped,
|
|
283
|
+
* not guessed at, when the adapter omits it).
|
|
284
|
+
* 2. A stale `identity.lastUpdateDate` (an edit/carry that crashed after
|
|
285
|
+
* `appendVersion`, before `touchIdentity`): the identity's timestamp
|
|
286
|
+
* predates its own latest version's `lastUpdateDate`, which feeds prune
|
|
287
|
+
* eligibility directly (`prune-cli.ts`). Healed by re-running
|
|
288
|
+
* `touchIdentity` with the version's own timestamp.
|
|
289
|
+
* 3. Two identities both claiming one path as their latest version's `path`
|
|
290
|
+
* (a review-accept that crashed after the carry landed, before the
|
|
291
|
+
* placeholder delete ran): under normal ladder operation a carry only
|
|
292
|
+
* ever targets a path with NO existing identity, so this can only be a
|
|
293
|
+
* crash artifact. The carried identity's version always has a strictly
|
|
294
|
+
* later `observedAt` than the placeholder's original mint, so the
|
|
295
|
+
* survivor is the entry with the latest `observedAt`; every other
|
|
296
|
+
* claimant is deleted.
|
|
297
|
+
*/
|
|
298
|
+
export function repairLadderState(store, tenancy) {
|
|
299
|
+
let healedOrphanIdentities = 0;
|
|
300
|
+
if (store.listIdentities !== undefined) {
|
|
301
|
+
for (const identity of store.listIdentities(tenancy)) {
|
|
302
|
+
if (store.latestVersion(identity.nectar) === undefined) {
|
|
303
|
+
store.deleteNectar(tenancy, identity.nectar);
|
|
304
|
+
healedOrphanIdentities += 1;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
// 4. An orphan VERSION (CodeRabbit PR-18 finding #8, layer b): a version row
|
|
309
|
+
// whose nectar has no identity row at all - the inverse of the orphan-
|
|
310
|
+
// identity case above. This happens when a durable `insertIdentity` flush
|
|
311
|
+
// failed but a later `appendVersion` for the same nectar still landed (the
|
|
312
|
+
// sync/async bridge's layer-a fix, `store-bridge.ts`, prevents this for NEW
|
|
313
|
+
// writes; this heals any that already exist). Reads join through identities
|
|
314
|
+
// (`listLatestVersions` et al never surface the row), so the only sound
|
|
315
|
+
// repair is reconstructing a minimal identity from the version row itself:
|
|
316
|
+
// the nectar ULID encodes `createdAt`, and the version row carries its own
|
|
317
|
+
// tenancy + `lastUpdateDate`. Requires the OPTIONAL `store.listVersionNectars`
|
|
318
|
+
// (skipped, not guessed at, when the adapter omits it, mirroring how
|
|
319
|
+
// orphan-identity healing above skips when `listIdentities` is omitted).
|
|
320
|
+
let healedOrphanVersions = 0;
|
|
321
|
+
if (store.listVersionNectars !== undefined) {
|
|
322
|
+
for (const nectar of store.listVersionNectars(tenancy)) {
|
|
323
|
+
if (store.getIdentity(nectar) !== undefined)
|
|
324
|
+
continue; // already has an identity
|
|
325
|
+
const version = store.latestVersion(nectar);
|
|
326
|
+
if (version === undefined)
|
|
327
|
+
continue; // nothing to reconstruct from
|
|
328
|
+
store.insertIdentity({
|
|
329
|
+
nectar,
|
|
330
|
+
kind: "file",
|
|
331
|
+
createdAt: nectarCreatedAt(nectar),
|
|
332
|
+
derivedFromNectar: "",
|
|
333
|
+
forkContentHash: "",
|
|
334
|
+
orgId: version.orgId,
|
|
335
|
+
workspaceId: version.workspaceId,
|
|
336
|
+
projectId: version.projectId,
|
|
337
|
+
lastUpdateDate: version.lastUpdateDate,
|
|
338
|
+
});
|
|
339
|
+
healedOrphanVersions += 1;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
const latest = store.listLatestVersions(tenancy);
|
|
343
|
+
let healedStaleLastUpdate = 0;
|
|
344
|
+
for (const lv of latest) {
|
|
345
|
+
const identityMs = Date.parse(lv.identity.lastUpdateDate);
|
|
346
|
+
const versionMs = Date.parse(lv.version.lastUpdateDate);
|
|
347
|
+
if (Number.isNaN(versionMs))
|
|
348
|
+
continue; // nothing trustworthy to catch up to
|
|
349
|
+
if (Number.isNaN(identityMs) || identityMs < versionMs) {
|
|
350
|
+
store.touchIdentity(lv.identity.nectar, lv.version.lastUpdateDate);
|
|
351
|
+
healedStaleLastUpdate += 1;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
let healedDuplicatePaths = 0;
|
|
355
|
+
const byPath = new Map();
|
|
356
|
+
for (const lv of latest) {
|
|
357
|
+
const group = byPath.get(lv.version.path) ?? [];
|
|
358
|
+
group.push(lv);
|
|
359
|
+
byPath.set(lv.version.path, group);
|
|
360
|
+
}
|
|
361
|
+
for (const group of byPath.values()) {
|
|
362
|
+
if (group.length <= 1)
|
|
363
|
+
continue;
|
|
364
|
+
let survivor = group[0];
|
|
365
|
+
for (const lv of group) {
|
|
366
|
+
if (Date.parse(lv.version.observedAt) > Date.parse(survivor.version.observedAt))
|
|
367
|
+
survivor = lv;
|
|
368
|
+
}
|
|
369
|
+
for (const lv of group) {
|
|
370
|
+
if (lv.identity.nectar === survivor.identity.nectar)
|
|
371
|
+
continue;
|
|
372
|
+
store.deleteNectar(tenancy, lv.identity.nectar);
|
|
373
|
+
healedDuplicatePaths += 1;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
return { healedOrphanIdentities, healedOrphanVersions, healedStaleLastUpdate, healedDuplicatePaths };
|
|
377
|
+
}
|
|
378
|
+
//# sourceMappingURL=ladder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ladder.js","sourceRoot":"","sources":["../../src/registration/ladder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* True when `relPath` is a safe workspace-relative path: non-empty, not absolute
|
|
3
|
+
* (POSIX `/...`, Windows `C:\...`, or a UNC/backslash root), and with no `..`
|
|
4
|
+
* segment. This is a lexical check only; it does not touch the disk.
|
|
5
|
+
*/
|
|
6
|
+
export declare function isSafeRelPath(relPath: string): boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Resolve `relPath` under `root` and return the absolute path ONLY if it stays
|
|
9
|
+
* within `root` (inclusive of `root` itself); otherwise null. Lexical: it does
|
|
10
|
+
* not resolve symlinks. Returns null for any path {@link isSafeRelPath} rejects.
|
|
11
|
+
*/
|
|
12
|
+
export declare function containedPath(root: string, relPath: string): string | null;
|
|
13
|
+
/**
|
|
14
|
+
* The symlink clamp for real disk reads: resolve symlinks on both the candidate
|
|
15
|
+
* and the root, and return the real candidate path ONLY if it stays under the
|
|
16
|
+
* real root; otherwise null. Returns null when the candidate does not exist (a
|
|
17
|
+
* broken symlink or missing file), when it is lexically unsafe, or when the real
|
|
18
|
+
* path escapes the root. Use this before reading content from a real filesystem.
|
|
19
|
+
*/
|
|
20
|
+
export declare function realpathContained(root: string, relPath: string): string | null;
|
|
21
|
+
//# sourceMappingURL=paths-safe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths-safe.d.ts","sourceRoot":"","sources":["../../src/registration/paths-safe.ts"],"names":[],"mappings":"AAwBA;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAUtD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM1E;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiB9E"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace path containment for the file-registration surface (CWE-22).
|
|
3
|
+
*
|
|
4
|
+
* `fs.watch` and any injected filesystem seam can hand the pipeline a path that
|
|
5
|
+
* escapes the workspace: an absolute path (Node `path.join(root, abs)` discards
|
|
6
|
+
* `root`), a `..` traversal (`join(root, "../../etc/passwd")` resolves outside
|
|
7
|
+
* `root`), or a symlink inside the root that points out of it. This module is
|
|
8
|
+
* the single, dependency-free (Node built-ins only) guard the intake, the
|
|
9
|
+
* persistence path, and the CLI all use so no such path is ever stat-ed, read,
|
|
10
|
+
* persisted, or allowed to trigger a cycle.
|
|
11
|
+
*
|
|
12
|
+
* Two levels:
|
|
13
|
+
* - {@link isSafeRelPath} / {@link containedPath}: purely lexical (no disk
|
|
14
|
+
* access). Reject absolute paths and `..` segments, resolve, and require the
|
|
15
|
+
* result to stay under the resolved root. Used everywhere a path is handled.
|
|
16
|
+
* - {@link realpathContained}: the symlink clamp. Resolves symlinks on both the
|
|
17
|
+
* candidate and the root via `realpathSync` and requires the REAL candidate
|
|
18
|
+
* to stay under the REAL root. Used only where content is actually read from
|
|
19
|
+
* a real disk (a symlink inside the root pointing outside is a lexical pass
|
|
20
|
+
* but a real-path escape).
|
|
21
|
+
*/
|
|
22
|
+
import { isAbsolute, resolve, sep } from "node:path";
|
|
23
|
+
import { realpathSync } from "node:fs";
|
|
24
|
+
/**
|
|
25
|
+
* True when `relPath` is a safe workspace-relative path: non-empty, not absolute
|
|
26
|
+
* (POSIX `/...`, Windows `C:\...`, or a UNC/backslash root), and with no `..`
|
|
27
|
+
* segment. This is a lexical check only; it does not touch the disk.
|
|
28
|
+
*/
|
|
29
|
+
export function isSafeRelPath(relPath) {
|
|
30
|
+
if (relPath === "")
|
|
31
|
+
return false;
|
|
32
|
+
const norm = relPath.replace(/\\/g, "/");
|
|
33
|
+
if (norm.startsWith("/"))
|
|
34
|
+
return false; // POSIX absolute (or a leading-slash escape)
|
|
35
|
+
if (/^[a-zA-Z]:/.test(norm))
|
|
36
|
+
return false; // Windows drive prefix (C:/... or C:\...)
|
|
37
|
+
if (isAbsolute(relPath))
|
|
38
|
+
return false; // catches remaining platform-absolute forms
|
|
39
|
+
for (const segment of norm.split("/")) {
|
|
40
|
+
if (segment === "..")
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Resolve `relPath` under `root` and return the absolute path ONLY if it stays
|
|
47
|
+
* within `root` (inclusive of `root` itself); otherwise null. Lexical: it does
|
|
48
|
+
* not resolve symlinks. Returns null for any path {@link isSafeRelPath} rejects.
|
|
49
|
+
*/
|
|
50
|
+
export function containedPath(root, relPath) {
|
|
51
|
+
if (!isSafeRelPath(relPath))
|
|
52
|
+
return null;
|
|
53
|
+
const rootResolved = resolve(root);
|
|
54
|
+
const candidate = resolve(rootResolved, relPath);
|
|
55
|
+
if (candidate !== rootResolved && !candidate.startsWith(rootResolved + sep))
|
|
56
|
+
return null;
|
|
57
|
+
return candidate;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The symlink clamp for real disk reads: resolve symlinks on both the candidate
|
|
61
|
+
* and the root, and return the real candidate path ONLY if it stays under the
|
|
62
|
+
* real root; otherwise null. Returns null when the candidate does not exist (a
|
|
63
|
+
* broken symlink or missing file), when it is lexically unsafe, or when the real
|
|
64
|
+
* path escapes the root. Use this before reading content from a real filesystem.
|
|
65
|
+
*/
|
|
66
|
+
export function realpathContained(root, relPath) {
|
|
67
|
+
const candidate = containedPath(root, relPath);
|
|
68
|
+
if (candidate === null)
|
|
69
|
+
return null;
|
|
70
|
+
let realRoot;
|
|
71
|
+
try {
|
|
72
|
+
realRoot = realpathSync(resolve(root));
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
let realCandidate;
|
|
78
|
+
try {
|
|
79
|
+
realCandidate = realpathSync(candidate);
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return null; // does not exist, or a broken symlink
|
|
83
|
+
}
|
|
84
|
+
if (realCandidate !== realRoot && !realCandidate.startsWith(realRoot + sep))
|
|
85
|
+
return null;
|
|
86
|
+
return realCandidate;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=paths-safe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths-safe.js","sourceRoot":"","sources":["../../src/registration/paths-safe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,IAAI,OAAO,KAAK,EAAE;QAAE,OAAO,KAAK,CAAC;IACjC,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACzC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC,CAAC,6CAA6C;IACrF,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC,CAAC,0CAA0C;IACrF,IAAI,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC,CAAC,4CAA4C;IACnF,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACtC,IAAI,OAAO,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC;IACrC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,OAAe;IACzD,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,SAAS,GAAG,OAAO,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACjD,IAAI,SAAS,KAAK,YAAY,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,YAAY,GAAG,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACzF,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,OAAe;IAC7D,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC/C,IAAI,SAAS,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACpC,IAAI,QAAgB,CAAC;IACrB,IAAI,CAAC;QACH,QAAQ,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,aAAqB,CAAC;IAC1B,IAAI,CAAC;QACH,aAAa,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC,CAAC,sCAAsC;IACrD,CAAC;IACD,IAAI,aAAa,KAAK,QAAQ,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,QAAQ,GAAG,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACzF,OAAO,aAAa,CAAC;AACvB,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `nectar prune [--confirm]` command logic (PRD-006d AC-19).
|
|
3
|
+
*
|
|
4
|
+
* The SOLE nectar-deletion path. The re-association ladder never deletes or
|
|
5
|
+
* reuses a nectar; deletion is a separate, explicit, human-triggered operation:
|
|
6
|
+
* - bare `prune` -> a preview/list of prune candidates (no deletion);
|
|
7
|
+
* - `prune --confirm` -> the destructive act (delete each candidate).
|
|
8
|
+
*
|
|
9
|
+
* A prune candidate is a nectar whose latest-version path is absent from disk and
|
|
10
|
+
* whose last observed change is older than the grace period. The grace period
|
|
11
|
+
* exists because a "missing" file may be on another checked-out branch or return
|
|
12
|
+
* after a merge, so pruning is conservative.
|
|
13
|
+
*
|
|
14
|
+
* DEFAULT (flagged, not load-bearing on any algorithm): the grace period is 30
|
|
15
|
+
* days ({@link PRUNE_GRACE_MS}), configurable via `graceMs`.
|
|
16
|
+
*/
|
|
17
|
+
import type { HiveGraphStore } from "../hive-graph/store.js";
|
|
18
|
+
import type { Tenancy } from "../hive-graph/model.js";
|
|
19
|
+
/** Prune grace period: 30 days - DEFAULT - confirm before implementation. Configurable via `graceMs`. */
|
|
20
|
+
export declare const PRUNE_GRACE_MS: number;
|
|
21
|
+
export interface PruneDeps {
|
|
22
|
+
readonly store: HiveGraphStore;
|
|
23
|
+
readonly tenancy: Tenancy;
|
|
24
|
+
/** Whether a repo-relative path currently exists on disk. */
|
|
25
|
+
existsOnDisk(relPath: string): boolean;
|
|
26
|
+
/** ISO 8601 "now"; injectable for deterministic tests. */
|
|
27
|
+
now(): string;
|
|
28
|
+
/** Grace window in ms; defaults to {@link PRUNE_GRACE_MS}. */
|
|
29
|
+
readonly graceMs?: number;
|
|
30
|
+
/** true = delete (the destructive act); false/undefined = preview only. */
|
|
31
|
+
readonly confirm?: boolean;
|
|
32
|
+
out(line: string): void;
|
|
33
|
+
}
|
|
34
|
+
export interface PruneCandidate {
|
|
35
|
+
readonly nectar: string;
|
|
36
|
+
readonly path: string;
|
|
37
|
+
readonly lastUpdateDate: string;
|
|
38
|
+
readonly ageMs: number;
|
|
39
|
+
}
|
|
40
|
+
export interface PruneResult {
|
|
41
|
+
readonly candidates: readonly PruneCandidate[];
|
|
42
|
+
readonly deleted: number;
|
|
43
|
+
readonly confirmed: boolean;
|
|
44
|
+
}
|
|
45
|
+
/** Compute the prune candidates: latest path absent from disk AND older than the grace window. */
|
|
46
|
+
export declare function findPruneCandidates(deps: PruneDeps): PruneCandidate[];
|
|
47
|
+
export declare function runPrune(deps: PruneDeps): PruneResult;
|
|
48
|
+
//# sourceMappingURL=prune-cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prune-cli.d.ts","sourceRoot":"","sources":["../../src/registration/prune-cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAGtD,yGAAyG;AACzG,eAAO,MAAM,cAAc,QAA2B,CAAC;AAEvD,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,6DAA6D;IAC7D,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IACvC,0DAA0D;IAC1D,GAAG,IAAI,MAAM,CAAC;IACd,8DAA8D;IAC9D,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,UAAU,EAAE,SAAS,cAAc,EAAE,CAAC;IAC/C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED,kGAAkG;AAClG,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,GAAG,cAAc,EAAE,CAcrE;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,WAAW,CAoCrD"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { inTenancy } from "../hive-graph/model.js";
|
|
2
|
+
/** Prune grace period: 30 days - DEFAULT - confirm before implementation. Configurable via `graceMs`. */
|
|
3
|
+
export const PRUNE_GRACE_MS = 30 * 24 * 60 * 60 * 1000;
|
|
4
|
+
/** Compute the prune candidates: latest path absent from disk AND older than the grace window. */
|
|
5
|
+
export function findPruneCandidates(deps) {
|
|
6
|
+
const graceMs = deps.graceMs ?? PRUNE_GRACE_MS;
|
|
7
|
+
const nowMs = Date.parse(deps.now());
|
|
8
|
+
const out = [];
|
|
9
|
+
for (const lv of deps.store.listLatestVersions(deps.tenancy)) {
|
|
10
|
+
if (deps.existsOnDisk(lv.version.path))
|
|
11
|
+
continue;
|
|
12
|
+
const lastMs = Date.parse(lv.identity.lastUpdateDate);
|
|
13
|
+
const ageMs = Number.isNaN(lastMs) ? Number.POSITIVE_INFINITY : nowMs - lastMs;
|
|
14
|
+
if (ageMs > graceMs) {
|
|
15
|
+
out.push({ nectar: lv.identity.nectar, path: lv.version.path, lastUpdateDate: lv.identity.lastUpdateDate, ageMs });
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
out.sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0));
|
|
19
|
+
return out;
|
|
20
|
+
}
|
|
21
|
+
export function runPrune(deps) {
|
|
22
|
+
const candidates = findPruneCandidates(deps);
|
|
23
|
+
const confirmed = deps.confirm === true;
|
|
24
|
+
if (candidates.length === 0) {
|
|
25
|
+
deps.out("Nothing to prune: no nectar is missing beyond the grace period.");
|
|
26
|
+
return { candidates, deleted: 0, confirmed };
|
|
27
|
+
}
|
|
28
|
+
if (!confirmed) {
|
|
29
|
+
deps.out(`${candidates.length} nectar(s) missing beyond the grace period (preview only):`);
|
|
30
|
+
for (const c of candidates) {
|
|
31
|
+
const days = Math.floor(c.ageMs / (24 * 60 * 60 * 1000));
|
|
32
|
+
deps.out(` ${c.nectar} ${c.path} (missing/last-updated ${c.lastUpdateDate}, ~${days}d)`);
|
|
33
|
+
}
|
|
34
|
+
deps.out("Run 'nectar prune --confirm' to delete these nectars. This is the only deletion path.");
|
|
35
|
+
return { candidates, deleted: 0, confirmed: false };
|
|
36
|
+
}
|
|
37
|
+
let deleted = 0;
|
|
38
|
+
for (const c of candidates) {
|
|
39
|
+
// Re-check ELIGIBILITY immediately before each destructive delete: the file
|
|
40
|
+
// may have reappeared (path returned to disk) between candidate computation
|
|
41
|
+
// and now, in which case it is no longer a prune candidate and must be kept.
|
|
42
|
+
if (deps.existsOnDisk(c.path))
|
|
43
|
+
continue;
|
|
44
|
+
// Defense in depth: re-verify the identity is in scope, even though candidates
|
|
45
|
+
// already come from a scoped listLatestVersions. The delete itself is
|
|
46
|
+
// tenancy-scoped too (AC-20).
|
|
47
|
+
const identity = deps.store.getIdentity(c.nectar);
|
|
48
|
+
if (identity === undefined || !inTenancy(identity, deps.tenancy))
|
|
49
|
+
continue;
|
|
50
|
+
deps.store.deleteNectar(deps.tenancy, c.nectar);
|
|
51
|
+
deps.out(`pruned ${c.nectar} (${c.path})`);
|
|
52
|
+
deleted += 1;
|
|
53
|
+
}
|
|
54
|
+
deps.out(`Pruned ${deleted} nectar(s).`);
|
|
55
|
+
return { candidates, deleted, confirmed: true };
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=prune-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prune-cli.js","sourceRoot":"","sources":["../../src/registration/prune-cli.ts"],"names":[],"mappings":"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"}
|