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,320 @@
1
+ import { createRequire as __lurqCreateRequire } from 'node:module'; const require = __lurqCreateRequire(import.meta.url);
2
+ import {
3
+ handleDiffSurface
4
+ } from "./chunk-BJT2LHAR.js";
5
+ import {
6
+ getPackageByName
7
+ } from "./chunk-NPVN2THM.js";
8
+ import {
9
+ enqueueSurface
10
+ } from "./chunk-ONDVTXUO.js";
11
+ import {
12
+ packages,
13
+ surfaceQueue
14
+ } from "./chunk-4JHDSVIN.js";
15
+ import {
16
+ require_semver
17
+ } from "./chunk-3GHJR7XR.js";
18
+ import {
19
+ logger
20
+ } from "./chunk-MYGSLK44.js";
21
+ import {
22
+ __toESM,
23
+ init_esm_shims
24
+ } from "./chunk-I3M2KJXB.js";
25
+
26
+ // src/mcp/publicUpgrades.ts
27
+ init_esm_shims();
28
+ var import_semver = __toESM(require_semver(), 1);
29
+ import { and as and2, count, desc as desc2, gte, isNotNull as isNotNull2, sql } from "drizzle-orm";
30
+
31
+ // src/mcp/publicSet.ts
32
+ init_esm_shims();
33
+ import { and, desc, isNotNull } from "drizzle-orm";
34
+ var PUBLIC_TOP_LIMIT = 5e3;
35
+ var NPM_NAME = /^(?:@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/i;
36
+ function validPackageName(name) {
37
+ return name.length > 0 && name.length <= 214 && NPM_NAME.test(name);
38
+ }
39
+ var floor = null;
40
+ async function publicDownloadFloor(db) {
41
+ if (floor && Date.now() - floor.at < 36e5) return floor.value;
42
+ const rows = await db.select({ downloads: packages.weeklyDownloads }).from(packages).where(and(isNotNull(packages.weeklyDownloads), isNotNull(packages.healthScore))).orderBy(desc(packages.weeklyDownloads)).offset(PUBLIC_TOP_LIMIT - 1).limit(1);
43
+ floor = { at: Date.now(), value: Number(rows[0]?.downloads ?? 0) };
44
+ return floor.value;
45
+ }
46
+ async function publicPackageRow(db, name) {
47
+ const [row, min] = await Promise.all([getPackageByName(db, name), publicDownloadFloor(db)]);
48
+ if (!row || row.healthScore === null || (row.weeklyDownloads ?? 0) < min) return null;
49
+ return row;
50
+ }
51
+
52
+ // src/mcp/publicUpgrades.ts
53
+ var PAIRS_PER_PACKAGE = 3;
54
+ var LIST_CAP = 500;
55
+ function majorPairs(latest, keep = PAIRS_PER_PACKAGE) {
56
+ const sorted = [...latest].sort((a, b) => a.major - b.major);
57
+ const pairs = [];
58
+ for (let i = 1; i < sorted.length; i++) {
59
+ const from = sorted[i - 1];
60
+ const to = sorted[i];
61
+ pairs.push({
62
+ fromMajor: from.major,
63
+ toMajor: to.major,
64
+ fromVersion: from.version,
65
+ toVersion: to.version,
66
+ ready: from.stored && to.stored
67
+ });
68
+ }
69
+ return pairs.slice(-keep);
70
+ }
71
+ function unextractedSides(latest, keep = PAIRS_PER_PACKAGE) {
72
+ if (latest.length < 2) return [];
73
+ const involved = [...latest].sort((a, b) => a.major - b.major).slice(-(keep + 1));
74
+ return involved.reverse().filter((l) => !l.stored && !l.attempted).map((l) => l.version);
75
+ }
76
+ function upgradeVerdict(d) {
77
+ if (d.inconclusive) return "unknown";
78
+ if (d.removed.length > 0 || d.renamed.length > 0) return "removes-exports";
79
+ if (d.arityChanged.length > 0) return "arity-changed";
80
+ if (d.typeOnlyRemoved.length > 0) return "types-only";
81
+ return "clean";
82
+ }
83
+ function toPublicUpgrade(pkg, pair, diff) {
84
+ const renamedPaths = new Set(diff.renamed.map((r) => r.path));
85
+ const removed = diff.removed.filter((r) => !renamedPaths.has(r.path));
86
+ const lists = [
87
+ removed,
88
+ diff.renamed,
89
+ diff.arityChanged,
90
+ diff.typeOnlyRemoved,
91
+ diff.deprecated
92
+ ];
93
+ const cap = (xs) => xs.slice(0, LIST_CAP);
94
+ return {
95
+ package: pkg,
96
+ pair,
97
+ status: "ready",
98
+ verdict: upgradeVerdict({ ...diff, removed }),
99
+ removed: cap(removed.map((r) => ({ path: r.path, kind: r.kind }))),
100
+ renamed: cap(diff.renamed),
101
+ arityChanged: cap(diff.arityChanged),
102
+ typeOnlyRemoved: cap(diff.typeOnlyRemoved),
103
+ deprecated: cap(diff.deprecated),
104
+ added: diff.added.length,
105
+ truncated: lists.some((l) => l.length > LIST_CAP),
106
+ tier: diff.tier ?? null,
107
+ inconclusive: diff.inconclusive ?? null,
108
+ observedAt: diff.observedAt ? new Date(diff.observedAt).toISOString() : null
109
+ };
110
+ }
111
+ function pendingUpgrade(pkg, pair) {
112
+ return {
113
+ package: pkg,
114
+ pair,
115
+ status: "pending",
116
+ verdict: "unknown",
117
+ removed: [],
118
+ renamed: [],
119
+ arityChanged: [],
120
+ typeOnlyRemoved: [],
121
+ deprecated: [],
122
+ added: 0,
123
+ truncated: false,
124
+ tier: null,
125
+ inconclusive: "Both versions are queued for extraction. NOT evidence that nothing changed.",
126
+ observedAt: null
127
+ };
128
+ }
129
+ function rowsOf(result) {
130
+ return result.rows ?? result;
131
+ }
132
+ async function latestOfMajors(db, names) {
133
+ const out = /* @__PURE__ */ new Map();
134
+ if (names.length === 0) return out;
135
+ const result = await db.execute(sql`
136
+ with stable as (
137
+ select package_name, version, (regexp_match(version, '^([0-9]+)\\.'))[1]::int as major
138
+ from package_versions
139
+ where package_name in (${sql.join(
140
+ names.map((n) => sql`${n}`),
141
+ sql`, `
142
+ )})
143
+ -- Stable releases only: an upgrade does not land on a prerelease.
144
+ and version ~ '^[0-9]+\\.[0-9]+\\.[0-9]+$'
145
+ ),
146
+ latest as (
147
+ select distinct on (package_name, major) package_name, major, version
148
+ from stable
149
+ -- Numeric, not lexical (16.10.0 is newer than 16.9.0), and numeric rather
150
+ -- than int so a date-stamped version cannot overflow the cast.
151
+ order by package_name, major, string_to_array(version, '.')::numeric[] desc
152
+ )
153
+ select
154
+ l.package_name,
155
+ l.major,
156
+ l.version,
157
+ exists (
158
+ select 1 from entities e
159
+ join symbols s on s.entity_id = e.id and s.tier = 'shipped_js_ast'
160
+ where e.canonical_key = 'package_surface:npm:' || l.package_name || ':' || l.version
161
+ and e.tenant_id = 0
162
+ ) as stored,
163
+ exists (
164
+ select 1 from entities e
165
+ where e.canonical_key = 'package_surface:npm:' || l.package_name || ':' || l.version
166
+ and e.tenant_id = 0
167
+ ) as attempted
168
+ from latest l
169
+ `);
170
+ for (const r of rowsOf(result)) {
171
+ const list = out.get(r.package_name) ?? [];
172
+ list.push({
173
+ major: Number(r.major),
174
+ version: r.version,
175
+ stored: Boolean(r.stored),
176
+ attempted: Boolean(r.attempted)
177
+ });
178
+ out.set(r.package_name, list);
179
+ }
180
+ return out;
181
+ }
182
+ async function upgradePairsFor(db, name) {
183
+ return majorPairs((await latestOfMajors(db, [name])).get(name) ?? []);
184
+ }
185
+ async function upgradeGuideFor(db, pkg, fromVersion, toVersion, webUrl) {
186
+ const from = import_semver.default.coerce(fromVersion)?.major;
187
+ const to = import_semver.default.coerce(toVersion)?.major;
188
+ if (from === void 0 || to === void 0 || to <= from) return null;
189
+ if (!await publicPackageRow(db, pkg)) return null;
190
+ const pair = (await upgradePairsFor(db, pkg)).find(
191
+ (p) => p.fromMajor === from && p.toMajor === to && p.ready
192
+ );
193
+ if (!pair) return null;
194
+ const path = `/npm/${pkg.split("/").map(encodeURIComponent).join("/")}/${from}-to-${to}`;
195
+ return {
196
+ url: `${webUrl.replace(/\/$/, "")}${path}`,
197
+ fromVersion: pair.fromVersion,
198
+ toVersion: pair.toVersion
199
+ };
200
+ }
201
+ async function publicNames(db, limit = PUBLIC_TOP_LIMIT) {
202
+ const min = await publicDownloadFloor(db);
203
+ const rows = await db.select({ name: packages.name }).from(packages).where(and2(isNotNull2(packages.healthScore), gte(packages.weeklyDownloads, min))).orderBy(desc2(packages.weeklyDownloads)).limit(limit);
204
+ return rows.map((r) => r.name);
205
+ }
206
+ var QUEUE_HEADROOM = 20;
207
+ async function enqueuePublicUpgrades(db, opts = {}) {
208
+ const [{ pending } = { pending: 0 }] = await db.select({ pending: count() }).from(surfaceQueue);
209
+ let budget = QUEUE_HEADROOM - Number(pending);
210
+ if (budget <= 0) return 0;
211
+ const names = await publicNames(db, opts.packages ?? 1e3);
212
+ let queued = 0;
213
+ for (let i = 0; i < names.length && budget > 0; i += 250) {
214
+ const chunk = names.slice(i, i + 250);
215
+ const latest = await latestOfMajors(db, chunk);
216
+ for (const name of chunk) {
217
+ for (const version of unextractedSides(latest.get(name) ?? [])) {
218
+ if (budget <= 0) break;
219
+ await enqueueSurface(db, name, version);
220
+ queued++;
221
+ budget--;
222
+ }
223
+ if (budget <= 0) break;
224
+ }
225
+ }
226
+ return queued;
227
+ }
228
+ function registerPublicUpgradeRoutes(app, db, limiter) {
229
+ const cacheable = (res) => res.setHeader("Cache-Control", "public, max-age=3600, s-maxage=86400");
230
+ app.get("/public/upgrade", limiter, async (req, res) => {
231
+ const name = typeof req.query.name === "string" ? req.query.name.trim() : "";
232
+ const from = Number(req.query.from);
233
+ const to = Number(req.query.to);
234
+ if (!validPackageName(name) || !Number.isInteger(from) || !Number.isInteger(to) || from < 0 || to <= from) {
235
+ res.status(400).json({ error: "Give an npm package name and two majors, from < to." });
236
+ return;
237
+ }
238
+ try {
239
+ if (!await publicPackageRow(db, name)) {
240
+ res.status(404).json({ error: "No public upgrade pages for that package." });
241
+ return;
242
+ }
243
+ const pairs = await upgradePairsFor(db, name);
244
+ const pair = pairs.find((p) => p.fromMajor === from && p.toMajor === to);
245
+ if (!pair) {
246
+ res.status(404).json({ error: "No upgrade page for that version jump.", pairs });
247
+ return;
248
+ }
249
+ if (!pair.ready) {
250
+ await Promise.all([
251
+ enqueueSurface(db, name, pair.fromVersion),
252
+ enqueueSurface(db, name, pair.toVersion)
253
+ ]).catch(() => {
254
+ });
255
+ res.setHeader("Cache-Control", "public, max-age=300, s-maxage=900");
256
+ res.json(pendingUpgrade(name, pair));
257
+ return;
258
+ }
259
+ const diff = await handleDiffSurface(db, {
260
+ package: name,
261
+ fromVersion: pair.fromVersion,
262
+ toVersion: pair.toVersion
263
+ });
264
+ const body = toPublicUpgrade(name, pair, diff);
265
+ if (body.verdict === "unknown")
266
+ res.setHeader("Cache-Control", "public, max-age=300, s-maxage=900");
267
+ else cacheable(res);
268
+ res.json(body);
269
+ } catch (err) {
270
+ logger.error("public upgrade read failed:", err instanceof Error ? err.message : String(err));
271
+ res.status(500).json({ error: "Could not read that upgrade." });
272
+ }
273
+ });
274
+ let index = null;
275
+ app.get("/public/upgrades", limiter, async (_req, res) => {
276
+ try {
277
+ if (!index || Date.now() - index.at > 36e5) {
278
+ const names = await publicNames(db);
279
+ const value = [];
280
+ for (let i = 0; i < names.length; i += 500) {
281
+ const chunk = names.slice(i, i + 500);
282
+ const latest = await latestOfMajors(db, chunk);
283
+ for (const name of chunk) {
284
+ const ready = majorPairs(latest.get(name) ?? []).filter((p) => p.ready);
285
+ if (ready.length) value.push({ package: name, pairs: ready });
286
+ }
287
+ }
288
+ index = { at: Date.now(), value };
289
+ }
290
+ cacheable(res);
291
+ res.json({ upgrades: index.value });
292
+ } catch (err) {
293
+ logger.error(
294
+ "public upgrade index failed:",
295
+ err instanceof Error ? err.message : String(err)
296
+ );
297
+ res.status(500).json({ error: "Could not list upgrade pages." });
298
+ }
299
+ });
300
+ }
301
+
302
+ export {
303
+ PUBLIC_TOP_LIMIT,
304
+ validPackageName,
305
+ publicDownloadFloor,
306
+ publicPackageRow,
307
+ PAIRS_PER_PACKAGE,
308
+ LIST_CAP,
309
+ majorPairs,
310
+ unextractedSides,
311
+ upgradeVerdict,
312
+ toPublicUpgrade,
313
+ pendingUpgrade,
314
+ latestOfMajors,
315
+ upgradePairsFor,
316
+ upgradeGuideFor,
317
+ QUEUE_HEADROOM,
318
+ enqueuePublicUpgrades,
319
+ registerPublicUpgradeRoutes
320
+ };
@@ -0,0 +1,240 @@
1
+ import { createRequire as __lurqCreateRequire } from 'node:module'; const require = __lurqCreateRequire(import.meta.url);
2
+ import {
3
+ UNBOUNDED_ARITY,
4
+ claims,
5
+ entities,
6
+ observations,
7
+ packages,
8
+ surfaceQueue,
9
+ symbols
10
+ } from "./chunk-4JHDSVIN.js";
11
+ import {
12
+ init_esm_shims
13
+ } from "./chunk-I3M2KJXB.js";
14
+
15
+ // src/db/surface.ts
16
+ init_esm_shims();
17
+ import { and as and2, desc, eq as eq2, isNotNull, isNull as isNull2, sql } from "drizzle-orm";
18
+
19
+ // src/db/graph.ts
20
+ init_esm_shims();
21
+ import { and, eq, isNull } from "drizzle-orm";
22
+ import { createHash } from "crypto";
23
+
24
+ // src/graph/types.ts
25
+ init_esm_shims();
26
+ function canonicalKey(ref) {
27
+ return `${ref.kind}:${ref.namespace}:${ref.name}:${ref.version ?? ""}`;
28
+ }
29
+
30
+ // src/db/graph.ts
31
+ async function upsertEntity(db, ref, tenantId = 0) {
32
+ const key = canonicalKey(ref);
33
+ const [row] = await db.insert(entities).values({
34
+ kind: ref.kind,
35
+ namespace: ref.namespace,
36
+ name: ref.name,
37
+ version: ref.version ?? null,
38
+ canonicalKey: key,
39
+ tenantId
40
+ }).onConflictDoUpdate({
41
+ target: [entities.canonicalKey, entities.tenantId],
42
+ set: { canonicalKey: key }
43
+ }).returning();
44
+ return row;
45
+ }
46
+ async function upsertClaim(db, args) {
47
+ const objectId = args.objectId ?? null;
48
+ const envId = args.environmentId ?? null;
49
+ const tenantId = args.tenantId ?? 0;
50
+ const existing = await db.select().from(claims).where(
51
+ and(
52
+ eq(claims.subjectId, args.subjectId),
53
+ objectId === null ? isNull(claims.objectId) : eq(claims.objectId, objectId),
54
+ eq(claims.relation, args.relation),
55
+ envId === null ? isNull(claims.environmentId) : eq(claims.environmentId, envId),
56
+ eq(claims.tenantId, tenantId)
57
+ )
58
+ ).limit(1);
59
+ if (existing[0]) return existing[0];
60
+ const [row] = await db.insert(claims).values({
61
+ subjectId: args.subjectId,
62
+ objectId,
63
+ relation: args.relation,
64
+ environmentId: envId,
65
+ tenantId
66
+ }).returning();
67
+ return row;
68
+ }
69
+ async function recordObservation(db, args) {
70
+ await db.insert(observations).values({
71
+ claimId: args.claimId,
72
+ verdict: args.verdict,
73
+ class: args.class ?? "executed",
74
+ tier: args.tier ?? null,
75
+ evidence: args.evidence ?? null,
76
+ oracleId: args.oracleId,
77
+ oracleVer: args.oracleVer,
78
+ costMillis: args.costMillis ?? null
79
+ });
80
+ }
81
+
82
+ // src/db/surface.ts
83
+ function surfaceRef(pkg, version) {
84
+ return { kind: "package_surface", namespace: "npm", name: pkg, version };
85
+ }
86
+ function mcpSurfaceRef(server, version) {
87
+ return { kind: "mcp_server", namespace: "npm", name: server, version };
88
+ }
89
+ async function isExtractionCached(db, ref, artifactHash, extractorVersion, tier = "shipped_js_ast", tenantId = 0) {
90
+ const row = await upsertEntity(db, ref, tenantId);
91
+ if (row.artifactHash !== artifactHash) return false;
92
+ const existing = await db.select({ id: symbols.id }).from(symbols).where(and2(eq2(symbols.entityId, row.id), eq2(symbols.tier, tier))).limit(1);
93
+ if (existing.length === 0) return false;
94
+ const seen = await db.select({ oracleVer: observations.oracleVer }).from(observations).innerJoin(claims, eq2(claims.id, observations.claimId)).where(
95
+ and2(
96
+ eq2(claims.subjectId, row.id),
97
+ eq2(claims.relation, "exposes"),
98
+ eq2(observations.tier, tier)
99
+ )
100
+ ).orderBy(desc(observations.observedAt)).limit(1);
101
+ return seen[0]?.oracleVer === extractorVersion;
102
+ }
103
+ async function storeSurface(db, surface, opts = {
104
+ extractorVersion: "1"
105
+ }) {
106
+ const tenantId = opts.tenantId ?? 0;
107
+ const ref = opts.ref ?? surfaceRef(surface.package, surface.version);
108
+ const entity = await upsertEntity(db, ref, tenantId);
109
+ if (opts.artifactHash) {
110
+ await db.update(entities).set({ artifactHash: opts.artifactHash }).where(eq2(entities.id, entity.id));
111
+ }
112
+ const claim = await upsertClaim(db, {
113
+ subjectId: entity.id,
114
+ relation: "exposes",
115
+ // Declared claims are environment-independent: a shipped-JS surface reads
116
+ // identically on every machine, so no fingerprint is attached (§5).
117
+ environmentId: null,
118
+ tenantId
119
+ });
120
+ const undeclared = surface.symbols.length === 0;
121
+ await recordObservation(db, {
122
+ claimId: claim.id,
123
+ verdict: undeclared ? "undeclared" : "verified_true",
124
+ class: "declared",
125
+ tier: surface.tier,
126
+ evidence: undeclared ? surface.undeclaredReason ?? "no symbols extracted" : `${surface.symbols.length} symbols from ${surface.filesWalked} file(s), entry ${surface.entry}`,
127
+ oracleId: opts.oracleId ?? "surface.tier_a",
128
+ oracleVer: opts.extractorVersion
129
+ });
130
+ if (undeclared) return { entityId: entity.id, symbolsWritten: 0, verdict: "undeclared" };
131
+ await db.delete(symbols).where(and2(eq2(symbols.entityId, entity.id), eq2(symbols.tier, surface.tier)));
132
+ const rows = surface.symbols.map((s) => ({
133
+ entityId: entity.id,
134
+ path: s.path,
135
+ kind: s.kind,
136
+ arity: s.arity,
137
+ origin: s.origin,
138
+ deprecated: s.deprecated,
139
+ tier: s.tier,
140
+ signature: s.signature ?? null,
141
+ sourceFile: s.sourceRef?.file ?? null,
142
+ sourceLine: s.sourceRef?.line ?? null,
143
+ sourceOffset: s.sourceRef?.offset ?? null,
144
+ maxArity: s.maxArity === void 0 ? null : s.maxArity ?? UNBOUNDED_ARITY
145
+ }));
146
+ for (let i = 0; i < rows.length; i += 500) {
147
+ await db.insert(symbols).values(rows.slice(i, i + 500)).onConflictDoNothing();
148
+ }
149
+ return { entityId: entity.id, symbolsWritten: rows.length, verdict: "verified_true" };
150
+ }
151
+ function specKey(pkg, version, kind = "package_surface") {
152
+ const base = `${pkg}@${version ?? "latest"}`;
153
+ return kind === "package_surface" ? base : `${kind}:${base}`;
154
+ }
155
+ async function getPackagesMissingGraphSurface(db, limit, opts = {}) {
156
+ const order = opts.byDownloads ? sql`${packages.weeklyDownloads} desc nulls last` : sql`random()`;
157
+ const rows = await db.select({ name: packages.name, version: packages.latestVersion }).from(packages).leftJoin(
158
+ entities,
159
+ and2(
160
+ eq2(entities.kind, "package_surface"),
161
+ eq2(entities.name, packages.name),
162
+ eq2(entities.version, packages.latestVersion)
163
+ )
164
+ ).where(and2(isNotNull(packages.latestVersion), isNull2(entities.id))).orderBy(order).limit(limit);
165
+ return rows.filter((r) => r.version !== null);
166
+ }
167
+ async function enqueueSurface(db, pkg, version, kind = "package_surface") {
168
+ await db.insert(surfaceQueue).values({ packageName: pkg, version, kind, specKey: specKey(pkg, version, kind) }).onConflictDoNothing();
169
+ }
170
+ async function getPendingSurfaces(db, limit = 10, kind = "package_surface") {
171
+ return db.select().from(surfaceQueue).where(
172
+ and2(
173
+ eq2(surfaceQueue.kind, kind),
174
+ // Specs backing off after a failure wait their turn instead of sitting
175
+ // at the head of an oldest-first queue every cycle.
176
+ sql`(${surfaceQueue.nextAttemptAt} is null or ${surfaceQueue.nextAttemptAt} <= now())`
177
+ )
178
+ ).orderBy(surfaceQueue.requestedAt).limit(limit);
179
+ }
180
+ async function surfaceQueueDepth(db) {
181
+ const [row] = await db.select({ n: sql`count(*)::int` }).from(surfaceQueue);
182
+ return Number(row?.n ?? 0);
183
+ }
184
+ async function dropSurfaceQueue(db, id) {
185
+ await db.delete(surfaceQueue).where(eq2(surfaceQueue.id, id));
186
+ }
187
+ async function bumpSurfaceAttempt(db, id) {
188
+ await db.update(surfaceQueue).set({
189
+ attempts: sql`${surfaceQueue.attempts} + 1`,
190
+ nextAttemptAt: sql`now() + interval '15 minutes' * power(4, ${surfaceQueue.attempts})`
191
+ }).where(eq2(surfaceQueue.id, id));
192
+ }
193
+ async function hasStoredSurface(db, pkg, version, tier = "shipped_js_ast", tenantId = 0, kind = "package_surface") {
194
+ const key = canonicalKey(
195
+ kind === "mcp_server" ? mcpSurfaceRef(pkg, version) : surfaceRef(pkg, version)
196
+ );
197
+ const [row] = await db.select({ id: entities.id }).from(entities).where(and2(eq2(entities.canonicalKey, key), eq2(entities.tenantId, tenantId))).limit(1);
198
+ if (!row) return false;
199
+ const [sym] = await db.select({ id: symbols.id }).from(symbols).where(and2(eq2(symbols.entityId, row.id), eq2(symbols.tier, tier))).limit(1);
200
+ return sym !== void 0;
201
+ }
202
+ async function enqueuePreviousSurface(db, pkg, version, history, kind = "package_surface") {
203
+ const previous = previousVersion(history, version);
204
+ if (previous === null) return false;
205
+ const tier = kind === "mcp_server" ? "mcp_tools_list" : "shipped_js_ast";
206
+ if (await hasStoredSurface(db, pkg, previous, tier, 0, kind)) return false;
207
+ await enqueueSurface(db, pkg, previous, kind);
208
+ return true;
209
+ }
210
+ function previousVersion(history, version) {
211
+ const idx = history.findIndex((h) => h.version === version);
212
+ if (idx === -1 || idx + 1 >= history.length) return null;
213
+ return history[idx + 1].version ?? null;
214
+ }
215
+ async function getMcpServerNames(db, tenantId = 0) {
216
+ const rows = await db.selectDistinct({ name: entities.name }).from(entities).where(and2(eq2(entities.kind, "mcp_server"), eq2(entities.tenantId, tenantId)));
217
+ return rows.map((r) => r.name);
218
+ }
219
+
220
+ export {
221
+ canonicalKey,
222
+ upsertEntity,
223
+ upsertClaim,
224
+ recordObservation,
225
+ surfaceRef,
226
+ mcpSurfaceRef,
227
+ isExtractionCached,
228
+ storeSurface,
229
+ specKey,
230
+ getPackagesMissingGraphSurface,
231
+ enqueueSurface,
232
+ getPendingSurfaces,
233
+ surfaceQueueDepth,
234
+ dropSurfaceQueue,
235
+ bumpSurfaceAttempt,
236
+ hasStoredSurface,
237
+ enqueuePreviousSurface,
238
+ previousVersion,
239
+ getMcpServerNames
240
+ };