lurqrun 0.1.7 → 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.
- package/README.md +312 -148
- package/dist/{auditHandler-JCOJSUYW.js → auditHandler-VWCXSDVO.js} +12 -11
- package/dist/autopilotInit-Q62MX5M6.js +178 -0
- package/dist/bin/lurq.js +235 -83
- package/dist/{browserAuth-B6G27USY.js → browserAuth-J7APSD4P.js} +4 -3
- package/dist/{cache-DKI34SVS.js → cache-AEAKCV4I.js} +2 -2
- package/dist/check-2JTQDQA6.js +2613 -0
- package/dist/{check-2FDGUOV7.js → check-PQSQ2MMA.js} +1 -1
- package/dist/checkUpgrade-5YW77OBL.js +24 -0
- package/dist/{chunk-BCANRN5B.js → chunk-2GAYNIHG.js} +8 -1
- package/dist/{chunk-EA3DP5HG.js → chunk-2O6Z37IT.js} +155 -25
- package/dist/{chunk-J5FZYN4A.js → chunk-2WD4QAH4.js} +1 -1
- package/dist/{chunk-CUP36ND3.js → chunk-3676XOBU.js} +145 -36
- package/dist/chunk-3D2MPGOQ.js +181 -0
- package/dist/{chunk-LYMPYETA.js → chunk-4JHDSVIN.js} +270 -6
- package/dist/chunk-53SG6XWA.js +141 -0
- package/dist/chunk-5ABNDB3I.js +37 -0
- package/dist/chunk-5ALIJFDA.js +114 -0
- package/dist/{chunk-BULZAX2U.js → chunk-64ZF7KO4.js} +55 -38
- package/dist/{chunk-2VMOWSRY.js → chunk-6DM6UQFD.js} +19 -1
- package/dist/{chunk-HWBBVLOT.js → chunk-6L67QMCP.js} +1 -1
- package/dist/{chunk-GPTKSNR6.js → chunk-72Y2FDVS.js} +2 -1
- package/dist/{chunk-B43LCXBM.js → chunk-A3TYI2TF.js} +81 -16
- package/dist/{chunk-IQ4SDKKY.js → chunk-B2UUYRBX.js} +31 -228
- package/dist/{chunk-DB2VF5UD.js → chunk-BJT2LHAR.js} +16 -11
- package/dist/chunk-BM3LF5T6.js +132 -0
- package/dist/{chunk-3N3Q3DSW.js → chunk-BN3NM47Q.js} +8 -8
- package/dist/chunk-D3K6IZVR.js +12845 -0
- package/dist/{chunk-AHBP533R.js → chunk-D3VTZS7V.js} +7 -5
- package/dist/{chunk-UDVNA7EA.js → chunk-DM37MTOO.js} +161 -8
- package/dist/chunk-DONTW3NE.js +171 -0
- package/dist/{chunk-M6NYEXCW.js → chunk-DSROTZ3Z.js} +1 -1
- package/dist/{chunk-4F7ZESPO.js → chunk-EQCXENKZ.js} +3 -5
- package/dist/{chunk-CW5HJ3LX.js → chunk-EYAKM6YN.js} +1 -1
- package/dist/{chunk-VL2E5T2A.js → chunk-FDFPMBCA.js} +6 -3
- package/dist/{chunk-BV32UNLL.js → chunk-FVYFV5HA.js} +2 -2
- package/dist/{chunk-DWAGCNEL.js → chunk-GM5Y555O.js} +36 -103
- package/dist/{chunk-PSX3GIAN.js → chunk-HWFX4BC4.js} +2 -1
- package/dist/chunk-IFNONGRQ.js +603 -0
- package/dist/chunk-J3U2CPSK.js +136 -0
- package/dist/{chunk-Y5GI7RL3.js → chunk-J6XQ7OPZ.js} +9 -1
- package/dist/{chunk-LBFGSSF2.js → chunk-KMV4Y6R3.js} +2 -1
- package/dist/{chunk-L6N4JFW2.js → chunk-KP5ZDDPE.js} +81 -4
- package/dist/{chunk-SJOVFF7B.js → chunk-KYKSZ3XZ.js} +3 -2
- package/dist/chunk-NEZNAPPN.js +41 -0
- package/dist/{chunk-NH5I4KHH.js → chunk-NPVN2THM.js} +1 -5
- package/dist/{chunk-6L3U7DZ5.js → chunk-NYZU5NCW.js} +1 -1
- package/dist/chunk-O4KHCV6I.js +320 -0
- package/dist/{chunk-LO35HLQZ.js → chunk-ONDVTXUO.js} +25 -4
- package/dist/{chunk-4ZYCIMY4.js → chunk-OTJFHESY.js} +25 -4
- package/dist/chunk-P6MIKSPY.js +243 -0
- package/dist/{checkUpgrade-F2WESBPM.js → chunk-QCRBX3LV.js} +72 -10
- package/dist/{chunk-LRD4GBYE.js → chunk-QUIMQ7YL.js} +1 -1
- package/dist/chunk-RG3YLU6E.js +49 -0
- package/dist/{chunk-ST2X2GYN.js → chunk-SHZFOSXC.js} +109 -20
- package/dist/{chunk-CIDWNUAP.js → chunk-SOXFMMXC.js} +8 -2
- package/dist/chunk-TDTYV6QI.js +119 -0
- package/dist/{chunk-FW6BD2NO.js → chunk-TUXQ32WE.js} +457 -121
- package/dist/{chunk-WQ23REYT.js → chunk-VGCDRK3S.js} +1 -1
- package/dist/{chunk-U5AT3TD4.js → chunk-X4W64MHU.js} +1735 -1858
- package/dist/chunk-XBQA4I36.js +92 -0
- package/dist/chunk-XGOV6KV4.js +413 -0
- package/dist/{chunk-OQS4GUSI.js → chunk-XIFQIFSZ.js} +210 -661
- package/dist/{chunk-XBIDMHSK.js → chunk-XLXPVN3Y.js} +2 -34
- package/dist/chunk-ZJMLQ37G.js +90 -0
- package/dist/{client-IRKAMDYZ.js → client-MU4EUDZV.js} +3 -3
- package/dist/{commands-FIL5ET6P.js → commands-UOOTMBKA.js} +145 -33
- package/dist/{compat-R3UTFQ5Q.js → compat-Q5DVPITN.js} +6 -6
- package/dist/constants-DJFOFZ44.js +24 -0
- package/dist/{dashboardIssue-WYYMBFIB.js → dashboardIssue-KBKLQMGC.js} +105 -23
- package/dist/{diff-GZA2774U.js → diff-I4SNUHU3.js} +1 -1
- package/dist/domains-VRT4BRVZ.js +14 -0
- package/dist/env-UN6KGZ7S.js +15 -0
- package/dist/envCheck-KUPTORFQ.js +71 -0
- package/dist/{extract-NKGKLIVT.js → extract-6WG265BL.js} +14 -3
- package/dist/{fetch-QYTUJVG2.js → fetch-PJ3SC32M.js} +4 -4
- package/dist/{firstTouch-QQTJH4QX.js → firstTouch-COJCMOB3.js} +1 -1
- package/dist/fix-3EDWNKW3.js +220 -0
- package/dist/{handlers-GEJAVZDK.js → handlers-4Q37WIFT.js} +19 -17
- package/dist/hook-NA66XJLC.js +412 -0
- package/dist/{http-ETPYMBGD.js → http-25GJ6SKK.js} +2078 -510
- package/dist/{ingestQueue-VKN4KBIF.js → ingestQueue-FSVJC3AA.js} +14 -12
- package/dist/{install-EK3W2COX.js → install-G2HHXYJ2.js} +6 -6
- package/dist/{installSkill-VQJWJVCL.js → installSkill-5TIMYIJZ.js} +21 -3
- package/dist/manifest-ENMIC54B.js +13 -0
- package/dist/{mcp-3JHD5SUZ.js → mcp-PENLL2PK.js} +60 -32
- package/dist/mcpConfig-3LYPRY5Q.js +80 -0
- package/dist/{mcpHandlers-QFN4MCFL.js → mcpHandlers-PO7GENA7.js} +7 -7
- package/dist/{mcpScan-QZHWENIP.js → mcpScan-ULP626TQ.js} +306 -442
- package/dist/{mcpScanWorkflow-JPYCBGC4.js → mcpScanWorkflow-27O44FOE.js} +29 -12
- package/dist/{mcpStack-BYJCZNIV.js → mcpStack-ZNYIFXZ5.js} +1 -1
- package/dist/model-ASMZWLM7.js +214 -0
- package/dist/{packages-THVFMWFP.js → packages-RWF2LXST.js} +3 -5
- package/dist/{plan-V4OEI3J4.js → plan-SDILIDZT.js} +23 -21
- package/dist/{planView-JRXGCG2N.js → planView-ZAKRTGVS.js} +4 -1
- package/dist/{policy-3P6BGRDN.js → policy-JAGNMQJI.js} +5 -5
- package/dist/probe-3IK646WN.js +610 -0
- package/dist/publicUpgrades-WTBGLDIK.js +42 -0
- package/dist/{references-6N7VEPHT.js → references-I6Y4BSRR.js} +3 -1
- package/dist/{release-4U4ABNSJ.js → release-7IU2R4YG.js} +5 -5
- package/dist/{remote-YGCXYI4V.js → remote-FN6225AH.js} +13 -3
- package/dist/rename-OS6JYBZQ.js +204 -0
- package/dist/{reportRuns-CKQQYLY4.js → reportRuns-O4X7ZFTX.js} +15 -2
- package/dist/safeFetch-COERXGFN.js +19 -0
- package/dist/{sandbox-MEZLAODF.js → sandbox-SAPSRKEI.js} +4 -4
- package/dist/sarif-WLVJFJ7U.js +125 -0
- package/dist/server-OLTY3NYT.js +59 -0
- package/dist/{surface-V62GE554.js → surface-7MHE3RL7.js} +18 -16
- package/dist/{surface-YL6O67W3.js → surface-JS2XU3U3.js} +5 -3
- package/dist/{surfaceHandlers-X2IZKA3E.js → surfaceHandlers-4B6TMZ34.js} +5 -5
- package/dist/{typecheck-X7U5ELMR.js → typecheck-NGOKNAJY.js} +23 -9
- package/dist/{uninstall-P7RGBX6G.js → uninstall-I2IJP5JZ.js} +30 -4
- package/dist/{upgrade-NQ5IWFZB.js → upgrade-FS26DJGG.js} +86 -32
- package/dist/{upgradePlan-A4LRKLEG.js → upgradePlan-ZS5IOVMZ.js} +46 -11
- package/dist/upkeepHandler-VFGYXJKB.js +13 -0
- package/dist/{userConfig-Z3GQE776.js → userConfig-ICASHI47.js} +1 -1
- package/dist/{watch-DGFMWUDL.js → watch-OCNEUXG6.js} +24 -34
- package/package.json +3 -2
- package/templates/skill-instructions.md +22 -3
- package/dist/chunk-6AAEVQ7I.js +0 -6336
- package/dist/chunk-I2JUKN6Z.js +0 -24
- package/dist/server-KFUD5X57.js +0 -55
|
@@ -8,24 +8,29 @@ import {
|
|
|
8
8
|
import {
|
|
9
9
|
BLOCK_START,
|
|
10
10
|
agentSpecs,
|
|
11
|
+
hasLurqHooks,
|
|
12
|
+
hookAgentFor,
|
|
13
|
+
hooksLabel,
|
|
14
|
+
hooksPath,
|
|
11
15
|
readJsonObject,
|
|
12
16
|
removeMarkedBlock,
|
|
13
17
|
resolveAgents,
|
|
14
18
|
stripTomlBlock,
|
|
19
|
+
withoutLurqHooks,
|
|
15
20
|
writeFileAtomic,
|
|
16
21
|
writeJson
|
|
17
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-DM37MTOO.js";
|
|
18
23
|
import "./chunk-LUAKDHLZ.js";
|
|
19
24
|
import "./chunk-MYGSLK44.js";
|
|
20
25
|
import {
|
|
21
26
|
clearUserConfig,
|
|
22
27
|
lurqHome,
|
|
23
28
|
userConfigPath
|
|
24
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-J6XQ7OPZ.js";
|
|
25
30
|
import {
|
|
26
31
|
KEYS_URL,
|
|
27
32
|
PACKAGE_NAME
|
|
28
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-72Y2FDVS.js";
|
|
29
34
|
import {
|
|
30
35
|
init_esm_shims
|
|
31
36
|
} from "./chunk-I3M2KJXB.js";
|
|
@@ -72,6 +77,15 @@ function mcpEntryRemoval(spec) {
|
|
|
72
77
|
}
|
|
73
78
|
};
|
|
74
79
|
}
|
|
80
|
+
function hooksRemoval(agent) {
|
|
81
|
+
const path = hooksPath(agent);
|
|
82
|
+
if (!existsSync(path) || !hasLurqHooks(readJsonObject(path))) return null;
|
|
83
|
+
return {
|
|
84
|
+
label: hooksLabel(agent),
|
|
85
|
+
path,
|
|
86
|
+
apply: () => writeJson(path, withoutLurqHooks(readJsonObject(path)))
|
|
87
|
+
};
|
|
88
|
+
}
|
|
75
89
|
function instructionsRemoval(spec) {
|
|
76
90
|
const target = spec.instructions;
|
|
77
91
|
if (!target || !existsSync(target.path)) return null;
|
|
@@ -108,6 +122,16 @@ function planUninstall(specs, opts) {
|
|
|
108
122
|
problems.push(`${spec.label}: ${err instanceof Error ? err.message : String(err)}`);
|
|
109
123
|
}
|
|
110
124
|
add(instructionsRemoval(spec));
|
|
125
|
+
const hookAgent = hookAgentFor(spec.id);
|
|
126
|
+
if (hookAgent) {
|
|
127
|
+
try {
|
|
128
|
+
add(hooksRemoval(hookAgent));
|
|
129
|
+
} catch (err) {
|
|
130
|
+
problems.push(
|
|
131
|
+
`${hooksLabel(hookAgent)}: ${err instanceof Error ? err.message : String(err)}`
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
111
135
|
}
|
|
112
136
|
if (opts.global) {
|
|
113
137
|
const guide = join(lurqHome(), "skill-instructions.md");
|
|
@@ -134,7 +158,9 @@ async function runUninstall(opts) {
|
|
|
134
158
|
const short = (p) => p.startsWith(homedir()) ? `~${p.slice(homedir().length)}` : p;
|
|
135
159
|
for (const p of problems) console.log(`${yellow("!")} ${p}`);
|
|
136
160
|
if (removals.length === 0) {
|
|
137
|
-
console.log(
|
|
161
|
+
console.log(
|
|
162
|
+
`Nothing to remove: lurq is not set up ${global ? "on this machine" : `for ${specs[0].label}`}.`
|
|
163
|
+
);
|
|
138
164
|
if (problems.length) process.exitCode = 1;
|
|
139
165
|
return;
|
|
140
166
|
}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
import { createRequire as __lurqCreateRequire } from 'node:module'; const require = __lurqCreateRequire(import.meta.url);
|
|
2
|
-
import {
|
|
3
|
-
SURFACE_CLAIM_KINDS
|
|
4
|
-
} from "./chunk-ST2X2GYN.js";
|
|
5
2
|
import {
|
|
6
3
|
diffSurfaces,
|
|
7
4
|
runtimeSymbols,
|
|
@@ -17,17 +14,20 @@ import {
|
|
|
17
14
|
extractUnpacked,
|
|
18
15
|
fetchManifest,
|
|
19
16
|
unpackPackage
|
|
20
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-FVYFV5HA.js";
|
|
21
18
|
import {
|
|
22
19
|
resolveRuntimeEngineConflicts
|
|
23
20
|
} from "./chunk-BUALU27S.js";
|
|
24
|
-
import "./chunk-
|
|
25
|
-
import "./chunk-
|
|
21
|
+
import "./chunk-D3VTZS7V.js";
|
|
22
|
+
import "./chunk-KYKSZ3XZ.js";
|
|
26
23
|
import {
|
|
27
24
|
require_semver
|
|
28
25
|
} from "./chunk-3GHJR7XR.js";
|
|
29
26
|
import "./chunk-MYGSLK44.js";
|
|
30
|
-
import "./chunk-
|
|
27
|
+
import "./chunk-72Y2FDVS.js";
|
|
28
|
+
import {
|
|
29
|
+
SURFACE_CLAIM_KINDS
|
|
30
|
+
} from "./chunk-SHZFOSXC.js";
|
|
31
31
|
import {
|
|
32
32
|
__toESM,
|
|
33
33
|
init_esm_shims
|
|
@@ -81,23 +81,41 @@ function judgeRequires(from, to, refs, ctx) {
|
|
|
81
81
|
if (!broken.has(`${file}:${line}`)) broken.set(`${file}:${line}`, { file, line, why });
|
|
82
82
|
};
|
|
83
83
|
if (to === "unexported") {
|
|
84
|
-
for (const r of requireSites)
|
|
84
|
+
for (const r of requireSites)
|
|
85
|
+
add(r.file, r.line, "the exports map no longer offers anything to require()");
|
|
85
86
|
} else if (ctx.asyncModule) {
|
|
86
87
|
for (const r of requireSites) {
|
|
87
|
-
add(
|
|
88
|
+
add(
|
|
89
|
+
r.file,
|
|
90
|
+
r.line,
|
|
91
|
+
"the ES module uses top-level await, so require() throws ERR_REQUIRE_ASYNC_MODULE on every Node"
|
|
92
|
+
);
|
|
88
93
|
}
|
|
89
94
|
} else {
|
|
90
95
|
for (const r of required) {
|
|
91
96
|
if (r.via === "default") {
|
|
92
97
|
for (const c of r.calls ?? []) {
|
|
93
|
-
if (c.args !== null)
|
|
98
|
+
if (c.args !== null)
|
|
99
|
+
add(
|
|
100
|
+
r.file,
|
|
101
|
+
c.line,
|
|
102
|
+
"require() now returns the module namespace, which cannot be called"
|
|
103
|
+
);
|
|
94
104
|
}
|
|
95
105
|
} else if ((r.via === "namespace" || r.via === "destructured") && ctx.fromExports && ctx.toExports && !ctx.fromExports.has(r.symbol) && !ctx.toExports.has(r.symbol)) {
|
|
96
|
-
add(
|
|
106
|
+
add(
|
|
107
|
+
r.file,
|
|
108
|
+
r.line,
|
|
109
|
+
`\`${r.symbol}\` is not an export of the ES module, so it reads as undefined`
|
|
110
|
+
);
|
|
97
111
|
}
|
|
98
112
|
}
|
|
99
113
|
}
|
|
100
|
-
const olderNode = to === "esm" && !ctx.asyncModule && !requireEsmGuaranteed(ctx.runtime) ? [
|
|
114
|
+
const olderNode = to === "esm" && !ctx.asyncModule && !requireEsmGuaranteed(ctx.runtime) ? [
|
|
115
|
+
...new Map(
|
|
116
|
+
requireSites.map((r) => [`${r.file}:${r.line}`, { file: r.file, line: r.line }])
|
|
117
|
+
).values()
|
|
118
|
+
] : [];
|
|
101
119
|
if (!broken.size && !olderNode.length) return null;
|
|
102
120
|
return { from, to, broken: [...broken.values()], olderNode };
|
|
103
121
|
}
|
|
@@ -120,12 +138,21 @@ function engineRequirements(from, to, runtime) {
|
|
|
120
138
|
const declared = runtime.engines;
|
|
121
139
|
if (declared && import_semver.default.validRange(declared) && subsetOf(declared, needs) === false) {
|
|
122
140
|
const alreadyOut = before && import_semver.default.validRange(before) && subsetOf(declared, before) === false;
|
|
123
|
-
if (!alreadyOut)
|
|
141
|
+
if (!alreadyOut)
|
|
142
|
+
out.push({ kind: "engines", name: "node", needs, has: `${declared} (package.json engines)` });
|
|
124
143
|
}
|
|
125
144
|
const pinned = runtime.nodeVersionFile;
|
|
126
145
|
if (pinned) {
|
|
127
146
|
const conflicts = (range) => Boolean(range) && resolveRuntimeEngineConflicts(
|
|
128
|
-
[
|
|
147
|
+
[
|
|
148
|
+
{
|
|
149
|
+
name: to.name ?? "package",
|
|
150
|
+
version: null,
|
|
151
|
+
peerDependencies: null,
|
|
152
|
+
peerDependenciesMeta: null,
|
|
153
|
+
engines: { node: range }
|
|
154
|
+
}
|
|
155
|
+
],
|
|
129
156
|
pinned.value
|
|
130
157
|
).length > 0;
|
|
131
158
|
if (conflicts(needs) && !conflicts(before)) {
|
|
@@ -159,7 +186,9 @@ function peerRequirements(from, to, runtime) {
|
|
|
159
186
|
function projectVersionOf(root, name) {
|
|
160
187
|
for (let dir = resolve(root); ; dir = dirname(dir)) {
|
|
161
188
|
try {
|
|
162
|
-
const { version } = JSON.parse(
|
|
189
|
+
const { version } = JSON.parse(
|
|
190
|
+
readFileSync(join(dir, "node_modules", name, "package.json"), "utf8")
|
|
191
|
+
);
|
|
163
192
|
if (version && import_semver.default.valid(version)) return { version, exact: true, source: "installed" };
|
|
164
193
|
} catch {
|
|
165
194
|
}
|
|
@@ -168,7 +197,8 @@ function projectVersionOf(root, name) {
|
|
|
168
197
|
try {
|
|
169
198
|
const manifest = JSON.parse(readFileSync(join(root, "package.json"), "utf8"));
|
|
170
199
|
const declared = manifest.dependencies?.[name] ?? manifest.devDependencies?.[name];
|
|
171
|
-
if (declared && import_semver.default.validRange(declared))
|
|
200
|
+
if (declared && import_semver.default.validRange(declared))
|
|
201
|
+
return { version: declared, exact: false, source: "package.json" };
|
|
172
202
|
} catch {
|
|
173
203
|
}
|
|
174
204
|
return null;
|
|
@@ -241,7 +271,12 @@ function compareEntry(from, to, symbols, specifier, isRoot) {
|
|
|
241
271
|
const renames = new Map(diff.renamed.map((r) => [r.path, r.to]));
|
|
242
272
|
const symbolsRemoved = diff.removed.filter((s) => referenced.has(s.path) && !toSurface.has(s.path)).map((s) => {
|
|
243
273
|
const renamedTo = renames.get(s.path);
|
|
244
|
-
return {
|
|
274
|
+
return {
|
|
275
|
+
symbol: s.path,
|
|
276
|
+
...tag,
|
|
277
|
+
...renamedTo ? { renamedTo } : {},
|
|
278
|
+
refs: symbols.get(s.path) ?? []
|
|
279
|
+
};
|
|
245
280
|
});
|
|
246
281
|
const stars = starReExports(to);
|
|
247
282
|
if (symbolsRemoved.length && stars.length) {
|
|
@@ -277,9 +312,13 @@ async function checkUpgradeOne(target, refs, opts = {}) {
|
|
|
277
312
|
if (!refs || refs.symbols.size === 0) return requirementsOnly(target, opts.runtime);
|
|
278
313
|
const byEntry = groupByEntry(refs, target.package);
|
|
279
314
|
if (byEntry.size === 0) return requirementsOnly(target, opts.runtime);
|
|
280
|
-
const loose = [target.fromVersion, target.toVersion].filter(
|
|
315
|
+
const loose = [target.fromVersion, target.toVersion].filter(
|
|
316
|
+
(v) => import_semver2.default.validRange(v) && !import_semver2.default.valid(v)
|
|
317
|
+
);
|
|
281
318
|
if (loose.length) {
|
|
282
|
-
return {
|
|
319
|
+
return {
|
|
320
|
+
unverified: `expected exact versions, got ${target.fromVersion}..${target.toVersion}`
|
|
321
|
+
};
|
|
283
322
|
}
|
|
284
323
|
const settled = await Promise.allSettled([
|
|
285
324
|
unpackPackage(target.package, target.fromVersion),
|
|
@@ -288,10 +327,16 @@ async function checkUpgradeOne(target, refs, opts = {}) {
|
|
|
288
327
|
try {
|
|
289
328
|
const failure = settled.find((s) => s.status === "rejected");
|
|
290
329
|
if (failure) throw failure.reason;
|
|
291
|
-
const [fromPkg, toPkg] = settled.map(
|
|
330
|
+
const [fromPkg, toPkg] = settled.map(
|
|
331
|
+
(s) => s.value
|
|
332
|
+
);
|
|
292
333
|
if (!fromPkg || !toPkg) {
|
|
293
|
-
const missing = [fromPkg ? null : target.fromVersion, toPkg ? null : target.toVersion].filter(
|
|
294
|
-
|
|
334
|
+
const missing = [fromPkg ? null : target.fromVersion, toPkg ? null : target.toVersion].filter(
|
|
335
|
+
Boolean
|
|
336
|
+
);
|
|
337
|
+
return {
|
|
338
|
+
unverified: `not published on npm: ${missing.map((v) => `${target.package}@${v}`).join(", ")}`
|
|
339
|
+
};
|
|
295
340
|
}
|
|
296
341
|
return await compareVersions(target, refs, byEntry, fromPkg, toPkg, opts);
|
|
297
342
|
} finally {
|
|
@@ -395,7 +440,7 @@ async function compareVersions(target, refs, byEntry, fromPkg, toPkg, opts) {
|
|
|
395
440
|
const exportNames = (s) => s.undeclaredReason || starReExports(s).length ? null : new Set(s.symbols.filter((x) => x.kind !== "type_only").map((x) => x.path));
|
|
396
441
|
const fromTarget = requireTarget(fromPkg.pkgDir);
|
|
397
442
|
const toTarget = requireTarget(toPkg.pkgDir);
|
|
398
|
-
const asyncModule = fromTarget?.format === "cjs" && toTarget?.format === "esm" && toTarget.file ? (await import("./extract-
|
|
443
|
+
const asyncModule = fromTarget?.format === "cjs" && toTarget?.format === "esm" && toTarget.file ? (await import("./extract-6WG265BL.js")).usesTopLevelAwait(toPkg.pkgDir, toTarget.file) : false;
|
|
399
444
|
const moduleFormat = judgeRequires(
|
|
400
445
|
fromTarget?.format ?? null,
|
|
401
446
|
toTarget?.format ?? null,
|
|
@@ -449,7 +494,10 @@ async function checkUpgrade(targets, references, opts = {}) {
|
|
|
449
494
|
const runtime = opts.rootDir ? readRepoRuntime(opts.rootDir) : {};
|
|
450
495
|
for (const t of targets) {
|
|
451
496
|
try {
|
|
452
|
-
const res = await checkUpgradeOne(t, byPkg.get(t.package), {
|
|
497
|
+
const res = await checkUpgradeOne(t, byPkg.get(t.package), {
|
|
498
|
+
typeCheck: opts.typeCheck,
|
|
499
|
+
runtime
|
|
500
|
+
});
|
|
453
501
|
if (res.types) {
|
|
454
502
|
types.push(
|
|
455
503
|
res.types.checked ? { package: t.package, checked: true, files: res.types.files } : { package: t.package, checked: false, reason: res.types.reason }
|
|
@@ -478,7 +526,10 @@ function capped(items, cap = REPORT_LOCATION_CAP) {
|
|
|
478
526
|
return items.length > cap ? `${shown} (+${items.length - cap} more)` : shown;
|
|
479
527
|
}
|
|
480
528
|
function locations(refs) {
|
|
481
|
-
const all = refs.flatMap((r) => [
|
|
529
|
+
const all = refs.flatMap((r) => [
|
|
530
|
+
`${r.file}:${r.line}`,
|
|
531
|
+
...(r.calls ?? []).map((c) => `${r.file}:${c.line}`)
|
|
532
|
+
]);
|
|
482
533
|
return capped([...new Set(all)]) || "(no location)";
|
|
483
534
|
}
|
|
484
535
|
function params(required, max) {
|
|
@@ -510,8 +561,10 @@ function formatUpgradeReport(report, title = "upgrade check") {
|
|
|
510
561
|
out.push(
|
|
511
562
|
m.to === "esm" ? ` require('${b.package}') now loads an ES module (was CommonJS)` : ` require('${b.package}') no longer resolves: its exports map offers require() nothing`
|
|
512
563
|
);
|
|
513
|
-
for (const x of m.broken.slice(0, REPORT_LOCATION_CAP))
|
|
514
|
-
|
|
564
|
+
for (const x of m.broken.slice(0, REPORT_LOCATION_CAP))
|
|
565
|
+
out.push(` \xB7 ${x.file}:${x.line} ${x.why}`);
|
|
566
|
+
if (m.broken.length > REPORT_LOCATION_CAP)
|
|
567
|
+
out.push(` \xB7 (+${m.broken.length - REPORT_LOCATION_CAP} more)`);
|
|
515
568
|
if (m.olderNode.length) {
|
|
516
569
|
out.push(
|
|
517
570
|
` \xB7 throws ERR_REQUIRE_ESM on Node before 20.19 / 22.12: ${capped(m.olderNode.map((s) => `${s.file}:${s.line}`))}`
|
|
@@ -566,16 +619,17 @@ function formatUpgradeReport(report, title = "upgrade check") {
|
|
|
566
619
|
out.push("");
|
|
567
620
|
}
|
|
568
621
|
const typed = report.types ?? [];
|
|
569
|
-
const unchecked = typed.filter(
|
|
570
|
-
(t) => !t.checked
|
|
571
|
-
);
|
|
622
|
+
const unchecked = typed.filter((t) => !t.checked);
|
|
572
623
|
if (typed.length > unchecked.length) {
|
|
573
|
-
out.push(
|
|
624
|
+
out.push(
|
|
625
|
+
`TYPES checked ${typed.length - unchecked.length} package(s) in the files that import them`
|
|
626
|
+
);
|
|
574
627
|
}
|
|
575
628
|
if (unchecked.length) {
|
|
576
629
|
out.push(`TYPES not checked for ${unchecked.length} package(s):`);
|
|
577
630
|
const byReason = /* @__PURE__ */ new Map();
|
|
578
|
-
for (const t of unchecked)
|
|
631
|
+
for (const t of unchecked)
|
|
632
|
+
byReason.set(t.reason, [...byReason.get(t.reason) ?? [], t.package]);
|
|
579
633
|
for (const [reason, names] of byReason) out.push(` \xB7 ${names.join(", ")}: ${reason}`);
|
|
580
634
|
}
|
|
581
635
|
if (typed.length) out.push("");
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import { createRequire as __lurqCreateRequire } from 'node:module'; const require = __lurqCreateRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
parseManifest
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-TDTYV6QI.js";
|
|
5
|
+
import "./chunk-GM5Y555O.js";
|
|
6
|
+
import "./chunk-2GAYNIHG.js";
|
|
7
|
+
import "./chunk-KYKSZ3XZ.js";
|
|
8
|
+
import "./chunk-A3TYI2TF.js";
|
|
8
9
|
import "./chunk-GRJXQBQZ.js";
|
|
9
10
|
import "./chunk-WHX2ZFCG.js";
|
|
11
|
+
import "./chunk-MYGSLK44.js";
|
|
10
12
|
import {
|
|
11
13
|
fetchUpgradePlan
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-GPTKSNR6.js";
|
|
14
|
+
} from "./chunk-OTJFHESY.js";
|
|
15
|
+
import "./chunk-J6XQ7OPZ.js";
|
|
16
|
+
import "./chunk-72Y2FDVS.js";
|
|
16
17
|
import {
|
|
17
18
|
init_esm_shims
|
|
18
19
|
} from "./chunk-I3M2KJXB.js";
|
|
@@ -111,13 +112,17 @@ function formatUpgradePlan(plan) {
|
|
|
111
112
|
if (upgrade.removed.length) {
|
|
112
113
|
const renamed = new Map((upgrade.renamed ?? []).map((r) => [r.path, r.to]));
|
|
113
114
|
const label = (path) => renamed.has(path) ? `${path} \u2192 ${renamed.get(path).join(" | ")}` : path;
|
|
114
|
-
out.push(
|
|
115
|
+
out.push(
|
|
116
|
+
` removes ${upgrade.removed.length}: ${upgrade.removed.slice(0, 8).map(label).join(", ")}`
|
|
117
|
+
);
|
|
115
118
|
}
|
|
116
119
|
for (const change of upgrade.arityChanged.slice(0, 5)) {
|
|
117
120
|
out.push(` arity ${change.path}: ${change.from ?? "?"} \u2192 ${change.to ?? "?"}`);
|
|
118
121
|
}
|
|
119
122
|
if (upgrade.hops?.length) {
|
|
120
|
-
out.push(
|
|
123
|
+
out.push(
|
|
124
|
+
` via ${[upgrade.fromVersion, ...upgrade.hops.map((h) => h.toVersion)].join(" \u2192 ")}`
|
|
125
|
+
);
|
|
121
126
|
for (const hop of upgrade.hops) {
|
|
122
127
|
const detail = hop.removed.length ? `removes ${hop.removed.slice(0, 5).join(", ")}` : hop.verdict === "unknown" ? "not yet analysed" : "no removals";
|
|
123
128
|
out.push(` ${hop.fromVersion} \u2192 ${hop.toVersion}: ${detail}`);
|
|
@@ -136,11 +141,41 @@ function formatUpgradePlan(plan) {
|
|
|
136
141
|
if (caveats.length) out.push("", `NOT COVERED: ${caveats.join("; ")}.`);
|
|
137
142
|
return out.join("\n");
|
|
138
143
|
}
|
|
144
|
+
function planHeadline(plan, source = []) {
|
|
145
|
+
const behind = plan.upgrades.length + plan.omitted;
|
|
146
|
+
const dead = source.filter((f) => f.severity === "blocking");
|
|
147
|
+
const parts = [];
|
|
148
|
+
if (dead.length) {
|
|
149
|
+
parts.push(`${dead.length} model id(s) the provider has retired \u2014 every call using them fails`);
|
|
150
|
+
}
|
|
151
|
+
if (behind === 0 && parts.length === 0) return null;
|
|
152
|
+
if (behind > 0) {
|
|
153
|
+
const advisories = plan.upgrades.filter((u) => u.advisories > 0).length;
|
|
154
|
+
const removes = plan.upgrades.filter((u) => u.verdict === "removes-exports").length;
|
|
155
|
+
parts.push(`${behind} of ${plan.deps} dependencies behind`);
|
|
156
|
+
if (advisories) parts.push(`${advisories} with a security advisory`);
|
|
157
|
+
if (removes) parts.push(`${removes} removing public exports`);
|
|
158
|
+
}
|
|
159
|
+
const unassessed = plan.omitted + plan.pending + plan.untracked;
|
|
160
|
+
return `${parts.join(", ")}.` + (unassessed ? ` ${unassessed} not assessed for breakage.` : "");
|
|
161
|
+
}
|
|
162
|
+
var HEADLINE_SCAN_LIMIT = 1500;
|
|
163
|
+
async function scanSourceDrift(dir, limit = HEADLINE_SCAN_LIMIT) {
|
|
164
|
+
try {
|
|
165
|
+
const { modelFindings } = await import("./model-ASMZWLM7.js");
|
|
166
|
+
return modelFindings(dir, { limit }).findings;
|
|
167
|
+
} catch {
|
|
168
|
+
return [];
|
|
169
|
+
}
|
|
170
|
+
}
|
|
139
171
|
export {
|
|
172
|
+
HEADLINE_SCAN_LIMIT,
|
|
140
173
|
buildUpgradePlan,
|
|
141
174
|
detectRepoFullName,
|
|
142
175
|
findManifests,
|
|
143
176
|
formatUpgradePlan,
|
|
144
177
|
mergedDeps,
|
|
145
|
-
|
|
178
|
+
planHeadline,
|
|
179
|
+
readManifests,
|
|
180
|
+
scanSourceDrift
|
|
146
181
|
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { createRequire as __lurqCreateRequire } from 'node:module'; const require = __lurqCreateRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
runDomains
|
|
4
|
+
} from "./chunk-XBQA4I36.js";
|
|
5
|
+
import {
|
|
6
|
+
init_esm_shims
|
|
7
|
+
} from "./chunk-I3M2KJXB.js";
|
|
8
|
+
|
|
9
|
+
// src/mcp/upkeepHandler.ts
|
|
10
|
+
init_esm_shims();
|
|
11
|
+
export {
|
|
12
|
+
runDomains as handleUpkeep
|
|
13
|
+
};
|
|
@@ -1,29 +1,32 @@
|
|
|
1
1
|
import { createRequire as __lurqCreateRequire } from 'node:module'; const require = __lurqCreateRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
} from "./chunk-LO35HLQZ.js";
|
|
6
|
-
import {
|
|
3
|
+
enqueueCandidates,
|
|
4
|
+
getQueuedNames,
|
|
7
5
|
syncOnePackage
|
|
8
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-TUXQ32WE.js";
|
|
9
7
|
import "./chunk-BUALU27S.js";
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-QUIMQ7YL.js";
|
|
9
|
+
import "./chunk-6DM6UQFD.js";
|
|
10
|
+
import "./chunk-EYAKM6YN.js";
|
|
11
|
+
import "./chunk-D3VTZS7V.js";
|
|
13
12
|
import "./chunk-4ESO33J6.js";
|
|
14
|
-
import "./chunk-CW5HJ3LX.js";
|
|
15
|
-
import "./chunk-AHBP533R.js";
|
|
16
|
-
import "./chunk-SJOVFF7B.js";
|
|
17
|
-
import "./chunk-HWBBVLOT.js";
|
|
18
13
|
import {
|
|
19
14
|
getAllPackageNames
|
|
20
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-NPVN2THM.js";
|
|
21
16
|
import "./chunk-VLRHFMGJ.js";
|
|
22
|
-
import "./chunk-
|
|
17
|
+
import "./chunk-VGCDRK3S.js";
|
|
18
|
+
import {
|
|
19
|
+
enqueueSurface,
|
|
20
|
+
getMcpServerNames
|
|
21
|
+
} from "./chunk-ONDVTXUO.js";
|
|
23
22
|
import {
|
|
24
|
-
discoveryQueue,
|
|
25
23
|
watchState
|
|
26
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-4JHDSVIN.js";
|
|
25
|
+
import "./chunk-GM5Y555O.js";
|
|
26
|
+
import "./chunk-2GAYNIHG.js";
|
|
27
|
+
import "./chunk-KYKSZ3XZ.js";
|
|
28
|
+
import "./chunk-A3TYI2TF.js";
|
|
29
|
+
import "./chunk-6L67QMCP.js";
|
|
27
30
|
import "./chunk-3GHJR7XR.js";
|
|
28
31
|
import "./chunk-GRJXQBQZ.js";
|
|
29
32
|
import "./chunk-WHX2ZFCG.js";
|
|
@@ -31,7 +34,7 @@ import "./chunk-LUAKDHLZ.js";
|
|
|
31
34
|
import {
|
|
32
35
|
logger
|
|
33
36
|
} from "./chunk-MYGSLK44.js";
|
|
34
|
-
import "./chunk-
|
|
37
|
+
import "./chunk-72Y2FDVS.js";
|
|
35
38
|
import {
|
|
36
39
|
init_esm_shims
|
|
37
40
|
} from "./chunk-I3M2KJXB.js";
|
|
@@ -39,25 +42,11 @@ import {
|
|
|
39
42
|
// src/pipeline/watch.ts
|
|
40
43
|
init_esm_shims();
|
|
41
44
|
|
|
42
|
-
// src/db/discovery.ts
|
|
43
|
-
init_esm_shims();
|
|
44
|
-
import { eq, sql } from "drizzle-orm";
|
|
45
|
-
async function getQueuedNames(db) {
|
|
46
|
-
const rows = await db.select({ name: discoveryQueue.name }).from(discoveryQueue);
|
|
47
|
-
return new Set(rows.map((r) => r.name));
|
|
48
|
-
}
|
|
49
|
-
async function enqueueCandidates(db, candidates) {
|
|
50
|
-
if (candidates.length === 0) return 0;
|
|
51
|
-
const rows = candidates.map((c) => ({ name: c.name, discoveredVia: c.via }));
|
|
52
|
-
const inserted = await db.insert(discoveryQueue).values(rows).onConflictDoNothing({ target: discoveryQueue.name }).returning({ id: discoveryQueue.id });
|
|
53
|
-
return inserted.length;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
45
|
// src/db/watch.ts
|
|
57
46
|
init_esm_shims();
|
|
58
|
-
import { eq
|
|
47
|
+
import { eq } from "drizzle-orm";
|
|
59
48
|
async function getWatchCursor(db, id) {
|
|
60
|
-
const rows = await db.select({ seq: watchState.seq }).from(watchState).where(
|
|
49
|
+
const rows = await db.select({ seq: watchState.seq }).from(watchState).where(eq(watchState.id, id)).limit(1);
|
|
61
50
|
return rows[0]?.seq ?? null;
|
|
62
51
|
}
|
|
63
52
|
async function setWatchCursor(db, id, seq) {
|
|
@@ -153,7 +142,7 @@ async function watchNpmChanges(db, opts = {}) {
|
|
|
153
142
|
if (signal?.aborted) break;
|
|
154
143
|
const route = routeChange(change, tracked, queued);
|
|
155
144
|
if (route === "resync") {
|
|
156
|
-
await syncOnePackage(db, change.id).catch(
|
|
145
|
+
await syncOnePackage(db, change.id, { fresh: true }).catch(
|
|
157
146
|
(err) => logger.warn(`watch: re-sync failed for ${change.id}: ${String(err)}`)
|
|
158
147
|
);
|
|
159
148
|
resynced++;
|
|
@@ -193,6 +182,7 @@ async function watchNpmChanges(db, opts = {}) {
|
|
|
193
182
|
logger.info("watch: stopped.");
|
|
194
183
|
}
|
|
195
184
|
function sleep(ms, signal) {
|
|
185
|
+
if (signal?.aborted) return Promise.resolve();
|
|
196
186
|
return new Promise((resolve) => {
|
|
197
187
|
const timer = setTimeout(resolve, ms);
|
|
198
188
|
signal?.addEventListener(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lurqrun",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"description": "Verify npm packages before your AI coding agent installs them: hallucinated and typosquatted names, advisories, API drift and version conflicts. MCP server, CLI and agent skill for Claude Code, Cursor and VS Code.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -93,7 +93,8 @@
|
|
|
93
93
|
"content:releases": "tsx scripts/gen-releases.ts"
|
|
94
94
|
},
|
|
95
95
|
"dependencies": {
|
|
96
|
-
"typescript": "^5.5.4"
|
|
96
|
+
"typescript": "^5.5.4",
|
|
97
|
+
"undici": "^7.29.1"
|
|
97
98
|
},
|
|
98
99
|
"devDependencies": {
|
|
99
100
|
"@eslint/js": "^9.9.0",
|
|
@@ -20,7 +20,7 @@ reads like a guess.
|
|
|
20
20
|
`verify` the one you choose. lurq checks candidates against evidence; it does not
|
|
21
21
|
search for them, so the list is yours to bring. The same applies before hand-rolling
|
|
22
22
|
something a well-maintained package may already do.
|
|
23
|
-
- **Install a specific package** → `verify` with the exact name
|
|
23
|
+
- **Install a specific package** → `verify` with the exact name _before_ adding it.
|
|
24
24
|
This catches hallucinated, deprecated, and typosquatted names (e.g. `lodahs` vs
|
|
25
25
|
`lodash`) and packages with known advisories. Cheap, and the highest-value call here.
|
|
26
26
|
- **Choose between options** → `compare` with 2–5 package names for a ranked,
|
|
@@ -46,14 +46,24 @@ reads like a guess.
|
|
|
46
46
|
shape, e.g. lodash); read its type declarations or use `resolve_surface`.
|
|
47
47
|
- **Check whether a symbol actually exists at runtime** → `resolve_surface` with the
|
|
48
48
|
package (and version, if you have one). `usage` reads the shipped `.d.ts`; this reads
|
|
49
|
-
the shipped JavaScript, and the difference matters: a removed
|
|
50
|
-
removed
|
|
49
|
+
the shipped JavaScript, and the difference matters: a removed _type_ breaks `tsc`, a
|
|
50
|
+
removed _runtime_ export breaks the running program. `UNKNOWN` means the surface has
|
|
51
51
|
not been extracted yet and queues extraction — it never means the symbol is absent, so
|
|
52
52
|
do not treat it as a negative answer.
|
|
53
53
|
- **Explain a break, or plan an upgrade** → `diff_surface` with the package and the two
|
|
54
54
|
versions. Returns what was removed, added, and what changed arity between them, with
|
|
55
55
|
type-only removals listed separately because those break the build rather than the
|
|
56
56
|
program. Static comparison of both published versions — no install, no test run.
|
|
57
|
+
- **Start work in a project you have just opened, or see what an upgrade broke** →
|
|
58
|
+
`upkeep` with its directory. It reads the project itself and returns what needs
|
|
59
|
+
fixing: environment variables the code reads that no `.env` file declares, and —
|
|
60
|
+
when you pass the versions you are moving between — the call sites an upgrade
|
|
61
|
+
breaks, the replacement the package itself proves, and the manifest ranges left
|
|
62
|
+
stale. Findings carry either exact edits you can apply or the facts you cannot
|
|
63
|
+
look up, such as the exports the target version actually ships with their
|
|
64
|
+
arities. A domain it could not run says so: an empty result is not a clean
|
|
65
|
+
project. Offered only when lurq runs beside your files (`lurq serve`) — the
|
|
66
|
+
hosted server cannot see them, so the tool is absent there rather than empty.
|
|
57
67
|
- **Take stock of a whole project** → `audit` with the inventory you read from its
|
|
58
68
|
`package.json` + lockfile and its MCP configs (names and versions only — never source).
|
|
59
69
|
One call returns every outdated, deprecated and vulnerable dependency plus every MCP
|
|
@@ -84,6 +94,15 @@ reads like a guess.
|
|
|
84
94
|
can catch it, and the symptom is a malformed call that looks like a model mistake.
|
|
85
95
|
**Privilege widening** is a tool that stopped being read-only or started being
|
|
86
96
|
destructive; nothing breaks, which is what makes it worse than a break.
|
|
97
|
+
- **Add an MCP server to a client, or a remote server will not connect** → `connect_check`
|
|
98
|
+
with the endpoint URL, registry name or npm package, and the `client` you are wiring it
|
|
99
|
+
into (`claude-code`, `cursor`, `vscode`, `chatgpt`, `claude-ai`, `codex`, `gemini-cli`, …).
|
|
100
|
+
Returns `works`, `needs_setup` with the exact steps (a key header, an OAuth client to
|
|
101
|
+
pre-register and its redirect URIs), `blocked` with the reason, or `unknown`, plus config
|
|
102
|
+
in that client's own format. Built from a credential-free probe of the server and the
|
|
103
|
+
client's documented constraints. Use the returned config instead of writing one from
|
|
104
|
+
memory, put any setup step in front of the user, and never invent a key: header values
|
|
105
|
+
are placeholders. `unknown` is not "will not work".
|
|
87
106
|
- **Visualize a stack you have already chosen** → `diagram` with the package names. A
|
|
88
107
|
labeled starting point by layer — not a validated architecture.
|
|
89
108
|
- **Unsure whether lurq covers the situation** → `capabilities` with what you are trying
|