lazycodex-ai 5.0.0-beta.49 → 5.0.0-beta.50
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/dist/cli/index.js +4682 -14969
- package/dist/cli-node/index.js +4727 -15014
- package/package.json +1 -1
- package/packages/lsp-daemon/dist/cli.js +181 -181
- package/packages/lsp-daemon/dist/client.js +232 -232
- package/packages/lsp-daemon/dist/index.js +132 -132
- package/packages/lsp-tools-mcp/dist/cli.js +103 -101
- package/packages/lsp-tools-mcp/dist/lsp/manager.js +14 -14
- package/packages/lsp-tools-mcp/dist/mcp.js +129 -129
- package/packages/lsp-tools-mcp/dist/tools.js +47 -47
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
- package/packages/omo-codex/plugin/README.md +4 -0
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +151 -102
- package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
- package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/AGENTS.md +2 -2
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/directive.md +2 -0
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/cli.js +35 -24
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/codex-hook.js +31 -21
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/types.d.ts +3 -0
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/codex-hook.ts +31 -23
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/types.ts +3 -0
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/cli.test.ts +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/codex-hook.test.ts +133 -7
- package/packages/omo-codex/plugin/components/lcx/skills/lcx-doctor/SKILL.md +3 -1
- package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +3 -3
- package/packages/omo-codex/plugin/components/lsp/dist/cli.js +298 -298
- package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/README.md +2 -0
- package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus/gpt-6.md +123 -0
- package/packages/omo-codex/plugin/components/rules/dist/cli.js +38 -30
- package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/rules/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/src/post-compact-budget.ts +6 -0
- package/packages/omo-codex/plugin/components/rules/test/hephaestus-model-variant.test.ts +38 -2
- package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +24 -0
- package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/package.json +2 -2
- package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +66 -357
- package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +66 -358
- package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/README.md +2 -0
- package/packages/omo-codex/plugin/components/ultrawork/agents/explorer.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-clone-fidelity-reviewer.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-code-reviewer.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-gate-reviewer.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-qa-executor.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-high.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-low.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-medium.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/librarian.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/metis.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/momus.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/dist/cli.js +3 -3
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +63 -63
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +5 -5
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/model-catalog.json +16 -7
- package/packages/omo-codex/plugin/package-lock.json +16 -16
- package/packages/omo-codex/plugin/package.json +1 -1
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/catalog.mjs +16 -7
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-v2-guard.mjs +8 -4
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/subagent-limit-guard.mjs +18 -90
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/toml-section-editor.mjs +1 -1
- package/packages/omo-codex/plugin/shared/package.json +1 -1
- package/packages/omo-codex/plugin/skills/lcx-doctor/SKILL.md +3 -1
- package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +12 -12
- package/packages/omo-codex/plugin/test/aggregate-model-catalog.test.mjs +14 -4
- package/packages/omo-codex/plugin/test/auto-update.test.mjs +4 -4
- package/packages/omo-codex/plugin/test/component-hook-contract-cases.mjs +25 -1
- package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +35 -35
- package/packages/omo-codex/plugin/test/multi-agent-v2-regression.test.mjs +1 -1
- package/packages/omo-codex/plugin/test/subagent-limit-migration.test.mjs +107 -15
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +318 -569
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
// src/cli.ts
|
|
4
|
+
import { argv, stderr } from "node:process";
|
|
5
|
+
|
|
3
6
|
// ../lsp-core/src/lsp/cleanup-errors.ts
|
|
4
7
|
function writeCleanupError(message) {
|
|
5
8
|
process.stderr.write(`${message}
|
|
@@ -1837,14 +1840,14 @@ function parseSinglePathResource(input, kind) {
|
|
|
1837
1840
|
return;
|
|
1838
1841
|
}
|
|
1839
1842
|
if (kind === "create") {
|
|
1840
|
-
const
|
|
1843
|
+
const options = parseOptions(change["options"], ["overwrite", "ignoreIfExists"], changeIndex);
|
|
1841
1844
|
target.operations.push({
|
|
1842
1845
|
kind,
|
|
1843
1846
|
changeIndex,
|
|
1844
1847
|
path: resolvedPath.path,
|
|
1845
1848
|
reportedPath: resolvedPath.requestedPath,
|
|
1846
|
-
overwrite:
|
|
1847
|
-
ignoreIfExists:
|
|
1849
|
+
overwrite: options["overwrite"] ?? false,
|
|
1850
|
+
ignoreIfExists: options["ignoreIfExists"] ?? false,
|
|
1848
1851
|
followedSymbolicLink: resolvedPath.followedSymbolicLink
|
|
1849
1852
|
});
|
|
1850
1853
|
return;
|
|
@@ -2314,11 +2317,11 @@ class PlanPathIndex {
|
|
|
2314
2317
|
}
|
|
2315
2318
|
}
|
|
2316
2319
|
}
|
|
2317
|
-
add(path,
|
|
2320
|
+
add(path, reportedPath, changeIndex) {
|
|
2318
2321
|
if (!this.firstChangeByPath.has(path))
|
|
2319
2322
|
this.firstChangeByPath.set(path, changeIndex);
|
|
2320
2323
|
if (!this.reportedPathByCanonical.has(path))
|
|
2321
|
-
this.reportedPathByCanonical.set(path,
|
|
2324
|
+
this.reportedPathByCanonical.set(path, reportedPath);
|
|
2322
2325
|
}
|
|
2323
2326
|
}
|
|
2324
2327
|
function fingerprintWorkspaceEdit(edit, workspaceRoot) {
|
|
@@ -2430,8 +2433,8 @@ class WorkspaceMutationController {
|
|
|
2430
2433
|
};
|
|
2431
2434
|
}
|
|
2432
2435
|
lease.phase = "applying";
|
|
2433
|
-
lease.applyCompletion = new Promise((
|
|
2434
|
-
lease.resolveApply =
|
|
2436
|
+
lease.applyCompletion = new Promise((resolve) => {
|
|
2437
|
+
lease.resolveApply = resolve;
|
|
2435
2438
|
});
|
|
2436
2439
|
const edit = isRecord3(params) ? params["edit"] : undefined;
|
|
2437
2440
|
const record = edit === undefined ? { fingerprint: null, result: failure("workspace/applyEdit params.edit is required", 0) } : await this.applyEdit(edit, lease);
|
|
@@ -2626,13 +2629,13 @@ class LspClient extends LspClientConnection {
|
|
|
2626
2629
|
if (!pushFallbackOnly) {
|
|
2627
2630
|
const cached = this.documents.getPullCache(snapshot);
|
|
2628
2631
|
try {
|
|
2629
|
-
const
|
|
2630
|
-
if (
|
|
2632
|
+
const remainingMs = deadlineAt - this.timerProvider.now();
|
|
2633
|
+
if (remainingMs <= 0)
|
|
2631
2634
|
return this.freshnessTimeout(absPath);
|
|
2632
2635
|
const result = await this.sendRequest("textDocument/diagnostic", {
|
|
2633
2636
|
textDocument: { uri },
|
|
2634
2637
|
...cached?.resultId === undefined ? {} : { previousResultId: cached.resultId }
|
|
2635
|
-
}, { timeoutMs:
|
|
2638
|
+
}, { timeoutMs: remainingMs, ...signal === undefined ? {} : { signal } });
|
|
2636
2639
|
if (!this.documents.isCurrentSnapshot(snapshot))
|
|
2637
2640
|
continue;
|
|
2638
2641
|
const report = this.parseDiagnosticPullReport(result);
|
|
@@ -2713,7 +2716,7 @@ function waitForDiagnosticsActivity(wait, signal) {
|
|
|
2713
2716
|
return wait;
|
|
2714
2717
|
if (signal.aborted)
|
|
2715
2718
|
return Promise.reject(abortError2(signal));
|
|
2716
|
-
return new Promise((
|
|
2719
|
+
return new Promise((resolve, reject) => {
|
|
2717
2720
|
const onAbort = () => {
|
|
2718
2721
|
signal.removeEventListener("abort", onAbort);
|
|
2719
2722
|
reject(abortError2(signal));
|
|
@@ -2721,7 +2724,7 @@ function waitForDiagnosticsActivity(wait, signal) {
|
|
|
2721
2724
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
2722
2725
|
wait.then(() => {
|
|
2723
2726
|
signal.removeEventListener("abort", onAbort);
|
|
2724
|
-
|
|
2727
|
+
resolve();
|
|
2725
2728
|
}, (error) => {
|
|
2726
2729
|
signal.removeEventListener("abort", onAbort);
|
|
2727
2730
|
reject(error);
|
|
@@ -2789,7 +2792,7 @@ async function stopClientBestEffort(client) {
|
|
|
2789
2792
|
function awaitWithSignal(promise, signal) {
|
|
2790
2793
|
if (!signal)
|
|
2791
2794
|
return promise;
|
|
2792
|
-
return new Promise((
|
|
2795
|
+
return new Promise((resolve, reject) => {
|
|
2793
2796
|
let settled = false;
|
|
2794
2797
|
const onAbort = () => {
|
|
2795
2798
|
if (settled)
|
|
@@ -2807,7 +2810,7 @@ function awaitWithSignal(promise, signal) {
|
|
|
2807
2810
|
return;
|
|
2808
2811
|
settled = true;
|
|
2809
2812
|
signal.removeEventListener("abort", onAbort);
|
|
2810
|
-
|
|
2813
|
+
resolve(value);
|
|
2811
2814
|
}, (err) => {
|
|
2812
2815
|
if (settled)
|
|
2813
2816
|
return;
|
|
@@ -3194,7 +3197,7 @@ ${body}` : `${body}
|
|
|
3194
3197
|
await writeChunk(output, payload);
|
|
3195
3198
|
}
|
|
3196
3199
|
function writeChunk(output, chunk) {
|
|
3197
|
-
return new Promise((
|
|
3200
|
+
return new Promise((resolve, reject) => {
|
|
3198
3201
|
let settled = false;
|
|
3199
3202
|
const onError = (error) => {
|
|
3200
3203
|
if (settled)
|
|
@@ -3214,7 +3217,7 @@ function writeChunk(output, chunk) {
|
|
|
3214
3217
|
return;
|
|
3215
3218
|
}
|
|
3216
3219
|
output.removeListener("error", onError);
|
|
3217
|
-
|
|
3220
|
+
resolve();
|
|
3218
3221
|
});
|
|
3219
3222
|
} catch (error) {
|
|
3220
3223
|
output.removeListener("error", onError);
|
|
@@ -3957,10 +3960,10 @@ function getMergedServers() {
|
|
|
3957
3960
|
}
|
|
3958
3961
|
if (seen.has(id))
|
|
3959
3962
|
continue;
|
|
3960
|
-
const
|
|
3961
|
-
if (!
|
|
3963
|
+
const server = createServerFromEntry(id, entry, source);
|
|
3964
|
+
if (!server)
|
|
3962
3965
|
continue;
|
|
3963
|
-
servers.push(
|
|
3966
|
+
servers.push(server);
|
|
3964
3967
|
seen.add(id);
|
|
3965
3968
|
}
|
|
3966
3969
|
}
|
|
@@ -3992,7 +3995,7 @@ function createServerFromEntry(id, entry, source) {
|
|
|
3992
3995
|
if (source === "project") {
|
|
3993
3996
|
if (!builtin)
|
|
3994
3997
|
return null;
|
|
3995
|
-
const
|
|
3998
|
+
const server = createServer({
|
|
3996
3999
|
id,
|
|
3997
4000
|
command: builtin.command,
|
|
3998
4001
|
extensions: entry.extensions ?? builtin.extensions,
|
|
@@ -4000,35 +4003,35 @@ function createServerFromEntry(id, entry, source) {
|
|
|
4000
4003
|
source
|
|
4001
4004
|
});
|
|
4002
4005
|
if (entry.initialization !== undefined) {
|
|
4003
|
-
|
|
4006
|
+
server.initialization = entry.initialization;
|
|
4004
4007
|
}
|
|
4005
|
-
return
|
|
4008
|
+
return server;
|
|
4006
4009
|
}
|
|
4007
4010
|
if (entry.command && entry.extensions) {
|
|
4008
|
-
const
|
|
4011
|
+
const server = createServer({
|
|
4009
4012
|
id,
|
|
4010
4013
|
command: entry.command,
|
|
4011
4014
|
extensions: entry.extensions,
|
|
4012
4015
|
priority: entry.priority ?? 0,
|
|
4013
4016
|
source
|
|
4014
4017
|
});
|
|
4015
|
-
applyOptionalServerFields(
|
|
4016
|
-
return
|
|
4018
|
+
applyOptionalServerFields(server, entry);
|
|
4019
|
+
return server;
|
|
4017
4020
|
}
|
|
4018
4021
|
if (!builtin)
|
|
4019
4022
|
return null;
|
|
4020
|
-
const
|
|
4023
|
+
const server = createServer({
|
|
4021
4024
|
id,
|
|
4022
4025
|
command: entry.command ?? builtin.command,
|
|
4023
4026
|
extensions: entry.extensions ?? builtin.extensions,
|
|
4024
4027
|
priority: entry.priority ?? 0,
|
|
4025
4028
|
source
|
|
4026
4029
|
});
|
|
4027
|
-
applyOptionalServerFields(
|
|
4028
|
-
return
|
|
4030
|
+
applyOptionalServerFields(server, entry);
|
|
4031
|
+
return server;
|
|
4029
4032
|
}
|
|
4030
4033
|
function createServer(input) {
|
|
4031
|
-
const
|
|
4034
|
+
const server = {
|
|
4032
4035
|
id: input.id,
|
|
4033
4036
|
command: input.command,
|
|
4034
4037
|
extensions: input.extensions,
|
|
@@ -4036,19 +4039,19 @@ function createServer(input) {
|
|
|
4036
4039
|
source: input.source
|
|
4037
4040
|
};
|
|
4038
4041
|
if (input.env !== undefined) {
|
|
4039
|
-
|
|
4042
|
+
server.env = input.env;
|
|
4040
4043
|
}
|
|
4041
4044
|
if (input.initialization !== undefined) {
|
|
4042
|
-
|
|
4045
|
+
server.initialization = input.initialization;
|
|
4043
4046
|
}
|
|
4044
|
-
return
|
|
4047
|
+
return server;
|
|
4045
4048
|
}
|
|
4046
|
-
function applyOptionalServerFields(
|
|
4049
|
+
function applyOptionalServerFields(server, entry) {
|
|
4047
4050
|
if (entry.env !== undefined) {
|
|
4048
|
-
|
|
4051
|
+
server.env = entry.env;
|
|
4049
4052
|
}
|
|
4050
4053
|
if (entry.initialization !== undefined) {
|
|
4051
|
-
|
|
4054
|
+
server.initialization = entry.initialization;
|
|
4052
4055
|
}
|
|
4053
4056
|
}
|
|
4054
4057
|
function isConfigJson(value) {
|
|
@@ -4239,24 +4242,24 @@ function withResolvedCommand(command, binaryPath) {
|
|
|
4239
4242
|
function findServerForExtension(ext) {
|
|
4240
4243
|
const servers = getMergedServers();
|
|
4241
4244
|
const workingDirectory = contextCwd();
|
|
4242
|
-
for (const
|
|
4243
|
-
if (!
|
|
4245
|
+
for (const server of servers) {
|
|
4246
|
+
if (!server.extensions.includes(ext))
|
|
4244
4247
|
continue;
|
|
4245
|
-
const binaryPath = resolveServerBinary(
|
|
4248
|
+
const binaryPath = resolveServerBinary(server.command, workingDirectory);
|
|
4246
4249
|
if (binaryPath !== null) {
|
|
4247
4250
|
const resolvedServer = {
|
|
4248
|
-
id:
|
|
4249
|
-
command: withResolvedCommand(
|
|
4250
|
-
extensions:
|
|
4251
|
-
priority:
|
|
4251
|
+
id: server.id,
|
|
4252
|
+
command: withResolvedCommand(server.command, binaryPath),
|
|
4253
|
+
extensions: server.extensions,
|
|
4254
|
+
priority: server.priority
|
|
4252
4255
|
};
|
|
4253
|
-
if (
|
|
4256
|
+
if (server.env !== undefined) {
|
|
4254
4257
|
return {
|
|
4255
4258
|
status: "found",
|
|
4256
4259
|
server: {
|
|
4257
4260
|
...resolvedServer,
|
|
4258
|
-
env:
|
|
4259
|
-
...
|
|
4261
|
+
env: server.env,
|
|
4262
|
+
...server.initialization === undefined ? {} : { initialization: server.initialization }
|
|
4260
4263
|
}
|
|
4261
4264
|
};
|
|
4262
4265
|
}
|
|
@@ -4264,20 +4267,20 @@ function findServerForExtension(ext) {
|
|
|
4264
4267
|
status: "found",
|
|
4265
4268
|
server: {
|
|
4266
4269
|
...resolvedServer,
|
|
4267
|
-
...
|
|
4270
|
+
...server.initialization === undefined ? {} : { initialization: server.initialization }
|
|
4268
4271
|
}
|
|
4269
4272
|
};
|
|
4270
4273
|
}
|
|
4271
4274
|
}
|
|
4272
|
-
for (const
|
|
4273
|
-
if (
|
|
4274
|
-
const installHint = LSP_INSTALL_HINTS[
|
|
4275
|
+
for (const server of servers) {
|
|
4276
|
+
if (server.extensions.includes(ext)) {
|
|
4277
|
+
const installHint = LSP_INSTALL_HINTS[server.id] ?? `Install '${server.command[0]}' and ensure it's in your PATH`;
|
|
4275
4278
|
return {
|
|
4276
4279
|
status: "not_installed",
|
|
4277
4280
|
server: {
|
|
4278
|
-
id:
|
|
4279
|
-
command:
|
|
4280
|
-
extensions:
|
|
4281
|
+
id: server.id,
|
|
4282
|
+
command: server.command,
|
|
4283
|
+
extensions: server.extensions
|
|
4281
4284
|
},
|
|
4282
4285
|
installHint
|
|
4283
4286
|
};
|
|
@@ -4296,18 +4299,18 @@ function getAllServers() {
|
|
|
4296
4299
|
const workingDirectory = contextCwd();
|
|
4297
4300
|
const result = [];
|
|
4298
4301
|
const seen = new Set;
|
|
4299
|
-
for (const
|
|
4300
|
-
if (seen.has(
|
|
4302
|
+
for (const server of servers) {
|
|
4303
|
+
if (seen.has(server.id))
|
|
4301
4304
|
continue;
|
|
4302
4305
|
result.push({
|
|
4303
|
-
id:
|
|
4304
|
-
installed: isServerInstalled(
|
|
4305
|
-
extensions:
|
|
4306
|
+
id: server.id,
|
|
4307
|
+
installed: isServerInstalled(server.command, workingDirectory),
|
|
4308
|
+
extensions: server.extensions,
|
|
4306
4309
|
disabled: false,
|
|
4307
|
-
source:
|
|
4308
|
-
priority:
|
|
4310
|
+
source: server.source,
|
|
4311
|
+
priority: server.priority
|
|
4309
4312
|
});
|
|
4310
|
-
seen.add(
|
|
4313
|
+
seen.add(server.id);
|
|
4311
4314
|
}
|
|
4312
4315
|
for (const id of disabled) {
|
|
4313
4316
|
if (seen.has(id))
|
|
@@ -4455,20 +4458,20 @@ function formatInstallOptions(serverId, installHint) {
|
|
|
4455
4458
|
];
|
|
4456
4459
|
}
|
|
4457
4460
|
function formatNotInstalled(result) {
|
|
4458
|
-
const { server
|
|
4459
|
-
const extensions =
|
|
4460
|
-
const decision = loadInstallDecision(
|
|
4461
|
+
const { server, installHint } = result;
|
|
4462
|
+
const extensions = server.extensions.join(", ");
|
|
4463
|
+
const decision = loadInstallDecision(server.id)?.decision;
|
|
4461
4464
|
const context = lspRequestContext();
|
|
4462
4465
|
if (decision === "declined") {
|
|
4463
|
-
return `LSP server '${
|
|
4466
|
+
return `LSP server '${server.id}' (${extensions}) is NOT INSTALLED; user previously declined installation — proceed without LSP.`;
|
|
4464
4467
|
}
|
|
4465
4468
|
const header = [
|
|
4466
|
-
`LSP server '${
|
|
4469
|
+
`LSP server '${server.id}' for ${extensions} is NOT INSTALLED.`,
|
|
4467
4470
|
"",
|
|
4468
|
-
`Command not found: ${
|
|
4471
|
+
`Command not found: ${server.command[0]}`,
|
|
4469
4472
|
""
|
|
4470
4473
|
];
|
|
4471
|
-
const installOptions = formatInstallOptions(
|
|
4474
|
+
const installOptions = formatInstallOptions(server.id, installHint);
|
|
4472
4475
|
if (decision === "allowed") {
|
|
4473
4476
|
return [
|
|
4474
4477
|
...header,
|
|
@@ -4494,7 +4497,7 @@ function formatNotInstalled(result) {
|
|
|
4494
4497
|
"ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
|
|
4495
4498
|
"- If the user agrees: run the install command above, then retry this tool.",
|
|
4496
4499
|
"- If the user declines, OR has NOT explicitly asked for LSP installation:",
|
|
4497
|
-
` call lsp_install_decision { server_id: "${
|
|
4500
|
+
` call lsp_install_decision { server_id: "${server.id}", decision: "declined" },`,
|
|
4498
4501
|
` which writes to ${context.installDecisionsPath},`,
|
|
4499
4502
|
" then ignore this message and proceed WITHOUT LSP."
|
|
4500
4503
|
].join(`
|
|
@@ -4518,26 +4521,26 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
|
4518
4521
|
if (result.status !== "found") {
|
|
4519
4522
|
throw new LspServerLookupError(formatServerLookupError(result), result);
|
|
4520
4523
|
}
|
|
4521
|
-
const
|
|
4524
|
+
const server = result.server;
|
|
4522
4525
|
const root = findWorkspaceRoot(absPath);
|
|
4523
|
-
const
|
|
4526
|
+
const manager = options.manager ?? getLspManager();
|
|
4524
4527
|
const acquireAndCall = async (allowRetry) => {
|
|
4525
|
-
const client = await
|
|
4528
|
+
const client = await manager.getClient(root, server, options.signal);
|
|
4526
4529
|
try {
|
|
4527
4530
|
return await fn(client, root, absPath);
|
|
4528
4531
|
} catch (err) {
|
|
4529
4532
|
if (allowRetry && READ_ONLY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
|
|
4530
|
-
|
|
4533
|
+
manager.invalidateClient(root, server.id, client);
|
|
4531
4534
|
return acquireAndCall(false);
|
|
4532
4535
|
}
|
|
4533
4536
|
if (err instanceof LspRequestTimeoutError) {
|
|
4534
|
-
if (
|
|
4537
|
+
if (manager.isServerInitializing(root, server.id)) {
|
|
4535
4538
|
throw new LspServerInitializingError(err);
|
|
4536
4539
|
}
|
|
4537
4540
|
}
|
|
4538
4541
|
throw err;
|
|
4539
4542
|
} finally {
|
|
4540
|
-
|
|
4543
|
+
manager.releaseClient(root, server.id);
|
|
4541
4544
|
}
|
|
4542
4545
|
};
|
|
4543
4546
|
return acquireAndCall(true);
|
|
@@ -4560,10 +4563,10 @@ function uriToPath(uri) {
|
|
|
4560
4563
|
}
|
|
4561
4564
|
function formatLocation(loc) {
|
|
4562
4565
|
if ("targetUri" in loc) {
|
|
4563
|
-
const
|
|
4564
|
-
const
|
|
4565
|
-
const
|
|
4566
|
-
return `${
|
|
4566
|
+
const uri = uriToPath(loc.targetUri);
|
|
4567
|
+
const line = loc.targetRange.start.line + 1;
|
|
4568
|
+
const char = loc.targetRange.start.character;
|
|
4569
|
+
return `${uri}:${line}:${char}`;
|
|
4567
4570
|
}
|
|
4568
4571
|
const uri = uriToPath(loc.uri);
|
|
4569
4572
|
const line = loc.range.start.line + 1;
|
|
@@ -4708,7 +4711,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
4708
4711
|
if (serverResult.status !== "found") {
|
|
4709
4712
|
throw new LspServerLookupError(formatServerLookupError(serverResult));
|
|
4710
4713
|
}
|
|
4711
|
-
const
|
|
4714
|
+
const server = serverResult.server;
|
|
4712
4715
|
const allFiles = (options.listFiles ?? collectFilesWithExtension)(absDir, extension, maxFiles + 1);
|
|
4713
4716
|
const wasCapped = allFiles.length > maxFiles;
|
|
4714
4717
|
const filesToProcess = allFiles.slice(0, maxFiles);
|
|
@@ -4723,12 +4726,12 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
4723
4726
|
return { output, totalDiagnostics: 0, fileFailures: [] };
|
|
4724
4727
|
}
|
|
4725
4728
|
const root = options.workspaceRoot ?? findWorkspaceRoot(absDir);
|
|
4726
|
-
const
|
|
4729
|
+
const manager = options.manager ?? getLspManager();
|
|
4727
4730
|
const allDiagnostics = [];
|
|
4728
4731
|
const fileErrors = [];
|
|
4729
4732
|
const maxConcurrency = Math.max(1, options.maxConcurrency ?? DIRECTORY_DIAGNOSTICS_MAX_CONCURRENCY);
|
|
4730
4733
|
options.signal?.throwIfAborted();
|
|
4731
|
-
const client = await
|
|
4734
|
+
const client = await manager.getClient(root, server, options.signal);
|
|
4732
4735
|
try {
|
|
4733
4736
|
let nextIndex = 0;
|
|
4734
4737
|
const workers = Array.from({ length: Math.min(maxConcurrency, filesToProcess.length) }, async () => {
|
|
@@ -4756,7 +4759,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
4756
4759
|
});
|
|
4757
4760
|
await Promise.all(workers);
|
|
4758
4761
|
} finally {
|
|
4759
|
-
|
|
4762
|
+
manager.releaseClient(root, server.id);
|
|
4760
4763
|
}
|
|
4761
4764
|
const displayDiagnostics = allDiagnostics.slice(0, DEFAULT_MAX_DIAGNOSTICS);
|
|
4762
4765
|
const wasDiagCapped = allDiagnostics.length > DEFAULT_MAX_DIAGNOSTICS;
|
|
@@ -4965,8 +4968,8 @@ function clientOptions(signal) {
|
|
|
4965
4968
|
}
|
|
4966
4969
|
|
|
4967
4970
|
// ../lsp-core/src/tools/result.ts
|
|
4968
|
-
function text(
|
|
4969
|
-
return { content: [{ type: "text", text
|
|
4971
|
+
function text(text, details, isError = false) {
|
|
4972
|
+
return { content: [{ type: "text", text }], details, isError };
|
|
4970
4973
|
}
|
|
4971
4974
|
|
|
4972
4975
|
// ../lsp-core/src/tools/diagnostics.ts
|
|
@@ -4986,7 +4989,7 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4986
4989
|
const extension = inferExtensionFromDirectory(absPath);
|
|
4987
4990
|
if (!extension) {
|
|
4988
4991
|
const message = `No supported source files found in directory: ${absPath}`;
|
|
4989
|
-
const
|
|
4992
|
+
const details = {
|
|
4990
4993
|
filePath,
|
|
4991
4994
|
severity,
|
|
4992
4995
|
mode: "directory",
|
|
@@ -4996,24 +4999,24 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4996
4999
|
error: message,
|
|
4997
5000
|
errorKind: "no_files"
|
|
4998
5001
|
};
|
|
4999
|
-
return text(message,
|
|
5002
|
+
return text(message, details);
|
|
5000
5003
|
}
|
|
5001
|
-
const
|
|
5002
|
-
const
|
|
5004
|
+
const output = await aggregateDiagnosticsForDirectory(absPath, extension, severity, undefined, signal === undefined ? {} : { signal });
|
|
5005
|
+
const details = {
|
|
5003
5006
|
filePath,
|
|
5004
5007
|
severity,
|
|
5005
5008
|
mode: "directory",
|
|
5006
5009
|
diagnostics: [],
|
|
5007
|
-
totalDiagnostics:
|
|
5010
|
+
totalDiagnostics: output.totalDiagnostics,
|
|
5008
5011
|
truncated: false,
|
|
5009
|
-
fileFailures: [...
|
|
5012
|
+
fileFailures: [...output.fileFailures]
|
|
5010
5013
|
};
|
|
5011
|
-
return text(
|
|
5014
|
+
return text(output.output, details);
|
|
5012
5015
|
}
|
|
5013
5016
|
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.diagnostics(resolvedFilePath, signal), "diagnostics", clientOptions(signal));
|
|
5014
5017
|
if (result.transientError) {
|
|
5015
5018
|
const message = result.transientError.message;
|
|
5016
|
-
const
|
|
5019
|
+
const details = {
|
|
5017
5020
|
filePath,
|
|
5018
5021
|
severity,
|
|
5019
5022
|
mode: "file",
|
|
@@ -5023,7 +5026,7 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
5023
5026
|
error: message,
|
|
5024
5027
|
errorKind: result.transientError.kind
|
|
5025
5028
|
};
|
|
5026
|
-
return text(message,
|
|
5029
|
+
return text(message, details, true);
|
|
5027
5030
|
}
|
|
5028
5031
|
const diagnostics = filterDiagnosticsBySeverity(asDiagnosticArray(result), severity);
|
|
5029
5032
|
const total = diagnostics.length;
|
|
@@ -5154,7 +5157,7 @@ async function executeLspInstallDecision(params) {
|
|
|
5154
5157
|
if (!isInstallDecision(decision)) {
|
|
5155
5158
|
return text(`Invalid decision '${String(decision)}'. Expected "declined" or "allowed".`, { serverId, errorKind: "invalid_decision" }, true);
|
|
5156
5159
|
}
|
|
5157
|
-
const serverIds = [...new Set(getMergedServers().map((
|
|
5160
|
+
const serverIds = [...new Set(getMergedServers().map((server) => server.id))];
|
|
5158
5161
|
if (!serverIds.includes(serverId)) {
|
|
5159
5162
|
const preview = serverIds.slice(0, 20).join(", ");
|
|
5160
5163
|
return text(`Unknown LSP server '${serverId}'. Known servers: ${preview}${serverIds.length > 20 ? "..." : ""}`, { serverId, errorKind: "unknown_server" }, true);
|
|
@@ -5294,10 +5297,10 @@ function objectSchema(properties, required = []) {
|
|
|
5294
5297
|
async function executeLspStatus() {
|
|
5295
5298
|
const servers = getAllServers();
|
|
5296
5299
|
const snapshots = getLspManager().getSnapshot();
|
|
5297
|
-
const installed = servers.filter((
|
|
5298
|
-
const configuredLines = servers.map((
|
|
5299
|
-
const state =
|
|
5300
|
-
return `- ${
|
|
5300
|
+
const installed = servers.filter((server) => server.installed && !server.disabled);
|
|
5301
|
+
const configuredLines = servers.map((server) => {
|
|
5302
|
+
const state = server.disabled ? "disabled" : server.installed ? "installed" : "missing";
|
|
5303
|
+
return `- ${server.id}: ${state}; source=${server.source}; extensions=${server.extensions.join(", ")}`;
|
|
5301
5304
|
});
|
|
5302
5305
|
const activeLines = snapshots.map((snapshot) => {
|
|
5303
5306
|
const state = snapshot.alive ? snapshot.isInitializing ? "initializing" : "alive" : "dead";
|
|
@@ -5340,8 +5343,8 @@ async function executeLspSymbols(params, signal) {
|
|
|
5340
5343
|
errorKind: "missing_query"
|
|
5341
5344
|
});
|
|
5342
5345
|
}
|
|
5343
|
-
const
|
|
5344
|
-
return formatSymbolsResult(filePath, scope,
|
|
5346
|
+
const symbols = await withLspClient(filePath, async (client) => client.workspaceSymbols(query, signal), "workspaceSymbols", clientOptions(signal));
|
|
5347
|
+
return formatSymbolsResult(filePath, scope, symbols, limit, query);
|
|
5345
5348
|
}
|
|
5346
5349
|
const symbols = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.documentSymbols(resolvedFilePath, signal), "documentSymbols", clientOptions(signal));
|
|
5347
5350
|
return formatSymbolsResult(filePath, scope, symbols, limit);
|
|
@@ -5596,7 +5599,6 @@ function requestedProtocolVersion(params) {
|
|
|
5596
5599
|
return params["protocolVersion"];
|
|
5597
5600
|
}
|
|
5598
5601
|
// src/cli.ts
|
|
5599
|
-
import { argv, stderr } from "node:process";
|
|
5600
5602
|
async function main() {
|
|
5601
5603
|
const [command = "mcp"] = argv.slice(2);
|
|
5602
5604
|
try {
|
|
@@ -1835,14 +1835,14 @@ function parseSinglePathResource(input, kind) {
|
|
|
1835
1835
|
return;
|
|
1836
1836
|
}
|
|
1837
1837
|
if (kind === "create") {
|
|
1838
|
-
const
|
|
1838
|
+
const options = parseOptions(change["options"], ["overwrite", "ignoreIfExists"], changeIndex);
|
|
1839
1839
|
target.operations.push({
|
|
1840
1840
|
kind,
|
|
1841
1841
|
changeIndex,
|
|
1842
1842
|
path: resolvedPath.path,
|
|
1843
1843
|
reportedPath: resolvedPath.requestedPath,
|
|
1844
|
-
overwrite:
|
|
1845
|
-
ignoreIfExists:
|
|
1844
|
+
overwrite: options["overwrite"] ?? false,
|
|
1845
|
+
ignoreIfExists: options["ignoreIfExists"] ?? false,
|
|
1846
1846
|
followedSymbolicLink: resolvedPath.followedSymbolicLink
|
|
1847
1847
|
});
|
|
1848
1848
|
return;
|
|
@@ -2312,11 +2312,11 @@ class PlanPathIndex {
|
|
|
2312
2312
|
}
|
|
2313
2313
|
}
|
|
2314
2314
|
}
|
|
2315
|
-
add(path,
|
|
2315
|
+
add(path, reportedPath, changeIndex) {
|
|
2316
2316
|
if (!this.firstChangeByPath.has(path))
|
|
2317
2317
|
this.firstChangeByPath.set(path, changeIndex);
|
|
2318
2318
|
if (!this.reportedPathByCanonical.has(path))
|
|
2319
|
-
this.reportedPathByCanonical.set(path,
|
|
2319
|
+
this.reportedPathByCanonical.set(path, reportedPath);
|
|
2320
2320
|
}
|
|
2321
2321
|
}
|
|
2322
2322
|
function fingerprintWorkspaceEdit(edit, workspaceRoot) {
|
|
@@ -2428,8 +2428,8 @@ class WorkspaceMutationController {
|
|
|
2428
2428
|
};
|
|
2429
2429
|
}
|
|
2430
2430
|
lease.phase = "applying";
|
|
2431
|
-
lease.applyCompletion = new Promise((
|
|
2432
|
-
lease.resolveApply =
|
|
2431
|
+
lease.applyCompletion = new Promise((resolve) => {
|
|
2432
|
+
lease.resolveApply = resolve;
|
|
2433
2433
|
});
|
|
2434
2434
|
const edit = isRecord3(params) ? params["edit"] : undefined;
|
|
2435
2435
|
const record = edit === undefined ? { fingerprint: null, result: failure("workspace/applyEdit params.edit is required", 0) } : await this.applyEdit(edit, lease);
|
|
@@ -2624,13 +2624,13 @@ class LspClient extends LspClientConnection {
|
|
|
2624
2624
|
if (!pushFallbackOnly) {
|
|
2625
2625
|
const cached = this.documents.getPullCache(snapshot);
|
|
2626
2626
|
try {
|
|
2627
|
-
const
|
|
2628
|
-
if (
|
|
2627
|
+
const remainingMs = deadlineAt - this.timerProvider.now();
|
|
2628
|
+
if (remainingMs <= 0)
|
|
2629
2629
|
return this.freshnessTimeout(absPath);
|
|
2630
2630
|
const result = await this.sendRequest("textDocument/diagnostic", {
|
|
2631
2631
|
textDocument: { uri },
|
|
2632
2632
|
...cached?.resultId === undefined ? {} : { previousResultId: cached.resultId }
|
|
2633
|
-
}, { timeoutMs:
|
|
2633
|
+
}, { timeoutMs: remainingMs, ...signal === undefined ? {} : { signal } });
|
|
2634
2634
|
if (!this.documents.isCurrentSnapshot(snapshot))
|
|
2635
2635
|
continue;
|
|
2636
2636
|
const report = this.parseDiagnosticPullReport(result);
|
|
@@ -2711,7 +2711,7 @@ function waitForDiagnosticsActivity(wait, signal) {
|
|
|
2711
2711
|
return wait;
|
|
2712
2712
|
if (signal.aborted)
|
|
2713
2713
|
return Promise.reject(abortError2(signal));
|
|
2714
|
-
return new Promise((
|
|
2714
|
+
return new Promise((resolve, reject) => {
|
|
2715
2715
|
const onAbort = () => {
|
|
2716
2716
|
signal.removeEventListener("abort", onAbort);
|
|
2717
2717
|
reject(abortError2(signal));
|
|
@@ -2719,7 +2719,7 @@ function waitForDiagnosticsActivity(wait, signal) {
|
|
|
2719
2719
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
2720
2720
|
wait.then(() => {
|
|
2721
2721
|
signal.removeEventListener("abort", onAbort);
|
|
2722
|
-
|
|
2722
|
+
resolve();
|
|
2723
2723
|
}, (error) => {
|
|
2724
2724
|
signal.removeEventListener("abort", onAbort);
|
|
2725
2725
|
reject(error);
|
|
@@ -2787,7 +2787,7 @@ async function stopClientBestEffort(client) {
|
|
|
2787
2787
|
function awaitWithSignal(promise, signal) {
|
|
2788
2788
|
if (!signal)
|
|
2789
2789
|
return promise;
|
|
2790
|
-
return new Promise((
|
|
2790
|
+
return new Promise((resolve, reject) => {
|
|
2791
2791
|
let settled = false;
|
|
2792
2792
|
const onAbort = () => {
|
|
2793
2793
|
if (settled)
|
|
@@ -2805,7 +2805,7 @@ function awaitWithSignal(promise, signal) {
|
|
|
2805
2805
|
return;
|
|
2806
2806
|
settled = true;
|
|
2807
2807
|
signal.removeEventListener("abort", onAbort);
|
|
2808
|
-
|
|
2808
|
+
resolve(value);
|
|
2809
2809
|
}, (err) => {
|
|
2810
2810
|
if (settled)
|
|
2811
2811
|
return;
|