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.
- package/README.md +18 -10
- package/dist/auditHandler-JCOJSUYW.js +23 -0
- package/dist/bin/lurq.js +3090 -23306
- package/dist/browserAuth-B6G27USY.js +95 -0
- package/dist/cache-DKI34SVS.js +12 -0
- package/dist/check-2FDGUOV7.js +192 -0
- package/dist/checkUpgrade-F2WESBPM.js +103 -0
- package/dist/chunk-2VMOWSRY.js +300 -0
- package/dist/chunk-3GHJR7XR.js +2049 -0
- package/dist/chunk-3N3Q3DSW.js +214 -0
- package/dist/chunk-4ESO33J6.js +34 -0
- package/dist/chunk-4F7ZESPO.js +132 -0
- package/dist/chunk-4KCPOMG6.js +68 -0
- package/dist/chunk-4ZYCIMY4.js +155 -0
- package/dist/chunk-63MUJNZL.js +318 -0
- package/dist/chunk-6AAEVQ7I.js +6336 -0
- package/dist/chunk-6EQ3ARXA.js +304 -0
- package/dist/chunk-6L3U7DZ5.js +23 -0
- package/dist/chunk-AHBP533R.js +220 -0
- package/dist/chunk-B43LCXBM.js +223 -0
- package/dist/chunk-BCANRN5B.js +33 -0
- package/dist/chunk-BUALU27S.js +123 -0
- package/dist/chunk-BULZAX2U.js +1554 -0
- package/dist/chunk-BV32UNLL.js +154 -0
- package/dist/chunk-C6GLE626.js +160 -0
- package/dist/chunk-CIDWNUAP.js +145 -0
- package/dist/chunk-CUP36ND3.js +2126 -0
- package/dist/chunk-CW5HJ3LX.js +96 -0
- package/dist/chunk-DB2VF5UD.js +315 -0
- package/dist/chunk-DWAGCNEL.js +210 -0
- package/dist/chunk-EA3DP5HG.js +293 -0
- package/dist/chunk-ELGCAM7P.js +184 -0
- package/dist/chunk-FW6BD2NO.js +1915 -0
- package/dist/chunk-GE37NVLN.js +15 -0
- package/dist/chunk-GPTKSNR6.js +171 -0
- package/dist/chunk-GRJXQBQZ.js +793 -0
- package/dist/chunk-HWBBVLOT.js +92 -0
- package/dist/chunk-I2JUKN6Z.js +24 -0
- package/dist/chunk-I3M2KJXB.js +56 -0
- package/dist/chunk-IQ4SDKKY.js +733 -0
- package/dist/chunk-J5FZYN4A.js +116 -0
- package/dist/chunk-L6N4JFW2.js +263 -0
- package/dist/chunk-LBFGSSF2.js +126 -0
- package/dist/chunk-LEGPB7DO.js +81 -0
- package/dist/chunk-LO35HLQZ.js +219 -0
- package/dist/chunk-LRD4GBYE.js +73 -0
- package/dist/chunk-LUAKDHLZ.js +40 -0
- package/dist/chunk-LYMPYETA.js +965 -0
- package/dist/chunk-M6NYEXCW.js +38 -0
- package/dist/chunk-MHUEVBVO.js +35 -0
- package/dist/chunk-MYGSLK44.js +37 -0
- package/dist/chunk-NH5I4KHH.js +201 -0
- package/dist/chunk-OQS4GUSI.js +1391 -0
- package/dist/chunk-PSX3GIAN.js +176 -0
- package/dist/chunk-Q5VPF4WI.js +26 -0
- package/dist/chunk-QKGYDMWB.js +7409 -0
- package/dist/chunk-QSL6QN5X.js +115 -0
- package/dist/chunk-SHCEBP3J.js +107 -0
- package/dist/chunk-SJOVFF7B.js +201 -0
- package/dist/chunk-ST2X2GYN.js +373 -0
- package/dist/chunk-TNTXWSYA.js +19 -0
- package/dist/chunk-U5AT3TD4.js +2128 -0
- package/dist/chunk-UDVNA7EA.js +483 -0
- package/dist/chunk-VL2E5T2A.js +109 -0
- package/dist/chunk-VLRHFMGJ.js +58 -0
- package/dist/chunk-WHX2ZFCG.js +4048 -0
- package/dist/chunk-WQ23REYT.js +37 -0
- package/dist/chunk-XBIDMHSK.js +15425 -0
- package/dist/chunk-Y5GI7RL3.js +66 -0
- package/dist/client-IRKAMDYZ.js +15 -0
- package/dist/commands-FIL5ET6P.js +911 -0
- package/dist/compat-R3UTFQ5Q.js +201 -0
- package/dist/dashboardIssue-WYYMBFIB.js +192 -0
- package/dist/diff-GZA2774U.js +13 -0
- package/dist/dist-4XXIXHHZ.js +12945 -0
- package/dist/e2b-FVPHDULZ.js +172 -0
- package/dist/extract-NKGKLIVT.js +444 -0
- package/dist/fetch-QYTUJVG2.js +22 -0
- package/dist/firstTouch-QQTJH4QX.js +55 -0
- package/dist/handlers-GEJAVZDK.js +53 -0
- package/dist/http-ETPYMBGD.js +5360 -0
- package/dist/ingestQueue-VKN4KBIF.js +35 -0
- package/dist/install-EK3W2COX.js +20 -0
- package/dist/installSkill-VQJWJVCL.js +52 -0
- package/dist/inventory-5AWSLJYU.js +31 -0
- package/dist/local-XPZMRH5R.js +13 -0
- package/dist/mcp-3JHD5SUZ.js +472 -0
- package/dist/mcpHandlers-QFN4MCFL.js +22 -0
- package/dist/mcpScan-QZHWENIP.js +1871 -0
- package/dist/mcpScanWorkflow-JPYCBGC4.js +81 -0
- package/dist/mcpStack-BYJCZNIV.js +20 -0
- package/dist/packages-THVFMWFP.js +42 -0
- package/dist/plan-V4OEI3J4.js +463 -0
- package/dist/planView-JRXGCG2N.js +79 -0
- package/dist/policy-3P6BGRDN.js +115 -0
- package/dist/references-6N7VEPHT.js +14 -0
- package/dist/release-4U4ABNSJ.js +128 -0
- package/dist/remote-YGCXYI4V.js +32 -0
- package/dist/reportRuns-CKQQYLY4.js +64 -0
- package/dist/sandbox-MEZLAODF.js +39 -0
- package/dist/server-KFUD5X57.js +55 -0
- package/dist/surface-V62GE554.js +141 -0
- package/dist/surface-YL6O67W3.js +36 -0
- package/dist/surfaceHandlers-X2IZKA3E.js +20 -0
- package/dist/typecheck-X7U5ELMR.js +268 -0
- package/dist/types-M5JP2W3D.js +10 -0
- package/dist/uninstall-P7RGBX6G.js +174 -0
- package/dist/upgrade-NQ5IWFZB.js +596 -0
- package/dist/upgradePlan-A4LRKLEG.js +146 -0
- package/dist/userConfig-Z3GQE776.js +20 -0
- package/dist/watch-DGFMWUDL.js +214 -0
- package/package.json +26 -21
- package/templates/agent-rules.md +4 -4
- package/templates/skill-instructions.md +13 -14
- package/dist/bin/lurq.js.map +0 -1
- package/dist/index.d.ts +0 -805
- package/dist/index.js +0 -23570
- package/dist/index.js.map +0 -1
- package/drizzle/0000_confused_fabian_cortez.sql +0 -54
- package/drizzle/0001_aspiring_timeslip.sql +0 -15
- package/drizzle/0002_lyrical_lila_cheney.sql +0 -14
- package/drizzle/0003_violet_giant_girl.sql +0 -14
- package/drizzle/0004_slim_valeria_richards.sql +0 -15
- package/drizzle/0005_petite_luke_cage.sql +0 -12
- package/drizzle/0006_calm_nighthawk.sql +0 -3
- package/drizzle/0007_slimy_naoko.sql +0 -1
- package/drizzle/0008_peaceful_tigra.sql +0 -1
- package/drizzle/0009_smooth_harrier.sql +0 -10
- package/drizzle/0010_curved_amphibian.sql +0 -2
- package/drizzle/0011_compat_provenance_closures.sql +0 -11
- package/drizzle/0012_api_surfaces.sql +0 -9
- package/drizzle/0013_nice_thanos.sql +0 -1
- package/drizzle/0014_luxuriant_malcolm_colcord.sql +0 -10
- package/drizzle/0015_past_fat_cobra.sql +0 -11
- package/drizzle/0016_futuristic_junta.sql +0 -50
- package/drizzle/0017_absent_grandmaster.sql +0 -20
- package/drizzle/0018_rainy_proemial_gods.sql +0 -1
- package/drizzle/0019_dashing_korvac.sql +0 -11
- package/drizzle/0020_normal_vulture.sql +0 -3
- package/drizzle/0021_dazzling_blue_shield.sql +0 -17
- package/drizzle/0022_massive_ghost_rider.sql +0 -24
- package/drizzle/0023_next_shatterstar.sql +0 -1
- package/drizzle/0024_dusty_maelstrom.sql +0 -15
- package/drizzle/0025_gifted_harpoon.sql +0 -5
- package/drizzle/0026_awesome_mordo.sql +0 -1
- package/drizzle/0027_charming_ulik.sql +0 -2
- package/drizzle/0028_romantic_loners.sql +0 -2
- package/drizzle/0029_busy_korvac.sql +0 -16
- package/drizzle/0030_steady_mathemanic.sql +0 -6
- package/drizzle/0031_redundant_maginty.sql +0 -2
- package/drizzle/0032_stack_resolutions.sql +0 -14
- package/drizzle/0033_graceful_tyger_tiger.sql +0 -3
- package/drizzle/0034_uneven_thunderbird.sql +0 -1
- package/drizzle/0035_api_key_scopes.sql +0 -1
- package/drizzle/0036_policy_audit.sql +0 -21
- package/drizzle/0037_subscription_seats.sql +0 -1
- package/drizzle/0038_symbol_offsets.sql +0 -2
- package/drizzle/0039_mcp_runtime_scans.sql +0 -80
- package/drizzle/0040_subscription_overage_and_interval.sql +0 -4
- package/drizzle/0041_account_email.sql +0 -38
- package/drizzle/0042_alert_channels.sql +0 -21
- package/drizzle/meta/0000_snapshot.json +0 -370
- package/drizzle/meta/0001_snapshot.json +0 -482
- package/drizzle/meta/0002_snapshot.json +0 -575
- package/drizzle/meta/0003_snapshot.json +0 -667
- package/drizzle/meta/0004_snapshot.json +0 -769
- package/drizzle/meta/0005_snapshot.json +0 -864
- package/drizzle/meta/0006_snapshot.json +0 -882
- package/drizzle/meta/0007_snapshot.json +0 -876
- package/drizzle/meta/0008_snapshot.json +0 -882
- package/drizzle/meta/0009_snapshot.json +0 -948
- package/drizzle/meta/0010_snapshot.json +0 -969
- package/drizzle/meta/0011_snapshot.json +0 -1049
- package/drizzle/meta/0012_snapshot.json +0 -1115
- package/drizzle/meta/0013_snapshot.json +0 -1121
- package/drizzle/meta/0014_snapshot.json +0 -1190
- package/drizzle/meta/0015_snapshot.json +0 -1280
- package/drizzle/meta/0016_snapshot.json +0 -1683
- package/drizzle/meta/0017_snapshot.json +0 -1834
- package/drizzle/meta/0018_snapshot.json +0 -1834
- package/drizzle/meta/0019_snapshot.json +0 -1909
- package/drizzle/meta/0020_snapshot.json +0 -1921
- package/drizzle/meta/0021_snapshot.json +0 -2045
- package/drizzle/meta/0022_snapshot.json +0 -2246
- package/drizzle/meta/0023_snapshot.json +0 -2252
- package/drizzle/meta/0024_snapshot.json +0 -2375
- package/drizzle/meta/0025_snapshot.json +0 -2407
- package/drizzle/meta/0026_snapshot.json +0 -2413
- package/drizzle/meta/0027_snapshot.json +0 -2425
- package/drizzle/meta/0028_snapshot.json +0 -2438
- package/drizzle/meta/0029_snapshot.json +0 -2546
- package/drizzle/meta/0030_snapshot.json +0 -2586
- package/drizzle/meta/0031_snapshot.json +0 -2598
- package/drizzle/meta/0032_snapshot.json +0 -2699
- package/drizzle/meta/0033_snapshot.json +0 -2712
- package/drizzle/meta/0034_snapshot.json +0 -2719
- package/drizzle/meta/0035_snapshot.json +0 -2726
- package/drizzle/meta/0036_snapshot.json +0 -2876
- package/drizzle/meta/0037_snapshot.json +0 -2883
- package/drizzle/meta/0038_snapshot.json +0 -2895
- package/drizzle/meta/0039_snapshot.json +0 -3501
- package/drizzle/meta/0040_snapshot.json +0 -3527
- package/drizzle/meta/0041_snapshot.json +0 -3824
- package/drizzle/meta/0042_snapshot.json +0 -3960
- package/drizzle/meta/_journal.json +0 -307
- package/src/data/seed.json +0 -253
|
@@ -0,0 +1,219 @@
|
|
|
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-LYMPYETA.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({ subjectId: args.subjectId, objectId, relation: args.relation, environmentId: envId, tenantId }).returning();
|
|
61
|
+
return row;
|
|
62
|
+
}
|
|
63
|
+
async function recordObservation(db, args) {
|
|
64
|
+
await db.insert(observations).values({
|
|
65
|
+
claimId: args.claimId,
|
|
66
|
+
verdict: args.verdict,
|
|
67
|
+
class: args.class ?? "executed",
|
|
68
|
+
tier: args.tier ?? null,
|
|
69
|
+
evidence: args.evidence ?? null,
|
|
70
|
+
oracleId: args.oracleId,
|
|
71
|
+
oracleVer: args.oracleVer,
|
|
72
|
+
costMillis: args.costMillis ?? null
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// src/db/surface.ts
|
|
77
|
+
function surfaceRef(pkg, version) {
|
|
78
|
+
return { kind: "package_surface", namespace: "npm", name: pkg, version };
|
|
79
|
+
}
|
|
80
|
+
function mcpSurfaceRef(server, version) {
|
|
81
|
+
return { kind: "mcp_server", namespace: "npm", name: server, version };
|
|
82
|
+
}
|
|
83
|
+
async function isExtractionCached(db, ref, artifactHash, extractorVersion, tier = "shipped_js_ast", tenantId = 0) {
|
|
84
|
+
const row = await upsertEntity(db, ref, tenantId);
|
|
85
|
+
if (row.artifactHash !== artifactHash) return false;
|
|
86
|
+
const existing = await db.select({ id: symbols.id }).from(symbols).where(and2(eq2(symbols.entityId, row.id), eq2(symbols.tier, tier))).limit(1);
|
|
87
|
+
if (existing.length === 0) return false;
|
|
88
|
+
const seen = await db.select({ oracleVer: observations.oracleVer }).from(observations).innerJoin(claims, eq2(claims.id, observations.claimId)).where(
|
|
89
|
+
and2(
|
|
90
|
+
eq2(claims.subjectId, row.id),
|
|
91
|
+
eq2(claims.relation, "exposes"),
|
|
92
|
+
eq2(observations.tier, tier)
|
|
93
|
+
)
|
|
94
|
+
).orderBy(desc(observations.observedAt)).limit(1);
|
|
95
|
+
return seen[0]?.oracleVer === extractorVersion;
|
|
96
|
+
}
|
|
97
|
+
async function storeSurface(db, surface, opts = {
|
|
98
|
+
extractorVersion: "1"
|
|
99
|
+
}) {
|
|
100
|
+
const tenantId = opts.tenantId ?? 0;
|
|
101
|
+
const ref = opts.ref ?? surfaceRef(surface.package, surface.version);
|
|
102
|
+
const entity = await upsertEntity(db, ref, tenantId);
|
|
103
|
+
if (opts.artifactHash) {
|
|
104
|
+
await db.update(entities).set({ artifactHash: opts.artifactHash }).where(eq2(entities.id, entity.id));
|
|
105
|
+
}
|
|
106
|
+
const claim = await upsertClaim(db, {
|
|
107
|
+
subjectId: entity.id,
|
|
108
|
+
relation: "exposes",
|
|
109
|
+
// Declared claims are environment-independent: a shipped-JS surface reads
|
|
110
|
+
// identically on every machine, so no fingerprint is attached (§5).
|
|
111
|
+
environmentId: null,
|
|
112
|
+
tenantId
|
|
113
|
+
});
|
|
114
|
+
const undeclared = surface.symbols.length === 0;
|
|
115
|
+
await recordObservation(db, {
|
|
116
|
+
claimId: claim.id,
|
|
117
|
+
verdict: undeclared ? "undeclared" : "verified_true",
|
|
118
|
+
class: "declared",
|
|
119
|
+
tier: surface.tier,
|
|
120
|
+
evidence: undeclared ? surface.undeclaredReason ?? "no symbols extracted" : `${surface.symbols.length} symbols from ${surface.filesWalked} file(s), entry ${surface.entry}`,
|
|
121
|
+
oracleId: opts.oracleId ?? "surface.tier_a",
|
|
122
|
+
oracleVer: opts.extractorVersion
|
|
123
|
+
});
|
|
124
|
+
if (undeclared) return { entityId: entity.id, symbolsWritten: 0, verdict: "undeclared" };
|
|
125
|
+
await db.delete(symbols).where(and2(eq2(symbols.entityId, entity.id), eq2(symbols.tier, surface.tier)));
|
|
126
|
+
const rows = surface.symbols.map((s) => ({
|
|
127
|
+
entityId: entity.id,
|
|
128
|
+
path: s.path,
|
|
129
|
+
kind: s.kind,
|
|
130
|
+
arity: s.arity,
|
|
131
|
+
origin: s.origin,
|
|
132
|
+
deprecated: s.deprecated,
|
|
133
|
+
tier: s.tier,
|
|
134
|
+
signature: s.signature ?? null,
|
|
135
|
+
sourceFile: s.sourceRef?.file ?? null,
|
|
136
|
+
sourceLine: s.sourceRef?.line ?? null,
|
|
137
|
+
sourceOffset: s.sourceRef?.offset ?? null,
|
|
138
|
+
maxArity: s.maxArity === void 0 ? null : s.maxArity ?? UNBOUNDED_ARITY
|
|
139
|
+
}));
|
|
140
|
+
for (let i = 0; i < rows.length; i += 500) {
|
|
141
|
+
await db.insert(symbols).values(rows.slice(i, i + 500)).onConflictDoNothing();
|
|
142
|
+
}
|
|
143
|
+
return { entityId: entity.id, symbolsWritten: rows.length, verdict: "verified_true" };
|
|
144
|
+
}
|
|
145
|
+
function specKey(pkg, version, kind = "package_surface") {
|
|
146
|
+
const base = `${pkg}@${version ?? "latest"}`;
|
|
147
|
+
return kind === "package_surface" ? base : `${kind}:${base}`;
|
|
148
|
+
}
|
|
149
|
+
async function getPackagesMissingGraphSurface(db, limit, opts = {}) {
|
|
150
|
+
const order = opts.byDownloads ? sql`${packages.weeklyDownloads} desc nulls last` : sql`random()`;
|
|
151
|
+
const rows = await db.select({ name: packages.name, version: packages.latestVersion }).from(packages).leftJoin(
|
|
152
|
+
entities,
|
|
153
|
+
and2(
|
|
154
|
+
eq2(entities.kind, "package_surface"),
|
|
155
|
+
eq2(entities.name, packages.name),
|
|
156
|
+
eq2(entities.version, packages.latestVersion)
|
|
157
|
+
)
|
|
158
|
+
).where(and2(isNotNull(packages.latestVersion), isNull2(entities.id))).orderBy(order).limit(limit);
|
|
159
|
+
return rows.filter((r) => r.version !== null);
|
|
160
|
+
}
|
|
161
|
+
async function enqueueSurface(db, pkg, version, kind = "package_surface") {
|
|
162
|
+
await db.insert(surfaceQueue).values({ packageName: pkg, version, kind, specKey: specKey(pkg, version, kind) }).onConflictDoNothing();
|
|
163
|
+
}
|
|
164
|
+
async function getPendingSurfaces(db, limit = 10, kind = "package_surface") {
|
|
165
|
+
return db.select().from(surfaceQueue).where(eq2(surfaceQueue.kind, kind)).orderBy(surfaceQueue.requestedAt).limit(limit);
|
|
166
|
+
}
|
|
167
|
+
async function dropSurfaceQueue(db, id) {
|
|
168
|
+
await db.delete(surfaceQueue).where(eq2(surfaceQueue.id, id));
|
|
169
|
+
}
|
|
170
|
+
async function bumpSurfaceAttempt(db, id) {
|
|
171
|
+
await db.update(surfaceQueue).set({ attempts: sql`${surfaceQueue.attempts} + 1` }).where(eq2(surfaceQueue.id, id));
|
|
172
|
+
}
|
|
173
|
+
async function hasStoredSurface(db, pkg, version, tier = "shipped_js_ast", tenantId = 0, kind = "package_surface") {
|
|
174
|
+
const key = canonicalKey(
|
|
175
|
+
kind === "mcp_server" ? mcpSurfaceRef(pkg, version) : surfaceRef(pkg, version)
|
|
176
|
+
);
|
|
177
|
+
const [row] = await db.select({ id: entities.id }).from(entities).where(and2(eq2(entities.canonicalKey, key), eq2(entities.tenantId, tenantId))).limit(1);
|
|
178
|
+
if (!row) return false;
|
|
179
|
+
const [sym] = await db.select({ id: symbols.id }).from(symbols).where(and2(eq2(symbols.entityId, row.id), eq2(symbols.tier, tier))).limit(1);
|
|
180
|
+
return sym !== void 0;
|
|
181
|
+
}
|
|
182
|
+
async function enqueuePreviousSurface(db, pkg, version, history, kind = "package_surface") {
|
|
183
|
+
const previous = previousVersion(history, version);
|
|
184
|
+
if (previous === null) return false;
|
|
185
|
+
const tier = kind === "mcp_server" ? "mcp_tools_list" : "shipped_js_ast";
|
|
186
|
+
if (await hasStoredSurface(db, pkg, previous, tier, 0, kind)) return false;
|
|
187
|
+
await enqueueSurface(db, pkg, previous, kind);
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
190
|
+
function previousVersion(history, version) {
|
|
191
|
+
const idx = history.findIndex((h) => h.version === version);
|
|
192
|
+
if (idx === -1 || idx + 1 >= history.length) return null;
|
|
193
|
+
return history[idx + 1].version ?? null;
|
|
194
|
+
}
|
|
195
|
+
async function getMcpServerNames(db, tenantId = 0) {
|
|
196
|
+
const rows = await db.selectDistinct({ name: entities.name }).from(entities).where(and2(eq2(entities.kind, "mcp_server"), eq2(entities.tenantId, tenantId)));
|
|
197
|
+
return rows.map((r) => r.name);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export {
|
|
201
|
+
canonicalKey,
|
|
202
|
+
upsertEntity,
|
|
203
|
+
upsertClaim,
|
|
204
|
+
recordObservation,
|
|
205
|
+
surfaceRef,
|
|
206
|
+
mcpSurfaceRef,
|
|
207
|
+
isExtractionCached,
|
|
208
|
+
storeSurface,
|
|
209
|
+
specKey,
|
|
210
|
+
getPackagesMissingGraphSurface,
|
|
211
|
+
enqueueSurface,
|
|
212
|
+
getPendingSurfaces,
|
|
213
|
+
dropSurfaceQueue,
|
|
214
|
+
bumpSurfaceAttempt,
|
|
215
|
+
hasStoredSurface,
|
|
216
|
+
enqueuePreviousSurface,
|
|
217
|
+
previousVersion,
|
|
218
|
+
getMcpServerNames
|
|
219
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { createRequire as __lurqCreateRequire } from 'node:module'; const require = __lurqCreateRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
httpRequest
|
|
4
|
+
} from "./chunk-SJOVFF7B.js";
|
|
5
|
+
import {
|
|
6
|
+
init_esm_shims
|
|
7
|
+
} from "./chunk-I3M2KJXB.js";
|
|
8
|
+
|
|
9
|
+
// src/ingestion/sources/osv.ts
|
|
10
|
+
init_esm_shims();
|
|
11
|
+
var HOST = "api.osv.dev";
|
|
12
|
+
var URL = `https://${HOST}/v1/querybatch`;
|
|
13
|
+
var BATCH = 250;
|
|
14
|
+
var CONCURRENCY = 4;
|
|
15
|
+
function installKey(name, version) {
|
|
16
|
+
return `${name}@${version}`;
|
|
17
|
+
}
|
|
18
|
+
async function queryVulnerableInstalls(installs, fetchImpl) {
|
|
19
|
+
const affected = /* @__PURE__ */ new Map();
|
|
20
|
+
if (installs.length === 0) return { affected, complete: true };
|
|
21
|
+
const unique = [...new Map(installs.map((i) => [installKey(i.name, i.version), i])).values()];
|
|
22
|
+
const batches = [];
|
|
23
|
+
for (let i = 0; i < unique.length; i += BATCH) batches.push(unique.slice(i, i + BATCH));
|
|
24
|
+
let complete = true;
|
|
25
|
+
let cursor = 0;
|
|
26
|
+
const worker = async () => {
|
|
27
|
+
for (let i = cursor++; i < batches.length; i = cursor++) {
|
|
28
|
+
const batch = batches[i];
|
|
29
|
+
try {
|
|
30
|
+
const { data } = await httpRequest(URL, {
|
|
31
|
+
host: HOST,
|
|
32
|
+
method: "POST",
|
|
33
|
+
headers: { "content-type": "application/json" },
|
|
34
|
+
body: JSON.stringify({
|
|
35
|
+
queries: batch.map((q) => ({
|
|
36
|
+
version: q.version,
|
|
37
|
+
package: { name: q.name, ecosystem: "npm" }
|
|
38
|
+
}))
|
|
39
|
+
}),
|
|
40
|
+
// Uncached on purpose. The shared cache keys on the URL, and every
|
|
41
|
+
// batch here posts to the same one with a different body — a cache hit
|
|
42
|
+
// would answer one tree's question with another tree's vulnerabilities.
|
|
43
|
+
ttlMs: 0,
|
|
44
|
+
// Best-effort by contract: the caller keeps its coarser answer when
|
|
45
|
+
// this fails, so exhausting the default retry ladder would only stall
|
|
46
|
+
// a scheduled scan behind an outage nobody is waiting on.
|
|
47
|
+
retries: 1,
|
|
48
|
+
fetchImpl
|
|
49
|
+
});
|
|
50
|
+
const results = data?.results ?? [];
|
|
51
|
+
if (results.length !== batch.length) {
|
|
52
|
+
complete = false;
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
results.forEach((result, j) => {
|
|
56
|
+
const ids = (result?.vulns ?? []).map((v) => v?.id).filter((id) => typeof id === "string");
|
|
57
|
+
if (ids.length === 0) return;
|
|
58
|
+
const q = batch[j];
|
|
59
|
+
affected.set(installKey(q.name, q.version), ids);
|
|
60
|
+
});
|
|
61
|
+
} catch {
|
|
62
|
+
complete = false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
await Promise.all(Array.from({ length: Math.min(CONCURRENCY, batches.length) }, worker));
|
|
67
|
+
return { affected, complete };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export {
|
|
71
|
+
installKey,
|
|
72
|
+
queryVulnerableInstalls
|
|
73
|
+
};
|
|
@@ -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
|
+
};
|