@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,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared `node:sqlite` plumbing for nectar's local telemetry database
|
|
3
|
+
* (PRD-017, doctor ADR-0001 / ADR-0002).
|
|
4
|
+
*
|
|
5
|
+
* ONE physical file (`~/.honeycomb/telemetry/nectar.sqlite` by default),
|
|
6
|
+
* three tables, per the pinned Contract B shared with doctor:
|
|
7
|
+
* - `service_status` single row (id=1, latest-wins): binding time, last-seen,
|
|
8
|
+
* health, and Deep Lake connectivity (PRD-017a).
|
|
9
|
+
* - `service_metrics` single row (id=1, latest-wins): the 5 since-restart
|
|
10
|
+
* pipeline counters (PRD-017b).
|
|
11
|
+
* - `service_logs` append-only, bounded/rotated by `logs.ts` (PRD-017c).
|
|
12
|
+
*
|
|
13
|
+
* Mirrors honeycomb's `daemon/runtime/logs/log-store.ts` precedent: `node:sqlite`
|
|
14
|
+
* is loaded via a DYNAMIC `require` (never a top-level import), so a Node that
|
|
15
|
+
* lacks the module (older than 22.5, or missing `--experimental-sqlite`) throws
|
|
16
|
+
* HERE and is caught by the fail-soft facade in `index.ts` (AC-7 / AC-017a's
|
|
17
|
+
* "never blocks boot or the pipeline"), rather than crashing at module load.
|
|
18
|
+
*
|
|
19
|
+
* WAL mode is set on open so doctor's read-only poller (~1s cadence, per
|
|
20
|
+
* ADR-0001) never contends with nectar's own writes. doctor is the ONLY
|
|
21
|
+
* external reader, and it opens read-only; this module is nectar's write
|
|
22
|
+
* side only.
|
|
23
|
+
*/
|
|
24
|
+
import { chmodSync, mkdirSync } from "node:fs";
|
|
25
|
+
import { createRequire } from "node:module";
|
|
26
|
+
import { homedir } from "node:os";
|
|
27
|
+
import { dirname, join } from "node:path";
|
|
28
|
+
import { RUNTIME_DIR_NAME } from "../config.js";
|
|
29
|
+
/** The subdirectory of the runtime dir the telemetry database lives under. */
|
|
30
|
+
export const TELEMETRY_DIR_NAME = "telemetry";
|
|
31
|
+
/** The telemetry database's filename, matching doctor's per-service naming (`<name>.sqlite`). */
|
|
32
|
+
export const TELEMETRY_DB_FILE_NAME = "nectar.sqlite";
|
|
33
|
+
/** Derive the telemetry DB path from a resolved runtime dir (keeps it alongside the pid/lock files). */
|
|
34
|
+
export function telemetryDbPathForRuntimeDir(runtimeDir) {
|
|
35
|
+
return join(runtimeDir, TELEMETRY_DIR_NAME, TELEMETRY_DB_FILE_NAME);
|
|
36
|
+
}
|
|
37
|
+
/** The default telemetry DB path: `~/.honeycomb/telemetry/nectar.sqlite`. */
|
|
38
|
+
export function defaultTelemetryDbPath(home = homedir()) {
|
|
39
|
+
return telemetryDbPathForRuntimeDir(join(home, RUNTIME_DIR_NAME));
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Load `node:sqlite` via a dynamic `require` (via `module.createRequire`, so it
|
|
43
|
+
* works under ESM) rather than a top-level import: a Node build without the
|
|
44
|
+
* module/flag throws HERE, inside the caller's try/catch, instead of crashing
|
|
45
|
+
* the whole daemon bundle at load time.
|
|
46
|
+
*/
|
|
47
|
+
function loadSqlite() {
|
|
48
|
+
const req = createRequire(import.meta.url);
|
|
49
|
+
return req("node:sqlite");
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Open (or create) the telemetry database at `dbPath` in WAL mode, creating all
|
|
53
|
+
* three tables (idempotent, additive) if absent. Throws on any failure (missing
|
|
54
|
+
* `node:sqlite`, an unwritable directory, a corrupt file, ...); the caller
|
|
55
|
+
* (`index.ts`'s `createTelemetry`) catches and degrades to a no-op rather than
|
|
56
|
+
* ever propagating into daemon boot or the nectar pipeline.
|
|
57
|
+
*/
|
|
58
|
+
export function openTelemetryDb(dbPath) {
|
|
59
|
+
const dbDir = dirname(dbPath);
|
|
60
|
+
// SECURITY (security-review finding, medium): owner-only mode, matching honeycomb's
|
|
61
|
+
// fleet-store.ts precedent. Without it, the default umask on a multi-user host often
|
|
62
|
+
// yields a world-readable/traversable directory, letting another local user read
|
|
63
|
+
// service_logs (paths, errors, partially-redacted text) and operational metrics.
|
|
64
|
+
mkdirSync(dbDir, { recursive: true, mode: 0o700 });
|
|
65
|
+
// mkdirSync's mode only applies to directories it CREATES; a telemetry dir
|
|
66
|
+
// left behind by a pre-fix install keeps its broader bits, so enforce
|
|
67
|
+
// owner-only explicitly too. POSIX mode bits are meaningless on Windows.
|
|
68
|
+
if (process.platform !== "win32")
|
|
69
|
+
chmodSync(dbDir, 0o700);
|
|
70
|
+
const sqlite = loadSqlite();
|
|
71
|
+
const db = new sqlite.DatabaseSync(dbPath);
|
|
72
|
+
try {
|
|
73
|
+
db.exec("PRAGMA journal_mode = WAL");
|
|
74
|
+
migrateSchema(db);
|
|
75
|
+
return db;
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
// Close the native handle before rethrowing into the fail-soft fallback,
|
|
79
|
+
// so a half-initialized open never leaks a descriptor/lock on the db path.
|
|
80
|
+
try {
|
|
81
|
+
db.close();
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// ignore cleanup failures on the fail-soft path
|
|
85
|
+
}
|
|
86
|
+
throw err;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Create the three telemetry tables + the log index if absent. Column/table
|
|
91
|
+
* names are fixed literal constants under our own control (never interpolated
|
|
92
|
+
* user input), matching the pinned Contract B schema doctor's poller reads
|
|
93
|
+
* verbatim - schema drift here is a cross-repo break, not a local style choice.
|
|
94
|
+
*/
|
|
95
|
+
function migrateSchema(db) {
|
|
96
|
+
db.exec(`CREATE TABLE IF NOT EXISTS service_status (
|
|
97
|
+
id INTEGER PRIMARY KEY CHECK (id = 1),
|
|
98
|
+
name TEXT NOT NULL,
|
|
99
|
+
binding_time TEXT NOT NULL,
|
|
100
|
+
last_seen TEXT NOT NULL,
|
|
101
|
+
health TEXT NOT NULL,
|
|
102
|
+
deeplake_connected INTEGER,
|
|
103
|
+
deeplake_last_comm TEXT
|
|
104
|
+
)`);
|
|
105
|
+
db.exec(`CREATE TABLE IF NOT EXISTS service_metrics (
|
|
106
|
+
id INTEGER PRIMARY KEY CHECK (id = 1),
|
|
107
|
+
files_registered INTEGER NOT NULL DEFAULT 0,
|
|
108
|
+
nectars_minted INTEGER NOT NULL DEFAULT 0,
|
|
109
|
+
descriptions_generated INTEGER NOT NULL DEFAULT 0,
|
|
110
|
+
hive_graph_versions INTEGER NOT NULL DEFAULT 0,
|
|
111
|
+
embeddings_computed INTEGER NOT NULL DEFAULT 0,
|
|
112
|
+
updated_at TEXT NOT NULL
|
|
113
|
+
)`);
|
|
114
|
+
db.exec(`CREATE TABLE IF NOT EXISTS service_logs (
|
|
115
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
116
|
+
ts TEXT NOT NULL,
|
|
117
|
+
level TEXT NOT NULL CHECK (level IN ('error','warn','info','debug')),
|
|
118
|
+
message TEXT NOT NULL
|
|
119
|
+
)`);
|
|
120
|
+
db.exec("CREATE INDEX IF NOT EXISTS idx_service_logs_ts ON service_logs(ts DESC)");
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=db.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/telemetry/db.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD,8EAA8E;AAC9E,MAAM,CAAC,MAAM,kBAAkB,GAAG,WAAW,CAAC;AAC9C,iGAAiG;AACjG,MAAM,CAAC,MAAM,sBAAsB,GAAG,eAAe,CAAC;AAEtD,wGAAwG;AACxG,MAAM,UAAU,4BAA4B,CAAC,UAAkB;IAC7D,OAAO,IAAI,CAAC,UAAU,EAAE,kBAAkB,EAAE,sBAAsB,CAAC,CAAC;AACtE,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,sBAAsB,CAAC,OAAe,OAAO,EAAE;IAC7D,OAAO,4BAA4B,CAAC,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC;AACpE,CAAC;AAuBD;;;;;GAKG;AACH,SAAS,UAAU;IACjB,MAAM,GAAG,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC3C,OAAO,GAAG,CAAC,aAAa,CAAiB,CAAC;AAC5C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,MAAc;IAC5C,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9B,oFAAoF;IACpF,qFAAqF;IACrF,iFAAiF;IACjF,iFAAiF;IACjF,SAAS,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACnD,2EAA2E;IAC3E,sEAAsE;IACtE,yEAAyE;IACzE,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;QAAE,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC1D,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,EAAE,GAAG,IAAI,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IAC3C,IAAI,CAAC;QACH,EAAE,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;QACrC,aAAa,CAAC,EAAE,CAAC,CAAC;QAClB,OAAO,EAAE,CAAC;IACZ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,yEAAyE;QACzE,2EAA2E;QAC3E,IAAI,CAAC;YACH,EAAE,CAAC,KAAK,EAAE,CAAC;QACb,CAAC;QAAC,MAAM,CAAC;YACP,gDAAgD;QAClD,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAS,aAAa,CAAC,EAAsB;IAC3C,EAAE,CAAC,IAAI,CACL;;;;;;;;MAQE,CACH,CAAC;IACF,EAAE,CAAC,IAAI,CACL;;;;;;;;MAQE,CACH,CAAC;IACF,EAAE,CAAC,IAAI,CACL;;;;;MAKE,CACH,CAAC;IACF,EAAE,CAAC,IAAI,CAAC,yEAAyE,CAAC,CAAC;AACrF,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The fail-soft telemetry facade (PRD-017), composing the check-in, metrics,
|
|
3
|
+
* and log writers behind ONE object `daemon.ts` (and, later, the registration
|
|
4
|
+
* pipeline) depends on.
|
|
5
|
+
*
|
|
6
|
+
* `createTelemetry()` NEVER throws (AC-7): opening the local SQLite database
|
|
7
|
+
* (`node:sqlite`, WAL mode, `db.ts`) is wrapped in a try/catch, and a failure
|
|
8
|
+
* degrades to {@link NULL_TELEMETRY} - a no-op that keeps the daemon boot and
|
|
9
|
+
* the nectar pipeline completely unaffected. Every method on the real,
|
|
10
|
+
* DB-backed implementation is individually fail-soft too (see `checkin.ts`,
|
|
11
|
+
* `metrics.ts`, `logs.ts`), so a write failure MID-LIFE (a locked file, a full
|
|
12
|
+
* disk) degrades the same way a failed OPEN does.
|
|
13
|
+
*/
|
|
14
|
+
import type { PipelineStatus } from "../health.js";
|
|
15
|
+
import type { Timer } from "../poll-loop.js";
|
|
16
|
+
import type { AsyncHiveGraphStore, HiveGraphStore } from "../hive-graph/store.js";
|
|
17
|
+
import { type LogLevel } from "./logs.js";
|
|
18
|
+
import { type MetricsSnapshot, type PipelineMetricsSink } from "./metrics.js";
|
|
19
|
+
export { DEFAULT_HEARTBEAT_INTERVAL_MS, CheckinService, CheckinWriter, } from "./checkin.js";
|
|
20
|
+
export { defaultTelemetryDbPath, telemetryDbPathForRuntimeDir, TELEMETRY_DIR_NAME, TELEMETRY_DB_FILE_NAME, type SqliteDatabaseLike, } from "./db.js";
|
|
21
|
+
export { DEFAULT_LOG_MAX_AGE_MS, MAX_LOG_MESSAGE_LENGTH, LOG_LEVELS, LogWriter, createLogTap, redactLogMessage, levelFromLine, messageFromLine, type LogLevel, type LogSink, } from "./logs.js";
|
|
22
|
+
export { MetricsWriter, wrapStoreWithMetrics, wrapAsyncStoreWithMetrics, type MetricsSnapshot, type PipelineMetricsSink, } from "./metrics.js";
|
|
23
|
+
export interface StopHeartbeat {
|
|
24
|
+
(): void;
|
|
25
|
+
}
|
|
26
|
+
export interface StartCheckinOptions {
|
|
27
|
+
readonly intervalMs?: number;
|
|
28
|
+
readonly timer?: Timer;
|
|
29
|
+
}
|
|
30
|
+
export interface Telemetry {
|
|
31
|
+
/** False when the local SQLite telemetry store could not be opened (AC-7); every method below is then a no-op. */
|
|
32
|
+
readonly enabled: boolean;
|
|
33
|
+
/** The database path this instance was opened against (or would have been). */
|
|
34
|
+
readonly dbPath: string;
|
|
35
|
+
/** The 5-counter since-restart metrics sink (PRD-017b). A no-op sink when `enabled` is false. */
|
|
36
|
+
readonly metrics: PipelineMetricsSink;
|
|
37
|
+
/** Read back the current metrics snapshot (test/introspection convenience). */
|
|
38
|
+
metricsSnapshot(): MetricsSnapshot;
|
|
39
|
+
/** Check in once, then heartbeat on an interval until the returned stop function is called (PRD-017a). */
|
|
40
|
+
startCheckin(health: () => PipelineStatus, opts?: StartCheckinOptions): StopHeartbeat;
|
|
41
|
+
/** Mirror one log line into `service_logs` (PRD-017c). Prefer `createLogTap` to wrap an existing sink. */
|
|
42
|
+
log(level: LogLevel, message: string): void;
|
|
43
|
+
/** Wrap a `HiveGraphStore` so nectar mints and version writes increment their counters at the real write (PRD-017b). */
|
|
44
|
+
wrapStore<T extends HiveGraphStore>(store: T): T;
|
|
45
|
+
/**
|
|
46
|
+
* Wrap an `AsyncHiveGraphStore` (the durable Deep Lake substrate) so the same
|
|
47
|
+
* counters increment on the LIVE brood path (PRD-017b). This is what moves the
|
|
48
|
+
* `descriptionsGenerated` / `hiveGraphVersions` / `embeddingsComputed` counters
|
|
49
|
+
* off 0 once a real daemon broods against Deep Lake.
|
|
50
|
+
*/
|
|
51
|
+
wrapAsyncStore<T extends AsyncHiveGraphStore>(store: T): T;
|
|
52
|
+
/** Close the backing SQLite handle (idempotent, never throws). */
|
|
53
|
+
close(): void;
|
|
54
|
+
}
|
|
55
|
+
export interface CreateTelemetryOptions {
|
|
56
|
+
/** Override the database path (default: {@link defaultTelemetryDbPath}). */
|
|
57
|
+
readonly dbPath?: string;
|
|
58
|
+
/** ISO 8601 "now"; injectable for deterministic tests. */
|
|
59
|
+
now?(): string;
|
|
60
|
+
/** A one-time failure sink for the open failure (defaults to a single stderr write). Never called per-write. */
|
|
61
|
+
onceFailure?(message: string): void;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The no-op telemetry the daemon falls back to when the local SQLite store is
|
|
65
|
+
* unavailable (AC-7), and the placeholder `daemon.ts` holds before the first
|
|
66
|
+
* `start()` (constructing/importing the daemon must never touch disk).
|
|
67
|
+
*/
|
|
68
|
+
export declare function createNullTelemetry(dbPath: string): Telemetry;
|
|
69
|
+
/**
|
|
70
|
+
* Open nectar's telemetry store and return the composed facade. NEVER
|
|
71
|
+
* throws: an open failure is reported ONCE (never per-write) and this returns
|
|
72
|
+
* {@link nullTelemetry} so the caller's boot sequence is completely unaffected
|
|
73
|
+
* (AC-7).
|
|
74
|
+
*/
|
|
75
|
+
export declare function createTelemetry(opts?: CreateTelemetryOptions): Telemetry;
|
|
76
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/telemetry/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAGlF,OAAO,EAAa,KAAK,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAIL,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACzB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,6BAA6B,EAC7B,cAAc,EACd,aAAa,GACd,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,sBAAsB,EACtB,4BAA4B,EAC5B,kBAAkB,EAClB,sBAAsB,EACtB,KAAK,kBAAkB,GACxB,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,UAAU,EACV,SAAS,EACT,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,KAAK,QAAQ,EACb,KAAK,OAAO,GACb,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,yBAAyB,EACzB,KAAK,eAAe,EACpB,KAAK,mBAAmB,GACzB,MAAM,cAAc,CAAC;AAEtB,MAAM,WAAW,aAAa;IAC5B,IAAI,IAAI,CAAC;CACV;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;CACxB;AAED,MAAM,WAAW,SAAS;IACxB,kHAAkH;IAClH,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,+EAA+E;IAC/E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,iGAAiG;IACjG,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAC;IACtC,+EAA+E;IAC/E,eAAe,IAAI,eAAe,CAAC;IACnC,0GAA0G;IAC1G,YAAY,CAAC,MAAM,EAAE,MAAM,cAAc,EAAE,IAAI,CAAC,EAAE,mBAAmB,GAAG,aAAa,CAAC;IACtF,0GAA0G;IAC1G,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,wHAAwH;IACxH,SAAS,CAAC,CAAC,SAAS,cAAc,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC;IACjD;;;;;OAKG;IACH,cAAc,CAAC,CAAC,SAAS,mBAAmB,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC;IAC3D,kEAAkE;IAClE,KAAK,IAAI,IAAI,CAAC;CACf;AAED,MAAM,WAAW,sBAAsB;IACrC,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,0DAA0D;IAC1D,GAAG,CAAC,IAAI,MAAM,CAAC;IACf,gHAAgH;IAChH,WAAW,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAWD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAyB7D;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,GAAE,sBAA2B,GAAG,SAAS,CA2C5E"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { CheckinService, CheckinWriter } from "./checkin.js";
|
|
2
|
+
import { defaultTelemetryDbPath, openTelemetryDb } from "./db.js";
|
|
3
|
+
import { LogWriter } from "./logs.js";
|
|
4
|
+
import { MetricsWriter, wrapAsyncStoreWithMetrics, wrapStoreWithMetrics, } from "./metrics.js";
|
|
5
|
+
export { DEFAULT_HEARTBEAT_INTERVAL_MS, CheckinService, CheckinWriter, } from "./checkin.js";
|
|
6
|
+
export { defaultTelemetryDbPath, telemetryDbPathForRuntimeDir, TELEMETRY_DIR_NAME, TELEMETRY_DB_FILE_NAME, } from "./db.js";
|
|
7
|
+
export { DEFAULT_LOG_MAX_AGE_MS, MAX_LOG_MESSAGE_LENGTH, LOG_LEVELS, LogWriter, createLogTap, redactLogMessage, levelFromLine, messageFromLine, } from "./logs.js";
|
|
8
|
+
export { MetricsWriter, wrapStoreWithMetrics, wrapAsyncStoreWithMetrics, } from "./metrics.js";
|
|
9
|
+
function defaultOnceFailure() {
|
|
10
|
+
let fired = false;
|
|
11
|
+
return (message) => {
|
|
12
|
+
if (fired)
|
|
13
|
+
return;
|
|
14
|
+
fired = true;
|
|
15
|
+
process.stderr.write(`${message}\n`);
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The no-op telemetry the daemon falls back to when the local SQLite store is
|
|
20
|
+
* unavailable (AC-7), and the placeholder `daemon.ts` holds before the first
|
|
21
|
+
* `start()` (constructing/importing the daemon must never touch disk).
|
|
22
|
+
*/
|
|
23
|
+
export function createNullTelemetry(dbPath) {
|
|
24
|
+
const noopMetrics = {
|
|
25
|
+
incrementFilesRegistered() { },
|
|
26
|
+
incrementNectarsMinted() { },
|
|
27
|
+
incrementDescriptionsGenerated() { },
|
|
28
|
+
incrementHiveGraphVersions() { },
|
|
29
|
+
incrementEmbeddingsComputed() { },
|
|
30
|
+
};
|
|
31
|
+
return {
|
|
32
|
+
enabled: false,
|
|
33
|
+
dbPath,
|
|
34
|
+
metrics: noopMetrics,
|
|
35
|
+
metricsSnapshot: () => ({
|
|
36
|
+
filesRegistered: 0,
|
|
37
|
+
nectarsMinted: 0,
|
|
38
|
+
descriptionsGenerated: 0,
|
|
39
|
+
hiveGraphVersions: 0,
|
|
40
|
+
embeddingsComputed: 0,
|
|
41
|
+
}),
|
|
42
|
+
startCheckin: () => () => { },
|
|
43
|
+
log: () => { },
|
|
44
|
+
wrapStore: (store) => store,
|
|
45
|
+
wrapAsyncStore: (store) => store,
|
|
46
|
+
close: () => { },
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Open nectar's telemetry store and return the composed facade. NEVER
|
|
51
|
+
* throws: an open failure is reported ONCE (never per-write) and this returns
|
|
52
|
+
* {@link nullTelemetry} so the caller's boot sequence is completely unaffected
|
|
53
|
+
* (AC-7).
|
|
54
|
+
*/
|
|
55
|
+
export function createTelemetry(opts = {}) {
|
|
56
|
+
const dbPath = opts.dbPath ?? defaultTelemetryDbPath();
|
|
57
|
+
const onceFailure = opts.onceFailure ?? defaultOnceFailure();
|
|
58
|
+
let db;
|
|
59
|
+
try {
|
|
60
|
+
db = openTelemetryDb(dbPath);
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
64
|
+
onceFailure(`nectar: telemetry unavailable (non-fatal), continuing without it: ${reason}`);
|
|
65
|
+
return createNullTelemetry(dbPath);
|
|
66
|
+
}
|
|
67
|
+
const checkinWriter = new CheckinWriter({ db, now: opts.now });
|
|
68
|
+
const metricsWriter = new MetricsWriter({ db, now: opts.now });
|
|
69
|
+
const logWriter = new LogWriter({ db, now: opts.now });
|
|
70
|
+
return {
|
|
71
|
+
enabled: true,
|
|
72
|
+
dbPath,
|
|
73
|
+
metrics: metricsWriter,
|
|
74
|
+
metricsSnapshot: () => metricsWriter.snapshot(),
|
|
75
|
+
startCheckin: (health, startOpts = {}) => {
|
|
76
|
+
const service = new CheckinService({
|
|
77
|
+
writer: checkinWriter,
|
|
78
|
+
health,
|
|
79
|
+
intervalMs: startOpts.intervalMs,
|
|
80
|
+
timer: startOpts.timer,
|
|
81
|
+
});
|
|
82
|
+
service.start();
|
|
83
|
+
return () => service.stop();
|
|
84
|
+
},
|
|
85
|
+
log: (level, message) => logWriter.write(level, message),
|
|
86
|
+
wrapStore: (store) => wrapStoreWithMetrics(store, metricsWriter),
|
|
87
|
+
wrapAsyncStore: (store) => wrapAsyncStoreWithMetrics(store, metricsWriter),
|
|
88
|
+
close: () => {
|
|
89
|
+
try {
|
|
90
|
+
db.close();
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
// Closing an already-closed/errored handle must never throw out of shutdown.
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/telemetry/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bounded, rotated log emission to local SQLite (PRD-017c), per doctor's
|
|
3
|
+
* `ADR-0001-hive-telemetry-transport-and-single-source-of-truth.md`.
|
|
4
|
+
*
|
|
5
|
+
* `service_logs` is append-only but bounded: every write opportunistically
|
|
6
|
+
* rotates out rows older than {@link DEFAULT_LOG_MAX_AGE_MS} (AC-017c.2), so
|
|
7
|
+
* the store never grows without limit and stays cheap for doctor's ~1s
|
|
8
|
+
* poll cycle. The retention policy is an AGE bound (decision #33, 2026-07-02,
|
|
9
|
+
* `PRD-DECISIONS-AND-DEFAULTS.md`), superseding the original 5,000-row cap:
|
|
10
|
+
* a quiet daemon keeps at most a day of history instead of an unbounded-age
|
|
11
|
+
* tail of stale lines. Consumers are unaffected (doctor reads whatever
|
|
12
|
+
* rows exist).
|
|
13
|
+
*
|
|
14
|
+
* `createLogTap` mirrors nectar's EXISTING structured daemon log sink
|
|
15
|
+
* (`daemon.ts`'s `(line: Record<string, unknown>) => void`) into this table,
|
|
16
|
+
* rather than introducing a second logging framework: every line the daemon
|
|
17
|
+
* already logs to stderr is ALSO redacted and written here, unchanged in its
|
|
18
|
+
* original stderr behavior. nectar's structured log lines only ever carry
|
|
19
|
+
* scope/message/error-string/path fields (see `daemon.ts`, `registration/
|
|
20
|
+
* service.ts`) - never raw file content or an LLM description body - so the
|
|
21
|
+
* redaction pass below is defense-in-depth, not the sole guarantee.
|
|
22
|
+
*/
|
|
23
|
+
import type { SqliteDatabaseLike } from "./db.js";
|
|
24
|
+
export type LogLevel = "error" | "warn" | "info" | "debug";
|
|
25
|
+
export declare const LOG_LEVELS: readonly LogLevel[];
|
|
26
|
+
/** The maximum age a log row is retained (decision #33: 24h age bound, superseding Contract B's 5,000-row cap). */
|
|
27
|
+
export declare const DEFAULT_LOG_MAX_AGE_MS: number;
|
|
28
|
+
/**
|
|
29
|
+
* A message longer than this is dropped rather than written (PRD-017c: "if a
|
|
30
|
+
* line cannot be safely redacted it is dropped"). A nectar structured log
|
|
31
|
+
* line (scope + a short message + maybe a path/error string) is always well
|
|
32
|
+
* under this; anything longer is far more likely to be an accidentally-passed
|
|
33
|
+
* file body or LLM description than a real operational log line, so length
|
|
34
|
+
* alone is a cheap, effective backstop against exactly the two payloads
|
|
35
|
+
* AC-017c.3.2 forbids.
|
|
36
|
+
*/
|
|
37
|
+
export declare const MAX_LOG_MESSAGE_LENGTH = 2000;
|
|
38
|
+
/**
|
|
39
|
+
* Redact secret-shaped substrings from `message`. Returns null (drop the line
|
|
40
|
+
* entirely) when the message is too long to plausibly be a normal operational
|
|
41
|
+
* log line (AC-017c.3.2's "cannot be safely redacted" case).
|
|
42
|
+
*/
|
|
43
|
+
export declare function redactLogMessage(message: string): string | null;
|
|
44
|
+
export interface LogWriterOptions {
|
|
45
|
+
readonly db: SqliteDatabaseLike;
|
|
46
|
+
/** Retention age bound in milliseconds (default: {@link DEFAULT_LOG_MAX_AGE_MS}). */
|
|
47
|
+
readonly maxAgeMs?: number;
|
|
48
|
+
/** ISO 8601 "now"; injectable for deterministic tests. */
|
|
49
|
+
now?(): string;
|
|
50
|
+
}
|
|
51
|
+
export declare class LogWriter {
|
|
52
|
+
private readonly db;
|
|
53
|
+
private readonly maxAgeMs;
|
|
54
|
+
private readonly nowFn;
|
|
55
|
+
constructor(opts: LogWriterOptions);
|
|
56
|
+
/** Append one log row (AC-017c.1.1/3.1) and rotate. Fail-soft (AC-7 / AC-017c). */
|
|
57
|
+
write(level: LogLevel, message: string): void;
|
|
58
|
+
/**
|
|
59
|
+
* Delete rows older than the `maxAgeMs` bound (AC-017c.2.1/2.2). ISO-8601 UTC
|
|
60
|
+
* timestamps compare correctly as strings, so the cutoff is a plain `<`.
|
|
61
|
+
* Fail-soft, including against a non-parseable injected "now" (no cutoff can
|
|
62
|
+
* be computed, so nothing is deleted rather than everything).
|
|
63
|
+
*/
|
|
64
|
+
private rotate;
|
|
65
|
+
}
|
|
66
|
+
/** Map a structured log line's `level` field to a declared verbosity, defaulting to "info". */
|
|
67
|
+
export declare function levelFromLine(line: Record<string, unknown>): LogLevel;
|
|
68
|
+
/** Render a structured log line (minus its `level`, stored in its own column) as the row's message text. */
|
|
69
|
+
export declare function messageFromLine(line: Record<string, unknown>): string;
|
|
70
|
+
/** The minimal sink `createLogTap` mirrors lines into (satisfied by the `Telemetry` facade in `index.ts`). */
|
|
71
|
+
export interface LogSink {
|
|
72
|
+
log(level: LogLevel, message: string): void;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Wrap nectar's existing structured log sink so every line is ALSO
|
|
76
|
+
* mirrored into the telemetry log table, unchanged in its original behavior
|
|
77
|
+
* (the wrapped sink is always called first, with the exact original line).
|
|
78
|
+
* A telemetry-mirror failure is swallowed here too, on top of `LogWriter`'s
|
|
79
|
+
* own fail-soft `write()`, so a telemetry hiccup can never affect the
|
|
80
|
+
* caller's real log sink.
|
|
81
|
+
*/
|
|
82
|
+
export declare function createLogTap(baseLog: (line: Record<string, unknown>) => void, sink: LogSink): (line: Record<string, unknown>) => void;
|
|
83
|
+
//# sourceMappingURL=logs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/telemetry/logs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAElD,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAC3D,eAAO,MAAM,UAAU,EAAE,SAAS,QAAQ,EAAuC,CAAC;AAElF,mHAAmH;AACnH,eAAO,MAAM,sBAAsB,QAAuB,CAAC;AAE3D;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,OAAQ,CAAC;AAQ5C;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAK/D;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,EAAE,kBAAkB,CAAC;IAChC,qFAAqF;IACrF,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,0DAA0D;IAC1D,GAAG,CAAC,IAAI,MAAM,CAAC;CAChB;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAqB;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;gBAEzB,IAAI,EAAE,gBAAgB;IAMlC,mFAAmF;IACnF,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAW7C;;;;;OAKG;IACH,OAAO,CAAC,MAAM;CAUf;AAOD,+FAA+F;AAC/F,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,QAAQ,CAErE;AAED,4GAA4G;AAC5G,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAOrE;AAED,8GAA8G;AAC9G,MAAM,WAAW,OAAO;IACtB,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7C;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,EAChD,IAAI,EAAE,OAAO,GACZ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CASzC"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
export const LOG_LEVELS = ["error", "warn", "info", "debug"];
|
|
2
|
+
/** The maximum age a log row is retained (decision #33: 24h age bound, superseding Contract B's 5,000-row cap). */
|
|
3
|
+
export const DEFAULT_LOG_MAX_AGE_MS = 24 * 60 * 60 * 1_000;
|
|
4
|
+
/**
|
|
5
|
+
* A message longer than this is dropped rather than written (PRD-017c: "if a
|
|
6
|
+
* line cannot be safely redacted it is dropped"). A nectar structured log
|
|
7
|
+
* line (scope + a short message + maybe a path/error string) is always well
|
|
8
|
+
* under this; anything longer is far more likely to be an accidentally-passed
|
|
9
|
+
* file body or LLM description than a real operational log line, so length
|
|
10
|
+
* alone is a cheap, effective backstop against exactly the two payloads
|
|
11
|
+
* AC-017c.3.2 forbids.
|
|
12
|
+
*/
|
|
13
|
+
export const MAX_LOG_MESSAGE_LENGTH = 2_000;
|
|
14
|
+
/** Secret-shaped substrings redacted before a line is written (defense-in-depth; see module doc). */
|
|
15
|
+
const SENSITIVE_PATTERNS = [
|
|
16
|
+
/\bBearer\s+[^\s"',}\]]+/gi,
|
|
17
|
+
/"?(authorization|api[_-]?key|apikey|access[_-]?token|refresh[_-]?token|secret|password|client[_-]?secret)"?\s*[:=]\s*"?[^",}\s]+"?/gi,
|
|
18
|
+
];
|
|
19
|
+
/**
|
|
20
|
+
* Redact secret-shaped substrings from `message`. Returns null (drop the line
|
|
21
|
+
* entirely) when the message is too long to plausibly be a normal operational
|
|
22
|
+
* log line (AC-017c.3.2's "cannot be safely redacted" case).
|
|
23
|
+
*/
|
|
24
|
+
export function redactLogMessage(message) {
|
|
25
|
+
if (message.length > MAX_LOG_MESSAGE_LENGTH)
|
|
26
|
+
return null;
|
|
27
|
+
let out = message;
|
|
28
|
+
for (const pattern of SENSITIVE_PATTERNS)
|
|
29
|
+
out = out.replace(pattern, "[REDACTED]");
|
|
30
|
+
return out;
|
|
31
|
+
}
|
|
32
|
+
export class LogWriter {
|
|
33
|
+
db;
|
|
34
|
+
maxAgeMs;
|
|
35
|
+
nowFn;
|
|
36
|
+
constructor(opts) {
|
|
37
|
+
this.db = opts.db;
|
|
38
|
+
this.maxAgeMs = Math.max(1, opts.maxAgeMs ?? DEFAULT_LOG_MAX_AGE_MS);
|
|
39
|
+
this.nowFn = opts.now ?? (() => new Date().toISOString());
|
|
40
|
+
}
|
|
41
|
+
/** Append one log row (AC-017c.1.1/3.1) and rotate. Fail-soft (AC-7 / AC-017c). */
|
|
42
|
+
write(level, message) {
|
|
43
|
+
const safeMessage = redactLogMessage(message);
|
|
44
|
+
if (safeMessage === null)
|
|
45
|
+
return; // unredactable/oversized: dropped, never written (AC-017c.3.2).
|
|
46
|
+
try {
|
|
47
|
+
this.db.prepare("INSERT INTO service_logs (ts, level, message) VALUES (?, ?, ?)").run(this.nowFn(), level, safeMessage);
|
|
48
|
+
this.rotate();
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
// fail-soft: a log write error never surfaces into the pipeline.
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Delete rows older than the `maxAgeMs` bound (AC-017c.2.1/2.2). ISO-8601 UTC
|
|
56
|
+
* timestamps compare correctly as strings, so the cutoff is a plain `<`.
|
|
57
|
+
* Fail-soft, including against a non-parseable injected "now" (no cutoff can
|
|
58
|
+
* be computed, so nothing is deleted rather than everything).
|
|
59
|
+
*/
|
|
60
|
+
rotate() {
|
|
61
|
+
try {
|
|
62
|
+
const nowMs = Date.parse(this.nowFn());
|
|
63
|
+
if (!Number.isFinite(nowMs))
|
|
64
|
+
return;
|
|
65
|
+
const cutoff = new Date(nowMs - this.maxAgeMs).toISOString();
|
|
66
|
+
this.db.prepare("DELETE FROM service_logs WHERE ts < ?").run(cutoff);
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
// fail-soft: a rotation error never surfaces into the pipeline.
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/** True iff `value` is one of the four declared verbosity levels. */
|
|
74
|
+
function isLogLevel(value) {
|
|
75
|
+
return typeof value === "string" && LOG_LEVELS.includes(value);
|
|
76
|
+
}
|
|
77
|
+
/** Map a structured log line's `level` field to a declared verbosity, defaulting to "info". */
|
|
78
|
+
export function levelFromLine(line) {
|
|
79
|
+
return isLogLevel(line["level"]) ? line["level"] : "info";
|
|
80
|
+
}
|
|
81
|
+
/** Render a structured log line (minus its `level`, stored in its own column) as the row's message text. */
|
|
82
|
+
export function messageFromLine(line) {
|
|
83
|
+
const { level: _level, ...rest } = line;
|
|
84
|
+
try {
|
|
85
|
+
return JSON.stringify(rest);
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return String(rest);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Wrap nectar's existing structured log sink so every line is ALSO
|
|
93
|
+
* mirrored into the telemetry log table, unchanged in its original behavior
|
|
94
|
+
* (the wrapped sink is always called first, with the exact original line).
|
|
95
|
+
* A telemetry-mirror failure is swallowed here too, on top of `LogWriter`'s
|
|
96
|
+
* own fail-soft `write()`, so a telemetry hiccup can never affect the
|
|
97
|
+
* caller's real log sink.
|
|
98
|
+
*/
|
|
99
|
+
export function createLogTap(baseLog, sink) {
|
|
100
|
+
return (line) => {
|
|
101
|
+
baseLog(line);
|
|
102
|
+
try {
|
|
103
|
+
sink.log(levelFromLine(line), messageFromLine(line));
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// fail-soft: never let the telemetry mirror affect the real log sink above.
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=logs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/telemetry/logs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { AsyncHiveGraphStore, HiveGraphStore } from "../hive-graph/store.js";
|
|
2
|
+
import type { SqliteDatabaseLike } from "./db.js";
|
|
3
|
+
export interface MetricsSnapshot {
|
|
4
|
+
readonly filesRegistered: number;
|
|
5
|
+
readonly nectarsMinted: number;
|
|
6
|
+
readonly descriptionsGenerated: number;
|
|
7
|
+
readonly hiveGraphVersions: number;
|
|
8
|
+
readonly embeddingsComputed: number;
|
|
9
|
+
}
|
|
10
|
+
/** The counter-increment surface pipeline touchpoints depend on (never the writer's SQLite internals). */
|
|
11
|
+
export interface PipelineMetricsSink {
|
|
12
|
+
/** One file processed through the re-association ladder (PRD-006), any outcome. */
|
|
13
|
+
incrementFilesRegistered(): void;
|
|
14
|
+
/** One fresh nectar minted (ladder step 5). */
|
|
15
|
+
incrementNectarsMinted(): void;
|
|
16
|
+
/** One LLM description produced (the enricher/brooding loop, PRD-007/PRD-016). */
|
|
17
|
+
incrementDescriptionsGenerated(): void;
|
|
18
|
+
/** One `hive_graph_versions` row written (PRD-005). */
|
|
19
|
+
incrementHiveGraphVersions(): void;
|
|
20
|
+
/** One embedding computed (PRD-014). */
|
|
21
|
+
incrementEmbeddingsComputed(): void;
|
|
22
|
+
}
|
|
23
|
+
export interface MetricsWriterOptions {
|
|
24
|
+
readonly db: SqliteDatabaseLike;
|
|
25
|
+
/** ISO 8601 "now"; injectable for deterministic tests. */
|
|
26
|
+
now?(): string;
|
|
27
|
+
}
|
|
28
|
+
export declare class MetricsWriter implements PipelineMetricsSink {
|
|
29
|
+
private readonly db;
|
|
30
|
+
private readonly nowFn;
|
|
31
|
+
private counts;
|
|
32
|
+
constructor(opts: MetricsWriterOptions);
|
|
33
|
+
snapshot(): MetricsSnapshot;
|
|
34
|
+
incrementFilesRegistered(): void;
|
|
35
|
+
incrementNectarsMinted(): void;
|
|
36
|
+
incrementDescriptionsGenerated(): void;
|
|
37
|
+
incrementHiveGraphVersions(): void;
|
|
38
|
+
incrementEmbeddingsComputed(): void;
|
|
39
|
+
private flush;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Wrap a {@link HiveGraphStore} so the two counters with a precise 1:1
|
|
43
|
+
* store-level definition increment at their REAL completion point, with ZERO
|
|
44
|
+
* changes to the ladder (`registration/ladder.ts`) or the store adapters:
|
|
45
|
+
*
|
|
46
|
+
* - `nectarsMinted`: one `insertIdentity()` call = one freshly minted nectar
|
|
47
|
+
* (the ladder's step-5 `mintOrCopy` is the only caller in this repo). A
|
|
48
|
+
* THROWING insert (duplicate nectar, the store's own dedup guard) never
|
|
49
|
+
* increments, because the throw happens before the increment line below -
|
|
50
|
+
* no double counting across a rejected mint.
|
|
51
|
+
* - `hiveGraphVersions`: one `appendVersion()` call = one
|
|
52
|
+
* `hive_graph_versions` row written (ladder steps 2/3/4/5), the exact
|
|
53
|
+
* PRD-005 catalog write.
|
|
54
|
+
*
|
|
55
|
+
* `descriptionsGenerated` and `embeddingsComputed` are wired to the CLOSEST
|
|
56
|
+
* REAL signal available in this repo today rather than a fabricated hook: a
|
|
57
|
+
* version row only ever carries `describeStatus === "described"` or a
|
|
58
|
+
* non-null `embedding` once the enricher (PRD-007/PRD-016) and the embeddings
|
|
59
|
+
* provider (PRD-014) actually populate those fields on the row they pass to
|
|
60
|
+
* `appendVersion`. Neither pipeline exists in this repo yet - `ladder.ts`'s
|
|
61
|
+
* `baseVersion()` always writes `title/description: ""`, `describeStatus:
|
|
62
|
+
* "pending"`, and `embedding: null` - so both counters correctly read 0 until
|
|
63
|
+
* those PRDs land. This is a documented, intentional approximation (see the
|
|
64
|
+
* PRD-017 ledger evidence): the day a future PRD starts writing a "described"
|
|
65
|
+
* row or a non-null embedding through this same `appendVersion` call, the
|
|
66
|
+
* counter starts moving with no further wiring required.
|
|
67
|
+
*/
|
|
68
|
+
export declare function wrapStoreWithMetrics<T extends HiveGraphStore>(store: T, sink: PipelineMetricsSink): T;
|
|
69
|
+
/**
|
|
70
|
+
* The async twin of {@link wrapStoreWithMetrics}: wrap an
|
|
71
|
+
* {@link AsyncHiveGraphStore} so the same four store-level counters increment at
|
|
72
|
+
* their REAL completion point on the LIVE (durable) brood path, with ZERO
|
|
73
|
+
* changes to `runBroodAsync` or the Deep Lake adapter. The increment fires only
|
|
74
|
+
* AFTER the awaited write resolves - a rejected `insertIdentity` (the mint dedup
|
|
75
|
+
* guard) or `appendVersion` never increments, because the `await` throws before
|
|
76
|
+
* the increment line. This is what makes the PRD-017b `descriptionsGenerated` /
|
|
77
|
+
* `hiveGraphVersions` / `embeddingsComputed` / `nectarsMinted` counters move in
|
|
78
|
+
* production once the daemon actually broods against Deep Lake (the counters that
|
|
79
|
+
* previously stayed 0 because the pipeline never ran on the live boot path).
|
|
80
|
+
*/
|
|
81
|
+
export declare function wrapAsyncStoreWithMetrics<T extends AsyncHiveGraphStore>(store: T, sink: PipelineMetricsSink): T;
|
|
82
|
+
//# sourceMappingURL=metrics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../src/telemetry/metrics.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAClF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAElD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACvC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;CACrC;AAED,0GAA0G;AAC1G,MAAM,WAAW,mBAAmB;IAClC,mFAAmF;IACnF,wBAAwB,IAAI,IAAI,CAAC;IACjC,+CAA+C;IAC/C,sBAAsB,IAAI,IAAI,CAAC;IAC/B,kFAAkF;IAClF,8BAA8B,IAAI,IAAI,CAAC;IACvC,uDAAuD;IACvD,0BAA0B,IAAI,IAAI,CAAC;IACnC,wCAAwC;IACxC,2BAA2B,IAAI,IAAI,CAAC;CACrC;AAoBD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,EAAE,kBAAkB,CAAC;IAChC,0DAA0D;IAC1D,GAAG,CAAC,IAAI,MAAM,CAAC;CAChB;AAED,qBAAa,aAAc,YAAW,mBAAmB;IACvD,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAqB;IACxC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;IACrC,OAAO,CAAC,MAAM,CAA+B;gBAEjC,IAAI,EAAE,oBAAoB;IAQtC,QAAQ,IAAI,eAAe;IAI3B,wBAAwB,IAAI,IAAI;IAKhC,sBAAsB,IAAI,IAAI;IAK9B,8BAA8B,IAAI,IAAI;IAKtC,0BAA0B,IAAI,IAAI;IAKlC,2BAA2B,IAAI,IAAI;IAKnC,OAAO,CAAC,KAAK;CA0Bd;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,cAAc,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,mBAAmB,GAAG,CAAC,CAoBrG;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CAAC,CAAC,SAAS,mBAAmB,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,mBAAmB,GAAG,CAAC,CAoB/G"}
|