lurqrun 0.1.6 → 0.1.8

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 (239) hide show
  1. package/README.md +311 -139
  2. package/dist/auditHandler-VWCXSDVO.js +24 -0
  3. package/dist/autopilotInit-Q62MX5M6.js +178 -0
  4. package/dist/bin/lurq.js +3255 -23319
  5. package/dist/browserAuth-J7APSD4P.js +96 -0
  6. package/dist/cache-AEAKCV4I.js +12 -0
  7. package/dist/check-2JTQDQA6.js +2613 -0
  8. package/dist/check-PQSQ2MMA.js +192 -0
  9. package/dist/checkUpgrade-5YW77OBL.js +24 -0
  10. package/dist/chunk-2GAYNIHG.js +40 -0
  11. package/dist/chunk-2O6Z37IT.js +423 -0
  12. package/dist/chunk-2WD4QAH4.js +116 -0
  13. package/dist/chunk-3676XOBU.js +2235 -0
  14. package/dist/chunk-3D2MPGOQ.js +181 -0
  15. package/dist/chunk-3GHJR7XR.js +2049 -0
  16. package/dist/chunk-4ESO33J6.js +34 -0
  17. package/dist/chunk-4JHDSVIN.js +1229 -0
  18. package/dist/chunk-4KCPOMG6.js +68 -0
  19. package/dist/chunk-53SG6XWA.js +141 -0
  20. package/dist/chunk-5ABNDB3I.js +37 -0
  21. package/dist/chunk-5ALIJFDA.js +114 -0
  22. package/dist/chunk-63MUJNZL.js +318 -0
  23. package/dist/chunk-64ZF7KO4.js +1571 -0
  24. package/dist/chunk-6DM6UQFD.js +318 -0
  25. package/dist/chunk-6EQ3ARXA.js +304 -0
  26. package/dist/chunk-6L67QMCP.js +92 -0
  27. package/dist/chunk-72Y2FDVS.js +172 -0
  28. package/dist/chunk-A3TYI2TF.js +288 -0
  29. package/dist/chunk-B2UUYRBX.js +536 -0
  30. package/dist/chunk-BJT2LHAR.js +320 -0
  31. package/dist/chunk-BM3LF5T6.js +132 -0
  32. package/dist/chunk-BN3NM47Q.js +214 -0
  33. package/dist/chunk-BUALU27S.js +123 -0
  34. package/dist/chunk-C6GLE626.js +160 -0
  35. package/dist/chunk-D3K6IZVR.js +12845 -0
  36. package/dist/chunk-D3VTZS7V.js +222 -0
  37. package/dist/chunk-DM37MTOO.js +636 -0
  38. package/dist/chunk-DONTW3NE.js +171 -0
  39. package/dist/chunk-DSROTZ3Z.js +38 -0
  40. package/dist/chunk-ELGCAM7P.js +184 -0
  41. package/dist/chunk-EQCXENKZ.js +130 -0
  42. package/dist/chunk-EYAKM6YN.js +96 -0
  43. package/dist/chunk-FDFPMBCA.js +112 -0
  44. package/dist/chunk-FVYFV5HA.js +154 -0
  45. package/dist/chunk-GE37NVLN.js +15 -0
  46. package/dist/chunk-GM5Y555O.js +143 -0
  47. package/dist/chunk-GRJXQBQZ.js +793 -0
  48. package/dist/chunk-HWFX4BC4.js +177 -0
  49. package/dist/chunk-I3M2KJXB.js +56 -0
  50. package/dist/chunk-IFNONGRQ.js +603 -0
  51. package/dist/chunk-J3U2CPSK.js +136 -0
  52. package/dist/chunk-J6XQ7OPZ.js +74 -0
  53. package/dist/chunk-KMV4Y6R3.js +127 -0
  54. package/dist/chunk-KP5ZDDPE.js +340 -0
  55. package/dist/chunk-KYKSZ3XZ.js +202 -0
  56. package/dist/chunk-LEGPB7DO.js +81 -0
  57. package/dist/chunk-LUAKDHLZ.js +40 -0
  58. package/dist/chunk-MHUEVBVO.js +35 -0
  59. package/dist/chunk-MYGSLK44.js +37 -0
  60. package/dist/chunk-NEZNAPPN.js +41 -0
  61. package/dist/chunk-NPVN2THM.js +197 -0
  62. package/dist/chunk-NYZU5NCW.js +23 -0
  63. package/dist/chunk-O4KHCV6I.js +320 -0
  64. package/dist/chunk-ONDVTXUO.js +240 -0
  65. package/dist/chunk-OTJFHESY.js +176 -0
  66. package/dist/chunk-P6MIKSPY.js +243 -0
  67. package/dist/chunk-Q5VPF4WI.js +26 -0
  68. package/dist/chunk-QCRBX3LV.js +165 -0
  69. package/dist/chunk-QKGYDMWB.js +7409 -0
  70. package/dist/chunk-QSL6QN5X.js +115 -0
  71. package/dist/chunk-QUIMQ7YL.js +73 -0
  72. package/dist/chunk-RG3YLU6E.js +49 -0
  73. package/dist/chunk-SHCEBP3J.js +107 -0
  74. package/dist/chunk-SHZFOSXC.js +462 -0
  75. package/dist/chunk-SOXFMMXC.js +151 -0
  76. package/dist/chunk-TDTYV6QI.js +119 -0
  77. package/dist/chunk-TNTXWSYA.js +19 -0
  78. package/dist/chunk-TUXQ32WE.js +2251 -0
  79. package/dist/chunk-VGCDRK3S.js +37 -0
  80. package/dist/chunk-VLRHFMGJ.js +58 -0
  81. package/dist/chunk-WHX2ZFCG.js +4048 -0
  82. package/dist/chunk-X4W64MHU.js +2005 -0
  83. package/dist/chunk-XBQA4I36.js +92 -0
  84. package/dist/chunk-XGOV6KV4.js +413 -0
  85. package/dist/chunk-XIFQIFSZ.js +940 -0
  86. package/dist/chunk-XLXPVN3Y.js +15393 -0
  87. package/dist/chunk-ZJMLQ37G.js +90 -0
  88. package/dist/client-MU4EUDZV.js +15 -0
  89. package/dist/commands-UOOTMBKA.js +1023 -0
  90. package/dist/compat-Q5DVPITN.js +201 -0
  91. package/dist/constants-DJFOFZ44.js +24 -0
  92. package/dist/dashboardIssue-KBKLQMGC.js +274 -0
  93. package/dist/diff-I4SNUHU3.js +13 -0
  94. package/dist/dist-4XXIXHHZ.js +12945 -0
  95. package/dist/domains-VRT4BRVZ.js +14 -0
  96. package/dist/e2b-FVPHDULZ.js +172 -0
  97. package/dist/env-UN6KGZ7S.js +15 -0
  98. package/dist/envCheck-KUPTORFQ.js +71 -0
  99. package/dist/extract-6WG265BL.js +455 -0
  100. package/dist/fetch-PJ3SC32M.js +22 -0
  101. package/dist/firstTouch-COJCMOB3.js +55 -0
  102. package/dist/fix-3EDWNKW3.js +220 -0
  103. package/dist/handlers-4Q37WIFT.js +55 -0
  104. package/dist/hook-NA66XJLC.js +412 -0
  105. package/dist/http-25GJ6SKK.js +6928 -0
  106. package/dist/ingestQueue-FSVJC3AA.js +37 -0
  107. package/dist/install-G2HHXYJ2.js +20 -0
  108. package/dist/installSkill-5TIMYIJZ.js +70 -0
  109. package/dist/inventory-5AWSLJYU.js +31 -0
  110. package/dist/local-XPZMRH5R.js +13 -0
  111. package/dist/manifest-ENMIC54B.js +13 -0
  112. package/dist/mcp-PENLL2PK.js +500 -0
  113. package/dist/mcpConfig-3LYPRY5Q.js +80 -0
  114. package/dist/mcpHandlers-PO7GENA7.js +22 -0
  115. package/dist/mcpScan-ULP626TQ.js +1735 -0
  116. package/dist/mcpScanWorkflow-27O44FOE.js +98 -0
  117. package/dist/mcpStack-ZNYIFXZ5.js +20 -0
  118. package/dist/model-ASMZWLM7.js +214 -0
  119. package/dist/packages-RWF2LXST.js +40 -0
  120. package/dist/plan-SDILIDZT.js +465 -0
  121. package/dist/planView-ZAKRTGVS.js +82 -0
  122. package/dist/policy-JAGNMQJI.js +115 -0
  123. package/dist/probe-3IK646WN.js +610 -0
  124. package/dist/publicUpgrades-WTBGLDIK.js +42 -0
  125. package/dist/references-I6Y4BSRR.js +16 -0
  126. package/dist/release-7IU2R4YG.js +128 -0
  127. package/dist/remote-FN6225AH.js +42 -0
  128. package/dist/rename-OS6JYBZQ.js +204 -0
  129. package/dist/reportRuns-O4X7ZFTX.js +77 -0
  130. package/dist/safeFetch-COERXGFN.js +19 -0
  131. package/dist/sandbox-SAPSRKEI.js +39 -0
  132. package/dist/sarif-WLVJFJ7U.js +125 -0
  133. package/dist/server-OLTY3NYT.js +59 -0
  134. package/dist/surface-7MHE3RL7.js +143 -0
  135. package/dist/surface-JS2XU3U3.js +38 -0
  136. package/dist/surfaceHandlers-4B6TMZ34.js +20 -0
  137. package/dist/typecheck-NGOKNAJY.js +282 -0
  138. package/dist/types-M5JP2W3D.js +10 -0
  139. package/dist/uninstall-I2IJP5JZ.js +200 -0
  140. package/dist/upgrade-FS26DJGG.js +650 -0
  141. package/dist/upgradePlan-ZS5IOVMZ.js +181 -0
  142. package/dist/upkeepHandler-VFGYXJKB.js +13 -0
  143. package/dist/userConfig-ICASHI47.js +20 -0
  144. package/dist/watch-OCNEUXG6.js +204 -0
  145. package/package.json +26 -20
  146. package/templates/agent-rules.md +4 -4
  147. package/templates/skill-instructions.md +35 -17
  148. package/dist/bin/lurq.js.map +0 -1
  149. package/dist/index.d.ts +0 -805
  150. package/dist/index.js +0 -23570
  151. package/dist/index.js.map +0 -1
  152. package/drizzle/0000_confused_fabian_cortez.sql +0 -54
  153. package/drizzle/0001_aspiring_timeslip.sql +0 -15
  154. package/drizzle/0002_lyrical_lila_cheney.sql +0 -14
  155. package/drizzle/0003_violet_giant_girl.sql +0 -14
  156. package/drizzle/0004_slim_valeria_richards.sql +0 -15
  157. package/drizzle/0005_petite_luke_cage.sql +0 -12
  158. package/drizzle/0006_calm_nighthawk.sql +0 -3
  159. package/drizzle/0007_slimy_naoko.sql +0 -1
  160. package/drizzle/0008_peaceful_tigra.sql +0 -1
  161. package/drizzle/0009_smooth_harrier.sql +0 -10
  162. package/drizzle/0010_curved_amphibian.sql +0 -2
  163. package/drizzle/0011_compat_provenance_closures.sql +0 -11
  164. package/drizzle/0012_api_surfaces.sql +0 -9
  165. package/drizzle/0013_nice_thanos.sql +0 -1
  166. package/drizzle/0014_luxuriant_malcolm_colcord.sql +0 -10
  167. package/drizzle/0015_past_fat_cobra.sql +0 -11
  168. package/drizzle/0016_futuristic_junta.sql +0 -50
  169. package/drizzle/0017_absent_grandmaster.sql +0 -20
  170. package/drizzle/0018_rainy_proemial_gods.sql +0 -1
  171. package/drizzle/0019_dashing_korvac.sql +0 -11
  172. package/drizzle/0020_normal_vulture.sql +0 -3
  173. package/drizzle/0021_dazzling_blue_shield.sql +0 -17
  174. package/drizzle/0022_massive_ghost_rider.sql +0 -24
  175. package/drizzle/0023_next_shatterstar.sql +0 -1
  176. package/drizzle/0024_dusty_maelstrom.sql +0 -15
  177. package/drizzle/0025_gifted_harpoon.sql +0 -5
  178. package/drizzle/0026_awesome_mordo.sql +0 -1
  179. package/drizzle/0027_charming_ulik.sql +0 -2
  180. package/drizzle/0028_romantic_loners.sql +0 -2
  181. package/drizzle/0029_busy_korvac.sql +0 -16
  182. package/drizzle/0030_steady_mathemanic.sql +0 -6
  183. package/drizzle/0031_redundant_maginty.sql +0 -2
  184. package/drizzle/0032_stack_resolutions.sql +0 -14
  185. package/drizzle/0033_graceful_tyger_tiger.sql +0 -3
  186. package/drizzle/0034_uneven_thunderbird.sql +0 -1
  187. package/drizzle/0035_api_key_scopes.sql +0 -1
  188. package/drizzle/0036_policy_audit.sql +0 -21
  189. package/drizzle/0037_subscription_seats.sql +0 -1
  190. package/drizzle/0038_symbol_offsets.sql +0 -2
  191. package/drizzle/0039_mcp_runtime_scans.sql +0 -80
  192. package/drizzle/0040_subscription_overage_and_interval.sql +0 -4
  193. package/drizzle/0041_account_email.sql +0 -38
  194. package/drizzle/0042_alert_channels.sql +0 -21
  195. package/drizzle/meta/0000_snapshot.json +0 -370
  196. package/drizzle/meta/0001_snapshot.json +0 -482
  197. package/drizzle/meta/0002_snapshot.json +0 -575
  198. package/drizzle/meta/0003_snapshot.json +0 -667
  199. package/drizzle/meta/0004_snapshot.json +0 -769
  200. package/drizzle/meta/0005_snapshot.json +0 -864
  201. package/drizzle/meta/0006_snapshot.json +0 -882
  202. package/drizzle/meta/0007_snapshot.json +0 -876
  203. package/drizzle/meta/0008_snapshot.json +0 -882
  204. package/drizzle/meta/0009_snapshot.json +0 -948
  205. package/drizzle/meta/0010_snapshot.json +0 -969
  206. package/drizzle/meta/0011_snapshot.json +0 -1049
  207. package/drizzle/meta/0012_snapshot.json +0 -1115
  208. package/drizzle/meta/0013_snapshot.json +0 -1121
  209. package/drizzle/meta/0014_snapshot.json +0 -1190
  210. package/drizzle/meta/0015_snapshot.json +0 -1280
  211. package/drizzle/meta/0016_snapshot.json +0 -1683
  212. package/drizzle/meta/0017_snapshot.json +0 -1834
  213. package/drizzle/meta/0018_snapshot.json +0 -1834
  214. package/drizzle/meta/0019_snapshot.json +0 -1909
  215. package/drizzle/meta/0020_snapshot.json +0 -1921
  216. package/drizzle/meta/0021_snapshot.json +0 -2045
  217. package/drizzle/meta/0022_snapshot.json +0 -2246
  218. package/drizzle/meta/0023_snapshot.json +0 -2252
  219. package/drizzle/meta/0024_snapshot.json +0 -2375
  220. package/drizzle/meta/0025_snapshot.json +0 -2407
  221. package/drizzle/meta/0026_snapshot.json +0 -2413
  222. package/drizzle/meta/0027_snapshot.json +0 -2425
  223. package/drizzle/meta/0028_snapshot.json +0 -2438
  224. package/drizzle/meta/0029_snapshot.json +0 -2546
  225. package/drizzle/meta/0030_snapshot.json +0 -2586
  226. package/drizzle/meta/0031_snapshot.json +0 -2598
  227. package/drizzle/meta/0032_snapshot.json +0 -2699
  228. package/drizzle/meta/0033_snapshot.json +0 -2712
  229. package/drizzle/meta/0034_snapshot.json +0 -2719
  230. package/drizzle/meta/0035_snapshot.json +0 -2726
  231. package/drizzle/meta/0036_snapshot.json +0 -2876
  232. package/drizzle/meta/0037_snapshot.json +0 -2883
  233. package/drizzle/meta/0038_snapshot.json +0 -2895
  234. package/drizzle/meta/0039_snapshot.json +0 -3501
  235. package/drizzle/meta/0040_snapshot.json +0 -3527
  236. package/drizzle/meta/0041_snapshot.json +0 -3824
  237. package/drizzle/meta/0042_snapshot.json +0 -3960
  238. package/drizzle/meta/_journal.json +0 -307
  239. package/src/data/seed.json +0 -253
@@ -0,0 +1,202 @@
1
+ import { createRequire as __lurqCreateRequire } from 'node:module'; const require = __lurqCreateRequire(import.meta.url);
2
+ import {
3
+ logger
4
+ } from "./chunk-MYGSLK44.js";
5
+ import {
6
+ init_esm_shims
7
+ } from "./chunk-I3M2KJXB.js";
8
+
9
+ // src/core/http.ts
10
+ init_esm_shims();
11
+ import { createHash } from "crypto";
12
+ import { mkdir, readFile, writeFile } from "fs/promises";
13
+ import { existsSync } from "fs";
14
+ import { homedir } from "os";
15
+ import { dirname, join } from "path";
16
+ var HttpError = class extends Error {
17
+ constructor(message, status, url) {
18
+ super(message);
19
+ this.status = status;
20
+ this.url = url;
21
+ this.name = "HttpError";
22
+ }
23
+ status;
24
+ url;
25
+ };
26
+ var DEFAULT_HOST_CONFIG = { maxConcurrent: 6, minIntervalMs: 0 };
27
+ var HOST_CONFIG = {
28
+ "api.github.com": { maxConcurrent: 4, minIntervalMs: 50 },
29
+ "registry.npmjs.org": { maxConcurrent: 4, minIntervalMs: 50 },
30
+ // The downloads API rate-limits aggressively — serialize with a steady gap.
31
+ // Weekly downloads go through the bulk endpoint; only growth hits this often.
32
+ "api.npmjs.org": { maxConcurrent: 1, minIntervalMs: 250 },
33
+ "api.deps.dev": { maxConcurrent: 4, minIntervalMs: 40 },
34
+ "raw.githubusercontent.com": { maxConcurrent: 4, minIntervalMs: 30 },
35
+ // Bundlephobia is slow/flaky — be gentle (§9.5).
36
+ "bundlephobia.com": { maxConcurrent: 2, minIntervalMs: 200 }
37
+ };
38
+ var HostLimiter = class {
39
+ constructor(config) {
40
+ this.config = config;
41
+ }
42
+ config;
43
+ active = 0;
44
+ nextAvailable = 0;
45
+ queue = [];
46
+ async acquire() {
47
+ if (this.active >= this.config.maxConcurrent) {
48
+ await new Promise((resolve) => this.queue.push(resolve));
49
+ }
50
+ this.active++;
51
+ const now = Date.now();
52
+ const wait = Math.max(0, this.nextAvailable - now);
53
+ this.nextAvailable = Math.max(now, this.nextAvailable) + this.config.minIntervalMs;
54
+ if (wait > 0) await delay(wait);
55
+ }
56
+ release() {
57
+ this.active--;
58
+ const next = this.queue.shift();
59
+ if (next) next();
60
+ }
61
+ };
62
+ var limiters = /* @__PURE__ */ new Map();
63
+ function limiterFor(host) {
64
+ let limiter = limiters.get(host);
65
+ if (!limiter) {
66
+ limiter = new HostLimiter(HOST_CONFIG[host] ?? DEFAULT_HOST_CONFIG);
67
+ limiters.set(host, limiter);
68
+ }
69
+ return limiter;
70
+ }
71
+ var MEMORY_CACHE_MAX = 500;
72
+ var memoryCache = /* @__PURE__ */ new Map();
73
+ function memoryCacheSet(key, entry) {
74
+ memoryCache.delete(key);
75
+ memoryCache.set(key, entry);
76
+ if (memoryCache.size > MEMORY_CACHE_MAX) {
77
+ const oldest = memoryCache.keys().next();
78
+ if (!oldest.done) memoryCache.delete(oldest.value);
79
+ }
80
+ }
81
+ var bypassCacheRead = false;
82
+ function cacheDir() {
83
+ return process.env.LURQ_CACHE_DIR ?? join(homedir(), ".cache", "lurq", "http");
84
+ }
85
+ function cacheFile(key) {
86
+ const hash = createHash("sha256").update(key).digest("hex");
87
+ return join(cacheDir(), `${hash}.json`);
88
+ }
89
+ async function readCache(key, ttlMs) {
90
+ const now = Date.now();
91
+ const mem = memoryCache.get(key);
92
+ if (mem && now - mem.fetchedAt < ttlMs) {
93
+ memoryCacheSet(key, mem);
94
+ return mem;
95
+ }
96
+ const file = cacheFile(key);
97
+ if (!existsSync(file)) return void 0;
98
+ try {
99
+ const entry = JSON.parse(await readFile(file, "utf8"));
100
+ if (now - entry.fetchedAt < ttlMs) {
101
+ memoryCacheSet(key, entry);
102
+ return entry;
103
+ }
104
+ } catch {
105
+ }
106
+ return void 0;
107
+ }
108
+ async function writeCache(key, entry) {
109
+ memoryCacheSet(key, entry);
110
+ const file = cacheFile(key);
111
+ try {
112
+ await mkdir(dirname(file), { recursive: true });
113
+ await writeFile(file, JSON.stringify(entry), "utf8");
114
+ } catch (err) {
115
+ logger.debug(`http cache write failed: ${err.message}`);
116
+ }
117
+ }
118
+ var RETRYABLE = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
119
+ async function httpRequest(url, opts) {
120
+ const {
121
+ host,
122
+ ttlMs,
123
+ method = "GET",
124
+ headers = {},
125
+ body,
126
+ accept = "json",
127
+ timeoutMs = 15e3,
128
+ retries = 3,
129
+ fetchImpl = fetch
130
+ } = opts;
131
+ const key = opts.cacheKey ?? `${method} ${url} ${body ?? ""}`;
132
+ if (ttlMs > 0 && !bypassCacheRead && !opts.fresh) {
133
+ const cached = await readCache(key, ttlMs);
134
+ if (cached) {
135
+ return { status: cached.status, data: decode(cached.body, accept), fromCache: true };
136
+ }
137
+ }
138
+ const limiter = limiterFor(host);
139
+ let lastErr;
140
+ for (let attempt = 0; attempt <= retries; attempt++) {
141
+ await limiter.acquire();
142
+ const controller = new AbortController();
143
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
144
+ try {
145
+ const res = await fetchImpl(url, { method, headers, body, signal: controller.signal });
146
+ const text = await res.text();
147
+ if (res.ok) {
148
+ if (ttlMs > 0)
149
+ await writeCache(key, { fetchedAt: Date.now(), status: res.status, body: text });
150
+ return { status: res.status, data: decode(text, accept), fromCache: false };
151
+ }
152
+ if (RETRYABLE.has(res.status) && attempt < retries) {
153
+ const retryAfter = parseRetryAfter(res.headers.get("retry-after"));
154
+ await delay(retryAfter ?? backoff(attempt));
155
+ lastErr = new HttpError(`HTTP ${res.status} for ${url}`, res.status, url);
156
+ continue;
157
+ }
158
+ throw new HttpError(`HTTP ${res.status} for ${url}`, res.status, url);
159
+ } catch (err) {
160
+ lastErr = err;
161
+ const isAbort = err instanceof Error && err.name === "AbortError";
162
+ const isHttp = err instanceof HttpError;
163
+ if (isHttp && !RETRYABLE.has(err.status)) throw err;
164
+ if (attempt < retries) {
165
+ await delay(backoff(attempt));
166
+ continue;
167
+ }
168
+ if (isAbort) throw new HttpError(`Timeout after ${timeoutMs}ms for ${url}`, 0, url);
169
+ } finally {
170
+ clearTimeout(timer);
171
+ limiter.release();
172
+ }
173
+ }
174
+ throw lastErr instanceof Error ? lastErr : new HttpError(`Request failed for ${url}`, 0, url);
175
+ }
176
+ async function httpGetJson(url, opts) {
177
+ return httpRequest(url, { ...opts, method: "GET", accept: "json" });
178
+ }
179
+ function decode(text, accept) {
180
+ if (accept === "text") return text;
181
+ return text ? JSON.parse(text) : null;
182
+ }
183
+ function backoff(attempt) {
184
+ const base = 500 * 2 ** attempt;
185
+ return base + Math.floor(attempt * 137 % 100 * 3);
186
+ }
187
+ function parseRetryAfter(value) {
188
+ if (!value) return void 0;
189
+ const seconds = Number(value);
190
+ if (!Number.isNaN(seconds)) return seconds * 1e3;
191
+ const date = Date.parse(value);
192
+ return Number.isNaN(date) ? void 0 : Math.max(0, date - Date.now());
193
+ }
194
+ function delay(ms) {
195
+ return new Promise((resolve) => setTimeout(resolve, ms));
196
+ }
197
+
198
+ export {
199
+ HttpError,
200
+ httpRequest,
201
+ httpGetJson
202
+ };
@@ -0,0 +1,81 @@
1
+ import { createRequire as __lurqCreateRequire } from 'node:module'; const require = __lurqCreateRequire(import.meta.url);
2
+ import {
3
+ logger
4
+ } from "./chunk-MYGSLK44.js";
5
+ import {
6
+ init_esm_shims
7
+ } from "./chunk-I3M2KJXB.js";
8
+
9
+ // src/surface/mcpRegistry.ts
10
+ init_esm_shims();
11
+ var REGISTRY = "https://registry.modelcontextprotocol.io/v0.1";
12
+ var TIMEOUT_MS = 8e3;
13
+ var memo = /* @__PURE__ */ new Map();
14
+ async function getJson(url) {
15
+ const ctl = new AbortController();
16
+ const timer = setTimeout(() => ctl.abort(), TIMEOUT_MS);
17
+ try {
18
+ const res = await fetch(url, { signal: ctl.signal, headers: { accept: "application/json" } });
19
+ if (!res.ok) return null;
20
+ return await res.json();
21
+ } catch (err) {
22
+ logger.debug?.({ url, err: String(err) }, "mcp registry unreachable");
23
+ return null;
24
+ } finally {
25
+ clearTimeout(timer);
26
+ }
27
+ }
28
+ function toManifest(server, npmPackage) {
29
+ const pkg = (server.packages ?? []).find(
30
+ (p) => p.registryType === "npm" && p.identifier === npmPackage
31
+ );
32
+ const remoteOnly = !pkg && (server.remotes ?? []).length > 0;
33
+ if (!pkg && !remoteOnly) return null;
34
+ const args = [...pkg?.runtimeArguments ?? [], ...pkg?.packageArguments ?? []].map((a) => a.value ?? a.name).filter((a) => typeof a === "string" && a.length > 0);
35
+ return {
36
+ registryName: server.name ?? npmPackage,
37
+ npmPackage,
38
+ version: pkg?.version ?? server.version ?? null,
39
+ transport: pkg?.transport?.type ?? (remoteOnly ? server.remotes?.[0]?.type ?? null : null),
40
+ env: (pkg?.environmentVariables ?? []).map((e) => ({
41
+ name: e.name ?? "",
42
+ description: e.description ?? null,
43
+ required: e.isRequired === true,
44
+ secret: e.isSecret === true,
45
+ format: e.format ?? null
46
+ })).filter((e) => e.name.length > 0),
47
+ args,
48
+ remoteOnly
49
+ };
50
+ }
51
+ async function fetchServerManifest(npmPackage) {
52
+ const hit = memo.get(npmPackage);
53
+ if (hit !== void 0) return hit;
54
+ const body = await getJson(
55
+ `${REGISTRY}/servers?search=${encodeURIComponent(npmPackage)}&limit=20`
56
+ );
57
+ let found = null;
58
+ for (const row of body?.servers ?? []) {
59
+ const m = row.server ? toManifest(row.server, npmPackage) : null;
60
+ if (m) {
61
+ found = m;
62
+ break;
63
+ }
64
+ }
65
+ memo.set(npmPackage, found);
66
+ return found;
67
+ }
68
+ function missingConfig(manifest, env = process.env) {
69
+ return (manifest?.env ?? []).filter((e) => e.required && !env[e.name]);
70
+ }
71
+ function configRequestLine(server, missing) {
72
+ if (missing.length === 0) return "";
73
+ const items = missing.map((m) => `${m.name}${m.description ? ` (${m.description})` : ""}`).join("; ");
74
+ return `${server} declares ${missing.length} required setting(s) before it will start: ${items}. Ask the user to supply ${missing.some((m) => m.secret) ? "these values (at least one is a credential \u2014 take it from the user, never from a log or a guess)" : "these values"}, then re-run the probe with them set.`;
75
+ }
76
+
77
+ export {
78
+ fetchServerManifest,
79
+ missingConfig,
80
+ configRequestLine
81
+ };
@@ -0,0 +1,40 @@
1
+ import { createRequire as __lurqCreateRequire } from 'node:module'; const require = __lurqCreateRequire(import.meta.url);
2
+ import {
3
+ init_esm_shims
4
+ } from "./chunk-I3M2KJXB.js";
5
+
6
+ // src/core/paths.ts
7
+ init_esm_shims();
8
+ import { existsSync } from "fs";
9
+ import { homedir } from "os";
10
+ import { dirname, join } from "path";
11
+ import { fileURLToPath } from "url";
12
+ var cachedRoot;
13
+ function packageRoot() {
14
+ if (cachedRoot) return cachedRoot;
15
+ let dir = dirname(fileURLToPath(import.meta.url));
16
+ for (; ; ) {
17
+ if (existsSync(join(dir, "package.json"))) {
18
+ cachedRoot = dir;
19
+ return dir;
20
+ }
21
+ const parent = dirname(dir);
22
+ if (parent === dir) break;
23
+ dir = parent;
24
+ }
25
+ cachedRoot = process.cwd();
26
+ return cachedRoot;
27
+ }
28
+ function userWeightsPath() {
29
+ const base = process.env.XDG_CONFIG_HOME || join(homedir(), ".config");
30
+ return join(base, "lurq", "weights.json");
31
+ }
32
+ function projectWeightsPath() {
33
+ return join(process.cwd(), ".lurq", "weights.json");
34
+ }
35
+
36
+ export {
37
+ packageRoot,
38
+ userWeightsPath,
39
+ projectWeightsPath
40
+ };
@@ -0,0 +1,35 @@
1
+ import { createRequire as __lurqCreateRequire } from 'node:module'; const require = __lurqCreateRequire(import.meta.url);
2
+ import {
3
+ init_esm_shims
4
+ } from "./chunk-I3M2KJXB.js";
5
+
6
+ // src/core/errors.ts
7
+ init_esm_shims();
8
+ var DEFAULT_MAX = 300;
9
+ function truncate(text, max) {
10
+ if (text.length <= max) return text;
11
+ return `${text.slice(0, max)}\u2026`;
12
+ }
13
+ function causeText(cause) {
14
+ if (cause == null) return null;
15
+ if (cause instanceof Error) {
16
+ const code = "code" in cause && (typeof cause.code === "string" || typeof cause.code === "number") ? String(cause.code) : null;
17
+ const msg = truncate(cause.message, DEFAULT_MAX);
18
+ return code ? `${code}: ${msg}` : msg;
19
+ }
20
+ if (typeof cause === "object" && cause !== null && "message" in cause) {
21
+ const msg = truncate(String(cause.message), DEFAULT_MAX);
22
+ const code = "code" in cause ? String(cause.code) : null;
23
+ return code ? `${code}: ${msg}` : msg;
24
+ }
25
+ return truncate(String(cause), DEFAULT_MAX);
26
+ }
27
+ function formatError(err, max = DEFAULT_MAX) {
28
+ const message = err instanceof Error ? truncate(err.message, max) : truncate(String(err), max);
29
+ const cause = err instanceof Error ? causeText(err.cause) : null;
30
+ return cause ? `${message} (cause: ${cause})` : message;
31
+ }
32
+
33
+ export {
34
+ formatError
35
+ };
@@ -0,0 +1,37 @@
1
+ import { createRequire as __lurqCreateRequire } from 'node:module'; const require = __lurqCreateRequire(import.meta.url);
2
+ import {
3
+ init_esm_shims
4
+ } from "./chunk-I3M2KJXB.js";
5
+
6
+ // src/core/logger.ts
7
+ init_esm_shims();
8
+ var LEVELS = { error: 0, warn: 1, info: 2, debug: 3 };
9
+ function currentLevel() {
10
+ const raw = process.env.LOG_LEVEL;
11
+ return raw && raw in LEVELS ? LEVELS[raw] : LEVELS.info;
12
+ }
13
+ function emit(level, args) {
14
+ if (LEVELS[level] > currentLevel()) return;
15
+ const parts = args.map(
16
+ (a) => typeof a === "string" ? a : a instanceof Error ? a.stack ?? a.message : safeStringify(a)
17
+ );
18
+ process.stderr.write(`[lurq] ${level.toUpperCase()} ${parts.join(" ")}
19
+ `);
20
+ }
21
+ function safeStringify(value) {
22
+ try {
23
+ return JSON.stringify(value);
24
+ } catch {
25
+ return String(value);
26
+ }
27
+ }
28
+ var logger = {
29
+ error: (...args) => emit("error", args),
30
+ warn: (...args) => emit("warn", args),
31
+ info: (...args) => emit("info", args),
32
+ debug: (...args) => emit("debug", args)
33
+ };
34
+
35
+ export {
36
+ logger
37
+ };
@@ -0,0 +1,41 @@
1
+ import { createRequire as __lurqCreateRequire } from 'node:module'; const require = __lurqCreateRequire(import.meta.url);
2
+ import {
3
+ JSONRPCMessageSchema
4
+ } from "./chunk-D3K6IZVR.js";
5
+ import {
6
+ init_esm_shims
7
+ } from "./chunk-I3M2KJXB.js";
8
+
9
+ // node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js
10
+ init_esm_shims();
11
+ var ReadBuffer = class {
12
+ append(chunk) {
13
+ this._buffer = this._buffer ? Buffer.concat([this._buffer, chunk]) : chunk;
14
+ }
15
+ readMessage() {
16
+ if (!this._buffer) {
17
+ return null;
18
+ }
19
+ const index = this._buffer.indexOf("\n");
20
+ if (index === -1) {
21
+ return null;
22
+ }
23
+ const line = this._buffer.toString("utf8", 0, index).replace(/\r$/, "");
24
+ this._buffer = this._buffer.subarray(index + 1);
25
+ return deserializeMessage(line);
26
+ }
27
+ clear() {
28
+ this._buffer = void 0;
29
+ }
30
+ };
31
+ function deserializeMessage(line) {
32
+ return JSONRPCMessageSchema.parse(JSON.parse(line));
33
+ }
34
+ function serializeMessage(message) {
35
+ return JSON.stringify(message) + "\n";
36
+ }
37
+
38
+ export {
39
+ ReadBuffer,
40
+ serializeMessage
41
+ };
@@ -0,0 +1,197 @@
1
+ import { createRequire as __lurqCreateRequire } from 'node:module'; const require = __lurqCreateRequire(import.meta.url);
2
+ import {
3
+ DEFAULT_ECOSYSTEM
4
+ } from "./chunk-VLRHFMGJ.js";
5
+ import {
6
+ packageVersions,
7
+ packages,
8
+ seedPackages,
9
+ syncRuns
10
+ } from "./chunk-4JHDSVIN.js";
11
+ import {
12
+ logger
13
+ } from "./chunk-MYGSLK44.js";
14
+ import {
15
+ init_esm_shims
16
+ } from "./chunk-I3M2KJXB.js";
17
+
18
+ // src/db/packages.ts
19
+ init_esm_shims();
20
+ import { and, desc, eq, gte, inArray, isNotNull, isNull, lt, notExists, sql } from "drizzle-orm";
21
+ var VERSION_CHUNK = 500;
22
+ var NAME_CHUNK = 500;
23
+ async function getSeedTargets(db) {
24
+ const rows = await db.select({ name: seedPackages.name, category: seedPackages.category }).from(seedPackages);
25
+ return rows.map((r) => ({ name: r.name, category: r.category ?? null }));
26
+ }
27
+ async function getStaleRefreshTargets(db, limit) {
28
+ if (limit <= 0) return [];
29
+ const rows = await db.select({
30
+ name: packages.name,
31
+ category: sql`case when ${packages.categorySource} = 'curated' then ${packages.category} end`
32
+ }).from(packages).where(
33
+ notExists(
34
+ db.select({ one: sql`1` }).from(seedPackages).where(eq(seedPackages.name, packages.name))
35
+ )
36
+ ).orderBy(sql`${packages.dataAsOf} asc nulls first`).limit(limit);
37
+ return rows.map((r) => ({ name: r.name, category: r.category ?? null }));
38
+ }
39
+ async function getPackageByName(db, name, ecosystem = DEFAULT_ECOSYSTEM) {
40
+ const rows = await db.select().from(packages).where(and(eq(packages.name, name), eq(packages.ecosystem, ecosystem))).limit(1);
41
+ return rows[0] ?? null;
42
+ }
43
+ async function latestVersionsFor(db, names, ecosystem = DEFAULT_ECOSYSTEM) {
44
+ const out = /* @__PURE__ */ new Map();
45
+ for (let i = 0; i < names.length; i += NAME_CHUNK) {
46
+ const rows = await db.select({ name: packages.name, latestVersion: packages.latestVersion }).from(packages).where(
47
+ and(
48
+ inArray(packages.name, names.slice(i, i + NAME_CHUNK)),
49
+ eq(packages.ecosystem, ecosystem)
50
+ )
51
+ );
52
+ for (const row of rows) out.set(row.name, row.latestVersion);
53
+ }
54
+ return out;
55
+ }
56
+ async function reusableFieldsFor(db, names, ecosystem = DEFAULT_ECOSYSTEM) {
57
+ const out = /* @__PURE__ */ new Map();
58
+ for (let i = 0; i < names.length; i += NAME_CHUNK) {
59
+ const rows = await db.select({
60
+ name: packages.name,
61
+ latestVersion: packages.latestVersion,
62
+ summary: packages.summary,
63
+ usageGuide: packages.usageGuide,
64
+ embedding: packages.embedding,
65
+ embeddingProvider: packages.embeddingProvider
66
+ }).from(packages).where(
67
+ and(
68
+ inArray(packages.name, names.slice(i, i + NAME_CHUNK)),
69
+ eq(packages.ecosystem, ecosystem)
70
+ )
71
+ );
72
+ for (const row of rows) {
73
+ const { name, ...fields } = row;
74
+ out.set(name, fields);
75
+ }
76
+ }
77
+ return out;
78
+ }
79
+ async function getAllPackageNames(db, ecosystem = DEFAULT_ECOSYSTEM) {
80
+ const rows = await db.select({ name: packages.name }).from(packages).where(eq(packages.ecosystem, ecosystem));
81
+ return rows.map((r) => r.name);
82
+ }
83
+ async function getPackageNamesCreatedSince(db, since) {
84
+ const rows = await db.select({ name: packages.name }).from(packages).where(gte(packages.createdAt, since));
85
+ return rows.map((r) => r.name);
86
+ }
87
+ async function upsertPackageVersions(db, name, versions) {
88
+ if (versions.length === 0) {
89
+ logger.debug(`no version timeline to store for ${name}: registry returned none`);
90
+ return;
91
+ }
92
+ for (let i = 0; i < versions.length; i += VERSION_CHUNK) {
93
+ const rows = versions.slice(i, i + VERSION_CHUNK).map((v) => ({
94
+ packageName: name,
95
+ version: v.version,
96
+ publishedAt: v.publishedAt,
97
+ peerDependencies: v.peerDependencies ?? null,
98
+ engines: v.engines ?? null
99
+ }));
100
+ await db.insert(packageVersions).values(rows).onConflictDoNothing();
101
+ }
102
+ }
103
+ async function getPackageVersions(db, name, limit = 50) {
104
+ const rows = await db.select({ version: packageVersions.version, publishedAt: packageVersions.publishedAt }).from(packageVersions).where(eq(packageVersions.packageName, name)).orderBy(desc(packageVersions.publishedAt)).limit(limit);
105
+ return rows.map((r) => ({ version: r.version, publishedAt: r.publishedAt }));
106
+ }
107
+ async function getTopPackageNames(db, limit = 1e3) {
108
+ const rows = await db.select({ name: packages.name }).from(packages).where(isNotNull(packages.weeklyDownloads)).orderBy(desc(packages.weeklyDownloads)).limit(limit);
109
+ return rows.map((r) => r.name);
110
+ }
111
+ async function upsertPackage(db, row) {
112
+ const { name: _name, ecosystem: _ecosystem, createdAt: _createdAt, ...mutable } = row;
113
+ await db.insert(packages).values(row).onConflictDoUpdate({
114
+ target: [packages.ecosystem, packages.name],
115
+ set: { ...mutable, updatedAt: /* @__PURE__ */ new Date() }
116
+ });
117
+ }
118
+ async function stampFirstRequester(db, name, ownerId, ecosystem = DEFAULT_ECOSYSTEM) {
119
+ await db.update(packages).set({ firstRequestedByOwnerId: ownerId }).where(
120
+ and(
121
+ eq(packages.name, name),
122
+ eq(packages.ecosystem, ecosystem),
123
+ isNull(packages.firstRequestedByOwnerId)
124
+ )
125
+ );
126
+ }
127
+ async function getContributionsByOwner(db, ownerId, opts = {}) {
128
+ const limit = opts.limit ?? 50;
129
+ const offset = opts.offset ?? 0;
130
+ const [rows, [countRow]] = await Promise.all([
131
+ db.select({
132
+ name: packages.name,
133
+ category: packages.category,
134
+ healthScore: packages.healthScore,
135
+ firstRequestedAt: packages.createdAt
136
+ }).from(packages).where(eq(packages.firstRequestedByOwnerId, ownerId)).orderBy(desc(packages.createdAt)).limit(limit).offset(offset),
137
+ db.select({ count: sql`count(*)::int` }).from(packages).where(eq(packages.firstRequestedByOwnerId, ownerId))
138
+ ]);
139
+ return { total: countRow?.count ?? 0, packages: rows };
140
+ }
141
+ function syncOrigin() {
142
+ const env = process.env.RAILWAY_ENVIRONMENT_NAME;
143
+ const service = process.env.RAILWAY_SERVICE_NAME;
144
+ if (!env && !service) return null;
145
+ return `${env ?? "?"}/${service ?? "?"}`;
146
+ }
147
+ var SYNC_STALE_MS = 6 * 60 * 60 * 1e3;
148
+ async function reapAbandonedSyncRuns(db) {
149
+ await db.update(syncRuns).set({
150
+ status: "failed",
151
+ finishedAt: /* @__PURE__ */ new Date(),
152
+ errors: [
153
+ {
154
+ package: "*",
155
+ source: "pipeline",
156
+ message: "abandoned: the process died before writing a terminal status"
157
+ }
158
+ ]
159
+ }).where(
160
+ and(
161
+ eq(syncRuns.status, "running"),
162
+ lt(syncRuns.startedAt, new Date(Date.now() - SYNC_STALE_MS))
163
+ )
164
+ );
165
+ }
166
+ async function startSyncRun(db) {
167
+ await reapAbandonedSyncRuns(db);
168
+ const [row] = await db.insert(syncRuns).values({ status: "running", origin: syncOrigin() }).returning({ id: syncRuns.id });
169
+ return row.id;
170
+ }
171
+ async function finishSyncRun(db, id, data) {
172
+ await db.update(syncRuns).set({
173
+ finishedAt: /* @__PURE__ */ new Date(),
174
+ packagesSeen: data.packagesSeen,
175
+ packagesUpdated: data.packagesUpdated,
176
+ errors: data.errors,
177
+ status: data.status
178
+ }).where(eq(syncRuns.id, id));
179
+ }
180
+
181
+ export {
182
+ getSeedTargets,
183
+ getStaleRefreshTargets,
184
+ getPackageByName,
185
+ latestVersionsFor,
186
+ reusableFieldsFor,
187
+ getAllPackageNames,
188
+ getPackageNamesCreatedSince,
189
+ upsertPackageVersions,
190
+ getPackageVersions,
191
+ getTopPackageNames,
192
+ upsertPackage,
193
+ stampFirstRequester,
194
+ getContributionsByOwner,
195
+ startSyncRun,
196
+ finishSyncRun
197
+ };
@@ -0,0 +1,23 @@
1
+ import { createRequire as __lurqCreateRequire } from 'node:module'; const require = __lurqCreateRequire(import.meta.url);
2
+ import {
3
+ verificationRuns
4
+ } from "./chunk-4JHDSVIN.js";
5
+ import {
6
+ init_esm_shims
7
+ } from "./chunk-I3M2KJXB.js";
8
+
9
+ // src/db/verification.ts
10
+ init_esm_shims();
11
+ import { desc, eq } from "drizzle-orm";
12
+ async function storeVerificationRun(db, run) {
13
+ await db.insert(verificationRuns).values(run);
14
+ }
15
+ async function getLatestVerificationByName(db, packageName) {
16
+ const rows = await db.select().from(verificationRuns).where(eq(verificationRuns.packageName, packageName)).orderBy(desc(verificationRuns.ranAt)).limit(1);
17
+ return rows[0] ?? null;
18
+ }
19
+
20
+ export {
21
+ storeVerificationRun,
22
+ getLatestVerificationByName
23
+ };