@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.
Files changed (467) hide show
  1. package/LICENSE.md +662 -0
  2. package/README.md +307 -0
  3. package/dist/api/daemon-api-wiring.d.ts +72 -0
  4. package/dist/api/daemon-api-wiring.d.ts.map +1 -0
  5. package/dist/api/daemon-api-wiring.js +150 -0
  6. package/dist/api/daemon-api-wiring.js.map +1 -0
  7. package/dist/api/hive-graph-api.d.ts +136 -0
  8. package/dist/api/hive-graph-api.d.ts.map +1 -0
  9. package/dist/api/hive-graph-api.js +234 -0
  10. package/dist/api/hive-graph-api.js.map +1 -0
  11. package/dist/api/loopback-client.d.ts +27 -0
  12. package/dist/api/loopback-client.d.ts.map +1 -0
  13. package/dist/api/loopback-client.js +87 -0
  14. package/dist/api/loopback-client.js.map +1 -0
  15. package/dist/api/router.d.ts +172 -0
  16. package/dist/api/router.d.ts.map +1 -0
  17. package/dist/api/router.js +212 -0
  18. package/dist/api/router.js.map +1 -0
  19. package/dist/api/status-query.d.ts +49 -0
  20. package/dist/api/status-query.d.ts.map +1 -0
  21. package/dist/api/status-query.js +103 -0
  22. package/dist/api/status-query.js.map +1 -0
  23. package/dist/brood-guard.d.ts +24 -0
  24. package/dist/brood-guard.d.ts.map +1 -0
  25. package/dist/brood-guard.js +19 -0
  26. package/dist/brood-guard.js.map +1 -0
  27. package/dist/brood-prereqs.d.ts +62 -0
  28. package/dist/brood-prereqs.d.ts.map +1 -0
  29. package/dist/brood-prereqs.js +87 -0
  30. package/dist/brood-prereqs.js.map +1 -0
  31. package/dist/brooding/bucketing.d.ts +68 -0
  32. package/dist/brooding/bucketing.d.ts.map +1 -0
  33. package/dist/brooding/bucketing.js +122 -0
  34. package/dist/brooding/bucketing.js.map +1 -0
  35. package/dist/brooding/cli.d.ts +78 -0
  36. package/dist/brooding/cli.d.ts.map +1 -0
  37. package/dist/brooding/cli.js +140 -0
  38. package/dist/brooding/cli.js.map +1 -0
  39. package/dist/brooding/constants.d.ts +75 -0
  40. package/dist/brooding/constants.d.ts.map +1 -0
  41. package/dist/brooding/constants.js +91 -0
  42. package/dist/brooding/constants.js.map +1 -0
  43. package/dist/brooding/cost.d.ts +110 -0
  44. package/dist/brooding/cost.d.ts.map +1 -0
  45. package/dist/brooding/cost.js +96 -0
  46. package/dist/brooding/cost.js.map +1 -0
  47. package/dist/brooding/describe.d.ts +152 -0
  48. package/dist/brooding/describe.d.ts.map +1 -0
  49. package/dist/brooding/describe.js +281 -0
  50. package/dist/brooding/describe.js.map +1 -0
  51. package/dist/brooding/discovery.d.ts +116 -0
  52. package/dist/brooding/discovery.d.ts.map +1 -0
  53. package/dist/brooding/discovery.js +179 -0
  54. package/dist/brooding/discovery.js.map +1 -0
  55. package/dist/brooding/index.d.ts +23 -0
  56. package/dist/brooding/index.d.ts.map +1 -0
  57. package/dist/brooding/index.js +33 -0
  58. package/dist/brooding/index.js.map +1 -0
  59. package/dist/brooding/pipeline-async.d.ts +97 -0
  60. package/dist/brooding/pipeline-async.d.ts.map +1 -0
  61. package/dist/brooding/pipeline-async.js +364 -0
  62. package/dist/brooding/pipeline-async.js.map +1 -0
  63. package/dist/brooding/pipeline.d.ts +198 -0
  64. package/dist/brooding/pipeline.d.ts.map +1 -0
  65. package/dist/brooding/pipeline.js +454 -0
  66. package/dist/brooding/pipeline.js.map +1 -0
  67. package/dist/brooding/precheck.d.ts +52 -0
  68. package/dist/brooding/precheck.d.ts.map +1 -0
  69. package/dist/brooding/precheck.js +143 -0
  70. package/dist/brooding/precheck.js.map +1 -0
  71. package/dist/brooding/resumability.d.ts +57 -0
  72. package/dist/brooding/resumability.d.ts.map +1 -0
  73. package/dist/brooding/resumability.js +46 -0
  74. package/dist/brooding/resumability.js.map +1 -0
  75. package/dist/cli.d.ts +139 -0
  76. package/dist/cli.d.ts.map +1 -0
  77. package/dist/cli.js +912 -0
  78. package/dist/cli.js.map +1 -0
  79. package/dist/config-file.d.ts +52 -0
  80. package/dist/config-file.d.ts.map +1 -0
  81. package/dist/config-file.js +130 -0
  82. package/dist/config-file.js.map +1 -0
  83. package/dist/config.d.ts +49 -0
  84. package/dist/config.d.ts.map +1 -0
  85. package/dist/config.js +98 -0
  86. package/dist/config.js.map +1 -0
  87. package/dist/daemon.d.ts +265 -0
  88. package/dist/daemon.d.ts.map +1 -0
  89. package/dist/daemon.js +664 -0
  90. package/dist/daemon.js.map +1 -0
  91. package/dist/doctor-registry.d.ts +134 -0
  92. package/dist/doctor-registry.d.ts.map +1 -0
  93. package/dist/doctor-registry.js +173 -0
  94. package/dist/doctor-registry.js.map +1 -0
  95. package/dist/embeddings/cohere-portkey.d.ts +67 -0
  96. package/dist/embeddings/cohere-portkey.d.ts.map +1 -0
  97. package/dist/embeddings/cohere-portkey.js +171 -0
  98. package/dist/embeddings/cohere-portkey.js.map +1 -0
  99. package/dist/embeddings/config.d.ts +74 -0
  100. package/dist/embeddings/config.d.ts.map +1 -0
  101. package/dist/embeddings/config.js +131 -0
  102. package/dist/embeddings/config.js.map +1 -0
  103. package/dist/embeddings/guard.d.ts +34 -0
  104. package/dist/embeddings/guard.d.ts.map +1 -0
  105. package/dist/embeddings/guard.js +67 -0
  106. package/dist/embeddings/guard.js.map +1 -0
  107. package/dist/embeddings/hosted-portkey.d.ts +73 -0
  108. package/dist/embeddings/hosted-portkey.d.ts.map +1 -0
  109. package/dist/embeddings/hosted-portkey.js +179 -0
  110. package/dist/embeddings/hosted-portkey.js.map +1 -0
  111. package/dist/embeddings/http.d.ts +33 -0
  112. package/dist/embeddings/http.d.ts.map +1 -0
  113. package/dist/embeddings/http.js +19 -0
  114. package/dist/embeddings/http.js.map +1 -0
  115. package/dist/embeddings/index.d.ts +17 -0
  116. package/dist/embeddings/index.d.ts.map +1 -0
  117. package/dist/embeddings/index.js +17 -0
  118. package/dist/embeddings/index.js.map +1 -0
  119. package/dist/embeddings/local-nomic.d.ts +78 -0
  120. package/dist/embeddings/local-nomic.d.ts.map +1 -0
  121. package/dist/embeddings/local-nomic.js +126 -0
  122. package/dist/embeddings/local-nomic.js.map +1 -0
  123. package/dist/embeddings/provider.d.ts +79 -0
  124. package/dist/embeddings/provider.d.ts.map +1 -0
  125. package/dist/embeddings/provider.js +50 -0
  126. package/dist/embeddings/provider.js.map +1 -0
  127. package/dist/enricher/config.d.ts +43 -0
  128. package/dist/enricher/config.d.ts.map +1 -0
  129. package/dist/enricher/config.js +34 -0
  130. package/dist/enricher/config.js.map +1 -0
  131. package/dist/enricher/content-cache.d.ts +29 -0
  132. package/dist/enricher/content-cache.d.ts.map +1 -0
  133. package/dist/enricher/content-cache.js +24 -0
  134. package/dist/enricher/content-cache.js.map +1 -0
  135. package/dist/enricher/cycle.d.ts +71 -0
  136. package/dist/enricher/cycle.d.ts.map +1 -0
  137. package/dist/enricher/cycle.js +319 -0
  138. package/dist/enricher/cycle.js.map +1 -0
  139. package/dist/enricher/describe.d.ts +61 -0
  140. package/dist/enricher/describe.d.ts.map +1 -0
  141. package/dist/enricher/describe.js +175 -0
  142. package/dist/enricher/describe.js.map +1 -0
  143. package/dist/enricher/failure.d.ts +25 -0
  144. package/dist/enricher/failure.d.ts.map +1 -0
  145. package/dist/enricher/failure.js +46 -0
  146. package/dist/enricher/failure.js.map +1 -0
  147. package/dist/enricher/index.d.ts +22 -0
  148. package/dist/enricher/index.d.ts.map +1 -0
  149. package/dist/enricher/index.js +22 -0
  150. package/dist/enricher/index.js.map +1 -0
  151. package/dist/enricher/jaccard.d.ts +11 -0
  152. package/dist/enricher/jaccard.d.ts.map +1 -0
  153. package/dist/enricher/jaccard.js +29 -0
  154. package/dist/enricher/jaccard.js.map +1 -0
  155. package/dist/enricher/loop.d.ts +22 -0
  156. package/dist/enricher/loop.d.ts.map +1 -0
  157. package/dist/enricher/loop.js +34 -0
  158. package/dist/enricher/loop.js.map +1 -0
  159. package/dist/enricher/meaningful-change.d.ts +28 -0
  160. package/dist/enricher/meaningful-change.d.ts.map +1 -0
  161. package/dist/enricher/meaningful-change.js +41 -0
  162. package/dist/enricher/meaningful-change.js.map +1 -0
  163. package/dist/enricher/observability.d.ts +22 -0
  164. package/dist/enricher/observability.d.ts.map +1 -0
  165. package/dist/enricher/observability.js +55 -0
  166. package/dist/enricher/observability.js.map +1 -0
  167. package/dist/enricher/pending-query.d.ts +35 -0
  168. package/dist/enricher/pending-query.d.ts.map +1 -0
  169. package/dist/enricher/pending-query.js +54 -0
  170. package/dist/enricher/pending-query.js.map +1 -0
  171. package/dist/enricher/sql-update.d.ts +7 -0
  172. package/dist/enricher/sql-update.d.ts.map +1 -0
  173. package/dist/enricher/sql-update.js +22 -0
  174. package/dist/enricher/sql-update.js.map +1 -0
  175. package/dist/enricher/store-adapter.d.ts +98 -0
  176. package/dist/enricher/store-adapter.d.ts.map +1 -0
  177. package/dist/enricher/store-adapter.js +129 -0
  178. package/dist/enricher/store-adapter.js.map +1 -0
  179. package/dist/enricher/store.d.ts +58 -0
  180. package/dist/enricher/store.d.ts.map +1 -0
  181. package/dist/enricher/store.js +126 -0
  182. package/dist/enricher/store.js.map +1 -0
  183. package/dist/enricher/tokenize.d.ts +10 -0
  184. package/dist/enricher/tokenize.d.ts.map +1 -0
  185. package/dist/enricher/tokenize.js +28 -0
  186. package/dist/enricher/tokenize.js.map +1 -0
  187. package/dist/errors.d.ts +41 -0
  188. package/dist/errors.d.ts.map +1 -0
  189. package/dist/errors.js +56 -0
  190. package/dist/errors.js.map +1 -0
  191. package/dist/health.d.ts +147 -0
  192. package/dist/health.d.ts.map +1 -0
  193. package/dist/health.js +168 -0
  194. package/dist/health.js.map +1 -0
  195. package/dist/hive-graph/deeplake-credentials.d.ts +68 -0
  196. package/dist/hive-graph/deeplake-credentials.d.ts.map +1 -0
  197. package/dist/hive-graph/deeplake-credentials.js +135 -0
  198. package/dist/hive-graph/deeplake-credentials.js.map +1 -0
  199. package/dist/hive-graph/deeplake-heal.d.ts +63 -0
  200. package/dist/hive-graph/deeplake-heal.d.ts.map +1 -0
  201. package/dist/hive-graph/deeplake-heal.js +118 -0
  202. package/dist/hive-graph/deeplake-heal.js.map +1 -0
  203. package/dist/hive-graph/deeplake-store.d.ts +199 -0
  204. package/dist/hive-graph/deeplake-store.d.ts.map +1 -0
  205. package/dist/hive-graph/deeplake-store.js +541 -0
  206. package/dist/hive-graph/deeplake-store.js.map +1 -0
  207. package/dist/hive-graph/deeplake-transport.d.ts +89 -0
  208. package/dist/hive-graph/deeplake-transport.d.ts.map +1 -0
  209. package/dist/hive-graph/deeplake-transport.js +145 -0
  210. package/dist/hive-graph/deeplake-transport.js.map +1 -0
  211. package/dist/hive-graph/hash.d.ts +3 -0
  212. package/dist/hive-graph/hash.d.ts.map +1 -0
  213. package/dist/hive-graph/hash.js +12 -0
  214. package/dist/hive-graph/hash.js.map +1 -0
  215. package/dist/hive-graph/memory-store.d.ts +39 -0
  216. package/dist/hive-graph/memory-store.d.ts.map +1 -0
  217. package/dist/hive-graph/memory-store.js +125 -0
  218. package/dist/hive-graph/memory-store.js.map +1 -0
  219. package/dist/hive-graph/model.d.ts +109 -0
  220. package/dist/hive-graph/model.d.ts.map +1 -0
  221. package/dist/hive-graph/model.js +36 -0
  222. package/dist/hive-graph/model.js.map +1 -0
  223. package/dist/hive-graph/paths.d.ts +7 -0
  224. package/dist/hive-graph/paths.d.ts.map +1 -0
  225. package/dist/hive-graph/paths.js +26 -0
  226. package/dist/hive-graph/paths.js.map +1 -0
  227. package/dist/hive-graph/project-scope.d.ts +99 -0
  228. package/dist/hive-graph/project-scope.d.ts.map +1 -0
  229. package/dist/hive-graph/project-scope.js +286 -0
  230. package/dist/hive-graph/project-scope.js.map +1 -0
  231. package/dist/hive-graph/schema.d.ts +53 -0
  232. package/dist/hive-graph/schema.d.ts.map +1 -0
  233. package/dist/hive-graph/schema.js +139 -0
  234. package/dist/hive-graph/schema.js.map +1 -0
  235. package/dist/hive-graph/search-types.d.ts +82 -0
  236. package/dist/hive-graph/search-types.d.ts.map +1 -0
  237. package/dist/hive-graph/search-types.js +2 -0
  238. package/dist/hive-graph/search-types.js.map +1 -0
  239. package/dist/hive-graph/search.d.ts +51 -0
  240. package/dist/hive-graph/search.d.ts.map +1 -0
  241. package/dist/hive-graph/search.js +417 -0
  242. package/dist/hive-graph/search.js.map +1 -0
  243. package/dist/hive-graph/sql-guards.d.ts +99 -0
  244. package/dist/hive-graph/sql-guards.d.ts.map +1 -0
  245. package/dist/hive-graph/sql-guards.js +129 -0
  246. package/dist/hive-graph/sql-guards.js.map +1 -0
  247. package/dist/hive-graph/store.d.ts +151 -0
  248. package/dist/hive-graph/store.d.ts.map +1 -0
  249. package/dist/hive-graph/store.js +2 -0
  250. package/dist/hive-graph/store.js.map +1 -0
  251. package/dist/hive-graph/ulid.d.ts +14 -0
  252. package/dist/hive-graph/ulid.d.ts.map +1 -0
  253. package/dist/hive-graph/ulid.js +109 -0
  254. package/dist/hive-graph/ulid.js.map +1 -0
  255. package/dist/hivedoctor-registry.d.ts +111 -0
  256. package/dist/hivedoctor-registry.d.ts.map +1 -0
  257. package/dist/hivedoctor-registry.js +143 -0
  258. package/dist/hivedoctor-registry.js.map +1 -0
  259. package/dist/index.d.ts +106 -0
  260. package/dist/index.d.ts.map +1 -0
  261. package/dist/index.js +78 -0
  262. package/dist/index.js.map +1 -0
  263. package/dist/lock.d.ts +66 -0
  264. package/dist/lock.d.ts.map +1 -0
  265. package/dist/lock.js +282 -0
  266. package/dist/lock.js.map +1 -0
  267. package/dist/poll-loop.d.ts +71 -0
  268. package/dist/poll-loop.d.ts.map +1 -0
  269. package/dist/poll-loop.js +130 -0
  270. package/dist/poll-loop.js.map +1 -0
  271. package/dist/portkey/config.d.ts +46 -0
  272. package/dist/portkey/config.d.ts.map +1 -0
  273. package/dist/portkey/config.js +68 -0
  274. package/dist/portkey/config.js.map +1 -0
  275. package/dist/portkey/describe-model.d.ts +53 -0
  276. package/dist/portkey/describe-model.d.ts.map +1 -0
  277. package/dist/portkey/describe-model.js +56 -0
  278. package/dist/portkey/describe-model.js.map +1 -0
  279. package/dist/portkey/headers.d.ts +31 -0
  280. package/dist/portkey/headers.d.ts.map +1 -0
  281. package/dist/portkey/headers.js +37 -0
  282. package/dist/portkey/headers.js.map +1 -0
  283. package/dist/portkey/transport.d.ts +89 -0
  284. package/dist/portkey/transport.d.ts.map +1 -0
  285. package/dist/portkey/transport.js +167 -0
  286. package/dist/portkey/transport.js.map +1 -0
  287. package/dist/projection/format.d.ts +51 -0
  288. package/dist/projection/format.d.ts.map +1 -0
  289. package/dist/projection/format.js +81 -0
  290. package/dist/projection/format.js.map +1 -0
  291. package/dist/projection/generate.d.ts +31 -0
  292. package/dist/projection/generate.d.ts.map +1 -0
  293. package/dist/projection/generate.js +83 -0
  294. package/dist/projection/generate.js.map +1 -0
  295. package/dist/projection/inherit.d.ts +27 -0
  296. package/dist/projection/inherit.d.ts.map +1 -0
  297. package/dist/projection/inherit.js +128 -0
  298. package/dist/projection/inherit.js.map +1 -0
  299. package/dist/projection/load.d.ts +47 -0
  300. package/dist/projection/load.d.ts.map +1 -0
  301. package/dist/projection/load.js +258 -0
  302. package/dist/projection/load.js.map +1 -0
  303. package/dist/projection/store-adapter.d.ts +42 -0
  304. package/dist/projection/store-adapter.d.ts.map +1 -0
  305. package/dist/projection/store-adapter.js +42 -0
  306. package/dist/projection/store-adapter.js.map +1 -0
  307. package/dist/projection/write.d.ts +79 -0
  308. package/dist/projection/write.d.ts.map +1 -0
  309. package/dist/projection/write.js +122 -0
  310. package/dist/projection/write.js.map +1 -0
  311. package/dist/registration/classify.d.ts +33 -0
  312. package/dist/registration/classify.d.ts.map +1 -0
  313. package/dist/registration/classify.js +32 -0
  314. package/dist/registration/classify.js.map +1 -0
  315. package/dist/registration/copy-detect.d.ts +22 -0
  316. package/dist/registration/copy-detect.d.ts.map +1 -0
  317. package/dist/registration/copy-detect.js +12 -0
  318. package/dist/registration/copy-detect.js.map +1 -0
  319. package/dist/registration/disk-fs.d.ts +41 -0
  320. package/dist/registration/disk-fs.d.ts.map +1 -0
  321. package/dist/registration/disk-fs.js +175 -0
  322. package/dist/registration/disk-fs.js.map +1 -0
  323. package/dist/registration/fs-watch.d.ts +114 -0
  324. package/dist/registration/fs-watch.d.ts.map +1 -0
  325. package/dist/registration/fs-watch.js +266 -0
  326. package/dist/registration/fs-watch.js.map +1 -0
  327. package/dist/registration/ignore.d.ts +77 -0
  328. package/dist/registration/ignore.d.ts.map +1 -0
  329. package/dist/registration/ignore.js +249 -0
  330. package/dist/registration/ignore.js.map +1 -0
  331. package/dist/registration/ladder.d.ts +211 -0
  332. package/dist/registration/ladder.d.ts.map +1 -0
  333. package/dist/registration/ladder.js +378 -0
  334. package/dist/registration/ladder.js.map +1 -0
  335. package/dist/registration/paths-safe.d.ts +21 -0
  336. package/dist/registration/paths-safe.d.ts.map +1 -0
  337. package/dist/registration/paths-safe.js +88 -0
  338. package/dist/registration/paths-safe.js.map +1 -0
  339. package/dist/registration/prune-cli.d.ts +48 -0
  340. package/dist/registration/prune-cli.d.ts.map +1 -0
  341. package/dist/registration/prune-cli.js +57 -0
  342. package/dist/registration/prune-cli.js.map +1 -0
  343. package/dist/registration/review-cli.d.ts +42 -0
  344. package/dist/registration/review-cli.d.ts.map +1 -0
  345. package/dist/registration/review-cli.js +110 -0
  346. package/dist/registration/review-cli.js.map +1 -0
  347. package/dist/registration/review-store.d.ts +73 -0
  348. package/dist/registration/review-store.d.ts.map +1 -0
  349. package/dist/registration/review-store.js +243 -0
  350. package/dist/registration/review-store.js.map +1 -0
  351. package/dist/registration/service.d.ts +196 -0
  352. package/dist/registration/service.d.ts.map +1 -0
  353. package/dist/registration/service.js +384 -0
  354. package/dist/registration/service.js.map +1 -0
  355. package/dist/registration/store-bridge.d.ts +133 -0
  356. package/dist/registration/store-bridge.d.ts.map +1 -0
  357. package/dist/registration/store-bridge.js +159 -0
  358. package/dist/registration/store-bridge.js.map +1 -0
  359. package/dist/registration/tlsh.d.ts +125 -0
  360. package/dist/registration/tlsh.d.ts.map +1 -0
  361. package/dist/registration/tlsh.js +274 -0
  362. package/dist/registration/tlsh.js.map +1 -0
  363. package/dist/server.d.ts +26 -0
  364. package/dist/server.d.ts.map +1 -0
  365. package/dist/server.js +156 -0
  366. package/dist/server.js.map +1 -0
  367. package/dist/service/argv.d.ts +52 -0
  368. package/dist/service/argv.d.ts.map +1 -0
  369. package/dist/service/argv.js +127 -0
  370. package/dist/service/argv.js.map +1 -0
  371. package/dist/service/command-runner.d.ts +54 -0
  372. package/dist/service/command-runner.d.ts.map +1 -0
  373. package/dist/service/command-runner.js +55 -0
  374. package/dist/service/command-runner.js.map +1 -0
  375. package/dist/service/index.d.ts +83 -0
  376. package/dist/service/index.d.ts.map +1 -0
  377. package/dist/service/index.js +270 -0
  378. package/dist/service/index.js.map +1 -0
  379. package/dist/service/platform.d.ts +110 -0
  380. package/dist/service/platform.d.ts.map +1 -0
  381. package/dist/service/platform.js +157 -0
  382. package/dist/service/platform.js.map +1 -0
  383. package/dist/service/templates.d.ts +88 -0
  384. package/dist/service/templates.d.ts.map +1 -0
  385. package/dist/service/templates.js +212 -0
  386. package/dist/service/templates.js.map +1 -0
  387. package/dist/source-graph/deeplake-credentials.d.ts +57 -0
  388. package/dist/source-graph/deeplake-credentials.d.ts.map +1 -0
  389. package/dist/source-graph/deeplake-credentials.js +109 -0
  390. package/dist/source-graph/deeplake-credentials.js.map +1 -0
  391. package/dist/source-graph/deeplake-heal.d.ts +53 -0
  392. package/dist/source-graph/deeplake-heal.d.ts.map +1 -0
  393. package/dist/source-graph/deeplake-heal.js +41 -0
  394. package/dist/source-graph/deeplake-heal.js.map +1 -0
  395. package/dist/source-graph/deeplake-store.d.ts +151 -0
  396. package/dist/source-graph/deeplake-store.d.ts.map +1 -0
  397. package/dist/source-graph/deeplake-store.js +389 -0
  398. package/dist/source-graph/deeplake-store.js.map +1 -0
  399. package/dist/source-graph/deeplake-transport.d.ts +74 -0
  400. package/dist/source-graph/deeplake-transport.d.ts.map +1 -0
  401. package/dist/source-graph/deeplake-transport.js +107 -0
  402. package/dist/source-graph/deeplake-transport.js.map +1 -0
  403. package/dist/source-graph/hash.d.ts +3 -0
  404. package/dist/source-graph/hash.d.ts.map +1 -0
  405. package/dist/source-graph/hash.js +12 -0
  406. package/dist/source-graph/hash.js.map +1 -0
  407. package/dist/source-graph/memory-store.d.ts +32 -0
  408. package/dist/source-graph/memory-store.d.ts.map +1 -0
  409. package/dist/source-graph/memory-store.js +81 -0
  410. package/dist/source-graph/memory-store.js.map +1 -0
  411. package/dist/source-graph/model.d.ts +102 -0
  412. package/dist/source-graph/model.d.ts.map +1 -0
  413. package/dist/source-graph/model.js +36 -0
  414. package/dist/source-graph/model.js.map +1 -0
  415. package/dist/source-graph/paths.d.ts +7 -0
  416. package/dist/source-graph/paths.d.ts.map +1 -0
  417. package/dist/source-graph/paths.js +26 -0
  418. package/dist/source-graph/paths.js.map +1 -0
  419. package/dist/source-graph/schema.d.ts +44 -0
  420. package/dist/source-graph/schema.d.ts.map +1 -0
  421. package/dist/source-graph/schema.js +123 -0
  422. package/dist/source-graph/schema.js.map +1 -0
  423. package/dist/source-graph/sql-guards.d.ts +99 -0
  424. package/dist/source-graph/sql-guards.d.ts.map +1 -0
  425. package/dist/source-graph/sql-guards.js +129 -0
  426. package/dist/source-graph/sql-guards.js.map +1 -0
  427. package/dist/source-graph/store.d.ts +101 -0
  428. package/dist/source-graph/store.d.ts.map +1 -0
  429. package/dist/source-graph/store.js +2 -0
  430. package/dist/source-graph/store.js.map +1 -0
  431. package/dist/source-graph/ulid.d.ts +9 -0
  432. package/dist/source-graph/ulid.d.ts.map +1 -0
  433. package/dist/source-graph/ulid.js +61 -0
  434. package/dist/source-graph/ulid.js.map +1 -0
  435. package/dist/telemetry/checkin.d.ts +66 -0
  436. package/dist/telemetry/checkin.d.ts.map +1 -0
  437. package/dist/telemetry/checkin.js +142 -0
  438. package/dist/telemetry/checkin.js.map +1 -0
  439. package/dist/telemetry/db.d.ts +34 -0
  440. package/dist/telemetry/db.d.ts.map +1 -0
  441. package/dist/telemetry/db.js +122 -0
  442. package/dist/telemetry/db.js.map +1 -0
  443. package/dist/telemetry/index.d.ts +76 -0
  444. package/dist/telemetry/index.d.ts.map +1 -0
  445. package/dist/telemetry/index.js +98 -0
  446. package/dist/telemetry/index.js.map +1 -0
  447. package/dist/telemetry/logs.d.ts +83 -0
  448. package/dist/telemetry/logs.d.ts.map +1 -0
  449. package/dist/telemetry/logs.js +110 -0
  450. package/dist/telemetry/logs.js.map +1 -0
  451. package/dist/telemetry/metrics.d.ts +82 -0
  452. package/dist/telemetry/metrics.d.ts.map +1 -0
  453. package/dist/telemetry/metrics.js +148 -0
  454. package/dist/telemetry/metrics.js.map +1 -0
  455. package/dist/telemetry-usage/emit.d.ts +105 -0
  456. package/dist/telemetry-usage/emit.d.ts.map +1 -0
  457. package/dist/telemetry-usage/emit.js +267 -0
  458. package/dist/telemetry-usage/emit.js.map +1 -0
  459. package/dist/telemetry-usage/posthog-key.d.ts +22 -0
  460. package/dist/telemetry-usage/posthog-key.d.ts.map +1 -0
  461. package/dist/telemetry-usage/posthog-key.js +22 -0
  462. package/dist/telemetry-usage/posthog-key.js.map +1 -0
  463. package/dist/worker.d.ts +69 -0
  464. package/dist/worker.d.ts.map +1 -0
  465. package/dist/worker.js +91 -0
  466. package/dist/worker.js.map +1 -0
  467. package/package.json +44 -0
package/dist/daemon.js ADDED
@@ -0,0 +1,664 @@
1
+ /**
2
+ * The nectar daemon composition root.
3
+ *
4
+ * Mirrors honeycomb's `assembleDaemon` + `runAssembledDaemon`
5
+ * (honeycomb/src/daemon/runtime/assemble.ts, honeycomb/src/daemon/index.ts:150-187)
6
+ * per PRD-002a, scoped to nectar's job surface. The load-bearing ordering is
7
+ * lock BEFORE bind (PRD-002a step 5 before step 7): a double-start fails fast at
8
+ * the lock before the port is bound, and a bind failure rolls the lifecycle back
9
+ * so no stale lock survives.
10
+ *
11
+ * `assembleDaemon()` constructs but never listens (importing the module is
12
+ * side-effect free). `start()` acquires the lock, starts the worker, and binds
13
+ * the socket. `shutdown()` drains the worker, closes the socket, and releases
14
+ * the lock, idempotently.
15
+ *
16
+ * PRD-017a wires nectar's telemetry check-in/heartbeat here: `start()`
17
+ * checks in (a fresh binding_time) right after `health.markStarted()` and arms
18
+ * a heartbeat interval; `shutdown()` disarms it and closes the SQLite handle.
19
+ * A fresh `Telemetry` is opened on every `start()` (not once at
20
+ * `assembleDaemon()` construction time), so a stop/start cycle on the SAME
21
+ * `AssembledDaemon` - not just a brand-new process - also gets a fresh
22
+ * binding_time and zeroed since-restart counters (AC-017a.3.2 / AC-017b.3.1).
23
+ * Opening/writing telemetry is fail-soft throughout (`telemetry/index.ts`):
24
+ * a SQLite failure never blocks the lock, the bind, or the pipeline (AC-7).
25
+ */
26
+ import { join } from "node:path";
27
+ import { resolveConfig, isLoopbackHost, } from "./config.js";
28
+ import { HealthState } from "./health.js";
29
+ import { resolvePortkeyConfig } from "./portkey/config.js";
30
+ import { resolveEmbeddingsConfig, } from "./embeddings/config.js";
31
+ import { acquireSingleInstanceLock, releaseSingleInstanceLock } from "./lock.js";
32
+ import { DaemonStartAbortedError, NonLoopbackOpenApiError } from "./errors.js";
33
+ import { createHttpServer, DEFAULT_CLOSE_GRACE_MS } from "./server.js";
34
+ import { NectarRouter, ROUTE_GROUPS, allowAllPermission, } from "./api/router.js";
35
+ import { mountHiveGraphApi } from "./api/hive-graph-api.js";
36
+ import { createBroodGuard } from "./brood-guard.js";
37
+ import { createLogTap, createNullTelemetry, createTelemetry, telemetryDbPathForRuntimeDir, } from "./telemetry/index.js";
38
+ import { HiveantennaeWorker, emptyJobSource, } from "./worker.js";
39
+ import { createDiskRegistrationFs } from "./registration/disk-fs.js";
40
+ import { RegistrationService } from "./registration/service.js";
41
+ import { StoreBridge } from "./registration/store-bridge.js";
42
+ import { createSharedIgnore } from "./registration/ignore.js";
43
+ import { createTlshFuzzyStep, DEFAULT_TUNABLE_FUZZY_CONFIG } from "./registration/tlsh.js";
44
+ import { FilePendingReviewStore } from "./registration/review-store.js";
45
+ import { createOffProvider } from "./embeddings/provider.js";
46
+ import { createEnricherLoop, EnricherInMemoryStore, } from "./enricher/index.js";
47
+ import { evaluateAutoBrood, evaluateAutoBroodAsync, runBrood, runBroodAsync, shouldAutoBrood, } from "./brooding/index.js";
48
+ import { loadProjection, loadProjectionFromFile } from "./projection/load.js";
49
+ import { inheritFromProjection } from "./projection/inherit.js";
50
+ /**
51
+ * Bounded drain timeout for `shutdown()` (PRD-018a NEC-033 / AC-018a.11): how
52
+ * long to wait for the in-flight worker tick and background boot tasks to settle
53
+ * before releasing the lock and proceeding. A drain that exceeds this logs and
54
+ * proceeds, so shutdown stays bounded (it must not reintroduce the NEC-021 hang).
55
+ */
56
+ export const DEFAULT_SHUTDOWN_DRAIN_MS = 5_000;
57
+ /**
58
+ * Await `work` but give up after `ms`. Resolves `true` when the work settled
59
+ * first, `false` on timeout. The timer is unref'd so it never keeps the process
60
+ * alive, and cleared on settle so it never leaks.
61
+ */
62
+ async function raceWithTimeout(work, ms) {
63
+ let timer;
64
+ const timeout = new Promise((resolve) => {
65
+ timer = setTimeout(() => resolve(false), ms);
66
+ timer.unref?.();
67
+ });
68
+ try {
69
+ return await Promise.race([work.then(() => true), timeout]);
70
+ }
71
+ finally {
72
+ if (timer !== undefined)
73
+ clearTimeout(timer);
74
+ }
75
+ }
76
+ /**
77
+ * Load + validate a projection on boot and, when disk hashes are supplied, run
78
+ * the fresh-clone inheritance (PRD-011b AC-6). Never throws: a validation
79
+ * failure returns `{ loaded: false, reason }`, and a `write` rejection is
80
+ * swallowed (recall is simply not pre-warmed). Uses `projection/load.ts` +
81
+ * `projection/inherit.ts` verbatim.
82
+ */
83
+ export async function runBootProjectionLoad(opts) {
84
+ let loaded;
85
+ try {
86
+ if (opts.doc !== undefined) {
87
+ loaded = loadProjection(opts.doc, opts.tenancy);
88
+ }
89
+ else if (opts.filePath !== undefined) {
90
+ loaded = loadProjectionFromFile(opts.filePath, { tenancy: opts.tenancy });
91
+ }
92
+ else {
93
+ return { loaded: false };
94
+ }
95
+ }
96
+ catch {
97
+ return { loaded: false };
98
+ }
99
+ if (!loaded.ok) {
100
+ const result = { loaded: false, reason: loaded.reason };
101
+ opts.onResult?.(result);
102
+ return result;
103
+ }
104
+ let inheritSummary;
105
+ if (opts.diskHashes !== undefined) {
106
+ const diskHashes = typeof opts.diskHashes === "function" ? await opts.diskHashes() : opts.diskHashes;
107
+ const existingNectars = typeof opts.existingNectars === "function" ? await opts.existingNectars() : opts.existingNectars;
108
+ inheritSummary = inheritFromProjection(loaded.doc, diskHashes, {
109
+ tenancy: opts.tenancy,
110
+ ...(opts.nowIso !== undefined ? { nowIso: opts.nowIso } : {}),
111
+ ...(existingNectars !== undefined ? { existingNectars } : {}),
112
+ });
113
+ if (opts.write !== undefined && inheritSummary.rows.length > 0) {
114
+ try {
115
+ await opts.write(inheritSummary.rows);
116
+ }
117
+ catch {
118
+ // fail-soft: recall is not pre-warmed, but the daemon still boots.
119
+ }
120
+ }
121
+ }
122
+ const result = inheritSummary !== undefined ? { loaded: true, inheritSummary } : { loaded: true };
123
+ opts.onResult?.(result);
124
+ return result;
125
+ }
126
+ /** Map the embeddings selector (`off | local | hosted`) to the health body's provider label. */
127
+ function embeddingsHealthProvider(selector) {
128
+ switch (selector) {
129
+ case "off":
130
+ return "off";
131
+ case "local":
132
+ return "local-nomic";
133
+ case "hosted":
134
+ return "hosted";
135
+ default: {
136
+ // Exhaustiveness: a new selector variant fails the build here until mapped.
137
+ const unreachable = selector;
138
+ return unreachable;
139
+ }
140
+ }
141
+ }
142
+ function defaultLog(line) {
143
+ process.stderr.write(`${JSON.stringify({ ts: new Date().toISOString(), ...line })}\n`);
144
+ }
145
+ /**
146
+ * Construct the daemon. Does NOT bind a socket or acquire the lock (that is
147
+ * `start()`), so importing/constructing is safe in tests.
148
+ */
149
+ export function assembleDaemon(options = {}) {
150
+ const config = resolveConfig(options);
151
+ const baseLog = options.log ?? defaultLog;
152
+ const health = new HealthState();
153
+ // Resolve the provider state ONCE here, not per /health request (decision #20).
154
+ // Both resolvers read only `process.env` (or an injected override bag) and never
155
+ // touch disk or the network, so this keeps construction side-effect free.
156
+ const portkeyConfig = resolvePortkeyConfig(options.portkey ?? {});
157
+ const embeddingsConfig = resolveEmbeddingsConfig(options.embeddings ?? {});
158
+ health.setProviderState({
159
+ portkeyEnabled: portkeyConfig.enabled,
160
+ embeddingsProvider: embeddingsHealthProvider(embeddingsConfig.selector),
161
+ });
162
+ // PRD-018k / NEC-023: surface the brooding-dormancy reason on /health as soon
163
+ // as the daemon is constructed, so a dormant daemon is observable before the
164
+ // auto-brood trigger even runs. Ready (or unspecified) leaves reason null.
165
+ const broodPrereqs = options.broodPrereqs;
166
+ if (broodPrereqs !== undefined) {
167
+ health.setBroodingState({ reason: broodPrereqs.ready ? null : broodPrereqs.reason });
168
+ }
169
+ const telemetryDbPath = options.telemetryDbPath ?? telemetryDbPathForRuntimeDir(config.runtimeDir);
170
+ // A no-op placeholder until the first start() actually opens the SQLite store
171
+ // (constructing/importing the daemon must stay side-effect free, unchanged).
172
+ let telemetry = createNullTelemetry(telemetryDbPath);
173
+ // Indirection so `log` (built once, below) always taps whatever `telemetry`
174
+ // CURRENTLY is, across every start()/shutdown() cycle that reassigns it.
175
+ const telemetrySink = { log: (level, message) => telemetry.log(level, message) };
176
+ const log = createLogTap(baseLog, telemetrySink);
177
+ const worker = new HiveantennaeWorker({
178
+ source: options.jobSource ?? emptyJobSource,
179
+ handlers: options.handlers ?? {},
180
+ pollIntervalMs: config.pollIntervalMs,
181
+ onError: (err) => log({ level: "error", scope: "worker", err: String(err) }),
182
+ });
183
+ // ── PRD-008a: the in-repo router seam over node:http ────────────────────────
184
+ // Constructed side-effect free (no socket): it holds the frozen ROUTE_GROUPS,
185
+ // the shared live route table, and the permission gate. `createHttpServer`
186
+ // consumes it at start(); `daemon.group("/api/hive-graph")` exposes the
187
+ // RouteGroup handle so `mountHiveGraphApi` can attach handlers before OR after
188
+ // the socket binds (the route table is consulted per request).
189
+ const router = new NectarRouter(ROUTE_GROUPS, options.apiPermission ?? allowAllPermission);
190
+ const apiPermission = options.apiPermission ?? allowAllPermission;
191
+ // Shared Wave C context: an empty placeholder tenancy means an empty store
192
+ // yields no work, so the default enricher loop is a harmless no-op until a
193
+ // real tenancy + store are wired in.
194
+ const waveCTenancy = options.tenancy ?? { orgId: "", workspaceId: "", projectId: "" };
195
+ const projectRoot = options.projectRoot ?? process.cwd();
196
+ // PRD-018c NEC-007 (AC-018c.1): the ONE shared ignore predicate (segments ∪
197
+ // graph-ignore ∪ gitignore semantics) - the SAME function reference is used
198
+ // by brood discovery (both its git and walk paths), the watch intake, and
199
+ // the resync path, so the three legs of the mission never disagree about
200
+ // what the codebase is again. Memoized and constructed LAZILY on first
201
+ // actual use (registration or brood activating), not at assembly time: a
202
+ // daemon that never wires a store (most unit tests) never spawns `git`.
203
+ let sharedIgnoreInstance;
204
+ function sharedIgnore() {
205
+ if (sharedIgnoreInstance === undefined)
206
+ sharedIgnoreInstance = createSharedIgnore(projectRoot);
207
+ return sharedIgnoreInstance;
208
+ }
209
+ const resolvedIgnore = options.registrationIgnore ?? ((relPath) => sharedIgnore().isIgnored(relPath));
210
+ // PRD-018g / NEC-011: the ONE shared brood guard. The boot auto-brood and the
211
+ // API `/build` handler both go through it, and the enricher pauses while it is
212
+ // active, so at most one brood runs per daemon and the enricher never races it.
213
+ const broodGuard = createBroodGuard();
214
+ // ── PRD-016: the enricher steady-state loop ─────────────────────────────────
215
+ // The loop reads/writes the SYNCHRONOUS EnricherStore seam; its per-cycle stats
216
+ // feed the /health enricher slice through `enricherHealthSink`. Started on
217
+ // start(), stopped on shutdown(). The durable Deep Lake bridge is injected via
218
+ // `enricherStore` (see enricher/store-adapter.ts); the default is an empty
219
+ // in-memory working set.
220
+ let enricherLoop = null;
221
+ if (options.enricherEnabled ?? true) {
222
+ const enricherStore = options.enricherStore ?? new EnricherInMemoryStore();
223
+ const nowIso = options.enricherCycle?.nowIso ?? (() => new Date().toISOString());
224
+ const enricherHealthSink = {
225
+ logCycle: (stats) => {
226
+ try {
227
+ health.setEnricherState({
228
+ queueDepth: stats.queueDepth,
229
+ lastCycleAt: nowIso(),
230
+ consecutiveFailures: enricherLoop?.getFailureState().consecutiveFailures ?? 0,
231
+ });
232
+ }
233
+ catch {
234
+ // fail-soft: /health is best-effort and never blocks a cycle.
235
+ }
236
+ },
237
+ };
238
+ // Default the enricher's metrics sink to the daemon's OWN telemetry (read
239
+ // lazily so it tracks the fresh instance opened on each start()), so a live
240
+ // enricher cycle that describes/embeds moves the PRD-017 counters. A caller
241
+ // may still override it via `enricherCycle.metrics`.
242
+ const enricherMetrics = options.enricherCycle?.metrics ?? {
243
+ incrementFilesRegistered: () => telemetry.metrics.incrementFilesRegistered(),
244
+ incrementNectarsMinted: () => telemetry.metrics.incrementNectarsMinted(),
245
+ incrementDescriptionsGenerated: () => telemetry.metrics.incrementDescriptionsGenerated(),
246
+ incrementHiveGraphVersions: () => telemetry.metrics.incrementHiveGraphVersions(),
247
+ incrementEmbeddingsComputed: () => telemetry.metrics.incrementEmbeddingsComputed(),
248
+ };
249
+ const cycleDeps = {
250
+ readContent: { read: () => null },
251
+ portkey: null,
252
+ embedProvider: createOffProvider(),
253
+ ...options.enricherCycle,
254
+ store: enricherStore,
255
+ tenancy: waveCTenancy,
256
+ logSink: enricherHealthSink,
257
+ metrics: enricherMetrics,
258
+ // AC-018g.1: pause the enricher while a brood is in flight (shared guard).
259
+ broodActive: () => broodGuard.active(),
260
+ };
261
+ enricherLoop = createEnricherLoop({
262
+ deps: cycleDeps,
263
+ ...(options.enricherPollIntervalMs !== undefined ? { pollIntervalMs: options.enricherPollIntervalMs } : {}),
264
+ ...(options.enricherTimer !== undefined ? { timer: options.enricherTimer } : {}),
265
+ onError: (err) => log({ level: "error", scope: "enricher", err: String(err) }),
266
+ });
267
+ }
268
+ /** Background boot tasks (projection load, auto-brood) from the latest start(); never blocks readiness. */
269
+ let bootSettled = Promise.resolve();
270
+ /** Record a completed brood's file/cost slices on /health (shared by both paths). */
271
+ function finishBrood(result) {
272
+ health.setBroodingState({
273
+ active: false,
274
+ filesDescribed: result.describedCount,
275
+ filesTotal: result.discoveredCount,
276
+ lastEventAt: new Date().toISOString(),
277
+ });
278
+ health.addBroodCost({ tokens: result.actualUsage.inputTokens, usd: result.actualUsage.usd });
279
+ }
280
+ /**
281
+ * PRD-007d automatic trigger: after the socket is bound, if the project has no
282
+ * hive_graph rows OR no projection, brood in the BACKGROUND (never blocks
283
+ * readiness). Runs against the durable ASYNC store when {@link asyncBroodStore}
284
+ * is wired (the sync/async bridge, counting via the daemon's telemetry), else
285
+ * against a sync {@link broodStore}; a no-op when neither is configured.
286
+ */
287
+ async function triggerAutoBrood() {
288
+ if ((options.autoBroodEnabled ?? true) === false)
289
+ return;
290
+ const asyncStore = options.asyncBroodStore;
291
+ const syncStore = options.broodStore;
292
+ if (asyncStore === undefined && syncStore === undefined)
293
+ return;
294
+ // AC-018g.2: route the boot auto-brood through the SAME shared guard the API
295
+ // `/build` handler uses, so a `/build` arriving during the boot brood is
296
+ // refused (409) and no two broods ever run - and no identity is double-minted.
297
+ if (!broodGuard.tryAcquire())
298
+ return;
299
+ try {
300
+ if (asyncStore !== undefined) {
301
+ if (!shouldAutoBrood(await evaluateAutoBroodAsync(asyncStore, waveCTenancy, projectRoot)))
302
+ return;
303
+ health.setBroodingState({ active: true, lastEventAt: new Date().toISOString() });
304
+ const config = {
305
+ isIgnored: resolvedIgnore,
306
+ ...options.broodConfigAsync,
307
+ store: telemetry.wrapAsyncStore(asyncStore),
308
+ tenancy: waveCTenancy,
309
+ root: projectRoot,
310
+ fs: options.broodConfigAsync?.fs ?? createDiskRegistrationFs(projectRoot, resolvedIgnore),
311
+ };
312
+ const run = options.broodRunAsync ?? runBroodAsync;
313
+ finishBrood(await run(config, options.broodDepsAsync ?? {}, options.broodOptions ?? {}));
314
+ return;
315
+ }
316
+ if (syncStore !== undefined) {
317
+ if (!shouldAutoBrood(evaluateAutoBrood(syncStore, waveCTenancy, projectRoot)))
318
+ return;
319
+ health.setBroodingState({ active: true, lastEventAt: new Date().toISOString() });
320
+ const config = {
321
+ isIgnored: resolvedIgnore,
322
+ ...options.broodConfig,
323
+ store: syncStore,
324
+ tenancy: waveCTenancy,
325
+ root: projectRoot,
326
+ fs: options.broodConfig?.fs ?? createDiskRegistrationFs(projectRoot, resolvedIgnore),
327
+ };
328
+ const run = options.broodRun ?? runBrood;
329
+ finishBrood(await run(config, options.broodDeps ?? {}, options.broodOptions ?? {}));
330
+ return;
331
+ }
332
+ }
333
+ catch (err) {
334
+ health.setBroodingState({ active: false });
335
+ log({ level: "error", scope: "brood", err: String(err) });
336
+ }
337
+ finally {
338
+ broodGuard.release();
339
+ }
340
+ }
341
+ /** PRD-011b AC-6: load + validate the projection and inherit hash-matched files, in the background. */
342
+ async function loadBootProjection() {
343
+ const boot = options.bootProjection;
344
+ if (boot === undefined)
345
+ return;
346
+ try {
347
+ const result = await runBootProjectionLoad(boot);
348
+ if (result.loaded && result.inheritSummary !== undefined && result.inheritSummary.inherited > 0) {
349
+ health.setProjectionState({ lastWriteAt: new Date().toISOString() });
350
+ }
351
+ }
352
+ catch (err) {
353
+ log({ level: "error", scope: "projection", err: String(err) });
354
+ }
355
+ }
356
+ // ── PRD-018b: the update-on-change registration pipeline ────────────────────
357
+ // Constructed at start() (after the bind) when a durable async store resolved,
358
+ // then hydrated + started + resynced in the background AFTER auto-brood settles
359
+ // (so a first boot's brood never races the watcher into a double mint, and an
360
+ // already-brooded boot still gets its cold catch-up). Stopped in shutdown()
361
+ // before the lock is released, with its durable writes drained.
362
+ const registrationStore = options.registrationStore;
363
+ const registrationOn = registrationStore !== undefined && (options.registrationEnabled ?? true);
364
+ let registration = null;
365
+ let bootResyncCount = 0;
366
+ /**
367
+ * Build the registration pipeline: a {@link StoreBridge} over the durable async
368
+ * store and a {@link RegistrationService} wired with the disk fs, ignore
369
+ * predicate, the tunable TLSH fuzzy step, and the file-backed review queue.
370
+ * Constructing the service does NOT start the watcher (that is `service.start()`).
371
+ */
372
+ function buildRegistration(store) {
373
+ const bridge = new StoreBridge({
374
+ durable: store,
375
+ onFlushError: (err, op) => {
376
+ health.recordWatchFlushFailure(new Date().toISOString());
377
+ log({ level: "error", scope: "registration.bridge", op, err: String(err) });
378
+ },
379
+ });
380
+ const reviews = options.registrationReviews ?? new FilePendingReviewStore(join(config.runtimeDir, "pending-reviews.json"));
381
+ const registrationMetrics = {
382
+ incrementFilesRegistered: () => telemetry.metrics.incrementFilesRegistered(),
383
+ incrementNectarsMinted: () => telemetry.metrics.incrementNectarsMinted(),
384
+ incrementDescriptionsGenerated: () => telemetry.metrics.incrementDescriptionsGenerated(),
385
+ incrementHiveGraphVersions: () => telemetry.metrics.incrementHiveGraphVersions(),
386
+ incrementEmbeddingsComputed: () => telemetry.metrics.incrementEmbeddingsComputed(),
387
+ };
388
+ const service = new RegistrationService({
389
+ store: bridge,
390
+ tenancy: waveCTenancy,
391
+ fs: options.registrationFs ?? createDiskRegistrationFs(projectRoot, resolvedIgnore),
392
+ root: projectRoot,
393
+ fuzzy: createTlshFuzzyStep(options.registrationFuzzyConfig ?? DEFAULT_TUNABLE_FUZZY_CONFIG),
394
+ pendingReviews: reviews,
395
+ isIgnored: resolvedIgnore,
396
+ ...(options.registrationTimer !== undefined ? { timer: options.registrationTimer } : {}),
397
+ ...(options.registrationDebounceMs !== undefined ? { debounceMs: options.registrationDebounceMs } : {}),
398
+ metrics: registrationMetrics,
399
+ log,
400
+ // PRD-018c NEC-007 point 1: refresh the shared predicate's gitignore
401
+ // snapshot on every resync (boot, directory-event, watcher-restart, and
402
+ // the periodic backstop all funnel through requestResync()), so the
403
+ // cache stays warm without spawning git per watch event. A no-op when
404
+ // `registrationIgnore` overrides the shared predicate (nothing to refresh).
405
+ onResyncRequested: () => sharedIgnoreInstance?.refresh(),
406
+ // PRD-018c AC-018c.6/7: surface watcher liveness on /health.
407
+ onWatcherStateChange: (state) => {
408
+ health.setWatchState({ state, running: state === "running" });
409
+ },
410
+ });
411
+ return { service, bridge };
412
+ }
413
+ /**
414
+ * Hydrate the mirror, start the watcher, and request the single cold-catch-up
415
+ * resync (AC-018b.5) - the boot sequencing step that runs AFTER auto-brood
416
+ * settles. A shutdown that raced boot sets `closed`; in that case this bails
417
+ * out so the watcher is never started during teardown (AC-018b.3).
418
+ */
419
+ async function startRegistrationPipeline() {
420
+ if (registration === null || closed)
421
+ return;
422
+ try {
423
+ await registration.bridge.hydrate(waveCTenancy);
424
+ }
425
+ catch (err) {
426
+ log({ level: "error", scope: "registration.hydrate", err: String(err) });
427
+ }
428
+ if (closed)
429
+ return; // a shutdown may have landed while hydrating
430
+ registration.service.start();
431
+ health.setWatchState({ running: true, reason: null });
432
+ registration.service.requestResync();
433
+ bootResyncCount += 1;
434
+ log({ level: "info", scope: "registration", msg: "watch leg started", root: projectRoot });
435
+ }
436
+ const lockPaths = { lockFilePath: config.lockFilePath, pidFilePath: config.pidFilePath };
437
+ const drainTimeoutMs = options.shutdownDrainMs ?? DEFAULT_SHUTDOWN_DRAIN_MS;
438
+ const closeGraceMs = options.shutdownCloseGraceMs ?? DEFAULT_CLOSE_GRACE_MS;
439
+ let server = null;
440
+ let closed = false;
441
+ let signalsInstalled = false;
442
+ /** The identity this instance stamped into the lock, or null when it holds no lock (never acquired, or released). */
443
+ let lockIdentity = null;
444
+ /** The one in-flight (or settled) startup. Concurrent/repeat callers share it, so nobody observes a "started" port before listen() actually succeeds. */
445
+ let startPromise = null;
446
+ /** Stops the check-in heartbeat armed by the current telemetry instance, or null before/after it is running. */
447
+ let stopHeartbeat = null;
448
+ async function start() {
449
+ if (startPromise !== null)
450
+ return startPromise;
451
+ startPromise = (async () => {
452
+ // CodeRabbit PR-18 finding #1: clear `closed` at the very top of the
453
+ // startPromise IIFE, before anything that can throw (the loopback guard,
454
+ // the lock acquire). On a REUSED daemon instance (start -> shutdown ->
455
+ // start again), a second start() that throws before this point used to
456
+ // leave `closed === true` from the prior shutdown; the catch handler's
457
+ // rollback `await shutdown()` then no-op'd on the `if (closed) return;`
458
+ // guard and never cleared `startPromise`, wedging every later start() on
459
+ // the same rejected promise forever. This is a synchronous assignment at
460
+ // the top of a prefix that is itself synchronous up to the awaited
461
+ // `listen()` call, so it does not affect the EX-1 race test's timing.
462
+ closed = false;
463
+ // PRD-018j / NEC-029: refuse to bind off loopback when the default open gate
464
+ // is active, so the API is never network-reachable without authentication.
465
+ if (apiPermission === allowAllPermission && !isLoopbackHost(config.host)) {
466
+ throw new NonLoopbackOpenApiError(config.host);
467
+ }
468
+ // Step 5 (PRD-002a): acquire the single-instance lock BEFORE the bind, and
469
+ // remember the identity we stamped so the rollback path releases only what
470
+ // THIS instance acquired (PRD-018a NEC-002).
471
+ lockIdentity = acquireSingleInstanceLock(lockPaths);
472
+ // Step 6: start services (the worker's adaptive poll loop + the enricher loop).
473
+ worker.start();
474
+ enricherLoop?.start();
475
+ health.markStarted();
476
+ // PRD-017a: open a FRESH telemetry store and check in (a new binding_time)
477
+ // on every start(), so a stop/start cycle on this SAME daemon object also
478
+ // resets since-restart state, not only a brand-new process. Fail-soft
479
+ // throughout (`createTelemetry`): a SQLite failure never blocks the bind.
480
+ telemetry = createTelemetry({
481
+ dbPath: telemetryDbPath,
482
+ onceFailure: (msg) => baseLog({ level: "warn", scope: "telemetry", msg }),
483
+ });
484
+ stopHeartbeat = telemetry.startCheckin(() => health.pipelineStatus, {
485
+ intervalMs: options.telemetryHeartbeatIntervalMs,
486
+ timer: options.telemetryTimer,
487
+ });
488
+ // Step 7: bind the socket. Use a local reference so a concurrent shutdown()
489
+ // that nulls `server` cannot turn the unwind below into a null deref.
490
+ const httpServer = createHttpServer(health, config.host, config.port, router);
491
+ server = httpServer;
492
+ const boundPort = await httpServer.listen();
493
+ // EX-1 / M6: a shutdown() may have raced this start between lock acquisition
494
+ // and the bind completing. If so, unwind: close the socket we just bound and
495
+ // release the lock this instance holds, so we never end up listening without
496
+ // a lock (which would let a second daemon start alongside us).
497
+ if (closed) {
498
+ await httpServer.close(closeGraceMs);
499
+ if (server === httpServer)
500
+ server = null;
501
+ if (lockIdentity !== null) {
502
+ releaseSingleInstanceLock(lockPaths, lockIdentity);
503
+ lockIdentity = null;
504
+ }
505
+ throw new DaemonStartAbortedError();
506
+ }
507
+ log({ level: "info", scope: "daemon", msg: "listening", host: config.host, port: boundPort });
508
+ // PRD-018k / NEC-023 (AC-018k.1 / AC-018k.2): a booted daemon that cannot
509
+ // brood says so loudly, enumerating exactly which prerequisites are unmet
510
+ // (the credentials file, and/or the specific NECTAR_PORTKEY_* variables),
511
+ // instead of silently describing nothing.
512
+ if (broodPrereqs !== undefined && !broodPrereqs.ready) {
513
+ log({
514
+ level: "warn",
515
+ scope: "brood",
516
+ msg: "brooding is dormant; the following prerequisites are missing",
517
+ reason: broodPrereqs.reason,
518
+ missing: broodPrereqs.missing,
519
+ });
520
+ }
521
+ // PRD-018b: construct the registration pipeline now (side-effect light: no
522
+ // watcher yet), and surface the watch-leg state on /health. Dormant with a
523
+ // reason when no durable store resolved (AC-018b.7); constructed-but-not-yet
524
+ // -started otherwise (the watcher starts in the boot task below).
525
+ if (registrationOn && registrationStore !== undefined) {
526
+ registration = buildRegistration(registrationStore);
527
+ health.setWatchState({ running: false, reason: null });
528
+ }
529
+ else {
530
+ health.setWatchState({
531
+ running: false,
532
+ reason: registrationStore === undefined ? "no-credentials" : "disabled",
533
+ });
534
+ }
535
+ // Step 8 (Wave C / PRD-018b): kick off the background boot tasks AFTER the
536
+ // daemon is accepting requests, so neither the fresh-clone projection load
537
+ // nor the auto-brood trigger ever blocks readiness (PRD-007d / PRD-011b
538
+ // AC-6). The registration watcher + cold-catch-up resync are sequenced
539
+ // AFTER auto-brood settles (AC-018b.5/6): on a first boot the order is
540
+ // brood, then watch, then resync; on a warm boot auto-brood is a no-op and
541
+ // the resync runs promptly. No lock is needed - the watcher simply is not
542
+ // running while the brood runs, so it cannot race a mint.
543
+ bootSettled = (async () => {
544
+ await Promise.allSettled([loadBootProjection(), triggerAutoBrood()]);
545
+ await startRegistrationPipeline();
546
+ })();
547
+ return boundPort;
548
+ })();
549
+ // Only the caller that created the promise drives rollback; concurrent
550
+ // callers returned the shared promise above and observe the same result.
551
+ try {
552
+ return await startPromise;
553
+ }
554
+ catch (err) {
555
+ log({ level: "error", scope: "daemon", msg: "start failed, rolling back", err: String(err) });
556
+ await shutdown(); // clears startPromise so a later start() can retry cleanly
557
+ throw err;
558
+ }
559
+ }
560
+ async function shutdown() {
561
+ if (closed)
562
+ return; // idempotent: a second signal is ignored
563
+ closed = true;
564
+ // EX-1 / M6: if a start is in flight, let IT observe `closed` and unwind
565
+ // itself (close its own socket, release its own lock) rather than racing to
566
+ // close a mid-bind socket here (which would leave the start's `listen()`
567
+ // unsettled and hang shutdown). Its rejection is expected during this race.
568
+ const inFlightStart = startPromise;
569
+ if (inFlightStart !== null) {
570
+ try {
571
+ await inFlightStart;
572
+ }
573
+ catch {
574
+ // An aborted or failed start during a racing shutdown is expected here.
575
+ }
576
+ }
577
+ // Disarm the poll loops so no NEW tick starts, then drain the in-flight tick
578
+ // and the background boot tasks (bootSettled) before releasing the lock.
579
+ worker.stop();
580
+ enricherLoop?.stop();
581
+ // PRD-018b AC-018b.3: stop the watcher NOW (before the lock is released) so no
582
+ // new watch event is scheduled; an in-flight cycle is drained below. This also
583
+ // means the boot task's `startRegistrationPipeline` (if it has not run yet)
584
+ // sees `closed` and never starts the watcher during teardown.
585
+ registration?.service.stop();
586
+ if (registration !== null)
587
+ health.setWatchState({ running: false });
588
+ // AC-018a.10/11 (NEC-033): await the in-flight worker tick and bootSettled
589
+ // under a bounded timeout so a shutdown that catches the worker busy drains
590
+ // the write instead of killing it mid-flight. The drain never rejects
591
+ // (errors are logged); a drain that exceeds the timeout logs and proceeds so
592
+ // shutdown stays bounded (it must not reintroduce the NEC-021 hang). PRD-018b:
593
+ // the registration cycle and its durable bridge flush are drained too, so a
594
+ // ladder write in flight lands durably before the lock is released.
595
+ const drainWork = (async () => {
596
+ await worker.whenIdle();
597
+ await bootSettled;
598
+ if (registration !== null) {
599
+ await registration.service._waitForIdle();
600
+ await registration.bridge.whenFlushed();
601
+ }
602
+ })().catch((err) => {
603
+ log({ level: "error", scope: "daemon", msg: "drain error", err: String(err) });
604
+ });
605
+ const drained = await raceWithTimeout(drainWork, drainTimeoutMs);
606
+ if (!drained) {
607
+ log({ level: "warn", scope: "daemon", msg: "drain timed out; proceeding with shutdown", timeoutMs: drainTimeoutMs });
608
+ }
609
+ if (server !== null) {
610
+ await server.close(closeGraceMs);
611
+ server = null;
612
+ }
613
+ stopHeartbeat?.();
614
+ stopHeartbeat = null;
615
+ // Ownership-checked release: only remove the lock this instance holds. A
616
+ // failed second start (which never acquired the lock) has lockIdentity null
617
+ // and touches nothing, so it can never delete the live daemon's lock (NEC-002).
618
+ if (lockIdentity !== null) {
619
+ releaseSingleInstanceLock(lockPaths, lockIdentity);
620
+ lockIdentity = null;
621
+ }
622
+ startPromise = null; // allow a fresh start after a clean shutdown
623
+ log({ level: "info", scope: "daemon", msg: "shutdown complete" });
624
+ telemetry.close();
625
+ telemetry = createNullTelemetry(telemetryDbPath);
626
+ }
627
+ function installSignalHandlers() {
628
+ if (signalsInstalled)
629
+ return;
630
+ signalsInstalled = true;
631
+ const onSignal = (sig) => {
632
+ log({ level: "info", scope: "daemon", msg: `received ${sig}, draining` });
633
+ void shutdown().then(() => process.exit(0));
634
+ };
635
+ process.once("SIGINT", () => onSignal("SIGINT"));
636
+ process.once("SIGTERM", () => onSignal("SIGTERM"));
637
+ }
638
+ const daemon = {
639
+ config,
640
+ health,
641
+ worker,
642
+ broodGuard,
643
+ start,
644
+ shutdown,
645
+ pipelineStatus: () => health.pipelineStatus,
646
+ telemetry: () => telemetry,
647
+ installSignalHandlers,
648
+ acknowledgeAlert: () => enricherLoop?.acknowledgeAlert(),
649
+ awaitBoot: () => bootSettled,
650
+ group: (path) => router.group(path),
651
+ registration: () => registration,
652
+ registrationBootResyncCount: () => bootResyncCount,
653
+ };
654
+ // PRD-008: attach the /api/hive-graph handlers when the caller wired the
655
+ // mechanics. The group is already scaffolded + protected regardless; this
656
+ // fills it. Callers may equivalently call mountHiveGraphApi(daemon, opts).
657
+ if (options.hiveGraphApi !== undefined) {
658
+ // Share the daemon's brood guard with the API `/build` handler (AC-018g.2)
659
+ // unless the caller already supplied one.
660
+ mountHiveGraphApi(daemon, { broodGuard, ...options.hiveGraphApi });
661
+ }
662
+ return daemon;
663
+ }
664
+ //# sourceMappingURL=daemon.js.map