lurqrun 0.1.6 → 0.1.7

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 (206) hide show
  1. package/README.md +18 -10
  2. package/dist/auditHandler-JCOJSUYW.js +23 -0
  3. package/dist/bin/lurq.js +3090 -23306
  4. package/dist/browserAuth-B6G27USY.js +95 -0
  5. package/dist/cache-DKI34SVS.js +12 -0
  6. package/dist/check-2FDGUOV7.js +192 -0
  7. package/dist/checkUpgrade-F2WESBPM.js +103 -0
  8. package/dist/chunk-2VMOWSRY.js +300 -0
  9. package/dist/chunk-3GHJR7XR.js +2049 -0
  10. package/dist/chunk-3N3Q3DSW.js +214 -0
  11. package/dist/chunk-4ESO33J6.js +34 -0
  12. package/dist/chunk-4F7ZESPO.js +132 -0
  13. package/dist/chunk-4KCPOMG6.js +68 -0
  14. package/dist/chunk-4ZYCIMY4.js +155 -0
  15. package/dist/chunk-63MUJNZL.js +318 -0
  16. package/dist/chunk-6AAEVQ7I.js +6336 -0
  17. package/dist/chunk-6EQ3ARXA.js +304 -0
  18. package/dist/chunk-6L3U7DZ5.js +23 -0
  19. package/dist/chunk-AHBP533R.js +220 -0
  20. package/dist/chunk-B43LCXBM.js +223 -0
  21. package/dist/chunk-BCANRN5B.js +33 -0
  22. package/dist/chunk-BUALU27S.js +123 -0
  23. package/dist/chunk-BULZAX2U.js +1554 -0
  24. package/dist/chunk-BV32UNLL.js +154 -0
  25. package/dist/chunk-C6GLE626.js +160 -0
  26. package/dist/chunk-CIDWNUAP.js +145 -0
  27. package/dist/chunk-CUP36ND3.js +2126 -0
  28. package/dist/chunk-CW5HJ3LX.js +96 -0
  29. package/dist/chunk-DB2VF5UD.js +315 -0
  30. package/dist/chunk-DWAGCNEL.js +210 -0
  31. package/dist/chunk-EA3DP5HG.js +293 -0
  32. package/dist/chunk-ELGCAM7P.js +184 -0
  33. package/dist/chunk-FW6BD2NO.js +1915 -0
  34. package/dist/chunk-GE37NVLN.js +15 -0
  35. package/dist/chunk-GPTKSNR6.js +171 -0
  36. package/dist/chunk-GRJXQBQZ.js +793 -0
  37. package/dist/chunk-HWBBVLOT.js +92 -0
  38. package/dist/chunk-I2JUKN6Z.js +24 -0
  39. package/dist/chunk-I3M2KJXB.js +56 -0
  40. package/dist/chunk-IQ4SDKKY.js +733 -0
  41. package/dist/chunk-J5FZYN4A.js +116 -0
  42. package/dist/chunk-L6N4JFW2.js +263 -0
  43. package/dist/chunk-LBFGSSF2.js +126 -0
  44. package/dist/chunk-LEGPB7DO.js +81 -0
  45. package/dist/chunk-LO35HLQZ.js +219 -0
  46. package/dist/chunk-LRD4GBYE.js +73 -0
  47. package/dist/chunk-LUAKDHLZ.js +40 -0
  48. package/dist/chunk-LYMPYETA.js +965 -0
  49. package/dist/chunk-M6NYEXCW.js +38 -0
  50. package/dist/chunk-MHUEVBVO.js +35 -0
  51. package/dist/chunk-MYGSLK44.js +37 -0
  52. package/dist/chunk-NH5I4KHH.js +201 -0
  53. package/dist/chunk-OQS4GUSI.js +1391 -0
  54. package/dist/chunk-PSX3GIAN.js +176 -0
  55. package/dist/chunk-Q5VPF4WI.js +26 -0
  56. package/dist/chunk-QKGYDMWB.js +7409 -0
  57. package/dist/chunk-QSL6QN5X.js +115 -0
  58. package/dist/chunk-SHCEBP3J.js +107 -0
  59. package/dist/chunk-SJOVFF7B.js +201 -0
  60. package/dist/chunk-ST2X2GYN.js +373 -0
  61. package/dist/chunk-TNTXWSYA.js +19 -0
  62. package/dist/chunk-U5AT3TD4.js +2128 -0
  63. package/dist/chunk-UDVNA7EA.js +483 -0
  64. package/dist/chunk-VL2E5T2A.js +109 -0
  65. package/dist/chunk-VLRHFMGJ.js +58 -0
  66. package/dist/chunk-WHX2ZFCG.js +4048 -0
  67. package/dist/chunk-WQ23REYT.js +37 -0
  68. package/dist/chunk-XBIDMHSK.js +15425 -0
  69. package/dist/chunk-Y5GI7RL3.js +66 -0
  70. package/dist/client-IRKAMDYZ.js +15 -0
  71. package/dist/commands-FIL5ET6P.js +911 -0
  72. package/dist/compat-R3UTFQ5Q.js +201 -0
  73. package/dist/dashboardIssue-WYYMBFIB.js +192 -0
  74. package/dist/diff-GZA2774U.js +13 -0
  75. package/dist/dist-4XXIXHHZ.js +12945 -0
  76. package/dist/e2b-FVPHDULZ.js +172 -0
  77. package/dist/extract-NKGKLIVT.js +444 -0
  78. package/dist/fetch-QYTUJVG2.js +22 -0
  79. package/dist/firstTouch-QQTJH4QX.js +55 -0
  80. package/dist/handlers-GEJAVZDK.js +53 -0
  81. package/dist/http-ETPYMBGD.js +5360 -0
  82. package/dist/ingestQueue-VKN4KBIF.js +35 -0
  83. package/dist/install-EK3W2COX.js +20 -0
  84. package/dist/installSkill-VQJWJVCL.js +52 -0
  85. package/dist/inventory-5AWSLJYU.js +31 -0
  86. package/dist/local-XPZMRH5R.js +13 -0
  87. package/dist/mcp-3JHD5SUZ.js +472 -0
  88. package/dist/mcpHandlers-QFN4MCFL.js +22 -0
  89. package/dist/mcpScan-QZHWENIP.js +1871 -0
  90. package/dist/mcpScanWorkflow-JPYCBGC4.js +81 -0
  91. package/dist/mcpStack-BYJCZNIV.js +20 -0
  92. package/dist/packages-THVFMWFP.js +42 -0
  93. package/dist/plan-V4OEI3J4.js +463 -0
  94. package/dist/planView-JRXGCG2N.js +79 -0
  95. package/dist/policy-3P6BGRDN.js +115 -0
  96. package/dist/references-6N7VEPHT.js +14 -0
  97. package/dist/release-4U4ABNSJ.js +128 -0
  98. package/dist/remote-YGCXYI4V.js +32 -0
  99. package/dist/reportRuns-CKQQYLY4.js +64 -0
  100. package/dist/sandbox-MEZLAODF.js +39 -0
  101. package/dist/server-KFUD5X57.js +55 -0
  102. package/dist/surface-V62GE554.js +141 -0
  103. package/dist/surface-YL6O67W3.js +36 -0
  104. package/dist/surfaceHandlers-X2IZKA3E.js +20 -0
  105. package/dist/typecheck-X7U5ELMR.js +268 -0
  106. package/dist/types-M5JP2W3D.js +10 -0
  107. package/dist/uninstall-P7RGBX6G.js +174 -0
  108. package/dist/upgrade-NQ5IWFZB.js +596 -0
  109. package/dist/upgradePlan-A4LRKLEG.js +146 -0
  110. package/dist/userConfig-Z3GQE776.js +20 -0
  111. package/dist/watch-DGFMWUDL.js +214 -0
  112. package/package.json +26 -21
  113. package/templates/agent-rules.md +4 -4
  114. package/templates/skill-instructions.md +13 -14
  115. package/dist/bin/lurq.js.map +0 -1
  116. package/dist/index.d.ts +0 -805
  117. package/dist/index.js +0 -23570
  118. package/dist/index.js.map +0 -1
  119. package/drizzle/0000_confused_fabian_cortez.sql +0 -54
  120. package/drizzle/0001_aspiring_timeslip.sql +0 -15
  121. package/drizzle/0002_lyrical_lila_cheney.sql +0 -14
  122. package/drizzle/0003_violet_giant_girl.sql +0 -14
  123. package/drizzle/0004_slim_valeria_richards.sql +0 -15
  124. package/drizzle/0005_petite_luke_cage.sql +0 -12
  125. package/drizzle/0006_calm_nighthawk.sql +0 -3
  126. package/drizzle/0007_slimy_naoko.sql +0 -1
  127. package/drizzle/0008_peaceful_tigra.sql +0 -1
  128. package/drizzle/0009_smooth_harrier.sql +0 -10
  129. package/drizzle/0010_curved_amphibian.sql +0 -2
  130. package/drizzle/0011_compat_provenance_closures.sql +0 -11
  131. package/drizzle/0012_api_surfaces.sql +0 -9
  132. package/drizzle/0013_nice_thanos.sql +0 -1
  133. package/drizzle/0014_luxuriant_malcolm_colcord.sql +0 -10
  134. package/drizzle/0015_past_fat_cobra.sql +0 -11
  135. package/drizzle/0016_futuristic_junta.sql +0 -50
  136. package/drizzle/0017_absent_grandmaster.sql +0 -20
  137. package/drizzle/0018_rainy_proemial_gods.sql +0 -1
  138. package/drizzle/0019_dashing_korvac.sql +0 -11
  139. package/drizzle/0020_normal_vulture.sql +0 -3
  140. package/drizzle/0021_dazzling_blue_shield.sql +0 -17
  141. package/drizzle/0022_massive_ghost_rider.sql +0 -24
  142. package/drizzle/0023_next_shatterstar.sql +0 -1
  143. package/drizzle/0024_dusty_maelstrom.sql +0 -15
  144. package/drizzle/0025_gifted_harpoon.sql +0 -5
  145. package/drizzle/0026_awesome_mordo.sql +0 -1
  146. package/drizzle/0027_charming_ulik.sql +0 -2
  147. package/drizzle/0028_romantic_loners.sql +0 -2
  148. package/drizzle/0029_busy_korvac.sql +0 -16
  149. package/drizzle/0030_steady_mathemanic.sql +0 -6
  150. package/drizzle/0031_redundant_maginty.sql +0 -2
  151. package/drizzle/0032_stack_resolutions.sql +0 -14
  152. package/drizzle/0033_graceful_tyger_tiger.sql +0 -3
  153. package/drizzle/0034_uneven_thunderbird.sql +0 -1
  154. package/drizzle/0035_api_key_scopes.sql +0 -1
  155. package/drizzle/0036_policy_audit.sql +0 -21
  156. package/drizzle/0037_subscription_seats.sql +0 -1
  157. package/drizzle/0038_symbol_offsets.sql +0 -2
  158. package/drizzle/0039_mcp_runtime_scans.sql +0 -80
  159. package/drizzle/0040_subscription_overage_and_interval.sql +0 -4
  160. package/drizzle/0041_account_email.sql +0 -38
  161. package/drizzle/0042_alert_channels.sql +0 -21
  162. package/drizzle/meta/0000_snapshot.json +0 -370
  163. package/drizzle/meta/0001_snapshot.json +0 -482
  164. package/drizzle/meta/0002_snapshot.json +0 -575
  165. package/drizzle/meta/0003_snapshot.json +0 -667
  166. package/drizzle/meta/0004_snapshot.json +0 -769
  167. package/drizzle/meta/0005_snapshot.json +0 -864
  168. package/drizzle/meta/0006_snapshot.json +0 -882
  169. package/drizzle/meta/0007_snapshot.json +0 -876
  170. package/drizzle/meta/0008_snapshot.json +0 -882
  171. package/drizzle/meta/0009_snapshot.json +0 -948
  172. package/drizzle/meta/0010_snapshot.json +0 -969
  173. package/drizzle/meta/0011_snapshot.json +0 -1049
  174. package/drizzle/meta/0012_snapshot.json +0 -1115
  175. package/drizzle/meta/0013_snapshot.json +0 -1121
  176. package/drizzle/meta/0014_snapshot.json +0 -1190
  177. package/drizzle/meta/0015_snapshot.json +0 -1280
  178. package/drizzle/meta/0016_snapshot.json +0 -1683
  179. package/drizzle/meta/0017_snapshot.json +0 -1834
  180. package/drizzle/meta/0018_snapshot.json +0 -1834
  181. package/drizzle/meta/0019_snapshot.json +0 -1909
  182. package/drizzle/meta/0020_snapshot.json +0 -1921
  183. package/drizzle/meta/0021_snapshot.json +0 -2045
  184. package/drizzle/meta/0022_snapshot.json +0 -2246
  185. package/drizzle/meta/0023_snapshot.json +0 -2252
  186. package/drizzle/meta/0024_snapshot.json +0 -2375
  187. package/drizzle/meta/0025_snapshot.json +0 -2407
  188. package/drizzle/meta/0026_snapshot.json +0 -2413
  189. package/drizzle/meta/0027_snapshot.json +0 -2425
  190. package/drizzle/meta/0028_snapshot.json +0 -2438
  191. package/drizzle/meta/0029_snapshot.json +0 -2546
  192. package/drizzle/meta/0030_snapshot.json +0 -2586
  193. package/drizzle/meta/0031_snapshot.json +0 -2598
  194. package/drizzle/meta/0032_snapshot.json +0 -2699
  195. package/drizzle/meta/0033_snapshot.json +0 -2712
  196. package/drizzle/meta/0034_snapshot.json +0 -2719
  197. package/drizzle/meta/0035_snapshot.json +0 -2726
  198. package/drizzle/meta/0036_snapshot.json +0 -2876
  199. package/drizzle/meta/0037_snapshot.json +0 -2883
  200. package/drizzle/meta/0038_snapshot.json +0 -2895
  201. package/drizzle/meta/0039_snapshot.json +0 -3501
  202. package/drizzle/meta/0040_snapshot.json +0 -3527
  203. package/drizzle/meta/0041_snapshot.json +0 -3824
  204. package/drizzle/meta/0042_snapshot.json +0 -3960
  205. package/drizzle/meta/_journal.json +0 -307
  206. package/src/data/seed.json +0 -253
package/dist/index.d.ts DELETED
@@ -1,805 +0,0 @@
1
- import { z } from 'zod';
2
- import { Command } from 'commander';
3
-
4
- /**
5
- * The single answer to "is it safe to install this?".
6
- *
7
- * This exists because lurq had several. `verify` rolled risk flags into a
8
- * level, `evaluate` reported a health score and a confidence tier, and `audit`
9
- * emitted findings — three code paths deriving safety from overlapping inputs
10
- * and disagreeing about the same package. A tool that answers one question
11
- * three ways has not answered it, and the disagreement always surfaced at the
12
- * worst moment, because the paths diverge exactly where the evidence is thin.
13
- *
14
- * Every surface now calls this and renders what it returns. Adding a signal
15
- * means editing one file, and no caller can accidentally be more reassuring
16
- * than the evidence supports.
17
- *
18
- * Three rules, each of which was a real defect:
19
- *
20
- * 1. A SECURITY FINDING OVERRIDES QUALITY. A package with a known advisory is
21
- * not "safe" because it is popular and well maintained. The health score
22
- * stays a quality measure — it is not fudged — but it never sets the
23
- * verdict, and the verdict is what every surface leads with.
24
- *
25
- * 2. UNKNOWN IS NOT CLEAN. `advisories` is NULL until the package has been
26
- * analysed and `[]` once it has, and collapsing those with `?? []` reported
27
- * "0 advisories" for a package nobody had looked at yet. Missing evidence
28
- * is carried in `unknowns` and suppresses reassurance outright.
29
- *
30
- * 3. A NAME THAT DOES NOT EXIST IS NOT A RISK RATING. It is bad input, and
31
- * saying "high risk" invites the reader to weigh it against a benefit. There
32
- * is no package to weigh.
33
- */
34
-
35
- /**
36
- * `invalid` is deliberately outside `RiskLevel`: it is a statement about the
37
- * INPUT, not about a package, and flattening it into `high` loses the only
38
- * thing the caller can act on — that there is nothing here to install.
39
- */
40
- type VerdictLevel = RiskLevel | 'invalid';
41
- interface SecurityVerdict {
42
- level: VerdictLevel;
43
- /** Why this is not clean, worst first. Empty only when nothing was found. */
44
- reasons: string[];
45
- /**
46
- * What was NOT established. Non-empty means `level` is provisional: it is the
47
- * worst we can currently justify, not the worst that is true.
48
- */
49
- unknowns: string[];
50
- /** Every input needed to justify a clean bill was present. */
51
- complete: boolean;
52
- /**
53
- * Safe to render as reassurance ("looks safe", a green tick).
54
- *
55
- * The one flag every renderer must consult. It requires a low level AND no
56
- * findings AND nothing unchecked, so a caller cannot produce a green tick
57
- * over a gap in the evidence by reading `level` alone.
58
- */
59
- reassuring: boolean;
60
- /** Advisories actually recorded. Null when none have been fetched yet. */
61
- advisoryCount: number | null;
62
- /**
63
- * WHICH version this verdict is about, in words a reader can act on.
64
- *
65
- * Without it the surfaces agree and still mislead. `verify vitest` answers
66
- * about the latest release and says "no problems found"; the audit answers
67
- * about the 2.1.9 you have installed and says "vulnerable". Both are correct
68
- * and they read as a contradiction, because neither said what it was talking
69
- * about. A clean bill for the newest version is not a clean bill for the one
70
- * running in your node_modules.
71
- */
72
- scope: string;
73
- }
74
-
75
- /**
76
- * Shared domain types and the v1 category taxonomy (§8.3).
77
- * These are the stable contracts the rest of the system builds on.
78
- */
79
- /**
80
- * Which registry a package lives in.
81
- *
82
- * `npm` is the default everywhere — every read path defaults to it, so adding
83
- * this type changed no existing behaviour. What it buys is that a package name
84
- * is only unique WITHIN a registry: `requests`, `redis`, `click` and `attrs` all
85
- * exist on both npm and PyPI as entirely unrelated software, and keying on the
86
- * bare name would let one overwrite the other's evidence.
87
- *
88
- * PyPI names normalise before they are stored (PEP 503: `Flask`, `flask` and
89
- * `Flask_SQLAlchemy` are the same project); that belongs in the PyPI client at
90
- * the ingestion boundary, not here, so `name` always holds the canonical form.
91
- */
92
- declare const ECOSYSTEMS: readonly ["npm", "pypi"];
93
- type Ecosystem = (typeof ECOSYSTEMS)[number];
94
- /**
95
- * The registry every existing caller means when it doesn't say.
96
- *
97
- * Every read helper takes `ecosystem` as a DEFAULTED parameter rather than a
98
- * required one. That is what let the composite key land as a pure no-op: not a
99
- * single call site changed, and npm behaviour is bit-identical. A PyPI caller
100
- * passes the argument; nobody else has to care.
101
- *
102
- * ponytail: only `packages` is keyed by registry so far. These are still keyed
103
- * by bare package name and WILL collide once PyPI rows exist — each one is safe
104
- * today only because nothing writes a PyPI row yet, so scope it in the phase
105
- * that first makes it multi-ecosystem, not speculatively now:
106
- *
107
- * package_versions → needed by PyPI compat (per-version requires-dist)
108
- * seed_packages → needed when a PyPI package can join the sync roster
109
- * discovery_queue → needed by PyPI discovery (classifiers + BigQuery seed)
110
- * api_surfaces,
111
- * surface_queue,
112
- * symbols, entities → needed by the Python surface worker
113
- * compat_edges,
114
- * resolved_closures → needed by the `uv` resolve-check
115
- *
116
- * The unscoped reads that go with them live in db/discovery.ts, db/apiSurfaces.ts
117
- * and pipeline/discovery.ts. Adding a PyPI write path without scoping the tables
118
- * it touches is how one registry starts answering for the other.
119
- *
120
- * RETRIEVAL IS THE ONE THIS DEFAULT CANNOT COVER, and it is the one that fails
121
- * quietly. A keyed lookup has a name to disambiguate, so a defaulted argument
122
- * resolves it. `search/recommend.ts` has no name — finding names IS the query —
123
- * so nothing here helps it, and the first PyPI row with an embedding puts
124
- * SQLAlchemy in the results for a TypeScript project. No error, just a wrong
125
- * answer. Retrieval has to take its ecosystem from the REQUEST (the repo whose
126
- * manifest was parsed, an explicit tool argument, or the stack the agent is
127
- * editing), never from a default.
128
- *
129
- * Two notes for whoever wires that up: filtering the HNSW index after the fact
130
- * loses recall — pre-filtered partial indexes per ecosystem keep it — and the
131
- * lexical `search_vector` needs the same treatment, or the hybrid's two halves
132
- * will disagree about which registry they are searching.
133
- */
134
- declare const DEFAULT_ECOSYSTEM: Ecosystem;
135
- /** Category taxonomy for the JS/TS web stack (§8.3). `other` is the fallback. */
136
- declare const CATEGORIES: readonly ["framework", "meta-framework", "state-management", "routing", "orm", "database-client", "ui-component-library", "styling", "forms", "validation", "data-fetching", "http-client", "auth", "testing", "build-tool", "bundler", "linting", "date-time", "animation", "charts", "i18n", "utility", "other"];
137
- type Category = (typeof CATEGORIES)[number];
138
- declare function isCategory(value: string): value is Category;
139
- /** Provenance of a package's stored category (§2A). `curated` comes from the
140
- * seed file or a manual arg; `inferred` was assigned automatically at ingest
141
- * and is safe for a later curation pass to override. */
142
- type CategorySource = 'curated' | 'inferred';
143
- /** How a candidate entered the discovery queue (§2B). `dependency-graph` and
144
- * `recent` are the long-tail channels; `category-search` is keyword-seeded;
145
- * `reactive` is an on-demand query that wasn't tracked yet. */
146
- type DiscoverySource = 'dependency-graph' | 'category-search' | 'recent' | 'reactive'
147
- /** Seen on npm's `_changes` replication feed — a name we had never heard of. */
148
- | 'npm-changes';
149
- /** Lifecycle of a discovery-queue candidate (§2B). */
150
- /**
151
- * `rejected` means the merit gate said no — a verdict about the package, and
152
- * permanent. `failed` means ingest itself kept throwing, which is a verdict
153
- * about us, and is cleared by re-queueing once the bug is fixed. Conflating the
154
- * two would either retry genuine rejects forever or bury a fixable bug.
155
- */
156
- type DiscoveryStatus = 'pending' | 'ingested' | 'rejected' | 'failed';
157
- /**
158
- * Categories for which bundle size is meaningful and Bundlephobia is consulted
159
- * (§9.5). Backend-only categories get a null bundle size, and their efficiency
160
- * weight is redistributed (§10, see scoring).
161
- */
162
- declare const FRONTEND_CATEGORIES: readonly ["ui-component-library", "styling", "state-management", "forms", "validation", "data-fetching", "charts", "animation", "date-time", "utility"];
163
- declare function isFrontendCategory(category: Category | null | undefined): boolean;
164
- /**
165
- * Evidence-trustworthiness label, independent of the numeric score (§10, §1).
166
- * Two-dimensional: `proven`/`emerging` are adoption ladders; `promising` is
167
- * adoption-independent (high intrinsic quality, new package).
168
- */
169
- type Confidence = 'proven' | 'emerging' | 'promising' | 'unproven';
170
- type Runtime = 'browser' | 'node' | 'both';
171
- /** Result of co-installing two package versions in the sandbox (compat matrix). */
172
- type CompatStatus = 'compatible' | 'conflict';
173
- /**
174
- * Evidence class behind a compat edge (§3, §4B). Ordered weakest→strongest for
175
- * upsert precedence: a mined `observed` must never overwrite a sandbox `verified`
176
- * or `conflict`. `declared` = Tier-0 peer/engine semver; `observed` = co-resolved
177
- * in N real dependency graphs; `verified` = sandbox co-install passed; `conflict`
178
- * = declared conflict or a sandbox co-install failed.
179
- */
180
- type CompatProvenance = 'declared' | 'observed' | 'verified' | 'conflict';
181
- /** Upsert precedence: higher wins, so mining can't erase a proven verdict. */
182
- declare const PROVENANCE_RANK: Record<CompatProvenance, number>;
183
- /** Coarse post-install result an agent reports back via `report_outcome` — never
184
- * source code, just whether the recommended package installed / compiled /
185
- * passed tests, or failed. Feeds the recommendation→outcome flywheel (§3.1). */
186
- type BuildSignal = 'installed' | 'compiled' | 'tests_passed' | 'failed';
187
- /** Sandbox verdict surfaced to agents: did this version actually install + load? */
188
- interface BuildVerified {
189
- version: string;
190
- installed: boolean;
191
- loaded: boolean | null;
192
- driver: string;
193
- ranAt: string;
194
- }
195
- /** A map of dependency/peer/engine name → semver range (from a manifest). */
196
- type DependencyRanges = Record<string, string>;
197
- /** `peerDependenciesMeta`: per-peer flags, notably `{ optional: true }`. */
198
- type PeerMeta = Record<string, {
199
- optional?: boolean;
200
- }>;
201
- /** One incompatibility found across a set of packages. */
202
- interface CompatConflict {
203
- /** Where the conflict came from. `peer-deps`/`engines` are Tier-1 (metadata,
204
- * instant, deterministic); `resolve` is npm's own ERESOLVE on the whole set;
205
- * `sandbox` is the empirical co-install under VM isolation.
206
- *
207
- * A `resolve` conflict is about the SET, not a pair — npm reports that these
208
- * packages cannot coexist, not which two are at fault — so `packages` carries
209
- * every member and `enumeratePairs` deliberately does not attribute it. */
210
- source: 'peer-deps' | 'engines' | 'sandbox' | 'resolve';
211
- /** The packages involved in the conflict. */
212
- packages: string[];
213
- detail: string;
214
- /** The same fact as `detail`, structured, so a consumer can lay it out without
215
- * parsing prose. Present on peer-range violations; absent for engine and
216
- * sandbox conflicts, which aren't about a single declared range. */
217
- requirement?: {
218
- /** The peer being asked for. */
219
- peer: string;
220
- /** The range the requirer declares. */
221
- range: string;
222
- /** What the set actually resolves that peer to, when it is in the set. */
223
- resolved: string | null;
224
- };
225
- }
226
- /**
227
- * One unordered pair among the checked members.
228
- *
229
- * A verdict belongs to a pair, not to a package: the same package can sit in a
230
- * held pair and a conflicting one, so grading packages would either contradict
231
- * itself or paint the whole set red. `held` means no declared constraint between
232
- * the two was violated — it does not mean the pair was executed. Nothing here
233
- * has been executed.
234
- */
235
- interface CompatPair {
236
- a: string;
237
- b: string;
238
- status: 'held' | 'conflict';
239
- /** Only on `conflict` — the conflict's own detail string. */
240
- detail?: string;
241
- /** Only on `conflict`, and only for peer-range violations. */
242
- requirement?: CompatConflict['requirement'];
243
- }
244
- /** One stored compat edge surfaced to agents, with its evidence class (§4B). */
245
- interface CompatEvidence {
246
- packages: [string, string];
247
- versions: [string, string];
248
- status: CompatStatus;
249
- provenance: CompatProvenance;
250
- /** Distinct resolved graphs an `observed` edge was witnessed in (0 otherwise).
251
- * Only a newly-fetched closure accrues one; the daily re-mine re-reads closures
252
- * it has already counted and deliberately does not. NOTE: rows minted before
253
- * that fix carry an inflated count (one per sync run, ~16× on average) and are
254
- * only corrected by a backfill, which has not been run. */
255
- witnessCount: number;
256
- }
257
- /**
258
- * How the set-level verdict was established.
259
- *
260
- * `source` distinguishes a cache hit from a resolve we just ran, which matters
261
- * for a caller deciding whether the answer is worth re-checking: a cached entry
262
- * is exact for those versions and immutable, but it was minted at `at` and the
263
- * publish that would have invalidated it may not have been seen yet.
264
- */
265
- interface CompatResolution {
266
- source: 'cache' | 'resolved';
267
- /** True when npm produced a lockfile for the exact set. */
268
- resolved: boolean;
269
- /** 'ERESOLVE' for a proven conflict; null when it resolved. */
270
- reason: 'ERESOLVE' | null;
271
- /** npm's own message on a conflict — names the packages and ranges. */
272
- detail?: string;
273
- /** ISO timestamp the resolution was established. */
274
- at: string;
275
- }
276
- /**
277
- * `compat` output: whole-architecture compatibility for a set of packages.
278
- * Tier-1 peer-dependency/engine analysis + any Tier-2 sandbox conflicts.
279
- */
280
- interface CompatOutput {
281
- packages: string[];
282
- /** Verdict about the *set*, not its pairs:
283
- * - `conflict` — proven broken: a peer-range violation, a sandbox conflict,
284
- * or npm's own ERESOLVE on this exact set.
285
- * - `compatible` — npm resolved these exact versions together.
286
- * - `unknown` — genuinely undetermined: a member we have no version for, or
287
- * a resolve that could not complete. Never a hedge on a set
288
- * we did resolve.
289
- *
290
- * There is deliberately no `likely`. It meant "no pair is known to be broken",
291
- * which is a statement about our coverage rather than about the packages, and
292
- * it was the answer real stacks got almost every time. */
293
- overall: 'compatible' | 'conflict' | 'unknown';
294
- conflicts: CompatConflict[];
295
- /** Packages lurq has no compatibility metadata for (counted toward `unknown`). */
296
- unverified: string[];
297
- /** The exact members the check ran over, name + resolved version. Versions are
298
- * always surfaced here, and the structure is stable for later scraping. */
299
- checked: {
300
- name: string;
301
- version: string | null;
302
- }[];
303
- /** Sandbox-established edges among these packages (verified/conflict) — the
304
- * one pairwise signal that is not derivable from a set resolution. */
305
- evidence: CompatEvidence[];
306
- /** How the set-level verdict was reached. Absent when a declared conflict made
307
- * a resolve unnecessary, or when a member had no version to key on. */
308
- resolution?: CompatResolution;
309
- /** Every unordered pair among `checked`, each with its own verdict — exactly
310
- * n(n−1)/2 entries. `conflicts` lists only what went wrong; this lists what
311
- * was compared, which is what lets a caller show coverage rather than just
312
- * failures. */
313
- pairs: CompatPair[];
314
- }
315
- /** Kind of an exported symbol, from its `.d.ts` declaration. */
316
- type ExportKind = 'function' | 'class' | 'interface' | 'type' | 'enum' | 'variable' | 'namespace' | 'unknown';
317
- /** One normalized exported symbol of a package version's public API surface. */
318
- interface ExportSymbol {
319
- name: string;
320
- kind: ExportKind;
321
- /** Single-line normalized signature (params/return for functions, etc.), or
322
- * null when the declaration carries no useful signature. */
323
- signature: string | null;
324
- }
325
- /** What changed between two API surfaces (§4D). Deltas are computed, not guessed. */
326
- interface SurfaceDelta {
327
- added: ExportSymbol[];
328
- removed: ExportSymbol[];
329
- /** A symbol that disappeared and a near-identical one that appeared — inferred
330
- * by signature similarity, so an agent sees a rename, not remove+add. */
331
- renamed: {
332
- from: ExportSymbol;
333
- to: ExportSymbol;
334
- }[];
335
- /** Same name, changed signature. */
336
- changed: {
337
- name: string;
338
- before: string | null;
339
- after: string | null;
340
- }[];
341
- }
342
- /** `usage` tool output: version-exact API surface + optional delta from a known
343
- * version the agent was trained/working on (§4D). */
344
- interface UsageOutput {
345
- package: string;
346
- version: string | null;
347
- /** Extracted export list, or null when types are unavailable (falls back to
348
- * the README, which is already fetched). */
349
- surface: ExportSymbol[] | null;
350
- available: boolean;
351
- /** Declared `engines` for this exact version (e.g. `{ node: ">=20" }`), or null
352
- * when the manifest declares none. Independent of `available` — the runtime
353
- * floor matters even for untyped packages. */
354
- engines: Record<string, string> | null;
355
- /** Present when a `knownVersion` was supplied and both surfaces resolved. */
356
- delta?: SurfaceDelta & {
357
- fromVersion: string;
358
- };
359
- /** Echo of a requested version the registry has never published. A structured
360
- * flag as well as prose, so an agent can branch on "this release does not
361
- * exist" without parsing `note` — it is a different answer from "we have no
362
- * surface for it yet", and only one of the two means stop. */
363
- unpublishedVersion?: string;
364
- /** Why a requested `knownVersion` delta is absent. Only set when one was asked
365
- * for and could not be produced — silence about a requested comparison reads
366
- * as "no changes", which is the one thing it never means. */
367
- deltaNote?: string;
368
- note?: string;
369
- }
370
- type AdvisorySeverity = 'critical' | 'high' | 'moderate' | 'low' | 'info';
371
- interface Advisory {
372
- id: string;
373
- severity: AdvisorySeverity;
374
- summary: string;
375
- }
376
- /** Sub-scores composing the health score (§10). `efficiency` is null when not
377
- * size-based (backend categories) — its weight is redistributed.
378
- * `quality` (§1) is a standalone, adoption-independent axis — it does NOT feed
379
- * the health composite; it blends with health only at ranking time. Null when
380
- * no manifest signals were available. */
381
- interface ScoreBreakdown {
382
- maintenance: number;
383
- adoption: number;
384
- reliability: number;
385
- efficiency: number | null;
386
- quality: number | null;
387
- /**
388
- * Field evidence (§3.1) — how this package actually fared after agents
389
- * installed it, from `recommendation_outcomes`. `null` means no reports yet
390
- * and the weight is redistributed, exactly like `efficiency`.
391
- *
392
- * Optional rather than required because it postdates the rows already in
393
- * `packages.score_breakdown`: a stored breakdown from before this shipped
394
- * decodes with the key absent, and `undefined` must read as "no evidence",
395
- * never as 0. Treating it as 0 would drop every un-reported package's health
396
- * the moment this deployed.
397
- */
398
- field?: number | null;
399
- }
400
- /**
401
- * Structured usage guide generated at ingest (product refinement: lurq explains,
402
- * not just ranks). Grounded in the package README/description — never fabricated.
403
- * Exact current API specifics are deferred to Context7 via `context7Hint`.
404
- */
405
- interface UsageGuide {
406
- whatItIs: string;
407
- whenToUse: string;
408
- whenNotToUse?: string;
409
- whereItFits: string;
410
- howToWireIn?: string;
411
- context7Hint?: string;
412
- }
413
- /** A single recommendation candidate (§12.3.1). Intentionally compact. */
414
- interface Candidate {
415
- name: string;
416
- category: Category | null;
417
- healthScore: number;
418
- qualityScore: number | null;
419
- confidence: Confidence;
420
- why: string;
421
- latestVersion: string | null;
422
- weeklyDownloads: number | null;
423
- lastReleaseAt: string | null;
424
- repoUrl: string | null;
425
- /**
426
- * The three facts that can reverse an install decision on their own.
427
- *
428
- * `recommend` is the call an agent makes *before* choosing a dependency, and
429
- * it carried none of them: a deprecated package could be returned with nothing
430
- * in the payload saying so, leaving `confidence` and a numeric score as the
431
- * only hints. Deprecation caps the maintenance component and bars `proven`,
432
- * but a low score reads as "less good", not "do not install this". `evaluate`
433
- * and `verify` have always carried these; the tool most likely to precede an
434
- * install should not be the one that hides them.
435
- *
436
- * Emitted even when false/zero — see mcp/compact, which keeps both on purpose,
437
- * so an agent never has to read meaning into an absent field.
438
- */
439
- deprecated: boolean;
440
- archived: boolean;
441
- advisories: number;
442
- }
443
- /** Full evidence read for one package (§12.3.2). */
444
- interface EvaluateOutput {
445
- dataAsOf: string;
446
- stale?: boolean;
447
- name: string;
448
- category: Category | null;
449
- healthScore: number;
450
- qualityScore: number | null;
451
- confidence: Confidence;
452
- scoreBreakdown: ScoreBreakdown;
453
- latestVersion: string | null;
454
- lastReleaseAt: string | null;
455
- weeklyDownloads: number | null;
456
- downloadGrowth90d: number | null;
457
- scorecard: number | null;
458
- bundleMinGzipKb: number | null;
459
- deprecated: boolean;
460
- archived: boolean;
461
- /** The shared safety call — identical to what `verify` and `audit` return. */
462
- verdict: SecurityVerdict;
463
- advisories: Advisory[];
464
- summary: string | null;
465
- usageGuide: UsageGuide | null;
466
- repoUrl: string | null;
467
- /** If this package is superseded, the recommended migration target (§1.2). */
468
- replacedBy?: {
469
- name: string;
470
- reason: string;
471
- } | null;
472
- /** Latest sandbox verdict for this package, if one has been run. */
473
- buildVerified?: BuildVerified | null;
474
- }
475
- /** `verify` output (§12.3.4). */
476
- /** Supply-chain risk gate: high = review before installing (see security/risk). */
477
- type RiskLevel = 'low' | 'medium' | 'high';
478
-
479
- interface VerifyOutput {
480
- exists: boolean;
481
- tracked: boolean;
482
- deprecated: boolean;
483
- archived: boolean;
484
- latestVersion: string | null;
485
- weeklyDownloads: number | null;
486
- riskFlags: string[];
487
- /** Overall supply-chain risk, rolled up from riskFlags. */
488
- risk: RiskLevel;
489
- /** Suspected typosquat target — a popular package this name closely mimics. */
490
- typosquatOf: string | null;
491
- confidence: Confidence | null;
492
- /** Null when this package has never been analysed — NOT the same as zero. */
493
- advisoryCount: number | null;
494
- /** The shared safety call. Read `verdict.reassuring` before showing a tick. */
495
- verdict: SecurityVerdict;
496
- }
497
-
498
- declare const SERVER_NAME = "lurq";
499
- /** Published npm package name (the CLI command and MCP nickname stay `lurq`).
500
- * Keep in sync with package.json "name". */
501
- declare const PACKAGE_NAME = "lurqrun";
502
- /**
503
- * Read from package.json rather than restated, so a release bump cannot leave
504
- * it behind. This used to be a literal under a "keep in sync" comment, and it
505
- * drifted the moment someone bumped package.json alone: 0.0.9 shipped to npm
506
- * announcing itself as 0.0.8.
507
- *
508
- * That is not only cosmetic. github/workflow.ts defaults `cliSpec()` to this
509
- * value and bakes it into the `npx lurqrun@<v>` line of every workflow lurq
510
- * generates, so a stale constant writes users a CI job pinned to a version
511
- * other than the one that wrote it.
512
- *
513
- * The import is resolved at build time — esbuild inlines the JSON, so there is
514
- * no file read at runtime and no dependence on where the bundle sits on disk.
515
- * That last part is why this is an import and not a `readFileSync` of a path
516
- * relative to `import.meta.url`: the public bin lands at dist/bin/lurq.js and
517
- * the library entry at dist/index.js, so any relative path correct for one is
518
- * wrong for the other.
519
- */
520
- declare const VERSION: string;
521
- /** Default hosted endpoint the install wizard writes into agent configs. The
522
- * marketing site is `lurq.run`; the MCP service lives on the `api.` subdomain.
523
- * Overridable per-invocation with `lurq install --url …` or `LURQ_ENDPOINT`. */
524
- declare const DEFAULT_ENDPOINT = "https://api.lurq.run/mcp";
525
- /** Prefix for issued API keys (the rest is high-entropy random). */
526
- declare const API_KEY_PREFIX = "lurq_live_";
527
- /** Embedding vector dimensionality (OpenAI text-embedding-3-small). The local
528
- * fallback embedder produces vectors of the same length so the DB column and
529
- * pgvector index never need to change. */
530
- declare const EMBEDDING_DIM = 1536;
531
- /** A package row is flagged `stale: true` in tool responses once its data is
532
- * older than this (§17). */
533
- declare const STALENESS_DAYS = 7;
534
- /** Per-source persistent-cache TTLs (§17). */
535
- declare const CACHE_TTL: {
536
- readonly npmRegistry: number;
537
- readonly npmDownloads: number;
538
- readonly github: number;
539
- readonly depsDev: number;
540
- readonly bundlephobia: number;
541
- };
542
-
543
- /**
544
- * Load env into process.env exactly once. Safe to call repeatedly.
545
- *
546
- * Layering: if `LURQ_ENV_FILE` is set (e.g. `.env.production`), that file loads
547
- * *first* so its values win, then `.env` fills in the rest (dotenv never
548
- * overrides an already-set key). This is how the explicit prod path works —
549
- * `LURQ_ENV_FILE=.env.production` supplies the prod DATABASE_URL while `.env`
550
- * still provides shared secrets — without prod ever being the ambient default.
551
- */
552
- declare function loadEnv(): void;
553
- declare const EnvSchema: z.ZodObject<{
554
- DATABASE_URL: z.ZodOptional<z.ZodString>;
555
- GITHUB_TOKEN: z.ZodOptional<z.ZodString>;
556
- EMBEDDING_PROVIDER: z.ZodDefault<z.ZodEnum<["openai", "local"]>>;
557
- EMBEDDING_API_KEY: z.ZodOptional<z.ZodString>;
558
- EMBEDDING_MODEL: z.ZodDefault<z.ZodString>;
559
- EMBEDDING_BASE_URL: z.ZodDefault<z.ZodString>;
560
- SUMMARY_PROVIDER: z.ZodDefault<z.ZodEnum<["openai", "none"]>>;
561
- SUMMARY_API_KEY: z.ZodOptional<z.ZodString>;
562
- SUMMARY_MODEL: z.ZodDefault<z.ZodString>;
563
- SUMMARY_BASE_URL: z.ZodDefault<z.ZodString>;
564
- /**
565
- * How many `npm install --package-lock-only` processes may run at once.
566
- *
567
- * Each one holds npm's arborist tree in memory — 200-500MB for a real stack —
568
- * so this is a memory cap wearing a concurrency hat. Eight concurrent resolves
569
- * is ~3GB and will OOM a small container; the work is network-bound anyway, so
570
- * raising it buys throughput only until the box runs out of RAM.
571
- */
572
- LURQ_RESOLVE_CONCURRENCY: z.ZodDefault<z.ZodNumber>;
573
- /**
574
- * Where npm keeps its metadata cache for stack resolution.
575
- *
576
- * Point this at a persistent volume in production. A warm cache is the
577
- * difference between 8.6s and 19.2s on a 15-package stack (measured), and an
578
- * ephemeral container filesystem means every redeploy pays cold cost again for
579
- * the first few hundred resolves. Unset = npm's default location.
580
- */
581
- LURQ_NPM_CACHE_DIR: z.ZodOptional<z.ZodString>;
582
- /** Budget for one stack resolve. Past this the answer is `unknown`, never a
583
- * guess — and nothing is cached, so the next ask gets a real attempt. */
584
- LURQ_RESOLVE_TIMEOUT_MS: z.ZodDefault<z.ZodNumber>;
585
- LURQ_SYNC_CONCURRENCY: z.ZodDefault<z.ZodNumber>;
586
- /** Stalest non-seed packages the daily sync refreshes on top of the seed list.
587
- * This is the rotation rate for everything discovery ingested: index size /
588
- * this = days to come all the way around. Raise it if the sync finishes well
589
- * inside the cron window; lower it if npm starts rate-limiting. 0 disables
590
- * the rotation (seeds only, the pre-rotation behaviour).
591
- *
592
- * It is also the discovery frontier's clock, which is why it is not a small
593
- * number. `graphChannel` re-expands a package only when its `latest_version`
594
- * moves, and nothing observes a version move except this rotation — so at 400
595
- * against a 20.8k index the graph channel could only re-arm on a 52-day lag
596
- * and had gone effectively silent. */
597
- LURQ_SYNC_REFRESH_CAP: z.ZodDefault<z.ZodNumber>;
598
- LOG_LEVEL: z.ZodDefault<z.ZodEnum<["error", "warn", "info", "debug"]>>;
599
- PORT: z.ZodDefault<z.ZodNumber>;
600
- /** Per-API-key rate limit: max requests per window. */
601
- LURQ_RATE_LIMIT_MAX: z.ZodDefault<z.ZodNumber>;
602
- /** Coarser per-IP rate limit (blunts unauthenticated floods before auth). */
603
- LURQ_IP_RATE_LIMIT_MAX: z.ZodDefault<z.ZodNumber>;
604
- /** Per-IP limit for `POST /scan/public`, the one unauthenticated route that
605
- * reads GitHub, queries the database, and queues ingestion work. The coarse
606
- * IP limit is the wrong ceiling for it: 240 scans a minute is nothing for a
607
- * JSON-RPC caller and a great deal of somebody else's GitHub budget. */
608
- LURQ_SCAN_RATE_LIMIT_MAX: z.ZodDefault<z.ZodNumber>;
609
- /** Rate-limit window, milliseconds (applies to both limiters). */
610
- LURQ_RATE_LIMIT_WINDOW_MS: z.ZodDefault<z.ZodNumber>;
611
- /** Bearer token guarding `/metrics`. Unset → the endpoint is disabled (404). */
612
- LURQ_METRICS_TOKEN: z.ZodOptional<z.ZodString>;
613
- /** Shared secret for self-serve key issuance (`POST /keys`). The Clerk-
614
- * authenticated web app presents it to mint a key for a signed-in user. Unset
615
- * → the endpoint is disabled (404). Keep it server-side, never in the client. */
616
- LURQ_ISSUER_SECRET: z.ZodOptional<z.ZodString>;
617
- /** PostHog project token (the public `phc_…` one, same as the web app's).
618
- * Set → the hosted service sends account-keyed product events (key issued,
619
- * tool called) that join the web app's identified visitors. Unset → nothing
620
- * is sent, which is every local and stdio install. */
621
- LURQ_POSTHOG_KEY: z.ZodOptional<z.ZodString>;
622
- /** Resend API key for account email: urgent alerts and the opt-in weekly
623
- * summary. Unset → nothing is sent; the dashboard and CLI still show all of it. */
624
- RESEND_API_KEY: z.ZodOptional<z.ZodString>;
625
- /** Sender, on a Resend-verified domain. */
626
- LURQ_MAIL_FROM: z.ZodDefault<z.ZodString>;
627
- /** Clerk secret key, used only to read a recipient's verified primary email at
628
- * send time — lurq stores no email addresses. Unset → nothing is sent. */
629
- CLERK_SECRET_KEY: z.ZodOptional<z.ZodString>;
630
- /** 32 random bytes, base64 (`openssl rand -base64 32`). Encrypts stored
631
- * Slack/Discord/Teams/webhook URLs, which are credentials. Unset → alert
632
- * channels are disabled rather than stored in the clear. */
633
- LURQ_SECRETS_KEY: z.ZodOptional<z.ZodString>;
634
- STRIPE_SECRET_KEY: z.ZodOptional<z.ZodString>;
635
- /** Signing secret for `POST /billing/webhook`. Unset → the endpoint is 404. */
636
- STRIPE_WEBHOOK_SECRET: z.ZodOptional<z.ZodString>;
637
- /** Price id backing the Pro plan. Unset → Pro cannot be checked out. */
638
- /**
639
- * Whether Stripe Managed Payments applies to our Checkout Sessions: Stripe as
640
- * merchant of record, taking over indirect tax registration and remittance,
641
- * disputes and fraud — the half `automatic_tax` alone does not buy.
642
- *
643
- * ALWAYS SENT, in both directions, and that is the point. Managed Payments has
644
- * an account-level default (on, for accounts created since it shipped), so
645
- * omitting the parameter hands the decision to a dashboard toggle instead of
646
- * to config. That is action at a distance: the same deploy behaves differently
647
- * per account, and the failure it produces is a 400 at the moment someone
648
- * tries to pay. Sending it explicitly makes the deployment the authority.
649
- *
650
- * Defaults true to match the account default. Every product must carry an
651
- * eligible `tax_code` (see billing/provision.ts) or Stripe rejects the session,
652
- * so `false` is the one-variable escape hatch if eligibility is ever in doubt.
653
- */
654
- STRIPE_MANAGED_PAYMENTS: z.ZodEffects<z.ZodDefault<z.ZodEnum<["true", "false"]>>, boolean, "true" | "false" | undefined>;
655
- STRIPE_PRICE_PRO: z.ZodOptional<z.ZodString>;
656
- /** Per-seat Price id backing Team. The subscription quantity is the seat count. */
657
- STRIPE_PRICE_TEAM: z.ZodOptional<z.ZodString>;
658
- /** Yearly Price ids, 20% under twelve months (core/plans ANNUAL_DISCOUNT). */
659
- STRIPE_PRICE_PRO_ANNUAL: z.ZodOptional<z.ZodString>;
660
- STRIPE_PRICE_TEAM_ANNUAL: z.ZodOptional<z.ZodString>;
661
- /** Metered Price billed from the overage meter, attached to monthly Team. */
662
- STRIPE_PRICE_TEAM_OVERAGE: z.ZodOptional<z.ZodString>;
663
- /** Price id backing Enterprise. Normally unset: Enterprise is sold by
664
- * conversation, and `contactOnly` in core/plans.ts is what the page reads. */
665
- STRIPE_PRICE_ENTERPRISE: z.ZodOptional<z.ZodString>;
666
- /** Absolute base URL the checkout returns to, e.g. https://lurq.run. */
667
- LURQ_WEB_URL: z.ZodDefault<z.ZodString>;
668
- /** Numeric App ID from the GitHub App settings page. */
669
- LURQ_GITHUB_APP_ID: z.ZodOptional<z.ZodString>;
670
- /** PEM private key. Accepts literal newlines or `\n` escapes (Railway/Vercel). */
671
- LURQ_GITHUB_APP_PRIVATE_KEY: z.ZodOptional<z.ZodString>;
672
- /** Webhook secret from the same App settings page, so repo changes made on
673
- * GitHub reach us. Unset → `POST /github/webhook` is disabled (404): an
674
- * unverified webhook is an open write endpoint, so no secret means no route. */
675
- LURQ_GITHUB_WEBHOOK_SECRET: z.ZodOptional<z.ZodString>;
676
- LURQ_ENDPOINT: z.ZodOptional<z.ZodString>;
677
- LURQ_API_KEY: z.ZodOptional<z.ZodString>;
678
- E2B_API_KEY: z.ZodOptional<z.ZodString>;
679
- E2B_TEMPLATE: z.ZodOptional<z.ZodString>;
680
- USE_LIVE_API: z.ZodOptional<z.ZodString>;
681
- }, "strip", z.ZodTypeAny, {
682
- EMBEDDING_PROVIDER: "openai" | "local";
683
- EMBEDDING_MODEL: string;
684
- EMBEDDING_BASE_URL: string;
685
- SUMMARY_PROVIDER: "openai" | "none";
686
- SUMMARY_MODEL: string;
687
- SUMMARY_BASE_URL: string;
688
- LURQ_RESOLVE_CONCURRENCY: number;
689
- LURQ_RESOLVE_TIMEOUT_MS: number;
690
- LURQ_SYNC_CONCURRENCY: number;
691
- LURQ_SYNC_REFRESH_CAP: number;
692
- LOG_LEVEL: "info" | "error" | "warn" | "debug";
693
- PORT: number;
694
- LURQ_RATE_LIMIT_MAX: number;
695
- LURQ_IP_RATE_LIMIT_MAX: number;
696
- LURQ_SCAN_RATE_LIMIT_MAX: number;
697
- LURQ_RATE_LIMIT_WINDOW_MS: number;
698
- LURQ_MAIL_FROM: string;
699
- STRIPE_MANAGED_PAYMENTS: boolean;
700
- LURQ_WEB_URL: string;
701
- DATABASE_URL?: string | undefined;
702
- GITHUB_TOKEN?: string | undefined;
703
- EMBEDDING_API_KEY?: string | undefined;
704
- SUMMARY_API_KEY?: string | undefined;
705
- LURQ_NPM_CACHE_DIR?: string | undefined;
706
- LURQ_METRICS_TOKEN?: string | undefined;
707
- LURQ_ISSUER_SECRET?: string | undefined;
708
- LURQ_POSTHOG_KEY?: string | undefined;
709
- RESEND_API_KEY?: string | undefined;
710
- CLERK_SECRET_KEY?: string | undefined;
711
- LURQ_SECRETS_KEY?: string | undefined;
712
- STRIPE_SECRET_KEY?: string | undefined;
713
- STRIPE_WEBHOOK_SECRET?: string | undefined;
714
- STRIPE_PRICE_PRO?: string | undefined;
715
- STRIPE_PRICE_TEAM?: string | undefined;
716
- STRIPE_PRICE_PRO_ANNUAL?: string | undefined;
717
- STRIPE_PRICE_TEAM_ANNUAL?: string | undefined;
718
- STRIPE_PRICE_TEAM_OVERAGE?: string | undefined;
719
- STRIPE_PRICE_ENTERPRISE?: string | undefined;
720
- LURQ_GITHUB_APP_ID?: string | undefined;
721
- LURQ_GITHUB_APP_PRIVATE_KEY?: string | undefined;
722
- LURQ_GITHUB_WEBHOOK_SECRET?: string | undefined;
723
- LURQ_ENDPOINT?: string | undefined;
724
- LURQ_API_KEY?: string | undefined;
725
- E2B_API_KEY?: string | undefined;
726
- E2B_TEMPLATE?: string | undefined;
727
- USE_LIVE_API?: string | undefined;
728
- }, {
729
- DATABASE_URL?: string | undefined;
730
- GITHUB_TOKEN?: string | undefined;
731
- EMBEDDING_PROVIDER?: "openai" | "local" | undefined;
732
- EMBEDDING_API_KEY?: string | undefined;
733
- EMBEDDING_MODEL?: string | undefined;
734
- EMBEDDING_BASE_URL?: string | undefined;
735
- SUMMARY_PROVIDER?: "openai" | "none" | undefined;
736
- SUMMARY_API_KEY?: string | undefined;
737
- SUMMARY_MODEL?: string | undefined;
738
- SUMMARY_BASE_URL?: string | undefined;
739
- LURQ_RESOLVE_CONCURRENCY?: number | undefined;
740
- LURQ_NPM_CACHE_DIR?: string | undefined;
741
- LURQ_RESOLVE_TIMEOUT_MS?: number | undefined;
742
- LURQ_SYNC_CONCURRENCY?: number | undefined;
743
- LURQ_SYNC_REFRESH_CAP?: number | undefined;
744
- LOG_LEVEL?: "info" | "error" | "warn" | "debug" | undefined;
745
- PORT?: number | undefined;
746
- LURQ_RATE_LIMIT_MAX?: number | undefined;
747
- LURQ_IP_RATE_LIMIT_MAX?: number | undefined;
748
- LURQ_SCAN_RATE_LIMIT_MAX?: number | undefined;
749
- LURQ_RATE_LIMIT_WINDOW_MS?: number | undefined;
750
- LURQ_METRICS_TOKEN?: string | undefined;
751
- LURQ_ISSUER_SECRET?: string | undefined;
752
- LURQ_POSTHOG_KEY?: string | undefined;
753
- RESEND_API_KEY?: string | undefined;
754
- LURQ_MAIL_FROM?: string | undefined;
755
- CLERK_SECRET_KEY?: string | undefined;
756
- LURQ_SECRETS_KEY?: string | undefined;
757
- STRIPE_SECRET_KEY?: string | undefined;
758
- STRIPE_WEBHOOK_SECRET?: string | undefined;
759
- STRIPE_MANAGED_PAYMENTS?: "true" | "false" | undefined;
760
- STRIPE_PRICE_PRO?: string | undefined;
761
- STRIPE_PRICE_TEAM?: string | undefined;
762
- STRIPE_PRICE_PRO_ANNUAL?: string | undefined;
763
- STRIPE_PRICE_TEAM_ANNUAL?: string | undefined;
764
- STRIPE_PRICE_TEAM_OVERAGE?: string | undefined;
765
- STRIPE_PRICE_ENTERPRISE?: string | undefined;
766
- LURQ_WEB_URL?: string | undefined;
767
- LURQ_GITHUB_APP_ID?: string | undefined;
768
- LURQ_GITHUB_APP_PRIVATE_KEY?: string | undefined;
769
- LURQ_GITHUB_WEBHOOK_SECRET?: string | undefined;
770
- LURQ_ENDPOINT?: string | undefined;
771
- LURQ_API_KEY?: string | undefined;
772
- E2B_API_KEY?: string | undefined;
773
- E2B_TEMPLATE?: string | undefined;
774
- USE_LIVE_API?: string | undefined;
775
- }>;
776
- type Config = z.infer<typeof EnvSchema>;
777
- declare class ConfigError extends Error {
778
- constructor(message: string);
779
- }
780
- /** Parse + validate the environment. Throws ConfigError on malformed values. */
781
- declare function getConfig(): Config;
782
- /**
783
- * Return the config but fail fast if any of the named required keys are absent.
784
- * Use in command handlers that genuinely need them (e.g. sync needs DATABASE_URL).
785
- */
786
- declare function requireConfig<K extends keyof Config>(keys: K[]): Config;
787
-
788
- declare const logger: {
789
- error: (...args: unknown[]) => void;
790
- warn: (...args: unknown[]) => void;
791
- info: (...args: unknown[]) => void;
792
- debug: (...args: unknown[]) => void;
793
- };
794
-
795
- /**
796
- * CLI command wiring (§13). Built with commander. Each command mirrors an MCP
797
- * tool or an operational task. Handlers are filled in across milestones M1–M7;
798
- * the command/option surface here is the final, stable shape.
799
- *
800
- * Every command supports `--json` for machine-readable output.
801
- */
802
-
803
- declare function buildProgram(): Command;
804
-
805
- export { API_KEY_PREFIX, type Advisory, type AdvisorySeverity, type BuildSignal, type BuildVerified, CACHE_TTL, CATEGORIES, type Candidate, type Category, type CategorySource, type CompatConflict, type CompatEvidence, type CompatOutput, type CompatPair, type CompatProvenance, type CompatResolution, type CompatStatus, type Confidence, type Config, ConfigError, DEFAULT_ECOSYSTEM, DEFAULT_ENDPOINT, type DependencyRanges, type DiscoverySource, type DiscoveryStatus, ECOSYSTEMS, EMBEDDING_DIM, type Ecosystem, type EvaluateOutput, type ExportKind, type ExportSymbol, FRONTEND_CATEGORIES, PACKAGE_NAME, PROVENANCE_RANK, type PeerMeta, type RiskLevel, type Runtime, SERVER_NAME, STALENESS_DAYS, type ScoreBreakdown, type SurfaceDelta, type UsageGuide, type UsageOutput, VERSION, type VerifyOutput, buildProgram, getConfig, isCategory, isFrontendCategory, loadEnv, logger, requireConfig };