@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/cli.js ADDED
@@ -0,0 +1,912 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * The nectar CLI.
4
+ *
5
+ * `nectar daemon` is the runnable process (PRD-002c): it invokes the
6
+ * composition root, acquires the single-instance lock before binding
7
+ * 127.0.0.1:3854, serves `/health`, and installs SIGINT/SIGTERM handlers.
8
+ *
9
+ * The operational verbs exit non-zero with a clear notice rather than a silent
10
+ * stub, in these shapes:
11
+ * - `brood` (PRD-007d): `--dry-run` runs a real local cost preview; a mutating
12
+ * brood dispatches daemon-side (PRD-008 build endpoint, a later wave).
13
+ * - `search` (PRD-012b): a thin loopback client of the daemon search endpoint
14
+ * (PRD-008b, a later wave); left unwired rather than importing the engine.
15
+ * - `prune` / `review-matches`: mechanics implemented and tested here
16
+ * (`runPrune` / `runReviewMatches`), but not yet wired to a durable,
17
+ * sync-capable hive-graph store (the NOT_WIRED map). They refuse to run
18
+ * against a throwaway empty store so a destructive verb never silently
19
+ * no-ops; the wiring lands with the daemon's registration-pipeline integration.
20
+ *
21
+ * `rebuild-projection` (and `project --rebuild-projection`) is wired REAL
22
+ * (PRD-011c): it scans the durable Deep Lake store for the latest described
23
+ * version per nectar scoped to the project and writes `.honeycomb/nectars.json`
24
+ * atomically. It resolves org/workspace from the shared `~/.deeplake`
25
+ * credentials the Deep Lake store already consumes and the project id + project
26
+ * root from `NECTAR_PROJECT_ID` / `NECTAR_PROJECT_ROOT` (see USAGE).
27
+ */
28
+ import { realpathSync } from "node:fs";
29
+ import { join } from "node:path";
30
+ import { fileURLToPath } from "node:url";
31
+ import { createInterface } from "node:readline/promises";
32
+ import { assembleDaemon } from "./daemon.js";
33
+ import { resolveConfig } from "./config.js";
34
+ import { mountHiveGraphApi } from "./api/hive-graph-api.js";
35
+ import { buildHiveGraphApiOptions } from "./api/daemon-api-wiring.js";
36
+ import { searchViaDaemon, DaemonUnreachableError, DaemonSearchError } from "./api/loopback-client.js";
37
+ import { createServiceModule, serviceStatus } from "./service/index.js";
38
+ import { registerWithDoctor } from "./doctor-registry.js";
39
+ import { emitInstalled, emitUninstalled, recordDaemonStart } from "./telemetry-usage/emit.js";
40
+ import { DeepLakeHiveGraphStore } from "./hive-graph/deeplake-store.js";
41
+ import { InMemoryHiveGraphStore } from "./hive-graph/memory-store.js";
42
+ import { loadDeepLakeCredentials, credentialsPath } from "./hive-graph/deeplake-credentials.js";
43
+ import { broodPrereqsFromEnv, formatFirstRunGuidance } from "./brood-prereqs.js";
44
+ import { resolveNectarTunables } from "./config-file.js";
45
+ import { resolveProjectScope } from "./hive-graph/project-scope.js";
46
+ import { createDiskRegistrationFs } from "./registration/disk-fs.js";
47
+ import { StoreBridge } from "./registration/store-bridge.js";
48
+ import { runPrune } from "./registration/prune-cli.js";
49
+ import { runReviewMatches } from "./registration/review-cli.js";
50
+ import { FilePendingReviewStore, } from "./registration/review-store.js";
51
+ import { rebuildProjectionAsync, projectionFinalPath, ProjectionWriter } from "./projection/write.js";
52
+ import { DEFAULT_PROJECTION_REL_PATH } from "./projection/format.js";
53
+ import { resolvePortkeyConfig } from "./portkey/config.js";
54
+ import { activeEmbedModelId, resolveEmbeddingsConfig, validateEmbedDimension } from "./embeddings/config.js";
55
+ import { resolveEmbedProvider } from "./embeddings/provider.js";
56
+ import { stderrDimRejectionSink } from "./embeddings/guard.js";
57
+ import { DeepLakeEnricherStore } from "./enricher/store-adapter.js";
58
+ import { createPriorContentCache } from "./enricher/content-cache.js";
59
+ import { parseBroodArgs, planBrood, formatDryRunReport, discoverFiles, prepareFiles, runBroodAsync, } from "./brooding/index.js";
60
+ const USAGE = `nectar - semantic memory layer over a source tree
61
+
62
+ Usage:
63
+ nectar daemon Start the hiveantennae daemon (127.0.0.1:3854, /health)
64
+ nectar install Register the OS service unit + the doctor registry entry (PRD-003)
65
+ nectar uninstall Deregister the OS service unit (PRD-003b)
66
+ nectar service-status Report the OS service unit's running state (PRD-003b)
67
+ nectar brood [flags] Full-codebase brood (PRD-007). --dry-run previews cost locally;
68
+ a mutating brood runs against the durable Deep Lake store (needs
69
+ Portkey configured). Flags: --force, --limit N, --dry-run, --model <id>
70
+ nectar search <query> [flags] Manual hive-graph search (PRD-012). Thin loopback client of the
71
+ daemon search endpoint (POST /api/hive-graph/search). Requires a
72
+ running 'nectar daemon'. Flags: --limit N, --json
73
+ nectar prune [--confirm] Prune long-missing nectars from the durable store (PRD-006d)
74
+ nectar review-matches Review low-confidence step-4 matches against the durable store (PRD-006d)
75
+ nectar rebuild-projection Regenerate .honeycomb/nectars.json from Deep Lake (PRD-011)
76
+ nectar project --rebuild-projection Project-scoped regeneration of .honeycomb/nectars.json (PRD-011)
77
+ nectar --help Show this help
78
+
79
+ rebuild-projection reads org_id/workspace_id from ~/.deeplake/credentials.json (the
80
+ shared file the Deep Lake store already uses). The project id resolves through the
81
+ per-project scope ladder (mirrors honeycomb's resolver, never requires honeycomb):
82
+ NECTAR_PROJECT_ID > detected HONEYCOMB_PROJECT_ID > ~/.deeplake/projects.json folder
83
+ binding (longest prefix) > git remote signal > the workspace __unsorted__ inbox.
84
+ The project root comes from NECTAR_PROJECT_ROOT (defaults to the current working
85
+ directory).
86
+ `;
87
+ /** The exec path the OS service unit will run (mirrors doctor's own CLI resolution). */
88
+ function resolveServiceExecPath() {
89
+ return process.argv[1] ?? "nectar";
90
+ }
91
+ /** Opt into a system-scoped unit via env (mirrors doctor's DOCTOR_SERVICE_SYSTEM). */
92
+ function preferSystemScope() {
93
+ return (process.env["NECTAR_SERVICE_SYSTEM"] ?? "") === "1";
94
+ }
95
+ /**
96
+ * `nectar install` (PRD-003): lays down the OS service unit (003b) AND appends
97
+ * nectar's entry to doctor's registry (003c) - the same installer performs
98
+ * both, per PRD-003c's "no two-phase hazard" note. Does not restart doctor;
99
+ * the registry entry takes effect at doctor's next natural boot.
100
+ */
101
+ async function runInstall() {
102
+ const config = resolveConfig();
103
+ const serviceModule = createServiceModule({
104
+ execPath: resolveServiceExecPath(),
105
+ preferSystemScope: preferSystemScope(),
106
+ });
107
+ const serviceResult = await serviceModule.install();
108
+ process.stdout.write(`${serviceResult.message}\n`);
109
+ try {
110
+ const registration = registerWithDoctor({ config });
111
+ const verb = registration.created ? "created" : registration.replaced ? "updated" : "appended to";
112
+ process.stdout.write(`doctor registry ${verb} at ${registration.registryPath} (healthUrl ${registration.entry.healthUrl}). ` +
113
+ "doctor will supervise nectar starting at its next boot.\n");
114
+ }
115
+ catch (err) {
116
+ process.stderr.write(`nectar install: could not update the doctor registry: ${err instanceof Error ? err.message : String(err)}\n`);
117
+ return 1;
118
+ }
119
+ // Usage telemetry: fired only on full success, after the user-facing output.
120
+ // emitInstalled never throws and is bounded, so it cannot alter the exit code.
121
+ if (serviceResult.ok) {
122
+ await emitInstalled();
123
+ }
124
+ return serviceResult.ok ? 0 : 1;
125
+ }
126
+ /** `nectar uninstall` (PRD-003b): deregisters the OS service unit so it does not resurrect. */
127
+ async function runUninstall() {
128
+ const serviceModule = createServiceModule({
129
+ execPath: resolveServiceExecPath(),
130
+ preferSystemScope: preferSystemScope(),
131
+ });
132
+ const result = await serviceModule.uninstall();
133
+ process.stdout.write(`${result.message}\n`);
134
+ // Usage telemetry (NEC-042 item 4 / AC-018l.11): fire only AFTER the uninstall
135
+ // outcome is known, and only on success - a failed/aborted uninstall must not
136
+ // emit a `nectar_uninstalled` event. emitUninstalled never throws and is
137
+ // bounded, so it cannot alter the exit code.
138
+ if (result.ok)
139
+ await emitUninstalled();
140
+ return result.ok ? 0 : 1;
141
+ }
142
+ /** `nectar service-status` (PRD-003b): reports the OS service manager's coarse state. */
143
+ async function runServiceStatus() {
144
+ const status = await serviceStatus({
145
+ execPath: resolveServiceExecPath(),
146
+ preferSystemScope: preferSystemScope(),
147
+ });
148
+ process.stdout.write(`${status}\n`);
149
+ return status === "unknown" ? 1 : 0;
150
+ }
151
+ /** Read an env var, treating unset OR blank/whitespace-only as absent (mirrors config.ts). */
152
+ function cliEnvStr(name) {
153
+ const raw = process.env[name];
154
+ if (raw === undefined || raw.trim() === "")
155
+ return undefined;
156
+ return raw;
157
+ }
158
+ /**
159
+ * Resolve the tenancy triple + project root for the projection CLI verbs. org
160
+ * and workspace come from the SAME `~/.deeplake/credentials.json` the Deep Lake
161
+ * store consumes (`deeplake-credentials.ts`); the project id resolves through
162
+ * the per-project scope ladder (`hive-graph/project-scope.ts`, mirroring
163
+ * honeycomb's resolver across the process boundary): NECTAR_PROJECT_ID, then
164
+ * the detected HONEYCOMB_PROJECT_ID, then the `~/.deeplake/projects.json`
165
+ * folder binding (longest prefix), then the git-remote signal, then the
166
+ * workspace `__unsorted__` inbox; the project root defaults to the current
167
+ * working directory. Returns a typed error string instead of throwing so the
168
+ * caller can print a clear notice and exit non-zero.
169
+ */
170
+ function resolveProjectionContext() {
171
+ let credentials;
172
+ try {
173
+ credentials = loadDeepLakeCredentials();
174
+ }
175
+ catch (err) {
176
+ return { ok: false, message: err instanceof Error ? err.message : String(err) };
177
+ }
178
+ const projectRoot = cliEnvStr("NECTAR_PROJECT_ROOT") ?? process.cwd();
179
+ const scope = resolveProjectScope({
180
+ cwd: projectRoot,
181
+ expect: { org: credentials.orgId, workspace: credentials.workspaceId },
182
+ });
183
+ const tenancy = {
184
+ orgId: credentials.orgId,
185
+ workspaceId: credentials.workspaceId,
186
+ projectId: scope.projectId,
187
+ };
188
+ const store = new DeepLakeHiveGraphStore({ credentials });
189
+ return { ok: true, tenancy, projectRoot, store, scopeSource: scope.source, credentials };
190
+ }
191
+ /**
192
+ * `nectar rebuild-projection` / `nectar project --rebuild-projection`
193
+ * (PRD-011c, trigger #3): a full regeneration of `.honeycomb/nectars.json` from
194
+ * a single Deep Lake scan (latest described version per nectar, scoped to the
195
+ * project), written atomically. Both verbs share this one routine.
196
+ */
197
+ async function runRebuildProjection() {
198
+ const ctx = resolveProjectionContext();
199
+ if (!ctx.ok) {
200
+ process.stderr.write(`nectar rebuild-projection: ${ctx.message}.\n` +
201
+ "org_id/workspace_id come from ~/.deeplake/credentials.json; the project id resolves via " +
202
+ "NECTAR_PROJECT_ID > detected HONEYCOMB_PROJECT_ID > ~/.deeplake/projects.json binding > git remote signal > __unsorted__.\n");
203
+ return 1;
204
+ }
205
+ const { doc, path } = await rebuildProjectionAsync(ctx.store, ctx.tenancy, { projectRoot: ctx.projectRoot });
206
+ const fileCount = Object.keys(doc.files).length;
207
+ process.stdout.write(`nectar rebuild-projection: regenerated ${path} (${fileCount} nectar${fileCount === 1 ? "" : "s"}, ` +
208
+ `project ${ctx.tenancy.orgId}/${ctx.tenancy.workspaceId}/${ctx.tenancy.projectId}, scope via ${ctx.scopeSource}).\n`);
209
+ return 0;
210
+ }
211
+ export function classifyBroodInvocation(broodArgs) {
212
+ const parsed = parseBroodArgs(broodArgs);
213
+ if (parsed.errors.length > 0)
214
+ return { kind: "errors", errors: parsed.errors };
215
+ if (parsed.options.dryRun === true)
216
+ return { kind: "dry-run", options: parsed.options };
217
+ return { kind: "run", options: parsed.options };
218
+ }
219
+ /**
220
+ * `nectar brood --dry-run` (PRD-007d): a real, read-only cost preview run
221
+ * locally via `planBrood` (discover -> pre-check -> bucket -> estimate), which
222
+ * makes NO LLM call and writes NOTHING. Runs against a throwaway in-memory store
223
+ * because the preview is `brooding-pipeline.md`'s "recommended first step on a
224
+ * new project" where the durable store is empty; the projection-inherited count
225
+ * still reads the on-disk `.honeycomb/nectars.json` faithfully. A daemon-side
226
+ * dry-run reflecting live store state lands with the PRD-008 build endpoint.
227
+ */
228
+ function runBroodDryRun() {
229
+ const ctx = resolveProjectionContext();
230
+ if (!ctx.ok) {
231
+ process.stderr.write(`nectar brood --dry-run: ${ctx.message}.\n` +
232
+ "org_id/workspace_id come from ~/.deeplake/credentials.json; the project id resolves via " +
233
+ "NECTAR_PROJECT_ID > detected HONEYCOMB_PROJECT_ID > ~/.deeplake/projects.json binding > git remote signal > __unsorted__.\n");
234
+ return 1;
235
+ }
236
+ const config = {
237
+ store: new InMemoryHiveGraphStore(),
238
+ tenancy: ctx.tenancy,
239
+ root: ctx.projectRoot,
240
+ fs: createDiskRegistrationFs(ctx.projectRoot),
241
+ };
242
+ const plan = planBrood(config);
243
+ process.stdout.write(`${formatDryRunReport({
244
+ discoveredCount: plan.discoveredCount,
245
+ inheritedCount: plan.inheritedCount,
246
+ skipBinaryCount: plan.skipBinaryCount,
247
+ skipTooLargeCount: plan.skipTooLargeCount,
248
+ batchFileCount: plan.batchFileCount,
249
+ soloFileCount: plan.soloFileCount,
250
+ batchCalls: plan.batchCalls,
251
+ soloCalls: plan.soloCalls,
252
+ estimate: plan.estimate,
253
+ // PRD-018c AC-018c.11: report the discovery source and, when git errored
254
+ // (not simply absent), the degradation reason.
255
+ source: plan.source,
256
+ ...(plan.degraded !== undefined ? { degraded: plan.degraded } : {}),
257
+ })}\n`);
258
+ return 0;
259
+ }
260
+ /**
261
+ * `nectar brood [flags]` (PRD-007d). `--dry-run` runs the local cost preview; a
262
+ * mutating brood executes daemon-side (PRD-007d "the brood mechanic executes
263
+ * daemon-side; the CLI dispatches to it") through the PRD-008
264
+ * `POST /api/hive-graph/build` endpoint, which lands in a later wave. A CLI-side
265
+ * durable brood is additionally blocked by the sync/async store split
266
+ * (`runBrood` needs the synchronous `HiveGraphStore`; the durable substrate is
267
+ * async — the deferral documented on `AsyncHiveGraphStore`), so it is not
268
+ * simulated against a throwaway store.
269
+ */
270
+ async function runBroodCommand(broodArgs) {
271
+ const invocation = classifyBroodInvocation(broodArgs);
272
+ switch (invocation.kind) {
273
+ case "errors":
274
+ for (const err of invocation.errors)
275
+ process.stderr.write(`nectar brood: ${err}\n`);
276
+ return 2;
277
+ case "dry-run":
278
+ return runBroodDryRun();
279
+ case "run":
280
+ return runBroodMutating(invocation.options);
281
+ default: {
282
+ const unreachable = invocation;
283
+ return unreachable;
284
+ }
285
+ }
286
+ }
287
+ /**
288
+ * Run a mutating brood against the durable async store (AC-018b.8): `runBroodAsync`
289
+ * discovers, mints, describes, and persists to Deep Lake directly (it consumes the
290
+ * async store, so no sync/async bridge is needed here). Returns 0 on success.
291
+ */
292
+ export async function runBroodMutatingVerb(d) {
293
+ const result = await runBroodAsync(d.config, d.deps, d.options ?? {});
294
+ d.out(`nectar brood: discovered ${result.discoveredCount} file(s); ` +
295
+ `${result.describedCount} described, ${result.failedCount} failed` +
296
+ `${result.projectionPath !== null ? `; projection ${result.projectionPath}` : ""}.`);
297
+ return 0;
298
+ }
299
+ /** Run `prune` (preview or `--confirm` delete) against the injected store (AC-018b.8). Returns 0. */
300
+ export function runPruneVerb(deps) {
301
+ runPrune({
302
+ store: deps.store,
303
+ tenancy: deps.tenancy,
304
+ existsOnDisk: (p) => deps.existsOnDisk(p),
305
+ now: deps.now ?? (() => new Date().toISOString()),
306
+ confirm: deps.confirm,
307
+ out: deps.out,
308
+ });
309
+ return 0;
310
+ }
311
+ /** Run `review-matches` against the injected store (AC-018b.8). Returns 0. */
312
+ export async function runReviewMatchesVerb(deps) {
313
+ await runReviewMatches({
314
+ store: deps.store,
315
+ tenancy: deps.tenancy,
316
+ pendingReviews: deps.pendingReviews,
317
+ decide: deps.decide,
318
+ out: deps.out,
319
+ now: deps.now ?? (() => new Date().toISOString()),
320
+ });
321
+ return 0;
322
+ }
323
+ /** The real stdin/stdout-backed {@link InteractiveReviewIo}. */
324
+ function realInteractiveReviewIo() {
325
+ const isTTY = process.stdin.isTTY === true;
326
+ if (!isTTY) {
327
+ return { isTTY, question: async () => "", write: () => { }, close: () => { } };
328
+ }
329
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
330
+ return {
331
+ isTTY,
332
+ question: (prompt) => rl.question(prompt),
333
+ write: (line) => process.stdout.write(`${line}\n`),
334
+ close: () => rl.close(),
335
+ };
336
+ }
337
+ /**
338
+ * A stdin-driven per-candidate decider for the interactive `review-matches`
339
+ * prompt. On a non-TTY stdin (a script, CI) it defaults every candidate to
340
+ * `skip` (the safe, non-destructive choice) rather than blocking on input; a
341
+ * real TTY gets the preview printed, then an accept/reject/skip prompt.
342
+ * Returns a `close` so the caller releases stdin (otherwise the readline
343
+ * interface would keep the process alive).
344
+ *
345
+ * CodeRabbit PR-18 finding #6: the prior implementation's `decide` ignored its
346
+ * `candidate`/`preview` parameters entirely, so on its own it asked
347
+ * accept/reject/skip with zero printed context. `runReviewMatches`
348
+ * (`review-cli.ts`) happens to print the same preview via `out()` immediately
349
+ * before calling `decide` today, but `decide` should not depend on that
350
+ * caller-side ordering to be usable - it prints the preview itself now.
351
+ */
352
+ export function interactiveReviewDecider(io = realInteractiveReviewIo()) {
353
+ if (!io.isTTY) {
354
+ return { decide: async () => "skip", close: io.close };
355
+ }
356
+ return {
357
+ decide: async (_candidate, preview) => {
358
+ io.write(preview);
359
+ const answer = (await io.question(" [a]ccept / [r]eject / [s]kip? ")).trim().toLowerCase();
360
+ if (answer === "a" || answer === "accept")
361
+ return "accept";
362
+ if (answer === "r" || answer === "reject")
363
+ return "reject";
364
+ return "skip";
365
+ },
366
+ close: io.close,
367
+ };
368
+ }
369
+ /**
370
+ * Resolve the embed provider + its active embed model id for the CLI's
371
+ * mutating brood deps, the same way the daemon wiring does
372
+ * (`api/daemon-api-wiring.ts`'s `activeEmbedModel`) - CodeRabbit PR-18 finding
373
+ * #7. Exported so the resolution itself (independent of the live Deep Lake
374
+ * context `runBroodMutating` also needs) is unit-testable without network
375
+ * credentials: without threading `embedModelId` through, CLI-brooded rows
376
+ * stamped `embed_model = null` and were never requeued on a provider switch
377
+ * (AC-018i.3).
378
+ */
379
+ export function resolveCliBroodEmbedDeps() {
380
+ const embeddingsConfig = resolveEmbeddingsConfig({});
381
+ return {
382
+ embedProvider: resolveEmbedProvider(embeddingsConfig),
383
+ embedModelId: activeEmbedModelId(embeddingsConfig),
384
+ };
385
+ }
386
+ /**
387
+ * `nectar brood` (mutating, PRD-018b AC-018b.8): resolve the Deep Lake context,
388
+ * require a Portkey describe transport (an LLM-less brood cannot describe), and
389
+ * run the real `runBroodAsync` against the durable store. Exits 1 (a real error,
390
+ * not a wiring stub) when credentials or Portkey are absent.
391
+ */
392
+ async function runBroodMutating(options) {
393
+ const ctx = resolveProjectionContext();
394
+ if (!ctx.ok) {
395
+ process.stderr.write(`nectar brood: ${ctx.message}.\n` +
396
+ "org_id/workspace_id come from ~/.deeplake/credentials.json; the project id resolves via " +
397
+ "NECTAR_PROJECT_ID > detected HONEYCOMB_PROJECT_ID > ~/.deeplake/projects.json binding > git remote signal > __unsorted__.\n");
398
+ return 1;
399
+ }
400
+ const portkey = resolvePortkeyConfig();
401
+ if (!portkey.enabled) {
402
+ process.stderr.write("nectar brood: a mutating brood needs a describe transport. Configure Portkey " +
403
+ "(PORTKEY_API_KEY + PORTKEY_CONFIG) and retry, or use 'nectar brood --dry-run' for a local cost preview.\n");
404
+ return 1;
405
+ }
406
+ const { embedProvider, embedModelId } = resolveCliBroodEmbedDeps();
407
+ return runBroodMutatingVerb({
408
+ config: {
409
+ store: ctx.store,
410
+ tenancy: ctx.tenancy,
411
+ root: ctx.projectRoot,
412
+ fs: createDiskRegistrationFs(ctx.projectRoot),
413
+ },
414
+ deps: { portkey, embedProvider, embedModelId },
415
+ options,
416
+ out: (line) => process.stdout.write(`${line}\n`),
417
+ });
418
+ }
419
+ /**
420
+ * Build a {@link StoreBridge} over the resolved durable store, hydrate it, run
421
+ * `body` against the SYNC bridge (so the tested `runPrune`/`runReviewMatches`
422
+ * mechanics run unchanged), then flush the durable writes. Returns the body's
423
+ * exit code, or 1 with a printed notice when no Deep Lake context resolves.
424
+ */
425
+ async function withDurableBridge(purpose, body) {
426
+ const ctx = resolveProjectionContext();
427
+ if (!ctx.ok) {
428
+ process.stderr.write(`nectar ${purpose}: ${ctx.message}.\n` +
429
+ "org_id/workspace_id come from ~/.deeplake/credentials.json; the project id resolves via " +
430
+ "NECTAR_PROJECT_ID > detected HONEYCOMB_PROJECT_ID > ~/.deeplake/projects.json binding > git remote signal > __unsorted__.\n");
431
+ return 1;
432
+ }
433
+ const bridge = new StoreBridge({
434
+ durable: ctx.store,
435
+ onFlushError: (err, op) => process.stderr.write(`nectar ${purpose}: durable ${op} failed (non-fatal): ${err instanceof Error ? err.message : String(err)}\n`),
436
+ });
437
+ await bridge.hydrate(ctx.tenancy);
438
+ const code = await body(bridge, ctx);
439
+ await bridge.whenFlushed();
440
+ if (bridge.durableFlushFailures > 0) {
441
+ process.stderr.write(`nectar ${purpose}: ${bridge.durableFlushFailures} durable write(s) failed to flush; ` +
442
+ "the local result above is applied but Deep Lake may be behind. Re-run once connectivity is restored.\n");
443
+ return 1;
444
+ }
445
+ return code;
446
+ }
447
+ /**
448
+ * `nectar prune [--confirm]` (PRD-018b AC-018b.8): the real `runPrune` mechanic
449
+ * against the durable store through the sync/async bridge.
450
+ */
451
+ async function runPruneCommand(args) {
452
+ const confirm = args.includes("--confirm");
453
+ return withDurableBridge("prune", async (bridge, ctx) => {
454
+ const fs = createDiskRegistrationFs(ctx.projectRoot);
455
+ return runPruneVerb({
456
+ store: bridge,
457
+ tenancy: ctx.tenancy,
458
+ existsOnDisk: (p) => fs.existsOnDisk(p),
459
+ confirm,
460
+ out: (line) => process.stdout.write(`${line}\n`),
461
+ });
462
+ });
463
+ }
464
+ /**
465
+ * `nectar review-matches` (PRD-018b AC-018b.8): the real `runReviewMatches`
466
+ * mechanic against the durable store through the sync/async bridge, reading the
467
+ * same file-backed pending-review queue the daemon writes.
468
+ */
469
+ async function runReviewMatchesCommand() {
470
+ const config = resolveConfig();
471
+ const reviews = new FilePendingReviewStore(join(config.runtimeDir, "pending-reviews.json"));
472
+ const decider = interactiveReviewDecider();
473
+ try {
474
+ return await withDurableBridge("review-matches", (bridge, ctx) => runReviewMatchesVerb({
475
+ store: bridge,
476
+ tenancy: ctx.tenancy,
477
+ pendingReviews: reviews,
478
+ decide: decider.decide,
479
+ out: (line) => process.stdout.write(`${line}\n`),
480
+ }));
481
+ }
482
+ finally {
483
+ decider.close();
484
+ }
485
+ }
486
+ /**
487
+ * Parse `nectar search <query> [--limit N] [--json]`. The positional
488
+ * (non-flag) tokens join into the query; `--limit N`/`--limit=N` sets the cap
489
+ * (a non-positive-integer value is an error); `--json` emits raw JSON. A
490
+ * missing query or an unknown flag is an error.
491
+ */
492
+ export function parseSearchArgs(args) {
493
+ const errors = [];
494
+ const queryParts = [];
495
+ let limit;
496
+ let json = false;
497
+ for (let i = 0; i < args.length; i++) {
498
+ const arg = args[i] ?? "";
499
+ if (arg === "--json") {
500
+ json = true;
501
+ }
502
+ else if (arg === "--limit") {
503
+ const raw = args[i + 1];
504
+ if (raw === undefined) {
505
+ errors.push("--limit requires a value");
506
+ }
507
+ else {
508
+ const n = Number.parseInt(raw, 10);
509
+ if (!Number.isFinite(n) || n < 1 || String(n) !== raw)
510
+ errors.push(`--limit expects a positive integer, got '${raw}'`);
511
+ else
512
+ limit = n;
513
+ i++;
514
+ }
515
+ }
516
+ else if (arg.startsWith("--limit=")) {
517
+ const raw = arg.slice("--limit=".length);
518
+ const n = Number.parseInt(raw, 10);
519
+ if (!Number.isFinite(n) || n < 1 || String(n) !== raw)
520
+ errors.push(`--limit expects a positive integer, got '${raw}'`);
521
+ else
522
+ limit = n;
523
+ }
524
+ else if (arg.startsWith("--")) {
525
+ errors.push(`unknown flag '${arg}'`);
526
+ }
527
+ else {
528
+ queryParts.push(arg);
529
+ }
530
+ }
531
+ const query = queryParts.join(" ").trim();
532
+ if (query === "")
533
+ errors.push("a query is required: nectar search <query> [--limit N] [--json]");
534
+ if (errors.length > 0)
535
+ return { kind: "errors", errors };
536
+ return { kind: "run", query, limit, json };
537
+ }
538
+ /** Truncate a one-line preview of a description for the human table. */
539
+ function truncateCell(value, max = 72) {
540
+ const oneLine = value.replace(/\s+/g, " ").trim();
541
+ return oneLine.length <= max ? oneLine : `${oneLine.slice(0, max - 1)}\u2026`;
542
+ }
543
+ /** Render the engine result as a human-readable ranked table (default, non-`--json`). */
544
+ export function renderSearchTable(result) {
545
+ const lines = [];
546
+ if (result.hits.length === 0) {
547
+ lines.push("No matching files.");
548
+ }
549
+ else {
550
+ lines.push(`${result.hits.length} result${result.hits.length === 1 ? "" : "s"}:`);
551
+ result.hits.forEach((hit, index) => {
552
+ lines.push(` ${index + 1}. ${hit.path}`);
553
+ if (hit.title.trim() !== "")
554
+ lines.push(` ${truncateCell(hit.title)}`);
555
+ if (hit.body.trim() !== "")
556
+ lines.push(` ${truncateCell(hit.body)}`);
557
+ });
558
+ }
559
+ if (result.degraded) {
560
+ lines.push("");
561
+ if (result.reason === "backend-error") {
562
+ lines.push("(degraded: one or more search backends failed; use --json for arm status)");
563
+ }
564
+ else {
565
+ lines.push("(degraded: semantic search did not run; results are lexical-only)");
566
+ }
567
+ }
568
+ return `${lines.join("\n")}\n`;
569
+ }
570
+ /**
571
+ * `nectar search <query> [--limit N] [--json]` (PRD-012b): a THIN loopback
572
+ * client of the daemon's `POST /api/hive-graph/search` endpoint (PRD-008b). It
573
+ * never imports the search engine or any Deep Lake path (AC-012b.3.1) — it only
574
+ * reaches the running daemon over loopback. When the daemon is not running the
575
+ * connection failure is reported clearly and the verb exits non-zero with NO
576
+ * local fallback (AC-012b.3.2).
577
+ */
578
+ async function runSearchCommand(args) {
579
+ const invocation = parseSearchArgs(args);
580
+ if (invocation.kind === "errors") {
581
+ for (const err of invocation.errors)
582
+ process.stderr.write(`nectar search: ${err}\n`);
583
+ return 2;
584
+ }
585
+ const config = resolveConfig();
586
+ try {
587
+ const result = await searchViaDaemon({
588
+ host: config.host,
589
+ port: config.port,
590
+ query: invocation.query,
591
+ limit: invocation.limit,
592
+ });
593
+ if (invocation.json)
594
+ process.stdout.write(`${JSON.stringify(result)}\n`);
595
+ else
596
+ process.stdout.write(renderSearchTable(result));
597
+ return 0;
598
+ }
599
+ catch (err) {
600
+ if (err instanceof DaemonUnreachableError) {
601
+ process.stderr.write(`nectar search: the nectar daemon is not reachable on ${config.host}:${config.port} (${err.message}).\n` +
602
+ "Start it with 'nectar daemon'. Search reaches the running daemon over loopback and does not fall back to a local index.\n");
603
+ return 2;
604
+ }
605
+ if (err instanceof DaemonSearchError) {
606
+ process.stderr.write(`nectar search: the daemon rejected the search: ${err.message}\n`);
607
+ return 1;
608
+ }
609
+ process.stderr.write(`nectar search: ${err instanceof Error ? err.message : String(err)}\n`);
610
+ return 1;
611
+ }
612
+ }
613
+ /**
614
+ * Build the boot projection load seam for the live daemon (PRD-011b AC-6): if a
615
+ * project context resolves, the daemon validates `.honeycomb/nectars.json` on
616
+ * boot and inherits hash-matched files into the durable Deep Lake store. All
617
+ * work is deferred to lazy providers so nothing scans disk or hits the network
618
+ * until AFTER the daemon is accepting requests; fail-soft throughout (a missing
619
+ * credentials file just skips the pre-warm). Returns undefined when no context
620
+ * resolves, so `nectar daemon` still starts on a bare machine.
621
+ */
622
+ function resolveBootProjection() {
623
+ const ctx = resolveProjectionContext();
624
+ if (!ctx.ok)
625
+ return undefined;
626
+ const { store, tenancy, projectRoot } = ctx;
627
+ return {
628
+ tenancy,
629
+ filePath: projectionFinalPath(projectRoot, DEFAULT_PROJECTION_REL_PATH),
630
+ diskHashes: () => {
631
+ const discovery = discoverFiles({ root: projectRoot, fs: createDiskRegistrationFs(projectRoot) });
632
+ const prepared = prepareFiles(createDiskRegistrationFs(projectRoot), discovery.files);
633
+ return new Map(prepared.map((p) => [p.file.relPath, p.contentHash]));
634
+ },
635
+ existingNectars: async () => {
636
+ const latest = await store.listLatestVersions(tenancy);
637
+ return new Set(latest.map((lv) => lv.identity.nectar));
638
+ },
639
+ write: async (rows) => {
640
+ for (const row of rows) {
641
+ if ((await store.getIdentity(row.identity.nectar)) === undefined) {
642
+ await store.insertIdentity(row.identity);
643
+ }
644
+ await store.appendVersion(row.version);
645
+ }
646
+ },
647
+ };
648
+ }
649
+ /** Resolve the Deep Lake project context, swallowing a missing-creds error into `undefined`. */
650
+ function safeResolveContext() {
651
+ try {
652
+ const result = resolveProjectionContext();
653
+ return result.ok ? result : undefined;
654
+ }
655
+ catch {
656
+ return undefined;
657
+ }
658
+ }
659
+ /** A metrics sink that delegates to the daemon's CURRENT telemetry (fresh per start()), for the live build brood path. */
660
+ function daemonMetricsProxy(daemon) {
661
+ return {
662
+ incrementFilesRegistered: () => daemon.telemetry().metrics.incrementFilesRegistered(),
663
+ incrementNectarsMinted: () => daemon.telemetry().metrics.incrementNectarsMinted(),
664
+ incrementDescriptionsGenerated: () => daemon.telemetry().metrics.incrementDescriptionsGenerated(),
665
+ incrementHiveGraphVersions: () => daemon.telemetry().metrics.incrementHiveGraphVersions(),
666
+ incrementEmbeddingsComputed: () => daemon.telemetry().metrics.incrementEmbeddingsComputed(),
667
+ };
668
+ }
669
+ /**
670
+ * Build the durable enricher store (hydrated per-nectar-latest from the async
671
+ * store, write-through UPDATEs over the daemon's transport) and a disk content
672
+ * reader for the live enricher cycle. `AsyncHiveGraphStore` exposes only
673
+ * latest-per-nectar reads, so hydration seeds the enricher's pending-selection
674
+ * working set from `listLatestVersions`; per-nectar history (cosmetic-inherit's
675
+ * `priorDescribedVersion`) is not carried across a cold boot, so that step
676
+ * degrades to a fresh describe rather than an inherit (documented, honest).
677
+ */
678
+ function buildLiveDurableWiring(ctx, portkey) {
679
+ const fs = createDiskRegistrationFs(ctx.projectRoot);
680
+ const readContent = {
681
+ read: (path) => {
682
+ const stat = fs.statPath(path);
683
+ if (stat === null)
684
+ return null;
685
+ try {
686
+ return Buffer.from(stat.readContent()).toString("utf8");
687
+ }
688
+ catch {
689
+ return null;
690
+ }
691
+ },
692
+ };
693
+ // PRD-018g / NEC-017: the durable write-back is a collision-safe VERSION-BUMP
694
+ // APPEND (`appendVersionAtNextSeq`), not the retired fire-and-forget in-place
695
+ // UPDATE. The cycle awaits it and only counts a file described on a confirmed
696
+ // durable write.
697
+ const enricher = new DeepLakeEnricherStore({
698
+ loadVersions: async (tenancy) => (await ctx.store.listLatestVersions(tenancy)).map((lv) => lv.version),
699
+ appendVersion: (row) => ctx.store.appendVersionAtNextSeq(row),
700
+ onWriteBackError: (err) => {
701
+ process.stderr.write(`nectar enricher: durable write-back failed (non-fatal): ${err instanceof Error ? err.message : String(err)}\n`);
702
+ },
703
+ });
704
+ return { portkey, enricher, readContent };
705
+ }
706
+ async function runDaemon() {
707
+ const ctx = safeResolveContext();
708
+ const portkey = resolvePortkeyConfig();
709
+ const embeddingsConfig = resolveEmbeddingsConfig({});
710
+ // AC-018i.7: catch a wrong NECTAR_EMBEDDINGS_OUTPUT_DIMENSION at config
711
+ // resolution and warn loudly rather than silently nulling every hosted vector.
712
+ const dimCheck = validateEmbedDimension(embeddingsConfig);
713
+ if (!dimCheck.ok)
714
+ process.stderr.write(`nectar daemon: ${dimCheck.message ?? "invalid embedding output dimension"}\n`);
715
+ // AC-018i.8: wire the dim-rejection sink at the daemon-path resolveEmbedProvider
716
+ // call site (the API path wires it separately in daemon-api-wiring).
717
+ const embedProvider = resolveEmbedProvider(embeddingsConfig, {
718
+ onDimRejected: stderrDimRejectionSink,
719
+ });
720
+ const embedModel = activeEmbedModelId(embeddingsConfig);
721
+ let bootProjection;
722
+ try {
723
+ bootProjection = resolveBootProjection();
724
+ }
725
+ catch {
726
+ // fail-soft: a boot pre-warm is best-effort and never blocks the daemon start.
727
+ bootProjection = undefined;
728
+ }
729
+ // Durable brood + enrich run live only when Deep Lake creds resolve AND a
730
+ // Portkey describe transport is configured: an LLM-less daemon genuinely
731
+ // cannot brood or enrich, so it stays dormant (honest, and no false-fail
732
+ // marking of pending rows). This is the bridge that closes the Wave D dormancy.
733
+ const live = ctx !== undefined && portkey.enabled ? buildLiveDurableWiring(ctx, portkey) : undefined;
734
+ // PRD-018k / NEC-023: resolve the brood prerequisites so a dormant daemon
735
+ // surfaces WHY on /health and in the startup log (and, on a TTY, prints the
736
+ // guided first-run steps below). PRD-018k / NEC-041: resolve the per-repo
737
+ // tunables (`~/.honeycomb/nectar.json`, env-over-file) once at boot.
738
+ const broodPrereqs = broodPrereqsFromEnv({ credentialsPresent: ctx !== undefined, credentialsPath: credentialsPath() });
739
+ const tunables = resolveNectarTunables();
740
+ const options = {
741
+ broodPrereqs,
742
+ ...(bootProjection !== undefined ? { bootProjection } : {}),
743
+ // PRD-018b: when Deep Lake creds resolve, start the update-on-change watch
744
+ // pipeline against the durable store (the watch leg needs no LLM - it appends
745
+ // pending version rows the enricher describes later). Absent creds -> the
746
+ // watch leg stays dormant and /health says so (AC-018b.7).
747
+ ...(ctx !== undefined
748
+ ? { tenancy: ctx.tenancy, projectRoot: ctx.projectRoot, registrationStore: ctx.store }
749
+ : {}),
750
+ ...(live !== undefined && ctx !== undefined
751
+ ? {
752
+ asyncBroodStore: ctx.store,
753
+ // AC-018i.1: stamp embed_model on auto-brood-embedded rows.
754
+ broodDepsAsync: { portkey: live.portkey, embedProvider, embedModelId: embedModel },
755
+ enricherStore: live.enricher,
756
+ enricherCycle: {
757
+ readContent: live.readContent,
758
+ portkey: live.portkey,
759
+ embedProvider,
760
+ // PRD-018k / NEC-041 AC-018k.6: source the redescribe threshold from
761
+ // ~/.honeycomb/nectar.json (env-over-file), falling back to the code
762
+ // default when neither the env var nor the file supplies one.
763
+ ...(tunables.redescribeThreshold !== undefined
764
+ ? { config: { redescribeThreshold: tunables.redescribeThreshold } }
765
+ : {}),
766
+ // AC-018i.1: stamp embed_model on enricher-embedded rows.
767
+ embedModel,
768
+ // AC-018g.6: re-seed the working set each cycle from the durable store.
769
+ refreshWorkingSet: () => live.enricher.refresh(ctx.tenancy),
770
+ // AC-018g.9: prior-content cache backs the cosmetic-change gate.
771
+ priorContentCache: createPriorContentCache(),
772
+ // AC-018g.11/.12: trigger #2 - a debounced projection write after a
773
+ // cycle that wrote descriptions, sourced from the enricher mirror.
774
+ projectionWriter: new ProjectionWriter({ projectRoot: ctx.projectRoot }),
775
+ projectionDoc: () => live.enricher.buildProjectionDoc(ctx.tenancy),
776
+ // Surface the underlying describe-batch error; without this the
777
+ // persistent-failure alert can trip with nothing in the logs to
778
+ // diagnose (2026-07-03 production soak stall).
779
+ onDescribeError: (err, paths) => {
780
+ process.stderr.write(`nectar enricher: describe batch failed (${paths.length} file(s), first: ${paths[0] ?? "?"}): ` +
781
+ `${err instanceof Error ? err.message : String(err)}\n`);
782
+ },
783
+ },
784
+ }
785
+ : {}),
786
+ };
787
+ const daemon = assembleDaemon(options);
788
+ // PRD-008: attach the /api/hive-graph handlers once, after assembleDaemon,
789
+ // mirroring mountGraphApi. When Deep Lake creds resolve the group is filled,
790
+ // and the LIVE build endpoint broods (when Portkey is configured); otherwise
791
+ // the group stays scaffolded + protected but unfilled (an honest 501 scaffold).
792
+ try {
793
+ if (ctx !== undefined) {
794
+ mountHiveGraphApi(daemon, buildHiveGraphApiOptions({
795
+ credentials: ctx.credentials,
796
+ tenancy: ctx.tenancy,
797
+ projectRoot: ctx.projectRoot,
798
+ store: ctx.store,
799
+ costSpentUsd: () => daemon.health.snapshot().cost.broodTotalUsd,
800
+ // PRD-018k / NEC-041 AC-018k.7: thread the loaded recall multiplier into
801
+ // the live search deps (the config surface reaches the recall path).
802
+ ...(tunables.recallMultiplier !== undefined ? { recallMultiplier: tunables.recallMultiplier } : {}),
803
+ brood: { portkey, embedProvider, metrics: daemonMetricsProxy(daemon) },
804
+ // AC-018g.2: share the daemon's brood guard with the API /build handler.
805
+ broodGuard: daemon.broodGuard,
806
+ }));
807
+ }
808
+ }
809
+ catch {
810
+ // fail-soft: a wiring failure never blocks the daemon from serving /health.
811
+ }
812
+ daemon.installSignalHandlers();
813
+ const port = await daemon.start();
814
+ process.stdout.write(`nectar daemon listening on http://${daemon.config.host}:${port}/health\n`);
815
+ // PRD-018k / NEC-023 (AC-018k.5, option B): a guided first-run experience.
816
+ // When brooding is dormant AND this is an interactive terminal, print the
817
+ // exact steps to configure the prerequisites. Never block or prompt; in a
818
+ // non-interactive context (a service unit, CI) nothing is printed - the loud
819
+ // startup log line already carried the machine-readable dormancy reason.
820
+ if (!broodPrereqs.ready && process.stdout.isTTY === true) {
821
+ process.stdout.write(formatFirstRunGuidance(broodPrereqs));
822
+ }
823
+ // Hydrate the durable enricher's working set from Deep Lake in the BACKGROUND
824
+ // (never blocks readiness; fail-soft). The enricher loop sees an empty working
825
+ // set until this settles, then picks up the seeded pending rows on its next cycle.
826
+ if (live !== undefined && ctx !== undefined) {
827
+ void live.enricher.hydrate(ctx.tenancy).catch((err) => {
828
+ process.stderr.write(`nectar daemon: enricher hydrate failed (non-fatal): ${err instanceof Error ? err.message : String(err)}\n`);
829
+ });
830
+ }
831
+ // Usage telemetry: first_run (once per machine) + updated (on a version
832
+ // change) fire AFTER a successful bind. Fire-and-forget: recordDaemonStart
833
+ // never throws and the daemon does not wait on it.
834
+ void recordDaemonStart();
835
+ // Keep the process alive; shutdown is driven by SIGINT/SIGTERM.
836
+ }
837
+ async function main(argv) {
838
+ const command = argv[0];
839
+ if (command === undefined || command === "--help" || command === "-h" || command === "help") {
840
+ process.stdout.write(USAGE);
841
+ return 0;
842
+ }
843
+ if (command === "daemon") {
844
+ await runDaemon();
845
+ return 0;
846
+ }
847
+ if (command === "install") {
848
+ return runInstall();
849
+ }
850
+ if (command === "uninstall") {
851
+ return runUninstall();
852
+ }
853
+ if (command === "service-status") {
854
+ return runServiceStatus();
855
+ }
856
+ if (command === "rebuild-projection") {
857
+ return runRebuildProjection();
858
+ }
859
+ if (command === "brood") {
860
+ return runBroodCommand(argv.slice(1));
861
+ }
862
+ if (command === "prune") {
863
+ return runPruneCommand(argv.slice(1));
864
+ }
865
+ if (command === "review-matches") {
866
+ return runReviewMatchesCommand();
867
+ }
868
+ if (command === "search") {
869
+ return runSearchCommand(argv.slice(1));
870
+ }
871
+ // `project` currently exposes only its `--rebuild-projection` flag (PRD-011c);
872
+ // the broader project verb surface lands with a later PRD.
873
+ if (command === "project") {
874
+ const flags = argv.slice(1);
875
+ if (flags.includes("--rebuild-projection")) {
876
+ return runRebuildProjection();
877
+ }
878
+ process.stderr.write("nectar project: only 'project --rebuild-projection' is implemented (PRD-011c).\n" +
879
+ "The broader project verb surface lands with a later PRD.\n");
880
+ return 2;
881
+ }
882
+ process.stderr.write(`nectar: unknown command '${command}'\n\n${USAGE}`);
883
+ return 1;
884
+ }
885
+ export { main };
886
+ /** True when this module is the process entry point (`node dist/cli.js ...`), not an import. */
887
+ function isDirectRun() {
888
+ const entry = process.argv[1];
889
+ if (entry === undefined)
890
+ return false;
891
+ try {
892
+ return realpathSync(entry) === realpathSync(fileURLToPath(import.meta.url));
893
+ }
894
+ catch {
895
+ return false;
896
+ }
897
+ }
898
+ // Only drive the CLI when executed directly. Importing this module (e.g. from a
899
+ // test that exercises `classifyBroodInvocation`) must not run `main`.
900
+ if (isDirectRun()) {
901
+ main(process.argv.slice(2))
902
+ .then((code) => {
903
+ if (code !== 0)
904
+ process.exit(code);
905
+ // code 0 for `daemon` keeps the event loop alive via the open socket.
906
+ })
907
+ .catch((err) => {
908
+ process.stderr.write(`nectar: ${err instanceof Error ? err.message : String(err)}\n`);
909
+ process.exit(1);
910
+ });
911
+ }
912
+ //# sourceMappingURL=cli.js.map