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
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createRequire as __lurqCreateRequire } from 'node:module'; const require = __lurqCreateRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
SCAN_LIMIT,
|
|
4
|
+
fixableTargets,
|
|
5
|
+
modeDisagreement,
|
|
6
|
+
parseUpgradeSpec,
|
|
7
|
+
planMode,
|
|
8
|
+
planUpgrades,
|
|
9
|
+
runCheckUpgrade,
|
|
10
|
+
targetsFromPlanFile,
|
|
11
|
+
targetsFromUpgrades
|
|
12
|
+
} from "./chunk-QCRBX3LV.js";
|
|
13
|
+
import "./chunk-I3M2KJXB.js";
|
|
14
|
+
export {
|
|
15
|
+
SCAN_LIMIT,
|
|
16
|
+
fixableTargets,
|
|
17
|
+
modeDisagreement,
|
|
18
|
+
parseUpgradeSpec,
|
|
19
|
+
planMode,
|
|
20
|
+
planUpgrades,
|
|
21
|
+
runCheckUpgrade,
|
|
22
|
+
targetsFromPlanFile,
|
|
23
|
+
targetsFromUpgrades
|
|
24
|
+
};
|
|
@@ -8,8 +8,14 @@ init_esm_shims();
|
|
|
8
8
|
var DEFAULT_REPO_POLICY = {
|
|
9
9
|
enabled: false,
|
|
10
10
|
scope: "blocking",
|
|
11
|
-
autoMerge: false
|
|
11
|
+
autoMerge: false,
|
|
12
|
+
// Stated rather than relied upon. `permits()` already reads an absent
|
|
13
|
+
// `checks` as on, so a repo connected before this shipped behaves the same as
|
|
14
|
+
// a new one — which is the point of the inversion. Writing it here keeps the
|
|
15
|
+
// default visible in the policy the dashboard round-trips.
|
|
16
|
+
checks: { env: true }
|
|
12
17
|
};
|
|
18
|
+
var RUN_TRIGGERS = ["schedule", "dispatch", "push", "pull_request", "other"];
|
|
13
19
|
var UPGRADE_SEVERITIES = ["blocking", "warning", "ok", "unverified"];
|
|
14
20
|
var UPGRADE_RUN_STATUSES = [
|
|
15
21
|
"checked",
|
|
@@ -25,6 +31,7 @@ var TRANSITIVE_DETAIL_CAP = 100;
|
|
|
25
31
|
|
|
26
32
|
export {
|
|
27
33
|
DEFAULT_REPO_POLICY,
|
|
34
|
+
RUN_TRIGGERS,
|
|
28
35
|
UPGRADE_SEVERITIES,
|
|
29
36
|
UPGRADE_RUN_STATUSES,
|
|
30
37
|
REPO_MANIFEST_CAP,
|
|
@@ -1,10 +1,4 @@
|
|
|
1
1
|
import { createRequire as __lurqCreateRequire } from 'node:module'; const require = __lurqCreateRequire(import.meta.url);
|
|
2
|
-
import {
|
|
3
|
-
MissingKeyError
|
|
4
|
-
} from "./chunk-4ZYCIMY4.js";
|
|
5
|
-
import {
|
|
6
|
-
openInBrowser
|
|
7
|
-
} from "./chunk-TNTXWSYA.js";
|
|
8
2
|
import {
|
|
9
3
|
bold,
|
|
10
4
|
dim,
|
|
@@ -18,18 +12,24 @@ import {
|
|
|
18
12
|
lurqInvocation,
|
|
19
13
|
printInstallReport,
|
|
20
14
|
resolveAgents
|
|
21
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-DM37MTOO.js";
|
|
16
|
+
import {
|
|
17
|
+
MissingKeyError
|
|
18
|
+
} from "./chunk-OTJFHESY.js";
|
|
22
19
|
import {
|
|
23
20
|
readUserConfig,
|
|
24
21
|
resolveApiKey,
|
|
25
22
|
resolveEndpoint,
|
|
26
23
|
writeUserConfig
|
|
27
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-J6XQ7OPZ.js";
|
|
25
|
+
import {
|
|
26
|
+
openInBrowser
|
|
27
|
+
} from "./chunk-TNTXWSYA.js";
|
|
28
28
|
import {
|
|
29
29
|
DEFAULT_ENDPOINT,
|
|
30
30
|
KEYS_URL,
|
|
31
31
|
PACKAGE_NAME
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-72Y2FDVS.js";
|
|
33
33
|
import {
|
|
34
34
|
init_esm_shims
|
|
35
35
|
} from "./chunk-I3M2KJXB.js";
|
|
@@ -37,6 +37,50 @@ import {
|
|
|
37
37
|
// src/cli/install.ts
|
|
38
38
|
init_esm_shims();
|
|
39
39
|
import { spawnSync } from "child_process";
|
|
40
|
+
|
|
41
|
+
// src/cli/agentLink.ts
|
|
42
|
+
init_esm_shims();
|
|
43
|
+
import { spawn } from "child_process";
|
|
44
|
+
var LINK_PREFIX = "LURQ_SIGNIN ";
|
|
45
|
+
var LINK_WAIT_MS = 15 * 6e4;
|
|
46
|
+
var START_TIMEOUT_MS = 15e3;
|
|
47
|
+
function setupMode(o) {
|
|
48
|
+
if (o.yes) return o.hasKey ? "non-interactive" : "needs-key";
|
|
49
|
+
if (o.tty) return "interactive";
|
|
50
|
+
if (o.hasKey) return "non-interactive";
|
|
51
|
+
return o.ci || o.selfHosted ? "needs-key" : "agent-link";
|
|
52
|
+
}
|
|
53
|
+
function startAgentLink(opts, spawnImpl = spawn) {
|
|
54
|
+
const args = [...process.execArgv, process.argv[1] ?? "", "setup", "--wait-for-signin"];
|
|
55
|
+
if (opts.agent) args.push("--agent", opts.agent);
|
|
56
|
+
if (opts.noOpen) args.push("--no-open");
|
|
57
|
+
const child = spawnImpl(process.execPath, args, {
|
|
58
|
+
detached: true,
|
|
59
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
60
|
+
// The link has to be the first thing it prints; an update notice first would only be noise.
|
|
61
|
+
env: { ...process.env, NO_UPDATE_NOTIFIER: "1" }
|
|
62
|
+
});
|
|
63
|
+
return new Promise((resolve) => {
|
|
64
|
+
let buffered = "";
|
|
65
|
+
const done = (link) => {
|
|
66
|
+
clearTimeout(timer);
|
|
67
|
+
child.stdout?.removeAllListeners("data");
|
|
68
|
+
child.stdout?.destroy();
|
|
69
|
+
child.unref();
|
|
70
|
+
resolve(link);
|
|
71
|
+
};
|
|
72
|
+
const timer = setTimeout(() => done(null), START_TIMEOUT_MS);
|
|
73
|
+
child.stdout?.on("data", (chunk) => {
|
|
74
|
+
buffered += chunk.toString();
|
|
75
|
+
const line = buffered.split("\n").find((l) => l.startsWith(LINK_PREFIX));
|
|
76
|
+
if (line) done(line.slice(LINK_PREFIX.length).trim());
|
|
77
|
+
});
|
|
78
|
+
child.once("error", () => done(null));
|
|
79
|
+
child.once("exit", () => done(null));
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// src/cli/install.ts
|
|
40
84
|
async function withSetupOnMissingKey(run, ask = askToConnect, setup = () => runSetup({})) {
|
|
41
85
|
try {
|
|
42
86
|
await run();
|
|
@@ -50,7 +94,10 @@ async function askToConnect() {
|
|
|
50
94
|
const interactive = process.stdin.isTTY && process.stdout.isTTY && !process.env.CI && !process.argv.includes("--json");
|
|
51
95
|
if (!interactive) return false;
|
|
52
96
|
const { confirm } = await import("./dist-4XXIXHHZ.js");
|
|
53
|
-
return confirm({
|
|
97
|
+
return confirm({
|
|
98
|
+
message: "This machine has no lurq API key yet. Connect it now?",
|
|
99
|
+
default: true
|
|
100
|
+
});
|
|
54
101
|
}
|
|
55
102
|
async function validateKey(url, apiKey) {
|
|
56
103
|
try {
|
|
@@ -91,20 +138,31 @@ function installGlobally() {
|
|
|
91
138
|
console.log(yellow("skipped"));
|
|
92
139
|
const reason = (res.stderr || res.error?.message || "").trim().split("\n").pop();
|
|
93
140
|
if (reason) console.log(dim(` ${reason}`));
|
|
94
|
-
console.log(
|
|
141
|
+
console.log(
|
|
142
|
+
dim(` Setup continues. Run \`npm install -g ${PACKAGE_NAME}\` later if you want it.`)
|
|
143
|
+
);
|
|
95
144
|
}
|
|
96
145
|
async function runSetup(opts) {
|
|
97
|
-
|
|
98
|
-
|
|
146
|
+
if (opts.waitForSignin) return waitForSigninAndFinish(opts);
|
|
147
|
+
const url = resolveEndpoint(opts.url) ?? DEFAULT_ENDPOINT;
|
|
148
|
+
let apiKey = resolveApiKey(opts.apiKey);
|
|
149
|
+
const selfHosted = url !== DEFAULT_ENDPOINT;
|
|
150
|
+
const mode = setupMode({
|
|
151
|
+
yes: Boolean(opts.yes),
|
|
152
|
+
tty: Boolean(process.stdin.isTTY && process.stdout.isTTY),
|
|
153
|
+
ci: Boolean(process.env.CI),
|
|
154
|
+
hasKey: Boolean(apiKey),
|
|
155
|
+
selfHosted
|
|
156
|
+
});
|
|
157
|
+
if (mode === "agent-link") return runAgentLink(opts);
|
|
158
|
+
if (mode === "needs-key" && !opts.yes) {
|
|
99
159
|
throw new Error(
|
|
100
160
|
`lurq setup asks questions, and this is not an interactive terminal (CI, a pipe, or an agent shell).
|
|
101
161
|
Run it non-interactively: npx ${PACKAGE_NAME} setup --yes --api-key <key>
|
|
102
162
|
Get a key at ${KEYS_URL}`
|
|
103
163
|
);
|
|
104
164
|
}
|
|
105
|
-
const
|
|
106
|
-
let apiKey = resolveApiKey(opts.apiKey);
|
|
107
|
-
const selfHosted = url !== DEFAULT_ENDPOINT;
|
|
165
|
+
const interactive = mode === "interactive";
|
|
108
166
|
if (interactive) {
|
|
109
167
|
const { input, checkbox, confirm, select } = await import("./dist-4XXIXHHZ.js");
|
|
110
168
|
console.log(`
|
|
@@ -129,7 +187,7 @@ Get a key at ${KEYS_URL}`
|
|
|
129
187
|
if (!reuse) apiKey = void 0;
|
|
130
188
|
}
|
|
131
189
|
if (!apiKey && !selfHosted) {
|
|
132
|
-
const { keyViaBrowser } = await import("./browserAuth-
|
|
190
|
+
const { keyViaBrowser } = await import("./browserAuth-J7APSD4P.js");
|
|
133
191
|
console.log(" Sign in and this machine gets its key. Nothing to copy.\n");
|
|
134
192
|
process.stdout.write(" Waiting for the browser\u2026 ");
|
|
135
193
|
const skip = new AbortController();
|
|
@@ -138,6 +196,7 @@ Get a key at ${KEYS_URL}`
|
|
|
138
196
|
const handoff = await keyViaBrowser({
|
|
139
197
|
noOpen: opts.noOpen,
|
|
140
198
|
signal: skip.signal,
|
|
199
|
+
via: "terminal",
|
|
141
200
|
// Printed rather than only opened: the browser may not have launched,
|
|
142
201
|
// and a spinner pointing at a URL nobody can see is a hung flow.
|
|
143
202
|
onUrl: (link) => console.log(`
|
|
@@ -235,7 +294,10 @@ Get a key at ${KEYS_URL}`
|
|
|
235
294
|
checked: s.detected
|
|
236
295
|
}))
|
|
237
296
|
});
|
|
238
|
-
await finish(
|
|
297
|
+
await finish(
|
|
298
|
+
specs.filter((s) => ids.includes(s.id)),
|
|
299
|
+
{ url, apiKey }
|
|
300
|
+
);
|
|
239
301
|
return;
|
|
240
302
|
}
|
|
241
303
|
if (!apiKey) {
|
|
@@ -257,6 +319,46 @@ Get a key at ${KEYS_URL}`
|
|
|
257
319
|
const selected = opts.agent ? resolveAgents(opts.agent) : agentSpecs().filter((s) => s.detected);
|
|
258
320
|
await finish(selected, { url, apiKey });
|
|
259
321
|
}
|
|
322
|
+
async function runAgentLink(opts) {
|
|
323
|
+
const link = await startAgentLink({ agent: opts.agent, noOpen: opts.noOpen });
|
|
324
|
+
if (!link) {
|
|
325
|
+
throw new Error(
|
|
326
|
+
`Could not start the sign-in listener on this machine.
|
|
327
|
+
Run it non-interactively instead: npx ${PACKAGE_NAME} setup --yes --api-key <key>
|
|
328
|
+
Get a key at ${KEYS_URL}`
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
const selected = opts.agent ? resolveAgents(opts.agent) : agentSpecs().filter((s) => s.detected);
|
|
332
|
+
console.log(
|
|
333
|
+
"lurq needs a one-time sign-in to connect this machine. Open this link on this computer:\n"
|
|
334
|
+
);
|
|
335
|
+
console.log(` ${link}
|
|
336
|
+
`);
|
|
337
|
+
console.log(
|
|
338
|
+
`Signing in finishes setup by itself: the key is stored${selected.length ? ` and lurq is connected to ${selected.map((s) => s.label).join(", ")}` : " for the lurq CLI (no coding agents detected)"}. The link works for ${LINK_WAIT_MS / 6e4} minutes.`
|
|
339
|
+
);
|
|
340
|
+
console.log("Afterwards, restart your coding agent so it loads lurq.");
|
|
341
|
+
}
|
|
342
|
+
async function waitForSigninAndFinish(opts) {
|
|
343
|
+
process.stdout.on("error", () => {
|
|
344
|
+
});
|
|
345
|
+
const { keyViaBrowser } = await import("./browserAuth-J7APSD4P.js");
|
|
346
|
+
const handoff = await keyViaBrowser({
|
|
347
|
+
noOpen: opts.noOpen,
|
|
348
|
+
deadlineMs: LINK_WAIT_MS,
|
|
349
|
+
via: "agent",
|
|
350
|
+
onUrl: (link) => {
|
|
351
|
+
process.stdout.write(`${LINK_PREFIX}${link}
|
|
352
|
+
`);
|
|
353
|
+
console.log = () => {
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
if (!handoff) return;
|
|
358
|
+
if (await validateKey(DEFAULT_ENDPOINT, handoff.key) !== "valid") return;
|
|
359
|
+
const selected = opts.agent ? resolveAgents(opts.agent) : agentSpecs().filter((s) => s.detected);
|
|
360
|
+
await finish(selected, { url: DEFAULT_ENDPOINT, apiKey: handoff.key });
|
|
361
|
+
}
|
|
260
362
|
async function finish(selected, remote) {
|
|
261
363
|
const configPath = writeUserConfig({
|
|
262
364
|
apiKey: remote.apiKey,
|
|
@@ -271,19 +373,47 @@ ${green("\u2713")} API key saved to ${configPath} ${dim("(mode 0600)")}`);
|
|
|
271
373
|
);
|
|
272
374
|
const { command } = lurqInvocation();
|
|
273
375
|
console.log(
|
|
274
|
-
dim(
|
|
376
|
+
dim(
|
|
377
|
+
` \`${command} verify <package>\`, \`evaluate\`, \`compare\`, \`usage\` now work anywhere.`
|
|
378
|
+
)
|
|
275
379
|
);
|
|
276
380
|
if (selected.length === 0) {
|
|
277
381
|
console.log(
|
|
278
382
|
"\nNo agents selected or detected. Re-run `lurq setup --agent <id>` once your assistant is installed."
|
|
279
383
|
);
|
|
280
|
-
|
|
384
|
+
} else {
|
|
385
|
+
const mode = { kind: "remote", ...remote };
|
|
386
|
+
const results = selected.map((s) => installAgent(s, mode));
|
|
387
|
+
const instructionsPath = installInstructionsFile();
|
|
388
|
+
console.log("");
|
|
389
|
+
printInstallReport(results, instructionsPath, mode);
|
|
390
|
+
}
|
|
391
|
+
await printFirstScan(remote);
|
|
392
|
+
}
|
|
393
|
+
var FIRST_SCAN_TIMEOUT_MS = 15e3;
|
|
394
|
+
async function printFirstScan(remote) {
|
|
395
|
+
try {
|
|
396
|
+
const { buildUpgradePlan, planHeadline, scanSourceDrift } = await import("./upgradePlan-ZS5IOVMZ.js");
|
|
397
|
+
const [plan, source] = await Promise.all([
|
|
398
|
+
buildUpgradePlan(process.cwd(), {
|
|
399
|
+
url: remote.url,
|
|
400
|
+
apiKey: remote.apiKey,
|
|
401
|
+
timeoutMs: FIRST_SCAN_TIMEOUT_MS
|
|
402
|
+
}),
|
|
403
|
+
scanSourceDrift(process.cwd())
|
|
404
|
+
]);
|
|
405
|
+
const headline = planHeadline(plan, source);
|
|
406
|
+
if (!headline) return;
|
|
407
|
+
const { command } = lurqInvocation();
|
|
408
|
+
console.log(`
|
|
409
|
+
${yellow("!")} ${bold("In this project right now:")} ${headline}`);
|
|
410
|
+
console.log(
|
|
411
|
+
dim(
|
|
412
|
+
` \`${command} upgrade-plan\` for the list, \`${command} fix\` to write the changes that need no judgement.`
|
|
413
|
+
)
|
|
414
|
+
);
|
|
415
|
+
} catch {
|
|
281
416
|
}
|
|
282
|
-
const mode = { kind: "remote", ...remote };
|
|
283
|
-
const results = selected.map((s) => installAgent(s, mode));
|
|
284
|
-
const instructionsPath = installInstructionsFile();
|
|
285
|
-
console.log("");
|
|
286
|
-
printInstallReport(results, instructionsPath, mode);
|
|
287
417
|
}
|
|
288
418
|
|
|
289
419
|
export {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire as __lurqCreateRequire } from 'node:module'; const require = __lurqCreateRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
stackResolutions
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-4JHDSVIN.js";
|
|
5
5
|
import {
|
|
6
6
|
getConfig
|
|
7
7
|
} from "./chunk-GRJXQBQZ.js";
|
|
@@ -1,11 +1,25 @@
|
|
|
1
1
|
import { createRequire as __lurqCreateRequire } from 'node:module'; const require = __lurqCreateRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
handleAudit
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-B2UUYRBX.js";
|
|
5
|
+
import {
|
|
6
|
+
ReadBuffer,
|
|
7
|
+
serializeMessage
|
|
8
|
+
} from "./chunk-NEZNAPPN.js";
|
|
9
|
+
import {
|
|
10
|
+
searchCapabilities
|
|
11
|
+
} from "./chunk-KP5ZDDPE.js";
|
|
12
|
+
import {
|
|
13
|
+
handleMcpDrift,
|
|
14
|
+
handleMcpSurface
|
|
15
|
+
} from "./chunk-BN3NM47Q.js";
|
|
16
|
+
import {
|
|
17
|
+
handleDiffSurface,
|
|
18
|
+
handleResolveSurface
|
|
19
|
+
} from "./chunk-BJT2LHAR.js";
|
|
5
20
|
import {
|
|
6
21
|
AjvJsonSchemaValidator,
|
|
7
22
|
Protocol,
|
|
8
|
-
ReadBuffer,
|
|
9
23
|
assertClientRequestTaskCapability,
|
|
10
24
|
assertToolsCallTaskCapability,
|
|
11
25
|
getLiteralValue,
|
|
@@ -19,20 +33,8 @@ import {
|
|
|
19
33
|
objectFromShape,
|
|
20
34
|
safeParse,
|
|
21
35
|
safeParseAsync,
|
|
22
|
-
serializeMessage,
|
|
23
36
|
toJsonSchemaCompat
|
|
24
|
-
} from "./chunk-
|
|
25
|
-
import {
|
|
26
|
-
searchCapabilities
|
|
27
|
-
} from "./chunk-L6N4JFW2.js";
|
|
28
|
-
import {
|
|
29
|
-
handleMcpDrift,
|
|
30
|
-
handleMcpSurface
|
|
31
|
-
} from "./chunk-3N3Q3DSW.js";
|
|
32
|
-
import {
|
|
33
|
-
handleDiffSurface,
|
|
34
|
-
handleResolveSurface
|
|
35
|
-
} from "./chunk-DB2VF5UD.js";
|
|
37
|
+
} from "./chunk-XLXPVN3Y.js";
|
|
36
38
|
import {
|
|
37
39
|
CallToolRequestSchema,
|
|
38
40
|
CallToolResultSchema,
|
|
@@ -59,10 +61,10 @@ import {
|
|
|
59
61
|
SetLevelRequestSchema,
|
|
60
62
|
assertCompleteRequestPrompt,
|
|
61
63
|
assertCompleteRequestResourceTemplate
|
|
62
|
-
} from "./chunk-
|
|
64
|
+
} from "./chunk-D3K6IZVR.js";
|
|
63
65
|
import {
|
|
64
66
|
handleDiagram
|
|
65
|
-
} from "./chunk-
|
|
67
|
+
} from "./chunk-EQCXENKZ.js";
|
|
66
68
|
import {
|
|
67
69
|
handleCompare,
|
|
68
70
|
handleCompat,
|
|
@@ -71,13 +73,13 @@ import {
|
|
|
71
73
|
handleReportOutcome,
|
|
72
74
|
handleUsage,
|
|
73
75
|
handleVerify
|
|
74
|
-
} from "./chunk-
|
|
76
|
+
} from "./chunk-64ZF7KO4.js";
|
|
75
77
|
import {
|
|
76
78
|
createDb
|
|
77
|
-
} from "./chunk-
|
|
79
|
+
} from "./chunk-VGCDRK3S.js";
|
|
78
80
|
import {
|
|
79
81
|
ownerUsageDaily
|
|
80
|
-
} from "./chunk-
|
|
82
|
+
} from "./chunk-4JHDSVIN.js";
|
|
81
83
|
import {
|
|
82
84
|
require_semver
|
|
83
85
|
} from "./chunk-3GHJR7XR.js";
|
|
@@ -94,7 +96,7 @@ import {
|
|
|
94
96
|
import {
|
|
95
97
|
SERVER_NAME,
|
|
96
98
|
VERSION
|
|
97
|
-
} from "./chunk-
|
|
99
|
+
} from "./chunk-72Y2FDVS.js";
|
|
98
100
|
import {
|
|
99
101
|
__toESM,
|
|
100
102
|
init_esm_shims
|
|
@@ -1654,6 +1656,32 @@ var StdioServerTransport = class {
|
|
|
1654
1656
|
// src/mcp/server.ts
|
|
1655
1657
|
var import_semver = __toESM(require_semver(), 1);
|
|
1656
1658
|
|
|
1659
|
+
// src/clients/types.ts
|
|
1660
|
+
init_esm_shims();
|
|
1661
|
+
var CLIENT_IDS = [
|
|
1662
|
+
"claude-code",
|
|
1663
|
+
"claude-desktop",
|
|
1664
|
+
"claude-ai",
|
|
1665
|
+
"claude-api",
|
|
1666
|
+
"chatgpt",
|
|
1667
|
+
"openai-responses",
|
|
1668
|
+
"codex",
|
|
1669
|
+
"gemini-cli",
|
|
1670
|
+
"cursor",
|
|
1671
|
+
"vscode",
|
|
1672
|
+
"windsurf",
|
|
1673
|
+
"zed",
|
|
1674
|
+
"jetbrains-ai",
|
|
1675
|
+
"junie",
|
|
1676
|
+
"cline",
|
|
1677
|
+
"continue",
|
|
1678
|
+
"goose",
|
|
1679
|
+
"lovable",
|
|
1680
|
+
"replit",
|
|
1681
|
+
"bolt",
|
|
1682
|
+
"v0"
|
|
1683
|
+
];
|
|
1684
|
+
|
|
1657
1685
|
// src/mcp/metrics.ts
|
|
1658
1686
|
init_esm_shims();
|
|
1659
1687
|
var stats = /* @__PURE__ */ new Map();
|
|
@@ -1754,12 +1782,7 @@ async function getUsageByTool(db, ownerId, days) {
|
|
|
1754
1782
|
const rows = await db.select({
|
|
1755
1783
|
tool: ownerUsageDaily.tool,
|
|
1756
1784
|
count: sql`sum(${ownerUsageDaily.count})::int`
|
|
1757
|
-
}).from(ownerUsageDaily).where(
|
|
1758
|
-
and(
|
|
1759
|
-
eq(ownerUsageDaily.ownerId, ownerId),
|
|
1760
|
-
gte(ownerUsageDaily.date, windowStart(days))
|
|
1761
|
-
)
|
|
1762
|
-
).groupBy(ownerUsageDaily.tool).orderBy(desc(sql`sum(${ownerUsageDaily.count})`));
|
|
1785
|
+
}).from(ownerUsageDaily).where(and(eq(ownerUsageDaily.ownerId, ownerId), gte(ownerUsageDaily.date, windowStart(days)))).groupBy(ownerUsageDaily.tool).orderBy(desc(sql`sum(${ownerUsageDaily.count})`));
|
|
1763
1786
|
return rows.map((r) => ({ tool: r.tool, count: Number(r.count) }));
|
|
1764
1787
|
}
|
|
1765
1788
|
|
|
@@ -1800,7 +1823,8 @@ async function flush() {
|
|
|
1800
1823
|
body: JSON.stringify({ api_key: key, batch }),
|
|
1801
1824
|
signal: AbortSignal.timeout(5e3)
|
|
1802
1825
|
});
|
|
1803
|
-
if (!res.ok)
|
|
1826
|
+
if (!res.ok)
|
|
1827
|
+
logger.warn(`posthog batch rejected (${res.status}), dropped ${batch.length} event(s)`);
|
|
1804
1828
|
} catch (err) {
|
|
1805
1829
|
logger.warn("posthog batch failed:", err instanceof Error ? err.message : String(err));
|
|
1806
1830
|
}
|
|
@@ -1834,7 +1858,7 @@ function buildMcpServer(db, ctx = {}) {
|
|
|
1834
1858
|
return result;
|
|
1835
1859
|
} finally {
|
|
1836
1860
|
void recordUsage(db, ctx.ownerId ?? null, tool);
|
|
1837
|
-
capture(ctx.ownerId, "tool_called", { tool, ok });
|
|
1861
|
+
capture(ctx.ownerId, "tool_called", { tool, ok, client: ctx.client ?? null });
|
|
1838
1862
|
}
|
|
1839
1863
|
})();
|
|
1840
1864
|
const reply = (obj) => {
|
|
@@ -1900,7 +1924,12 @@ function buildMcpServer(db, ctx = {}) {
|
|
|
1900
1924
|
package: npmName.describe("npm package name to verify")
|
|
1901
1925
|
}
|
|
1902
1926
|
},
|
|
1903
|
-
async (args) =>
|
|
1927
|
+
async (args) => {
|
|
1928
|
+
const result = await run("verify", () => handleVerify(db, args, ctx.ownerId ?? null));
|
|
1929
|
+
const usable = result.exists && result.verdict.level !== "invalid" && result.verdict.level !== "high";
|
|
1930
|
+
const next = `Before writing code against ${args.package}, call usage with it (and knownVersion if you remember one): its API may have moved since your training.`;
|
|
1931
|
+
return reply(usable ? { ...result, next } : result);
|
|
1932
|
+
}
|
|
1904
1933
|
);
|
|
1905
1934
|
server.registerTool(
|
|
1906
1935
|
"usage",
|
|
@@ -1955,7 +1984,21 @@ function buildMcpServer(db, ctx = {}) {
|
|
|
1955
1984
|
toVersion: external_exports.string().describe("Version you are moving to")
|
|
1956
1985
|
}
|
|
1957
1986
|
},
|
|
1958
|
-
async (args) => reply(
|
|
1987
|
+
async (args) => reply(
|
|
1988
|
+
await run("diff_surface", async () => {
|
|
1989
|
+
const diff = await handleDiffSurface(db, args);
|
|
1990
|
+
if (diff.verdict === "unknown") return diff;
|
|
1991
|
+
const { upgradeGuideFor } = await import("./publicUpgrades-WTBGLDIK.js");
|
|
1992
|
+
const guide = await upgradeGuideFor(
|
|
1993
|
+
db,
|
|
1994
|
+
args.package,
|
|
1995
|
+
args.fromVersion,
|
|
1996
|
+
args.toVersion,
|
|
1997
|
+
getConfig().LURQ_WEB_URL
|
|
1998
|
+
).catch(() => null);
|
|
1999
|
+
return guide ? { ...diff, upgradeGuide: guide } : diff;
|
|
2000
|
+
})
|
|
2001
|
+
)
|
|
1959
2002
|
);
|
|
1960
2003
|
server.registerTool(
|
|
1961
2004
|
"mcp_stack",
|
|
@@ -1966,14 +2009,18 @@ function buildMcpServer(db, ctx = {}) {
|
|
|
1966
2009
|
inputSchema: {
|
|
1967
2010
|
servers: external_exports.array(
|
|
1968
2011
|
external_exports.object({
|
|
1969
|
-
server: external_exports.string().trim().min(1).max(300).describe(
|
|
2012
|
+
server: external_exports.string().trim().min(1).max(300).describe(
|
|
2013
|
+
"npm package name of the MCP server, or any label when `tools` is given"
|
|
2014
|
+
),
|
|
1970
2015
|
version: external_exports.string().max(100).nullable().optional(),
|
|
1971
2016
|
tools: external_exports.array(
|
|
1972
2017
|
external_exports.object({
|
|
1973
2018
|
name: external_exports.string().min(1).max(256),
|
|
1974
2019
|
annotations: external_exports.record(external_exports.unknown()).optional()
|
|
1975
2020
|
})
|
|
1976
|
-
).max(2e3).optional().describe(
|
|
2021
|
+
).max(2e3).optional().describe(
|
|
2022
|
+
"The tool list as the agent received it; names and annotations are enough"
|
|
2023
|
+
)
|
|
1977
2024
|
}).refine((s) => s.tools !== void 0 || npmName.safeParse(s.server).success, {
|
|
1978
2025
|
message: "server must be an npm package name unless tools are given"
|
|
1979
2026
|
})
|
|
@@ -1982,7 +2029,7 @@ function buildMcpServer(db, ctx = {}) {
|
|
|
1982
2029
|
},
|
|
1983
2030
|
async (args) => reply(
|
|
1984
2031
|
await run("mcp_stack", async () => {
|
|
1985
|
-
const { checkMcpStack } = await import("./mcpStack-
|
|
2032
|
+
const { checkMcpStack } = await import("./mcpStack-ZNYIFXZ5.js");
|
|
1986
2033
|
return checkMcpStack(
|
|
1987
2034
|
db,
|
|
1988
2035
|
args.servers.map((s) => ({
|
|
@@ -2021,6 +2068,66 @@ function buildMcpServer(db, ctx = {}) {
|
|
|
2021
2068
|
},
|
|
2022
2069
|
async (args) => reply(await run("mcp_drift", () => handleMcpDrift(db, args)))
|
|
2023
2070
|
);
|
|
2071
|
+
server.registerTool(
|
|
2072
|
+
"connect_check",
|
|
2073
|
+
{
|
|
2074
|
+
title: "Will this MCP server work in my client?",
|
|
2075
|
+
description: "Before wiring an MCP server into a client, find out whether it will work there and exactly what it takes. Accepts an endpoint URL, an official-registry server name, or an npm package name. Answers per client (Claude Code, Claude.ai, ChatGPT, Cursor, VS Code, Codex, Gemini CLI and more): WORKS; NEEDS_SETUP with the steps (a key to send as a header, an OAuth client to pre-register and the redirect URIs to allow, a URL placeholder to fill); BLOCKED with the reason and which side causes it; or UNKNOWN when a decisive fact is not established. Built from a credential-free probe of the endpoint (whether it answers, how it authenticates, which OAuth registration methods it offers, spec deviations strict clients refuse, tool names and schemas) and from primary-sourced client constraints. Returns ready-to-paste config in each client's own format, with placeholder values. Tell the user what it found, including which client it was checked for. UNKNOWN never means it will not work.",
|
|
2076
|
+
annotations: READ_LIVE,
|
|
2077
|
+
inputSchema: {
|
|
2078
|
+
server: external_exports.string().trim().min(1).max(2048).describe(
|
|
2079
|
+
"Endpoint URL (https://\u2026), official registry name (io.github.acme/weather), or npm package name"
|
|
2080
|
+
),
|
|
2081
|
+
client: external_exports.enum(CLIENT_IDS).optional().describe(
|
|
2082
|
+
"One client to check, e.g. claude-code, cursor, chatgpt; omit for every client"
|
|
2083
|
+
)
|
|
2084
|
+
}
|
|
2085
|
+
},
|
|
2086
|
+
async (args) => reply(
|
|
2087
|
+
await run("connect_check", async () => {
|
|
2088
|
+
const [{ handleConnectCheck }, { sharedSafeFetch }] = await Promise.all([
|
|
2089
|
+
import("./check-2JTQDQA6.js"),
|
|
2090
|
+
import("./safeFetch-COERXGFN.js")
|
|
2091
|
+
]);
|
|
2092
|
+
return handleConnectCheck(
|
|
2093
|
+
db,
|
|
2094
|
+
{ server: args.server, client: args.client ?? null },
|
|
2095
|
+
{ liveProbe: { fetch: sharedSafeFetch() } }
|
|
2096
|
+
);
|
|
2097
|
+
})
|
|
2098
|
+
)
|
|
2099
|
+
);
|
|
2100
|
+
if (ctx.local) {
|
|
2101
|
+
server.registerTool(
|
|
2102
|
+
"upkeep",
|
|
2103
|
+
{
|
|
2104
|
+
title: "What needs fixing in this project",
|
|
2105
|
+
description: "The upkeep plan for the project you are editing, read from its own files. Returns findings across domains: environment variables the code reads that no .env file declares, model identifiers the provider has retired or put an end date on, and \u2014 when you pass `upgrade` \u2014 the call sites an upgrade breaks, the replacement the package itself proves, and the manifest ranges left stale. Each finding carries either exact edits (a rename the package proves, byte ranges you can apply) or a brief with the facts you cannot look up: the exports the target version actually ships, with their kinds and arities. A domain that could not run says so; a skipped domain is never the same as a clean one. Needs no API key. Use it before editing a project you have just opened, or after an upgrade to see what it broke.",
|
|
2106
|
+
annotations: READ_LIVE,
|
|
2107
|
+
inputSchema: {
|
|
2108
|
+
dir: external_exports.string().max(4096).optional().describe(
|
|
2109
|
+
"Project root. Defaults to the working directory this server was started in."
|
|
2110
|
+
),
|
|
2111
|
+
upgrade: external_exports.array(
|
|
2112
|
+
external_exports.object({
|
|
2113
|
+
package: npmName,
|
|
2114
|
+
fromVersion: external_exports.string().min(1).max(100),
|
|
2115
|
+
toVersion: external_exports.string().min(1).max(100)
|
|
2116
|
+
})
|
|
2117
|
+
).max(50).optional().describe(
|
|
2118
|
+
"Upgrades to assess. Without this the package domain is skipped, because working out what moved needs the index and this tool runs without a key."
|
|
2119
|
+
),
|
|
2120
|
+
domains: external_exports.array(external_exports.enum(["package", "mcp-config", "env", "api", "model"])).max(5).optional().describe("Limit to these domains. Default: every domain with a detector.")
|
|
2121
|
+
}
|
|
2122
|
+
},
|
|
2123
|
+
async (args) => reply(
|
|
2124
|
+
await run("upkeep", async () => {
|
|
2125
|
+
const { handleUpkeep } = await import("./upkeepHandler-VFGYXJKB.js");
|
|
2126
|
+
return handleUpkeep(args);
|
|
2127
|
+
})
|
|
2128
|
+
)
|
|
2129
|
+
);
|
|
2130
|
+
}
|
|
2024
2131
|
server.registerTool(
|
|
2025
2132
|
"audit",
|
|
2026
2133
|
{
|
|
@@ -2088,7 +2195,9 @@ function buildMcpServer(db, ctx = {}) {
|
|
|
2088
2195
|
);
|
|
2089
2196
|
server.server.registerCapabilities({ resources: {}, prompts: {} });
|
|
2090
2197
|
server.server.setRequestHandler(ListResourcesRequestSchema, () => ({ resources: [] }));
|
|
2091
|
-
server.server.setRequestHandler(ListResourceTemplatesRequestSchema, () => ({
|
|
2198
|
+
server.server.setRequestHandler(ListResourceTemplatesRequestSchema, () => ({
|
|
2199
|
+
resourceTemplates: []
|
|
2200
|
+
}));
|
|
2092
2201
|
server.server.setRequestHandler(ListPromptsRequestSchema, () => ({ prompts: [] }));
|
|
2093
2202
|
return server;
|
|
2094
2203
|
}
|
|
@@ -2096,7 +2205,7 @@ var SERVE_NEEDS_DATABASE = "`lurq serve` answers from a local lurq index and nee
|
|
|
2096
2205
|
async function startMcpServer() {
|
|
2097
2206
|
if (!getConfig().DATABASE_URL) throw new Error(SERVE_NEEDS_DATABASE);
|
|
2098
2207
|
const { db, close } = createDb();
|
|
2099
|
-
const server = buildMcpServer(db);
|
|
2208
|
+
const server = buildMcpServer(db, { local: true });
|
|
2100
2209
|
const shutdown = async () => {
|
|
2101
2210
|
try {
|
|
2102
2211
|
await close();
|