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
@@ -0,0 +1,38 @@
1
+ import { createRequire as __lurqCreateRequire } from 'node:module'; const require = __lurqCreateRequire(import.meta.url);
2
+ import {
3
+ apiSurfaces,
4
+ packages
5
+ } from "./chunk-LYMPYETA.js";
6
+ import {
7
+ init_esm_shims
8
+ } from "./chunk-I3M2KJXB.js";
9
+
10
+ // src/db/apiSurfaces.ts
11
+ init_esm_shims();
12
+ import { and, eq, isNotNull, isNull, sql } from "drizzle-orm";
13
+ async function getStoredSurface(db, packageName, version) {
14
+ const [row] = await db.select({ surface: apiSurfaces.surface }).from(apiSurfaces).where(and(eq(apiSurfaces.packageName, packageName), eq(apiSurfaces.version, version))).limit(1);
15
+ return row?.surface ?? null;
16
+ }
17
+ async function upsertSurface(db, packageName, version, surface) {
18
+ await db.insert(apiSurfaces).values({ packageName, version, surface }).onConflictDoUpdate({
19
+ target: [apiSurfaces.packageName, apiSurfaces.version],
20
+ set: { surface, extractedAt: /* @__PURE__ */ new Date() }
21
+ });
22
+ }
23
+ async function getPackagesWithSurface(db, limit = 100) {
24
+ const rows = await db.select({ name: packages.name, version: packages.latestVersion }).from(packages).innerJoin(
25
+ apiSurfaces,
26
+ and(
27
+ eq(apiSurfaces.packageName, packages.name),
28
+ eq(apiSurfaces.version, packages.latestVersion)
29
+ )
30
+ ).where(isNotNull(packages.latestVersion)).orderBy(sql`random()`).limit(limit);
31
+ return rows.filter((r) => r.version !== null);
32
+ }
33
+
34
+ export {
35
+ getStoredSurface,
36
+ upsertSurface,
37
+ getPackagesWithSurface
38
+ };
@@ -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,201 @@
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-LYMPYETA.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 ensureSeedEntry(db, name, category) {
112
+ await db.insert(seedPackages).values({ name, category }).onConflictDoNothing({ target: seedPackages.name });
113
+ }
114
+ async function upsertPackage(db, row) {
115
+ const { name: _name, ecosystem: _ecosystem, createdAt: _createdAt, ...mutable } = row;
116
+ await db.insert(packages).values(row).onConflictDoUpdate({
117
+ target: [packages.ecosystem, packages.name],
118
+ set: { ...mutable, updatedAt: /* @__PURE__ */ new Date() }
119
+ });
120
+ }
121
+ async function stampFirstRequester(db, name, ownerId, ecosystem = DEFAULT_ECOSYSTEM) {
122
+ await db.update(packages).set({ firstRequestedByOwnerId: ownerId }).where(
123
+ and(
124
+ eq(packages.name, name),
125
+ eq(packages.ecosystem, ecosystem),
126
+ isNull(packages.firstRequestedByOwnerId)
127
+ )
128
+ );
129
+ }
130
+ async function getContributionsByOwner(db, ownerId, opts = {}) {
131
+ const limit = opts.limit ?? 50;
132
+ const offset = opts.offset ?? 0;
133
+ const [rows, [countRow]] = await Promise.all([
134
+ db.select({
135
+ name: packages.name,
136
+ category: packages.category,
137
+ healthScore: packages.healthScore,
138
+ firstRequestedAt: packages.createdAt
139
+ }).from(packages).where(eq(packages.firstRequestedByOwnerId, ownerId)).orderBy(desc(packages.createdAt)).limit(limit).offset(offset),
140
+ db.select({ count: sql`count(*)::int` }).from(packages).where(eq(packages.firstRequestedByOwnerId, ownerId))
141
+ ]);
142
+ return { total: countRow?.count ?? 0, packages: rows };
143
+ }
144
+ function syncOrigin() {
145
+ const env = process.env.RAILWAY_ENVIRONMENT_NAME;
146
+ const service = process.env.RAILWAY_SERVICE_NAME;
147
+ if (!env && !service) return null;
148
+ return `${env ?? "?"}/${service ?? "?"}`;
149
+ }
150
+ var SYNC_STALE_MS = 6 * 60 * 60 * 1e3;
151
+ async function reapAbandonedSyncRuns(db) {
152
+ await db.update(syncRuns).set({
153
+ status: "failed",
154
+ finishedAt: /* @__PURE__ */ new Date(),
155
+ errors: [
156
+ {
157
+ package: "*",
158
+ source: "pipeline",
159
+ message: "abandoned: the process died before writing a terminal status"
160
+ }
161
+ ]
162
+ }).where(
163
+ and(
164
+ eq(syncRuns.status, "running"),
165
+ lt(syncRuns.startedAt, new Date(Date.now() - SYNC_STALE_MS))
166
+ )
167
+ );
168
+ }
169
+ async function startSyncRun(db) {
170
+ await reapAbandonedSyncRuns(db);
171
+ const [row] = await db.insert(syncRuns).values({ status: "running", origin: syncOrigin() }).returning({ id: syncRuns.id });
172
+ return row.id;
173
+ }
174
+ async function finishSyncRun(db, id, data) {
175
+ await db.update(syncRuns).set({
176
+ finishedAt: /* @__PURE__ */ new Date(),
177
+ packagesSeen: data.packagesSeen,
178
+ packagesUpdated: data.packagesUpdated,
179
+ errors: data.errors,
180
+ status: data.status
181
+ }).where(eq(syncRuns.id, id));
182
+ }
183
+
184
+ export {
185
+ getSeedTargets,
186
+ getStaleRefreshTargets,
187
+ getPackageByName,
188
+ latestVersionsFor,
189
+ reusableFieldsFor,
190
+ getAllPackageNames,
191
+ getPackageNamesCreatedSince,
192
+ upsertPackageVersions,
193
+ getPackageVersions,
194
+ getTopPackageNames,
195
+ ensureSeedEntry,
196
+ upsertPackage,
197
+ stampFirstRequester,
198
+ getContributionsByOwner,
199
+ startSyncRun,
200
+ finishSyncRun
201
+ };