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.
Files changed (122) hide show
  1. package/README.md +312 -148
  2. package/dist/{auditHandler-JCOJSUYW.js → auditHandler-VWCXSDVO.js} +12 -11
  3. package/dist/autopilotInit-Q62MX5M6.js +178 -0
  4. package/dist/bin/lurq.js +235 -83
  5. package/dist/{browserAuth-B6G27USY.js → browserAuth-J7APSD4P.js} +4 -3
  6. package/dist/{cache-DKI34SVS.js → cache-AEAKCV4I.js} +2 -2
  7. package/dist/check-2JTQDQA6.js +2613 -0
  8. package/dist/{check-2FDGUOV7.js → check-PQSQ2MMA.js} +1 -1
  9. package/dist/checkUpgrade-5YW77OBL.js +24 -0
  10. package/dist/{chunk-BCANRN5B.js → chunk-2GAYNIHG.js} +8 -1
  11. package/dist/{chunk-EA3DP5HG.js → chunk-2O6Z37IT.js} +155 -25
  12. package/dist/{chunk-J5FZYN4A.js → chunk-2WD4QAH4.js} +1 -1
  13. package/dist/{chunk-CUP36ND3.js → chunk-3676XOBU.js} +145 -36
  14. package/dist/chunk-3D2MPGOQ.js +181 -0
  15. package/dist/{chunk-LYMPYETA.js → chunk-4JHDSVIN.js} +270 -6
  16. package/dist/chunk-53SG6XWA.js +141 -0
  17. package/dist/chunk-5ABNDB3I.js +37 -0
  18. package/dist/chunk-5ALIJFDA.js +114 -0
  19. package/dist/{chunk-BULZAX2U.js → chunk-64ZF7KO4.js} +55 -38
  20. package/dist/{chunk-2VMOWSRY.js → chunk-6DM6UQFD.js} +19 -1
  21. package/dist/{chunk-HWBBVLOT.js → chunk-6L67QMCP.js} +1 -1
  22. package/dist/{chunk-GPTKSNR6.js → chunk-72Y2FDVS.js} +2 -1
  23. package/dist/{chunk-B43LCXBM.js → chunk-A3TYI2TF.js} +81 -16
  24. package/dist/{chunk-IQ4SDKKY.js → chunk-B2UUYRBX.js} +31 -228
  25. package/dist/{chunk-DB2VF5UD.js → chunk-BJT2LHAR.js} +16 -11
  26. package/dist/chunk-BM3LF5T6.js +132 -0
  27. package/dist/{chunk-3N3Q3DSW.js → chunk-BN3NM47Q.js} +8 -8
  28. package/dist/chunk-D3K6IZVR.js +12845 -0
  29. package/dist/{chunk-AHBP533R.js → chunk-D3VTZS7V.js} +7 -5
  30. package/dist/{chunk-UDVNA7EA.js → chunk-DM37MTOO.js} +161 -8
  31. package/dist/chunk-DONTW3NE.js +171 -0
  32. package/dist/{chunk-M6NYEXCW.js → chunk-DSROTZ3Z.js} +1 -1
  33. package/dist/{chunk-4F7ZESPO.js → chunk-EQCXENKZ.js} +3 -5
  34. package/dist/{chunk-CW5HJ3LX.js → chunk-EYAKM6YN.js} +1 -1
  35. package/dist/{chunk-VL2E5T2A.js → chunk-FDFPMBCA.js} +6 -3
  36. package/dist/{chunk-BV32UNLL.js → chunk-FVYFV5HA.js} +2 -2
  37. package/dist/{chunk-DWAGCNEL.js → chunk-GM5Y555O.js} +36 -103
  38. package/dist/{chunk-PSX3GIAN.js → chunk-HWFX4BC4.js} +2 -1
  39. package/dist/chunk-IFNONGRQ.js +603 -0
  40. package/dist/chunk-J3U2CPSK.js +136 -0
  41. package/dist/{chunk-Y5GI7RL3.js → chunk-J6XQ7OPZ.js} +9 -1
  42. package/dist/{chunk-LBFGSSF2.js → chunk-KMV4Y6R3.js} +2 -1
  43. package/dist/{chunk-L6N4JFW2.js → chunk-KP5ZDDPE.js} +81 -4
  44. package/dist/{chunk-SJOVFF7B.js → chunk-KYKSZ3XZ.js} +3 -2
  45. package/dist/chunk-NEZNAPPN.js +41 -0
  46. package/dist/{chunk-NH5I4KHH.js → chunk-NPVN2THM.js} +1 -5
  47. package/dist/{chunk-6L3U7DZ5.js → chunk-NYZU5NCW.js} +1 -1
  48. package/dist/chunk-O4KHCV6I.js +320 -0
  49. package/dist/{chunk-LO35HLQZ.js → chunk-ONDVTXUO.js} +25 -4
  50. package/dist/{chunk-4ZYCIMY4.js → chunk-OTJFHESY.js} +25 -4
  51. package/dist/chunk-P6MIKSPY.js +243 -0
  52. package/dist/{checkUpgrade-F2WESBPM.js → chunk-QCRBX3LV.js} +72 -10
  53. package/dist/{chunk-LRD4GBYE.js → chunk-QUIMQ7YL.js} +1 -1
  54. package/dist/chunk-RG3YLU6E.js +49 -0
  55. package/dist/{chunk-ST2X2GYN.js → chunk-SHZFOSXC.js} +109 -20
  56. package/dist/{chunk-CIDWNUAP.js → chunk-SOXFMMXC.js} +8 -2
  57. package/dist/chunk-TDTYV6QI.js +119 -0
  58. package/dist/{chunk-FW6BD2NO.js → chunk-TUXQ32WE.js} +457 -121
  59. package/dist/{chunk-WQ23REYT.js → chunk-VGCDRK3S.js} +1 -1
  60. package/dist/{chunk-U5AT3TD4.js → chunk-X4W64MHU.js} +1735 -1858
  61. package/dist/chunk-XBQA4I36.js +92 -0
  62. package/dist/chunk-XGOV6KV4.js +413 -0
  63. package/dist/{chunk-OQS4GUSI.js → chunk-XIFQIFSZ.js} +210 -661
  64. package/dist/{chunk-XBIDMHSK.js → chunk-XLXPVN3Y.js} +2 -34
  65. package/dist/chunk-ZJMLQ37G.js +90 -0
  66. package/dist/{client-IRKAMDYZ.js → client-MU4EUDZV.js} +3 -3
  67. package/dist/{commands-FIL5ET6P.js → commands-UOOTMBKA.js} +145 -33
  68. package/dist/{compat-R3UTFQ5Q.js → compat-Q5DVPITN.js} +6 -6
  69. package/dist/constants-DJFOFZ44.js +24 -0
  70. package/dist/{dashboardIssue-WYYMBFIB.js → dashboardIssue-KBKLQMGC.js} +105 -23
  71. package/dist/{diff-GZA2774U.js → diff-I4SNUHU3.js} +1 -1
  72. package/dist/domains-VRT4BRVZ.js +14 -0
  73. package/dist/env-UN6KGZ7S.js +15 -0
  74. package/dist/envCheck-KUPTORFQ.js +71 -0
  75. package/dist/{extract-NKGKLIVT.js → extract-6WG265BL.js} +14 -3
  76. package/dist/{fetch-QYTUJVG2.js → fetch-PJ3SC32M.js} +4 -4
  77. package/dist/{firstTouch-QQTJH4QX.js → firstTouch-COJCMOB3.js} +1 -1
  78. package/dist/fix-3EDWNKW3.js +220 -0
  79. package/dist/{handlers-GEJAVZDK.js → handlers-4Q37WIFT.js} +19 -17
  80. package/dist/hook-NA66XJLC.js +412 -0
  81. package/dist/{http-ETPYMBGD.js → http-25GJ6SKK.js} +2078 -510
  82. package/dist/{ingestQueue-VKN4KBIF.js → ingestQueue-FSVJC3AA.js} +14 -12
  83. package/dist/{install-EK3W2COX.js → install-G2HHXYJ2.js} +6 -6
  84. package/dist/{installSkill-VQJWJVCL.js → installSkill-5TIMYIJZ.js} +21 -3
  85. package/dist/manifest-ENMIC54B.js +13 -0
  86. package/dist/{mcp-3JHD5SUZ.js → mcp-PENLL2PK.js} +60 -32
  87. package/dist/mcpConfig-3LYPRY5Q.js +80 -0
  88. package/dist/{mcpHandlers-QFN4MCFL.js → mcpHandlers-PO7GENA7.js} +7 -7
  89. package/dist/{mcpScan-QZHWENIP.js → mcpScan-ULP626TQ.js} +306 -442
  90. package/dist/{mcpScanWorkflow-JPYCBGC4.js → mcpScanWorkflow-27O44FOE.js} +29 -12
  91. package/dist/{mcpStack-BYJCZNIV.js → mcpStack-ZNYIFXZ5.js} +1 -1
  92. package/dist/model-ASMZWLM7.js +214 -0
  93. package/dist/{packages-THVFMWFP.js → packages-RWF2LXST.js} +3 -5
  94. package/dist/{plan-V4OEI3J4.js → plan-SDILIDZT.js} +23 -21
  95. package/dist/{planView-JRXGCG2N.js → planView-ZAKRTGVS.js} +4 -1
  96. package/dist/{policy-3P6BGRDN.js → policy-JAGNMQJI.js} +5 -5
  97. package/dist/probe-3IK646WN.js +610 -0
  98. package/dist/publicUpgrades-WTBGLDIK.js +42 -0
  99. package/dist/{references-6N7VEPHT.js → references-I6Y4BSRR.js} +3 -1
  100. package/dist/{release-4U4ABNSJ.js → release-7IU2R4YG.js} +5 -5
  101. package/dist/{remote-YGCXYI4V.js → remote-FN6225AH.js} +13 -3
  102. package/dist/rename-OS6JYBZQ.js +204 -0
  103. package/dist/{reportRuns-CKQQYLY4.js → reportRuns-O4X7ZFTX.js} +15 -2
  104. package/dist/safeFetch-COERXGFN.js +19 -0
  105. package/dist/{sandbox-MEZLAODF.js → sandbox-SAPSRKEI.js} +4 -4
  106. package/dist/sarif-WLVJFJ7U.js +125 -0
  107. package/dist/server-OLTY3NYT.js +59 -0
  108. package/dist/{surface-V62GE554.js → surface-7MHE3RL7.js} +18 -16
  109. package/dist/{surface-YL6O67W3.js → surface-JS2XU3U3.js} +5 -3
  110. package/dist/{surfaceHandlers-X2IZKA3E.js → surfaceHandlers-4B6TMZ34.js} +5 -5
  111. package/dist/{typecheck-X7U5ELMR.js → typecheck-NGOKNAJY.js} +23 -9
  112. package/dist/{uninstall-P7RGBX6G.js → uninstall-I2IJP5JZ.js} +30 -4
  113. package/dist/{upgrade-NQ5IWFZB.js → upgrade-FS26DJGG.js} +86 -32
  114. package/dist/{upgradePlan-A4LRKLEG.js → upgradePlan-ZS5IOVMZ.js} +46 -11
  115. package/dist/upkeepHandler-VFGYXJKB.js +13 -0
  116. package/dist/{userConfig-Z3GQE776.js → userConfig-ICASHI47.js} +1 -1
  117. package/dist/{watch-DGFMWUDL.js → watch-OCNEUXG6.js} +24 -34
  118. package/package.json +3 -2
  119. package/templates/skill-instructions.md +22 -3
  120. package/dist/chunk-6AAEVQ7I.js +0 -6336
  121. package/dist/chunk-I2JUKN6Z.js +0 -24
  122. package/dist/server-KFUD5X57.js +0 -55
@@ -0,0 +1,141 @@
1
+ import { createRequire as __lurqCreateRequire } from 'node:module'; const require = __lurqCreateRequire(import.meta.url);
2
+ import {
3
+ SseError,
4
+ StreamableHTTPError,
5
+ UnauthorizedError
6
+ } from "./chunk-X4W64MHU.js";
7
+ import {
8
+ ErrorCode,
9
+ McpError
10
+ } from "./chunk-D3K6IZVR.js";
11
+ import {
12
+ init_esm_shims
13
+ } from "./chunk-I3M2KJXB.js";
14
+
15
+ // src/mcpScan/errors.ts
16
+ init_esm_shims();
17
+ var ENV_COMPLAINT = /\b([A-Z][A-Z0-9]{2,}(?:_[A-Z0-9]+)+)\b[^.\n]{0,60}?\b(required|must be set|not set|missing|is not defined)\b|\b(required|must be set|missing)\b[^.\n]{0,60}?\b([A-Z][A-Z0-9]{2,}(?:_[A-Z0-9]+)+)\b/;
18
+ function sniffMissingEnv(text) {
19
+ const m = ENV_COMPLAINT.exec(text);
20
+ return m ? m[1] ?? m[4] ?? null : null;
21
+ }
22
+ var NETWORK_CODES = /* @__PURE__ */ new Set([
23
+ "ECONNREFUSED",
24
+ "ENOTFOUND",
25
+ "EAI_AGAIN",
26
+ "ECONNRESET",
27
+ "ETIMEDOUT",
28
+ "EHOSTUNREACH",
29
+ "ENETUNREACH",
30
+ "UND_ERR_CONNECT_TIMEOUT",
31
+ "UND_ERR_SOCKET",
32
+ "CERT_HAS_EXPIRED",
33
+ "DEPTH_ZERO_SELF_SIGNED_CERT",
34
+ "SELF_SIGNED_CERT_IN_CHAIN",
35
+ "UNABLE_TO_VERIFY_LEAF_SIGNATURE",
36
+ "ERR_TLS_CERT_ALTNAME_INVALID"
37
+ ]);
38
+ function causeCode(err) {
39
+ let cur = err;
40
+ for (let i = 0; i < 5 && cur; i++) {
41
+ const code = cur.code;
42
+ if (typeof code === "string") return code;
43
+ cur = cur.cause;
44
+ }
45
+ return null;
46
+ }
47
+ var msg = (err) => err instanceof Error ? err.message : String(err);
48
+ function classifyError(err, ctx) {
49
+ const message = msg(err).slice(0, 500);
50
+ if (err instanceof UnauthorizedError) {
51
+ return {
52
+ status: "auth_required",
53
+ error: message || "the server requires authorization",
54
+ hint: "this server signs in with OAuth, and lurq cannot reuse the token your agent holds; ask your agent to pass its tool list to the mcp_stack tool instead"
55
+ };
56
+ }
57
+ const httpCode = err instanceof StreamableHTTPError || err instanceof SseError ? err.code : void 0;
58
+ if (httpCode === 401 || httpCode === 403) {
59
+ return {
60
+ status: "auth_required",
61
+ error: `HTTP ${httpCode}`,
62
+ hint: "the server rejected the credentials in this config; check the Authorization header or token it is given"
63
+ };
64
+ }
65
+ if (typeof httpCode === "number" && httpCode > 0) {
66
+ return {
67
+ status: "unreachable",
68
+ error: `HTTP ${httpCode}: ${message}`,
69
+ hint: httpCode === 404 ? "nothing answers MCP at this url; check the path" : null
70
+ };
71
+ }
72
+ if (err instanceof McpError && err.code === ErrorCode.RequestTimeout) {
73
+ return {
74
+ status: "timeout",
75
+ error: message,
76
+ hint: ctx.transport === "stdio" ? "the server did not answer in time; a first run of npx/uvx downloads the package, so try again with a longer --timeout" : null
77
+ };
78
+ }
79
+ const code = causeCode(err);
80
+ if (code === "ENOENT" && ctx.transport === "stdio") {
81
+ return {
82
+ status: "spawn_failed",
83
+ error: `command not found: ${ctx.command ?? "(none)"}`,
84
+ hint: "install it, or use an absolute path in the config"
85
+ };
86
+ }
87
+ if (code && NETWORK_CODES.has(code)) {
88
+ return { status: "unreachable", error: `${code}: ${message}`, hint: null };
89
+ }
90
+ if (err instanceof TypeError && /fetch failed/i.test(message)) {
91
+ const cause = err.cause;
92
+ return {
93
+ status: "unreachable",
94
+ error: cause ? `fetch failed: ${msg(cause).slice(0, 300)}` : message,
95
+ hint: null
96
+ };
97
+ }
98
+ const closed = err instanceof McpError && err.code === ErrorCode.ConnectionClosed || /connection closed/i.test(message);
99
+ if (closed && ctx.transport === "stdio") {
100
+ const missing = sniffMissingEnv(ctx.stderrTail);
101
+ if (missing) {
102
+ return {
103
+ status: "needs_config",
104
+ error: `the server exited, and its output names ${missing} as required`,
105
+ hint: `set ${missing} in this server's env block`
106
+ };
107
+ }
108
+ if (ctx.stdoutNoise > 0 && !ctx.stderrTail.trim()) {
109
+ return {
110
+ status: "protocol_error",
111
+ error: "the server wrote non-protocol output to stdout and then closed",
112
+ hint: "stdio servers must log to stderr; stdout is reserved for JSON-RPC"
113
+ };
114
+ }
115
+ return {
116
+ status: "spawn_failed",
117
+ error: ctx.stderrTail.trim() ? `exited before completing the handshake: ${ctx.stderrTail.trim().split("\n").slice(-3).join(" | ")}` : "exited before completing the handshake",
118
+ hint: null
119
+ };
120
+ }
121
+ if (/protocol version is not supported/i.test(message)) {
122
+ return {
123
+ status: "protocol_error",
124
+ error: message,
125
+ hint: "the server speaks a protocol revision this lurq version does not; upgrade lurq"
126
+ };
127
+ }
128
+ if (ctx.stdoutNoise > 0) {
129
+ return {
130
+ status: "protocol_error",
131
+ error: `${message} (the server also wrote ${ctx.stdoutNoise} non-protocol line(s) to stdout)`,
132
+ hint: "stdio servers must log to stderr; stdout is reserved for JSON-RPC"
133
+ };
134
+ }
135
+ return { status: "protocol_error", error: message || "unknown error", hint: null };
136
+ }
137
+
138
+ export {
139
+ sniffMissingEnv,
140
+ classifyError
141
+ };
@@ -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/remoteProbe/url.ts
7
+ init_esm_shims();
8
+ var PLACEHOLDER = /\{[^{}]+\}/;
9
+ function endpointIdentity(raw) {
10
+ if (typeof raw !== "string") return null;
11
+ const trimmed = raw.trim();
12
+ if (!trimmed || trimmed.length > 2048) return null;
13
+ const templated = PLACEHOLDER.test(trimmed);
14
+ let parsed;
15
+ try {
16
+ parsed = new URL(templated ? trimmed.replace(/\{[^{}]+\}/g, "placeholder") : trimmed);
17
+ } catch {
18
+ return null;
19
+ }
20
+ if (parsed.protocol !== "https:" && parsed.protocol !== "http:") return null;
21
+ const host = parsed.hostname.toLowerCase();
22
+ if (!host) return null;
23
+ if (templated) return { url: trimmed, host, templated: true };
24
+ parsed.hash = "";
25
+ const path = parsed.pathname === "/" ? "" : parsed.pathname;
26
+ const port = parsed.port ? `:${parsed.port}` : "";
27
+ const auth = parsed.username ? `${parsed.username}${parsed.password ? `:${parsed.password}` : ""}@` : "";
28
+ return {
29
+ url: `${parsed.protocol}//${auth}${host}${port}${path}${parsed.search}`,
30
+ host,
31
+ templated: false
32
+ };
33
+ }
34
+
35
+ export {
36
+ endpointIdentity
37
+ };
@@ -0,0 +1,114 @@
1
+ import { createRequire as __lurqCreateRequire } from 'node:module'; const require = __lurqCreateRequire(import.meta.url);
2
+ import {
3
+ require_semver
4
+ } from "./chunk-3GHJR7XR.js";
5
+ import {
6
+ __toESM,
7
+ init_esm_shims
8
+ } from "./chunk-I3M2KJXB.js";
9
+
10
+ // src/fix/manifest.ts
11
+ init_esm_shims();
12
+ var import_semver = __toESM(require_semver(), 1);
13
+ import { readFileSync } from "fs";
14
+ import { join } from "path";
15
+ import ts from "typescript";
16
+ var BLOCKS = ["dependencies", "devDependencies", "optionalDependencies"];
17
+ var SIMPLE_RANGE = /^(\^|~)?(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)$/;
18
+ function declaredRange(text, pkg) {
19
+ const sf = ts.parseJsonText("package.json", text);
20
+ const root = sf.statements[0]?.expression;
21
+ if (!root || !ts.isObjectLiteralExpression(root)) return null;
22
+ const propNamed = (obj, name) => obj.properties.find(
23
+ (p) => ts.isPropertyAssignment(p) && ts.isStringLiteral(p.name) && p.name.text === name
24
+ );
25
+ for (const block of BLOCKS) {
26
+ const blockProp = propNamed(root, block);
27
+ if (!blockProp || !ts.isObjectLiteralExpression(blockProp.initializer)) continue;
28
+ const dep = propNamed(blockProp.initializer, pkg);
29
+ if (!dep || !ts.isStringLiteral(dep.initializer)) continue;
30
+ const node = dep.initializer;
31
+ return { block, range: node.text, start: node.getStart(sf) + 1, end: node.getEnd() - 1 };
32
+ }
33
+ return null;
34
+ }
35
+ function decideRange(file, found, toVersion) {
36
+ if (!import_semver.default.valid(toVersion)) {
37
+ return { refusedBecause: `${toVersion} is not an exact version` };
38
+ }
39
+ if (import_semver.default.validRange(found.range) && import_semver.default.satisfies(toVersion, found.range)) {
40
+ return { satisfied: true };
41
+ }
42
+ const simple = SIMPLE_RANGE.exec(found.range);
43
+ if (!simple) {
44
+ return {
45
+ refusedBecause: `"${found.range}" is not a plain ^, ~ or exact range, so what it should become is a judgement`
46
+ };
47
+ }
48
+ const prefix = simple[1] ?? "";
49
+ return {
50
+ edit: {
51
+ file,
52
+ start: found.start,
53
+ end: found.end,
54
+ text: `${prefix}${toVersion}`,
55
+ was: found.range
56
+ }
57
+ };
58
+ }
59
+ function manifestFindings(root, targets, opts = {}) {
60
+ const files = opts.files ?? ["package.json"];
61
+ const read = opts.read ?? ((file) => {
62
+ try {
63
+ return readFileSync(join(root, file), "utf8");
64
+ } catch {
65
+ return null;
66
+ }
67
+ });
68
+ const texts = /* @__PURE__ */ new Map();
69
+ for (const file of files) {
70
+ const text = read(file);
71
+ if (text !== null) texts.set(file, text);
72
+ }
73
+ const findings = [];
74
+ const refused = [];
75
+ for (const target of targets) {
76
+ const edits = [];
77
+ const bumped = [];
78
+ for (const [file, text] of texts) {
79
+ const found = declaredRange(text, target.package);
80
+ if (!found) continue;
81
+ const decision = decideRange(file, found, target.toVersion);
82
+ if (decision.edit) {
83
+ edits.push(decision.edit);
84
+ bumped.push(file);
85
+ } else if (decision.refusedBecause) {
86
+ refused.push({ package: target.package, file, reason: decision.refusedBecause });
87
+ }
88
+ }
89
+ if (edits.length === 0) continue;
90
+ findings.push({
91
+ domain: "package",
92
+ code: `outdated-range:${target.package}`,
93
+ // Blocking: with the source rewritten and the range still pinning the old
94
+ // major, the next install puts the old version back under new code.
95
+ severity: "blocking",
96
+ detail: `${target.package} is declared at a range that excludes ${target.toVersion} in ${bumped.length} manifest(s): ${bumped.join(", ")}`,
97
+ file: bumped[0],
98
+ evidence: `upgrading ${target.package} ${target.fromVersion} \u2192 ${target.toVersion}`,
99
+ fix: {
100
+ summary: `bump ${target.package} to ${target.toVersion} in ${bumped.length} manifest(s)`,
101
+ edits,
102
+ // Installing is the user's call; the type check is what proves the tree agrees.
103
+ verify: ["typecheck"]
104
+ }
105
+ });
106
+ }
107
+ return { findings, refused };
108
+ }
109
+
110
+ export {
111
+ declaredRange,
112
+ decideRange,
113
+ manifestFindings
114
+ };
@@ -2,27 +2,19 @@ import { createRequire as __lurqCreateRequire } from 'node:module'; const requir
2
2
  import {
3
3
  assessVerdict
4
4
  } from "./chunk-QSL6QN5X.js";
5
- import {
6
- getStoredSurface,
7
- upsertSurface
8
- } from "./chunk-M6NYEXCW.js";
9
5
  import {
10
6
  getLatestVerificationByName
11
- } from "./chunk-6L3U7DZ5.js";
7
+ } from "./chunk-NYZU5NCW.js";
12
8
  import {
13
9
  getStackResolution,
14
10
  recordStackResolution,
15
11
  resolveSet,
16
12
  stackKey
17
- } from "./chunk-J5FZYN4A.js";
13
+ } from "./chunk-2WD4QAH4.js";
18
14
  import {
19
- applyPolicy,
20
- check,
21
- describeRules,
22
- diffPolicies,
23
- hasRules,
24
- withoutExpired
25
- } from "./chunk-PSX3GIAN.js";
15
+ getStoredSurface,
16
+ upsertSurface
17
+ } from "./chunk-DSROTZ3Z.js";
26
18
  import {
27
19
  FIRST_TOUCH_BUDGET_MS,
28
20
  assembleMembers,
@@ -35,7 +27,7 @@ import {
35
27
  lookupSuccessor,
36
28
  recordOutcome,
37
29
  truncateSentences
38
- } from "./chunk-FW6BD2NO.js";
30
+ } from "./chunk-TUXQ32WE.js";
39
31
  import {
40
32
  resolveArchitectureCompat,
41
33
  resolveRuntimeEngineConflicts
@@ -44,32 +36,25 @@ import {
44
36
  CONFIDENCE_WEIGHT,
45
37
  RANKING,
46
38
  loadWeights
47
- } from "./chunk-2VMOWSRY.js";
48
- import {
49
- withBudget
50
- } from "./chunk-4ESO33J6.js";
39
+ } from "./chunk-6DM6UQFD.js";
51
40
  import {
52
41
  enqueueCompatVerify,
53
42
  getSandboxEdges,
54
43
  pairKey
55
- } from "./chunk-CW5HJ3LX.js";
44
+ } from "./chunk-EYAKM6YN.js";
56
45
  import {
57
46
  fetchNpmCompatAtVersion,
58
47
  fetchNpmRegistry,
59
48
  npmPackageExists,
60
49
  npmVersionExists
61
- } from "./chunk-AHBP533R.js";
62
- import {
63
- HttpError,
64
- httpRequest
65
- } from "./chunk-SJOVFF7B.js";
50
+ } from "./chunk-D3VTZS7V.js";
66
51
  import {
67
- cached
68
- } from "./chunk-HWBBVLOT.js";
52
+ withBudget
53
+ } from "./chunk-4ESO33J6.js";
69
54
  import {
70
55
  getPackageByName,
71
56
  getTopPackageNames
72
- } from "./chunk-NH5I4KHH.js";
57
+ } from "./chunk-NPVN2THM.js";
73
58
  import {
74
59
  DEFAULT_ECOSYSTEM
75
60
  } from "./chunk-VLRHFMGJ.js";
@@ -78,14 +63,29 @@ import {
78
63
  policyDecisions,
79
64
  selectionPolicies,
80
65
  selectionPolicyChanges
81
- } from "./chunk-LYMPYETA.js";
66
+ } from "./chunk-4JHDSVIN.js";
67
+ import {
68
+ HttpError,
69
+ httpRequest
70
+ } from "./chunk-KYKSZ3XZ.js";
71
+ import {
72
+ applyPolicy,
73
+ check,
74
+ describeRules,
75
+ diffPolicies,
76
+ hasRules,
77
+ withoutExpired
78
+ } from "./chunk-HWFX4BC4.js";
79
+ import {
80
+ cached
81
+ } from "./chunk-6L67QMCP.js";
82
82
  import {
83
83
  logger
84
84
  } from "./chunk-MYGSLK44.js";
85
85
  import {
86
86
  CACHE_TTL,
87
87
  STALENESS_DAYS
88
- } from "./chunk-GPTKSNR6.js";
88
+ } from "./chunk-72Y2FDVS.js";
89
89
  import {
90
90
  init_esm_shims
91
91
  } from "./chunk-I3M2KJXB.js";
@@ -616,9 +616,25 @@ async function recommend(db, opts, provider = createEmbeddingProvider()) {
616
616
  if (!queryVec) opts.onDegraded?.("vector retrieval unavailable");
617
617
  const category = opts.category ?? inferCategory(opts.need);
618
618
  const pool = Math.max(limit * 5, 25);
619
- let fused = await hybridSearch(db, queryVec, provider.id, opts.need, opts.constraints, category, pool);
619
+ let fused = await hybridSearch(
620
+ db,
621
+ queryVec,
622
+ provider.id,
623
+ opts.need,
624
+ opts.constraints,
625
+ category,
626
+ pool
627
+ );
620
628
  if (category && fused.length < limit) {
621
- const broad = await hybridSearch(db, queryVec, provider.id, opts.need, opts.constraints, null, pool);
629
+ const broad = await hybridSearch(
630
+ db,
631
+ queryVec,
632
+ provider.id,
633
+ opts.need,
634
+ opts.constraints,
635
+ null,
636
+ pool
637
+ );
622
638
  const seen = new Set(fused.map((f) => f.row.name));
623
639
  fused = fused.concat(broad.filter((f) => !seen.has(f.row.name)));
624
640
  }
@@ -695,7 +711,10 @@ async function runVectorQuery(db, queryVec, providerId, constraints, category, p
695
711
  async function runLexicalQuery(db, need, constraints, category, pool) {
696
712
  const tsquery = sql`websearch_to_tsquery('english', ${need})`;
697
713
  const rank = sql`ts_rank(${packages.searchVector}, ${tsquery})`;
698
- const conditions = [sql`${packages.searchVector} @@ ${tsquery}`, ...buildConditions(constraints, category)];
714
+ const conditions = [
715
+ sql`${packages.searchVector} @@ ${tsquery}`,
716
+ ...buildConditions(constraints, category)
717
+ ];
699
718
  return db.select(ROW_COLUMNS).from(packages).where(and(...conditions)).orderBy(sql`${rank} desc`).limit(pool);
700
719
  }
701
720
  function toCandidate(row) {
@@ -1087,11 +1106,7 @@ function editDistance(a, b) {
1087
1106
  cur[0] = i;
1088
1107
  for (let j = 1; j <= n; j++) {
1089
1108
  const cost = a[i - 1] === b[j - 1] ? 0 : 1;
1090
- let val = Math.min(
1091
- (prev[j] ?? 0) + 1,
1092
- (cur[j - 1] ?? 0) + 1,
1093
- (prev[j - 1] ?? 0) + cost
1094
- );
1109
+ let val = Math.min((prev[j] ?? 0) + 1, (cur[j - 1] ?? 0) + 1, (prev[j - 1] ?? 0) + cost);
1095
1110
  if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) {
1096
1111
  val = Math.min(val, (prevPrev[j - 2] ?? 0) + 1);
1097
1112
  }
@@ -1506,7 +1521,9 @@ async function handleUsage(db, input) {
1506
1521
  // The README is not in this response, so "fall back to the README"
1507
1522
  // left the agent with nothing to act on. Name the two things it can do.
1508
1523
  `No type-derived API surface for ${input.package}@${version}: it ships no .d.ts and ${types} has no matching major, or extraction is still running (retry in a few seconds). For the names it exports at runtime call resolve_surface; for usage, read https://www.npmjs.com/package/${input.package}/v/${version}.`
1509
- ) : shallow ? `Shallow surface: ${input.package} exports one value typed by ${surface.filter((s) => s.name !== "default").map((s) => s.name).join(", ")}, so its methods are that interface's members and are NOT listed here. Read them in its type declarations (${types} if the package bundles none), or call resolve_surface for the names it exports at runtime.` : page?.note
1524
+ ) : shallow ? `Shallow surface: ${input.package} exports one value typed by ${surface.filter((s) => s.name !== "default").map((s) => s.name).join(
1525
+ ", "
1526
+ )}, so its methods are that interface's members and are NOT listed here. Read them in its type declarations (${types} if the package bundles none), or call resolve_surface for the names it exports at runtime.` : page?.note
1510
1527
  };
1511
1528
  if (input.knownVersion && input.knownVersion !== version && surface) {
1512
1529
  const known = await getOrExtractSurface(db, input.package, input.knownVersion, {
@@ -115,12 +115,29 @@ var FIELD = {
115
115
  /** Reports at or above this cap the confidence note as fully-evidenced. */
116
116
  wellEvidencedReports: 25
117
117
  };
118
+ var DISCOVERY = {
119
+ /** A queued candidate must clear this quality pre-score to graduate to ingest. */
120
+ minPreScore: 45,
121
+ /** Max candidates fully ingested per crawler run (cost bound). */
122
+ perRunCap: 25,
123
+ /** npm-search hits to pull per category keyword. */
124
+ searchSizePerCategory: 10,
125
+ /** Max dependency-graph neighbors to enqueue per tracked seed. */
126
+ graphNeighborsPerSeed: 20,
127
+ /** Ingest failures a candidate gets before it is marked `failed` and stops
128
+ * being retried. Three, because the failures worth retrying are transient
129
+ * (a registry 5xx, a GitHub rate limit) and clear within an hour or two,
130
+ * while the ones that are not — a manifest we cannot parse — would otherwise
131
+ * re-buy an LLM summary every cycle for as long as the crawler runs. */
132
+ maxIngestAttempts: 3
133
+ };
118
134
  var DEFAULT_WEIGHTS = {
119
135
  health: { ...HEALTH_WEIGHTS },
120
136
  composite: { ...COMPOSITE }
121
137
  };
122
138
  function activeWeightsPath() {
123
- if (existsSync(projectWeightsPath())) return { path: projectWeightsPath(), source: "project-config" };
139
+ if (existsSync(projectWeightsPath()))
140
+ return { path: projectWeightsPath(), source: "project-config" };
124
141
  if (existsSync(userWeightsPath())) return { path: userWeightsPath(), source: "user-config" };
125
142
  return null;
126
143
  }
@@ -288,6 +305,7 @@ export {
288
305
  RELIABILITY,
289
306
  EFFICIENCY,
290
307
  FIELD,
308
+ DISCOVERY,
291
309
  activeWeightsPath,
292
310
  loadWeights,
293
311
  validateWeights,
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-MYGSLK44.js";
5
5
  import {
6
6
  VERSION
7
- } from "./chunk-GPTKSNR6.js";
7
+ } from "./chunk-72Y2FDVS.js";
8
8
  import {
9
9
  init_esm_shims
10
10
  } from "./chunk-I3M2KJXB.js";
@@ -9,7 +9,7 @@ init_esm_shims();
9
9
  // package.json
10
10
  var package_default = {
11
11
  name: "lurqrun",
12
- version: "0.1.7",
12
+ version: "0.1.8",
13
13
  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.",
14
14
  type: "module",
15
15
  license: "MIT",
@@ -116,6 +116,7 @@ var package_default = {
116
116
  semver: "^7.8.5",
117
117
  stripe: "^22.6.0",
118
118
  typescript: "^5.5.4",
119
+ undici: "^7.29.1",
119
120
  yaml: "^2.9.0",
120
121
  zod: "^3.23.8"
121
122
  },