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,318 @@
|
|
|
1
|
+
import { createRequire as __lurqCreateRequire } from 'node:module'; const require = __lurqCreateRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
require_dist
|
|
4
|
+
} from "./chunk-QKGYDMWB.js";
|
|
5
|
+
import {
|
|
6
|
+
__toESM,
|
|
7
|
+
init_esm_shims
|
|
8
|
+
} from "./chunk-I3M2KJXB.js";
|
|
9
|
+
|
|
10
|
+
// src/audit/inventory.ts
|
|
11
|
+
init_esm_shims();
|
|
12
|
+
var import_yaml = __toESM(require_dist(), 1);
|
|
13
|
+
import { existsSync, readFileSync, readdirSync } from "fs";
|
|
14
|
+
import { homedir } from "os";
|
|
15
|
+
import { isAbsolute, join, relative, resolve } from "path";
|
|
16
|
+
var DEP_SECTIONS = ["dependencies", "devDependencies", "optionalDependencies"];
|
|
17
|
+
var MAX_ITEMS = 600;
|
|
18
|
+
var MAX_TRANSITIVES = 4e3;
|
|
19
|
+
function readJson(path) {
|
|
20
|
+
try {
|
|
21
|
+
return JSON.parse(readFileSync(path, "utf8"));
|
|
22
|
+
} catch {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function splitSpec(spec) {
|
|
27
|
+
const at = spec.lastIndexOf("@");
|
|
28
|
+
if (at <= 0) return { name: spec, version: null };
|
|
29
|
+
const name = spec.slice(0, at);
|
|
30
|
+
const version = spec.slice(at + 1);
|
|
31
|
+
if (!/^\d/.test(version)) return { name, version: null };
|
|
32
|
+
return { name, version };
|
|
33
|
+
}
|
|
34
|
+
var NPM_RUNNERS = /* @__PURE__ */ new Set(["npx", "bunx", "pnpx"]);
|
|
35
|
+
var RUNNER_FLAGS = /* @__PURE__ */ new Set(["-y", "--yes", "--no-install", "--silent", "-q", "--quiet", "-p"]);
|
|
36
|
+
var OTHER_RUNNERS = /* @__PURE__ */ new Set(["uvx", "pipx", "uv", "pip", "python", "python3", "go", "cargo"]);
|
|
37
|
+
function classifyServer(alias, raw) {
|
|
38
|
+
const base = { alias, packageName: null, version: null, endpoint: null };
|
|
39
|
+
if (typeof raw.url === "string" && raw.url) {
|
|
40
|
+
let endpoint = raw.url;
|
|
41
|
+
try {
|
|
42
|
+
endpoint = new URL(raw.url).host;
|
|
43
|
+
} catch {
|
|
44
|
+
}
|
|
45
|
+
return { ...base, kind: "remote", endpoint };
|
|
46
|
+
}
|
|
47
|
+
const command = typeof raw.command === "string" ? raw.command : "";
|
|
48
|
+
const args = Array.isArray(raw.args) ? raw.args.filter((a) => typeof a === "string") : [];
|
|
49
|
+
const bin = command.split(/[\\/]/).pop() ?? "";
|
|
50
|
+
if (OTHER_RUNNERS.has(bin)) return { ...base, kind: "other-registry" };
|
|
51
|
+
if (NPM_RUNNERS.has(bin) || bin === "pnpm" && args[0] === "dlx") {
|
|
52
|
+
const rest = bin === "pnpm" ? args.slice(1) : args;
|
|
53
|
+
const spec = rest.find((a) => !a.startsWith("-") && !RUNNER_FLAGS.has(a));
|
|
54
|
+
if (!spec) return { ...base, kind: "npm-stdio" };
|
|
55
|
+
const { name, version } = splitSpec(spec);
|
|
56
|
+
return { ...base, kind: "npm-stdio", packageName: name, version };
|
|
57
|
+
}
|
|
58
|
+
return { ...base, kind: "local" };
|
|
59
|
+
}
|
|
60
|
+
function serversFromConfig(config, file) {
|
|
61
|
+
if (!config || typeof config !== "object") return [];
|
|
62
|
+
const out = [];
|
|
63
|
+
for (const section of ["mcpServers", "servers"]) {
|
|
64
|
+
const block = config[section];
|
|
65
|
+
if (!block || typeof block !== "object") continue;
|
|
66
|
+
for (const [alias, raw] of Object.entries(block)) {
|
|
67
|
+
if (!raw || typeof raw !== "object") continue;
|
|
68
|
+
out.push({
|
|
69
|
+
...classifyServer(alias, raw),
|
|
70
|
+
sources: [{ file, section }]
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return out;
|
|
75
|
+
}
|
|
76
|
+
function mcpConfigPaths(root, home = homedir()) {
|
|
77
|
+
return [
|
|
78
|
+
join(root, ".mcp.json"),
|
|
79
|
+
join(root, ".cursor", "mcp.json"),
|
|
80
|
+
join(root, ".vscode", "mcp.json"),
|
|
81
|
+
join(root, ".windsurf", "mcp.json"),
|
|
82
|
+
join(home, ".claude.json"),
|
|
83
|
+
join(home, ".cursor", "mcp.json"),
|
|
84
|
+
join(home, ".codeium", "windsurf", "mcp_config.json"),
|
|
85
|
+
join(home, ".gemini", "settings.json")
|
|
86
|
+
];
|
|
87
|
+
}
|
|
88
|
+
function installedFrom(root, name, lock) {
|
|
89
|
+
const pkgJson = join(root, "node_modules", ...name.split("/"), "package.json");
|
|
90
|
+
if (existsSync(pkgJson)) {
|
|
91
|
+
const m = readJson(pkgJson);
|
|
92
|
+
if (m && typeof m.version === "string") return m.version;
|
|
93
|
+
}
|
|
94
|
+
return lock.get(name) ?? null;
|
|
95
|
+
}
|
|
96
|
+
function readLockTree(root) {
|
|
97
|
+
const installs = /* @__PURE__ */ new Map();
|
|
98
|
+
const edges = /* @__PURE__ */ new Map();
|
|
99
|
+
const lock = readJson(join(root, "package-lock.json"));
|
|
100
|
+
if (!lock) return { installs, edges, present: false };
|
|
101
|
+
const addEdge = (parent, child) => {
|
|
102
|
+
if (!parent || !child || parent === child) return;
|
|
103
|
+
const set = edges.get(parent);
|
|
104
|
+
if (set) set.add(child);
|
|
105
|
+
else edges.set(parent, /* @__PURE__ */ new Set([child]));
|
|
106
|
+
};
|
|
107
|
+
for (const [path, entry] of Object.entries(lock.packages ?? {})) {
|
|
108
|
+
const idx = path.lastIndexOf("node_modules/");
|
|
109
|
+
if (idx < 0) continue;
|
|
110
|
+
const name = path.slice(idx + "node_modules/".length);
|
|
111
|
+
if (!name) continue;
|
|
112
|
+
if (typeof entry?.version === "string" && !installs.has(name))
|
|
113
|
+
installs.set(name, entry.version);
|
|
114
|
+
for (const dep of Object.keys(entry?.dependencies ?? {})) addEdge(name, dep);
|
|
115
|
+
for (const dep of Object.keys(entry?.optionalDependencies ?? {})) addEdge(name, dep);
|
|
116
|
+
}
|
|
117
|
+
for (const [name, entry] of Object.entries(lock.dependencies ?? {})) {
|
|
118
|
+
if (typeof entry?.version === "string" && !installs.has(name))
|
|
119
|
+
installs.set(name, entry.version);
|
|
120
|
+
for (const dep of Object.keys(entry?.dependencies ?? {})) addEdge(name, dep);
|
|
121
|
+
}
|
|
122
|
+
return { installs, edges, present: true };
|
|
123
|
+
}
|
|
124
|
+
function readLockfile(root) {
|
|
125
|
+
return readLockTree(root).installs;
|
|
126
|
+
}
|
|
127
|
+
function attributeTree(directs, edges, maxDepth = 12) {
|
|
128
|
+
const via = /* @__PURE__ */ new Map();
|
|
129
|
+
for (const root of directs) {
|
|
130
|
+
const seen = /* @__PURE__ */ new Set([root]);
|
|
131
|
+
let frontier = [root];
|
|
132
|
+
for (let depth = 0; depth < maxDepth && frontier.length; depth++) {
|
|
133
|
+
const next = [];
|
|
134
|
+
for (const node of frontier) {
|
|
135
|
+
for (const child of edges.get(node) ?? []) {
|
|
136
|
+
if (seen.has(child)) continue;
|
|
137
|
+
seen.add(child);
|
|
138
|
+
next.push(child);
|
|
139
|
+
const list = via.get(child);
|
|
140
|
+
if (list) {
|
|
141
|
+
if (!list.includes(root)) list.push(root);
|
|
142
|
+
} else via.set(child, [root]);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
frontier = next;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return via;
|
|
149
|
+
}
|
|
150
|
+
var MAX_WORKSPACE_DEPTH = 5;
|
|
151
|
+
var SKIP_DIRS = /* @__PURE__ */ new Set(["node_modules", "dist", "build", "coverage", ".git", ".next"]);
|
|
152
|
+
function workspacePatterns(root) {
|
|
153
|
+
const m = readJson(join(root, "package.json"));
|
|
154
|
+
const fromNpm = Array.isArray(m?.workspaces) ? m.workspaces : Array.isArray(m?.workspaces?.packages) ? m.workspaces.packages : [];
|
|
155
|
+
const pnpmPath = join(root, "pnpm-workspace.yaml");
|
|
156
|
+
let fromPnpm = [];
|
|
157
|
+
if (existsSync(pnpmPath)) {
|
|
158
|
+
try {
|
|
159
|
+
const doc = (0, import_yaml.parse)(readFileSync(pnpmPath, "utf8"));
|
|
160
|
+
if (Array.isArray(doc?.packages)) fromPnpm = doc.packages;
|
|
161
|
+
} catch {
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return [...fromNpm, ...fromPnpm].filter((p) => typeof p === "string");
|
|
165
|
+
}
|
|
166
|
+
function childDirs(dir) {
|
|
167
|
+
try {
|
|
168
|
+
return readdirSync(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && !SKIP_DIRS.has(e.name) && !e.name.startsWith(".")).map((e) => join(dir, e.name));
|
|
169
|
+
} catch {
|
|
170
|
+
return [];
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
function expandWorkspaces(root, patterns) {
|
|
174
|
+
const includes = patterns.filter((p) => !p.startsWith("!"));
|
|
175
|
+
const excludes = patterns.filter((p) => p.startsWith("!")).map((p) => resolve(root, p.slice(1).replace(/\/\*+$/, "")));
|
|
176
|
+
const dirs = /* @__PURE__ */ new Set();
|
|
177
|
+
for (const pattern of includes) {
|
|
178
|
+
const deep = /\/\*\*$/.test(pattern);
|
|
179
|
+
const shallow = !deep && /\/\*$/.test(pattern);
|
|
180
|
+
const base = resolve(root, pattern.replace(/\/\*+$/, ""));
|
|
181
|
+
if (!existsSync(base)) continue;
|
|
182
|
+
if (!deep && !shallow) {
|
|
183
|
+
dirs.add(base);
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
let frontier = childDirs(base);
|
|
187
|
+
for (const d of frontier) dirs.add(d);
|
|
188
|
+
if (!deep) continue;
|
|
189
|
+
for (let depth = 1; depth < MAX_WORKSPACE_DEPTH && frontier.length; depth++) {
|
|
190
|
+
const next = frontier.flatMap(childDirs);
|
|
191
|
+
for (const d of next) dirs.add(d);
|
|
192
|
+
frontier = next;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
const out = [];
|
|
196
|
+
for (const dir of dirs) {
|
|
197
|
+
if (excludes.some((x) => dir === x || dir.startsWith(`${x}/`))) continue;
|
|
198
|
+
const manifest = join(dir, "package.json");
|
|
199
|
+
if (existsSync(manifest)) out.push(manifest);
|
|
200
|
+
}
|
|
201
|
+
return out.sort();
|
|
202
|
+
}
|
|
203
|
+
function collectInventory(root, opts = {}) {
|
|
204
|
+
const abs = resolve(root);
|
|
205
|
+
const max = opts.maxItems ?? MAX_ITEMS;
|
|
206
|
+
const filesRead = [];
|
|
207
|
+
const notes = [];
|
|
208
|
+
const rel = (p) => isAbsolute(p) && p.startsWith(abs) ? relative(abs, p) || "." : p;
|
|
209
|
+
const byName = /* @__PURE__ */ new Map();
|
|
210
|
+
const rootManifest = join(abs, "package.json");
|
|
211
|
+
const manifests = [];
|
|
212
|
+
if (existsSync(rootManifest)) {
|
|
213
|
+
manifests.push(rootManifest);
|
|
214
|
+
manifests.push(...expandWorkspaces(abs, workspacePatterns(abs)));
|
|
215
|
+
} else {
|
|
216
|
+
notes.push(`no package.json at ${abs}; npm half of the audit is empty`);
|
|
217
|
+
}
|
|
218
|
+
const tree = readLockTree(abs);
|
|
219
|
+
const lock = tree.installs;
|
|
220
|
+
for (const path of manifests) {
|
|
221
|
+
const m = readJson(path);
|
|
222
|
+
if (!m) {
|
|
223
|
+
notes.push(`could not parse ${rel(path)}`);
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
filesRead.push(rel(path));
|
|
227
|
+
for (const section of DEP_SECTIONS) {
|
|
228
|
+
const block = m[section];
|
|
229
|
+
if (!block || typeof block !== "object") continue;
|
|
230
|
+
for (const [name, range] of Object.entries(block)) {
|
|
231
|
+
if (typeof range !== "string") continue;
|
|
232
|
+
const src = { file: rel(path), section };
|
|
233
|
+
const seen = byName.get(name);
|
|
234
|
+
if (seen) {
|
|
235
|
+
seen.sources.push(src);
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
byName.set(name, {
|
|
239
|
+
name,
|
|
240
|
+
range,
|
|
241
|
+
installed: installedFrom(abs, name, lock),
|
|
242
|
+
sources: [src]
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
const byAlias = /* @__PURE__ */ new Map();
|
|
248
|
+
for (const path of mcpConfigPaths(abs, opts.home)) {
|
|
249
|
+
if (opts.projectOnly && !path.startsWith(abs)) continue;
|
|
250
|
+
if (!existsSync(path)) continue;
|
|
251
|
+
const cfg = readJson(path);
|
|
252
|
+
if (!cfg) {
|
|
253
|
+
notes.push(`could not parse ${rel(path)}`);
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
const found = serversFromConfig(cfg, rel(path));
|
|
257
|
+
if (found.length) filesRead.push(rel(path));
|
|
258
|
+
for (const s of found) {
|
|
259
|
+
const key = s.packageName ?? s.endpoint ?? `${s.kind}:${s.alias}`;
|
|
260
|
+
const seen = byAlias.get(key);
|
|
261
|
+
if (seen) {
|
|
262
|
+
seen.sources.push(...s.sources);
|
|
263
|
+
seen.version ??= s.version;
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
byAlias.set(key, s);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
const packages = [...byName.values()];
|
|
270
|
+
const mcpServers = [...byAlias.values()];
|
|
271
|
+
const directNames = new Set(byName.keys());
|
|
272
|
+
const via = attributeTree([...directNames], tree.edges);
|
|
273
|
+
const transitives = [];
|
|
274
|
+
for (const [name, version] of tree.installs) {
|
|
275
|
+
if (directNames.has(name)) continue;
|
|
276
|
+
if (transitives.length >= MAX_TRANSITIVES) {
|
|
277
|
+
notes.push(
|
|
278
|
+
`resolved tree exceeds ${MAX_TRANSITIVES} installs; the remainder were not checked for vulnerabilities`
|
|
279
|
+
);
|
|
280
|
+
break;
|
|
281
|
+
}
|
|
282
|
+
transitives.push({ name, version, via: via.get(name) ?? [] });
|
|
283
|
+
}
|
|
284
|
+
if (!tree.present && packages.length > 0) {
|
|
285
|
+
notes.push(
|
|
286
|
+
"no package-lock.json, so the dependency tree below your manifest was never read \u2014 transitive vulnerabilities are NOT covered by this run"
|
|
287
|
+
);
|
|
288
|
+
}
|
|
289
|
+
const total = packages.length + mcpServers.length;
|
|
290
|
+
if (total > max) {
|
|
291
|
+
notes.push(
|
|
292
|
+
`${total} items discovered, auditing the first ${max}; the remainder are reported as truncated rather than dropped`
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
return {
|
|
296
|
+
root: abs,
|
|
297
|
+
packages: packages.slice(0, max),
|
|
298
|
+
mcpServers: mcpServers.slice(0, Math.max(0, max - packages.length)),
|
|
299
|
+
transitives,
|
|
300
|
+
filesRead,
|
|
301
|
+
notes
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
export {
|
|
306
|
+
MAX_ITEMS,
|
|
307
|
+
MAX_TRANSITIVES,
|
|
308
|
+
splitSpec,
|
|
309
|
+
classifyServer,
|
|
310
|
+
serversFromConfig,
|
|
311
|
+
mcpConfigPaths,
|
|
312
|
+
readLockTree,
|
|
313
|
+
readLockfile,
|
|
314
|
+
attributeTree,
|
|
315
|
+
workspacePatterns,
|
|
316
|
+
expandWorkspaces,
|
|
317
|
+
collectInventory
|
|
318
|
+
};
|