oh-my-opencode 5.0.0-beta.23 → 5.0.0-beta.25
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 +141 -184
- package/dist/cli-node/index.js +141 -184
- package/dist/index.js +1508 -1567
- package/dist/skills/debugging/SKILL.md +0 -2
- package/dist/skills/debugging/references/methodology/00-setup.md +0 -12
- package/dist/skills/debugging/references/methodology/02-investigate.md +0 -21
- package/dist/skills/debugging/references/runtimes/go.md +1 -15
- package/dist/skills/debugging/references/runtimes/native-binary.md +0 -38
- package/dist/skills/debugging/references/runtimes/node.md +0 -25
- package/dist/skills/debugging/references/runtimes/python.md +0 -13
- package/dist/skills/debugging/references/runtimes/rust.md +0 -41
- package/dist/tools/delegate-task/types.d.ts +0 -3
- package/dist/tui.js +0 -25
- package/package.json +15 -18
- package/packages/lsp-core/src/index.ts +0 -1
- package/packages/lsp-core/src/lsp/client-wrapper.ts +5 -25
- package/packages/lsp-core/src/lsp/client.ts +0 -26
- package/packages/lsp-core/src/lsp/connection.ts +0 -16
- package/packages/lsp-core/src/lsp/constants.ts +0 -1
- package/packages/lsp-core/src/lsp/manager.ts +1 -34
- package/packages/lsp-core/src/lsp/server-definitions.ts +0 -29
- package/packages/lsp-core/src/lsp/server-installation.ts +27 -200
- package/packages/lsp-core/src/lsp/server-resolution.ts +5 -18
- package/packages/lsp-core/src/lsp/transport.ts +0 -9
- package/packages/lsp-core/src/lsp/types.ts +0 -8
- package/packages/lsp-core/src/tool-surface.test.ts +1 -13
- package/packages/lsp-core/src/tools/definitions.ts +0 -14
- package/packages/lsp-core/src/tools/index.ts +0 -1
- package/packages/lsp-core/src/tools/types.ts +0 -10
- package/packages/lsp-daemon/dist/cli.js +144 -432
- package/packages/lsp-daemon/dist/client.d.ts +0 -10
- package/packages/lsp-daemon/dist/client.js +107 -401
- package/packages/lsp-daemon/dist/daemon-client.d.ts +0 -1
- package/packages/lsp-daemon/dist/daemon-client.js +0 -3
- package/packages/lsp-daemon/dist/index.js +107 -395
- package/packages/lsp-tools-mcp/dist/cli.js +99 -384
- package/packages/lsp-tools-mcp/dist/lsp/manager.js +0 -53
- package/packages/lsp-tools-mcp/dist/mcp.js +99 -384
- package/packages/lsp-tools-mcp/dist/tools.js +99 -385
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +2 -2
- 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/codegraph/dist/cli.js +35 -69
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +2 -21
- package/packages/omo-codex/plugin/components/codegraph/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/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -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 +121 -404
- 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/dist/cli.js +3 -3
- 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 +3 -3
- package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +4 -4
- package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +15 -30
- package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +15 -30
- 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/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/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
- 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-codegraph-init-guidance.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/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-checking-codegraph-bootstrap.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-checking-ulw-execute-continuation.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 +3 -3
- package/packages/omo-codex/plugin/package-lock.json +13 -13
- package/packages/omo-codex/plugin/package.json +1 -1
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/catalog.mjs +3 -3
- package/packages/omo-codex/plugin/skills/debugging/SKILL.md +0 -2
- package/packages/omo-codex/plugin/skills/debugging/references/methodology/00-setup.md +0 -12
- package/packages/omo-codex/plugin/skills/debugging/references/methodology/02-investigate.md +0 -21
- package/packages/omo-codex/plugin/skills/debugging/references/runtimes/go.md +1 -15
- package/packages/omo-codex/plugin/skills/debugging/references/runtimes/native-binary.md +0 -38
- package/packages/omo-codex/plugin/skills/debugging/references/runtimes/node.md +0 -25
- package/packages/omo-codex/plugin/skills/debugging/references/runtimes/python.md +0 -13
- package/packages/omo-codex/plugin/skills/debugging/references/runtimes/rust.md +0 -41
- package/packages/omo-codex/plugin/test/aggregate-model-catalog.test.mjs +1 -1
- package/packages/omo-codex/plugin/test/auto-update.test.mjs +2 -2
- package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +8 -8
- package/packages/omo-codex/scripts/install-config-reasoning.test.mjs +2 -2
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +23 -38
- package/packages/shared-skills/skills/debugging/SKILL.md +0 -2
- package/packages/shared-skills/skills/debugging/references/methodology/00-setup.md +0 -12
- package/packages/shared-skills/skills/debugging/references/methodology/02-investigate.md +0 -21
- package/packages/shared-skills/skills/debugging/references/runtimes/go.md +1 -15
- package/packages/shared-skills/skills/debugging/references/runtimes/native-binary.md +0 -38
- package/packages/shared-skills/skills/debugging/references/runtimes/node.md +0 -25
- package/packages/shared-skills/skills/debugging/references/runtimes/python.md +0 -13
- package/packages/shared-skills/skills/debugging/references/runtimes/rust.md +0 -41
- package/dist/skills/debugging/references/scripts/dap.mjs +0 -267
- package/dist/skills/debugging/references/scripts/dap.test.ts +0 -86
- package/dist/skills/debugging/references/scripts/fixture-adapter.mjs +0 -59
- package/dist/skills/debugging/references/tools/dap.md +0 -103
- package/dist/skills/debugging/references/tools/frida.md +0 -193
- package/packages/lsp-core/src/lsp/format-document.test.ts +0 -143
- package/packages/lsp-core/src/lsp/format-document.ts +0 -90
- package/packages/lsp-core/src/lsp/manager-max-clients.test.ts +0 -151
- package/packages/lsp-core/src/lsp/server-installation.test.ts +0 -376
- package/packages/lsp-core/src/lsp/server-resolution-local-binary.test.ts +0 -170
- package/packages/lsp-core/src/tools/format.test.ts +0 -56
- package/packages/lsp-core/src/tools/format.ts +0 -56
- package/packages/omo-codex/plugin/skills/debugging/references/scripts/dap.mjs +0 -267
- package/packages/omo-codex/plugin/skills/debugging/references/scripts/fixture-adapter.mjs +0 -59
- package/packages/omo-codex/plugin/skills/debugging/references/tools/dap.md +0 -103
- package/packages/omo-codex/plugin/skills/debugging/references/tools/frida.md +0 -193
- package/packages/shared-skills/skills/debugging/references/scripts/dap.mjs +0 -267
- package/packages/shared-skills/skills/debugging/references/scripts/dap.test.ts +0 -86
- package/packages/shared-skills/skills/debugging/references/scripts/fixture-adapter.mjs +0 -59
- package/packages/shared-skills/skills/debugging/references/tools/dap.md +0 -103
- package/packages/shared-skills/skills/debugging/references/tools/frida.md +0 -193
|
@@ -49,35 +49,6 @@ export const LSP_INSTALL_HINTS: Record<string, string> = {
|
|
|
49
49
|
"Install: dotnet tool install -g roslyn-language-server --prerelease (requires v5.8.0+). See https://github.com/dotnet/razor",
|
|
50
50
|
};
|
|
51
51
|
|
|
52
|
-
/**
|
|
53
|
-
* Repo-local install commands, offered ahead of the global hints in `LSP_INSTALL_HINTS`.
|
|
54
|
-
*
|
|
55
|
-
* A devDependency (or project venv) is resolvable by `resolveServerBinary()` without any
|
|
56
|
-
* global install, and it pins the version the project actually expects. Only servers that
|
|
57
|
-
* are genuinely distributed per-project belong here; toolchain-wide servers (rust-analyzer,
|
|
58
|
-
* gopls, clangd, ...) keep their global hint alone.
|
|
59
|
-
*/
|
|
60
|
-
export const LSP_LOCAL_INSTALL_HINTS: Record<string, string> = {
|
|
61
|
-
typescript: "bun add -d typescript-language-server typescript",
|
|
62
|
-
vue: "bun add -d @vue/language-server",
|
|
63
|
-
eslint: "bun add -d vscode-langservers-extracted",
|
|
64
|
-
oxlint: "bun add -d oxlint",
|
|
65
|
-
biome: "bun add -d @biomejs/biome",
|
|
66
|
-
svelte: "bun add -d svelte-language-server",
|
|
67
|
-
astro: "bun add -d @astrojs/language-server",
|
|
68
|
-
bash: "bun add -d bash-language-server",
|
|
69
|
-
"bash-ls": "bun add -d bash-language-server",
|
|
70
|
-
"yaml-ls": "bun add -d yaml-language-server",
|
|
71
|
-
php: "bun add -d intelephense",
|
|
72
|
-
prisma: "bun add -d prisma",
|
|
73
|
-
dockerfile: "bun add -d dockerfile-language-server-nodejs",
|
|
74
|
-
pyright: "uv add --dev pyright",
|
|
75
|
-
basedpyright: "uv add --dev basedpyright",
|
|
76
|
-
ruff: "uv add --dev ruff",
|
|
77
|
-
ty: "uv add --dev ty",
|
|
78
|
-
"ruby-lsp": "bundle add ruby-lsp --group development",
|
|
79
|
-
};
|
|
80
|
-
|
|
81
52
|
export const BUILTIN_SERVERS: Record<string, Omit<LspServerConfig, "id">> = {
|
|
82
53
|
typescript: {
|
|
83
54
|
command: ["typescript-language-server", "--stdio"],
|
|
@@ -1,218 +1,45 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
|
-
import { delimiter,
|
|
2
|
+
import { delimiter, join } from "node:path";
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
*
|
|
7
|
-
* A local bin directory is only trusted when the sibling marker proves the directory
|
|
8
|
-
* belongs to a project of that ecosystem. An unmarked `node_modules/.bin` is ignored so
|
|
9
|
-
* that a stray directory cannot inject an executable into the resolution order.
|
|
10
|
-
*/
|
|
11
|
-
interface LocalBinRule {
|
|
12
|
-
readonly markers: readonly string[];
|
|
13
|
-
readonly binDirs: readonly string[];
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const LOCAL_BIN_RULES: readonly LocalBinRule[] = [
|
|
17
|
-
{
|
|
18
|
-
markers: ["package.json", "bun.lock", "bun.lockb", "package-lock.json", "yarn.lock", "pnpm-lock.yaml"],
|
|
19
|
-
binDirs: [join("node_modules", ".bin")],
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
markers: [
|
|
23
|
-
"pyproject.toml",
|
|
24
|
-
"ty.toml",
|
|
25
|
-
"requirements.txt",
|
|
26
|
-
"setup.py",
|
|
27
|
-
"setup.cfg",
|
|
28
|
-
"Pipfile",
|
|
29
|
-
"pyrightconfig.json",
|
|
30
|
-
"ruff.toml",
|
|
31
|
-
".ruff.toml",
|
|
32
|
-
],
|
|
33
|
-
binDirs: [
|
|
34
|
-
join(".venv", "bin"),
|
|
35
|
-
join(".venv", "Scripts"),
|
|
36
|
-
join("venv", "bin"),
|
|
37
|
-
join("venv", "Scripts"),
|
|
38
|
-
join(".env", "bin"),
|
|
39
|
-
join(".env", "Scripts"),
|
|
40
|
-
],
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
markers: ["Gemfile", "Gemfile.lock"],
|
|
44
|
-
binDirs: [join("vendor", "bundle", "bin"), "bin"],
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
markers: ["go.mod", "go.sum", "go.work"],
|
|
48
|
-
binDirs: ["bin"],
|
|
49
|
-
},
|
|
50
|
-
];
|
|
51
|
-
|
|
52
|
-
export interface ResolveServerBinaryOptions {
|
|
53
|
-
/**
|
|
54
|
-
* Upward walk boundary. The walk never ascends above this directory, which lets callers
|
|
55
|
-
* confine resolution to a trusted request cwd.
|
|
56
|
-
*/
|
|
57
|
-
readonly stopAt?: string;
|
|
58
|
-
readonly platform?: NodeJS.Platform;
|
|
59
|
-
readonly pathExt?: string;
|
|
60
|
-
readonly pathEnv?: string;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const resolutionCache = new Map<string, string | null>();
|
|
64
|
-
let probeCount = 0;
|
|
65
|
-
|
|
66
|
-
/** Test seam: clears the per-process resolution cache. */
|
|
67
|
-
export function __resetServerBinaryResolutionCacheForTests(): void {
|
|
68
|
-
resolutionCache.clear();
|
|
69
|
-
probeCount = 0;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/** Test seam: counts filesystem probes so cache hits are observable. */
|
|
73
|
-
export function __serverBinaryProbeCountForTests(): number {
|
|
74
|
-
return probeCount;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function probe(path: string): boolean {
|
|
78
|
-
probeCount += 1;
|
|
79
|
-
return existsSync(path);
|
|
80
|
-
}
|
|
4
|
+
export function isServerInstalled(command: string[], _workingDirectory?: string): boolean {
|
|
5
|
+
if (command.length === 0) return false;
|
|
81
6
|
|
|
82
|
-
|
|
83
|
-
if (
|
|
84
|
-
const configured = pathExt ?? process.env["PATHEXT"] ?? "";
|
|
85
|
-
// PATHEXT is conventionally uppercase, but the on-disk shims npm/bun write are lowercase.
|
|
86
|
-
// Probe lowercase first so the returned path matches the real filename on case-sensitive
|
|
87
|
-
// filesystems; the resolved path is spawned, so its casing has to be exact.
|
|
88
|
-
const systemExts = configured
|
|
89
|
-
.split(";")
|
|
90
|
-
.filter((entry) => entry.length > 0)
|
|
91
|
-
.map((entry) => entry.toLowerCase());
|
|
92
|
-
return [...new Set(["", ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
|
|
93
|
-
}
|
|
7
|
+
const [cmd] = command;
|
|
8
|
+
if (!cmd) return false;
|
|
94
9
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
const candidate = join(directory, command + suffix);
|
|
98
|
-
if (probe(candidate)) return candidate;
|
|
10
|
+
if (cmd.includes("/") || cmd.includes("\\")) {
|
|
11
|
+
if (existsSync(cmd)) return true;
|
|
99
12
|
}
|
|
100
|
-
return null;
|
|
101
|
-
}
|
|
102
13
|
|
|
103
|
-
|
|
104
|
-
command: string,
|
|
105
|
-
workingDirectory: string,
|
|
106
|
-
suffixes: readonly string[],
|
|
107
|
-
stopAt: string | undefined,
|
|
108
|
-
): string | null {
|
|
109
|
-
const boundary = stopAt === undefined ? undefined : resolve(stopAt);
|
|
110
|
-
let current = resolve(workingDirectory);
|
|
14
|
+
const isWindows = process.platform === "win32";
|
|
111
15
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
16
|
+
let exts = [""];
|
|
17
|
+
if (isWindows) {
|
|
18
|
+
const pathExt = process.env["PATHEXT"] ?? "";
|
|
19
|
+
if (pathExt) {
|
|
20
|
+
const systemExts = pathExt.split(";").filter(Boolean);
|
|
21
|
+
exts = [...new Set([...exts, ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
|
|
22
|
+
} else {
|
|
23
|
+
exts = ["", ".exe", ".cmd", ".bat", ".ps1"];
|
|
119
24
|
}
|
|
120
|
-
|
|
121
|
-
// A repository root ends the walk: tooling above it belongs to a different project.
|
|
122
|
-
if (probe(join(current, ".git"))) return null;
|
|
123
|
-
if (boundary !== undefined && current === boundary) return null;
|
|
124
|
-
|
|
125
|
-
const parent = dirname(current);
|
|
126
|
-
if (parent === current) return null;
|
|
127
|
-
current = parent;
|
|
128
25
|
}
|
|
129
|
-
}
|
|
130
26
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
suffixes: readonly string[],
|
|
134
|
-
platform: NodeJS.Platform,
|
|
135
|
-
pathEnvOverride: string | undefined,
|
|
136
|
-
): string | null {
|
|
137
|
-
let pathEnv = pathEnvOverride ?? process.env["PATH"] ?? "";
|
|
138
|
-
if (platform === "win32" && !pathEnv) {
|
|
27
|
+
let pathEnv = process.env["PATH"] ?? "";
|
|
28
|
+
if (isWindows && !pathEnv) {
|
|
139
29
|
pathEnv = process.env["Path"] ?? "";
|
|
140
30
|
}
|
|
141
31
|
|
|
142
|
-
|
|
143
|
-
if (entry.length === 0) continue;
|
|
144
|
-
const found = probeWithSuffixes(entry, command, suffixes);
|
|
145
|
-
if (found !== null) return found;
|
|
146
|
-
}
|
|
147
|
-
return null;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Resolves the absolute path of an LSP server binary.
|
|
152
|
-
*
|
|
153
|
-
* Probing order:
|
|
154
|
-
* 1. a path-shaped command is validated as-is,
|
|
155
|
-
* 2. marker-gated repo-local bin directories, walking up from `workingDirectory`,
|
|
156
|
-
* 3. `PATH` (including Windows executable suffixes),
|
|
157
|
-
* 4. `null` when nothing matches.
|
|
158
|
-
*
|
|
159
|
-
* Results are cached per process, keyed by working directory and command.
|
|
160
|
-
*/
|
|
161
|
-
export function resolveServerBinary(
|
|
162
|
-
command: string[],
|
|
163
|
-
workingDirectory?: string,
|
|
164
|
-
options: ResolveServerBinaryOptions = {},
|
|
165
|
-
): string | null {
|
|
166
|
-
if (command.length === 0) return null;
|
|
167
|
-
const [cmd] = command;
|
|
168
|
-
if (cmd === undefined || cmd.length === 0) return null;
|
|
169
|
-
|
|
170
|
-
const platform = options.platform ?? process.platform;
|
|
171
|
-
const suffixes = executableSuffixes(platform, options.pathExt);
|
|
172
|
-
|
|
173
|
-
if (cmd.includes("/") || cmd.includes("\\")) {
|
|
174
|
-
const explicit = isAbsolute(cmd) ? cmd : resolve(workingDirectory ?? process.cwd(), cmd);
|
|
175
|
-
return probe(explicit) ? explicit : null;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
const cacheKey = JSON.stringify([
|
|
179
|
-
workingDirectory ?? "",
|
|
180
|
-
cmd,
|
|
181
|
-
platform,
|
|
182
|
-
options.stopAt ?? "",
|
|
183
|
-
options.pathExt ?? "",
|
|
184
|
-
options.pathEnv ?? process.env["PATH"] ?? "",
|
|
185
|
-
]);
|
|
186
|
-
const cached = resolutionCache.get(cacheKey);
|
|
187
|
-
if (cached !== undefined) return cached;
|
|
32
|
+
const paths = pathEnv.split(delimiter);
|
|
188
33
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
34
|
+
for (const p of paths) {
|
|
35
|
+
for (const suffix of exts) {
|
|
36
|
+
if (existsSync(join(p, cmd + suffix))) {
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
192
40
|
}
|
|
193
|
-
resolved ??= resolveFromPath(cmd, suffixes, platform, options.pathEnv);
|
|
194
|
-
// A configured server may be launched through the interpreter itself, e.g.
|
|
195
|
-
// { command: ["node", "my-ls.js"] }. isServerInstalled() has always treated bare `node`
|
|
196
|
-
// as available regardless of PATH, so keep those servers selectable instead of
|
|
197
|
-
// regressing them into a not_installed result. The name is returned unresolved so the
|
|
198
|
-
// spawn still goes through `node`; rewriting it to process.execPath would silently
|
|
199
|
-
// substitute a different interpreter (bun) for the one the config asked for.
|
|
200
|
-
if (resolved === null && cmd === "node") resolved = cmd;
|
|
201
41
|
|
|
202
|
-
|
|
203
|
-
return resolved;
|
|
204
|
-
}
|
|
42
|
+
if (cmd === "node") return true;
|
|
205
43
|
|
|
206
|
-
|
|
207
|
-
* Reports whether an LSP server binary is available.
|
|
208
|
-
*
|
|
209
|
-
* Retained for existing consumers; `resolveServerBinary` is the richer entry point.
|
|
210
|
-
*/
|
|
211
|
-
export function isServerInstalled(
|
|
212
|
-
command: string[],
|
|
213
|
-
workingDirectory?: string,
|
|
214
|
-
options: ResolveServerBinaryOptions = {},
|
|
215
|
-
): boolean {
|
|
216
|
-
if (command.length === 0) return false;
|
|
217
|
-
return resolveServerBinary(command, workingDirectory, options) !== null;
|
|
44
|
+
return false;
|
|
218
45
|
}
|
|
@@ -1,28 +1,16 @@
|
|
|
1
|
-
import { contextCwd } from "../request-context.js";
|
|
2
1
|
import { getDisabledServerIds, getMergedServers } from "./config-loader.js";
|
|
3
2
|
import { BUILTIN_SERVERS, LSP_INSTALL_HINTS } from "./server-definitions.js";
|
|
4
|
-
import { isServerInstalled
|
|
3
|
+
import { isServerInstalled } from "./server-installation.js";
|
|
5
4
|
import type { ServerLookupResult } from "./types.js";
|
|
6
5
|
|
|
7
|
-
/**
|
|
8
|
-
* Replaces the command name with the absolute binary path so the client spawns the exact
|
|
9
|
-
* binary that was resolved -- in particular a repo-local one that is absent from PATH.
|
|
10
|
-
*/
|
|
11
|
-
function withResolvedCommand(command: string[], binaryPath: string): string[] {
|
|
12
|
-
return [binaryPath, ...command.slice(1)];
|
|
13
|
-
}
|
|
14
|
-
|
|
15
6
|
export function findServerForExtension(ext: string): ServerLookupResult {
|
|
16
7
|
const servers = getMergedServers();
|
|
17
|
-
const workingDirectory = contextCwd();
|
|
18
8
|
|
|
19
9
|
for (const server of servers) {
|
|
20
|
-
if (
|
|
21
|
-
const binaryPath = resolveServerBinary(server.command, workingDirectory);
|
|
22
|
-
if (binaryPath !== null) {
|
|
10
|
+
if (server.extensions.includes(ext) && isServerInstalled(server.command)) {
|
|
23
11
|
const resolvedServer = {
|
|
24
12
|
id: server.id,
|
|
25
|
-
command:
|
|
13
|
+
command: server.command,
|
|
26
14
|
extensions: server.extensions,
|
|
27
15
|
priority: server.priority,
|
|
28
16
|
};
|
|
@@ -82,7 +70,6 @@ export interface ServerStatus {
|
|
|
82
70
|
export function getAllServers(): ServerStatus[] {
|
|
83
71
|
const servers = getMergedServers();
|
|
84
72
|
const disabled = getDisabledServerIds();
|
|
85
|
-
const workingDirectory = contextCwd();
|
|
86
73
|
|
|
87
74
|
const result: ServerStatus[] = [];
|
|
88
75
|
const seen = new Set<string>();
|
|
@@ -91,7 +78,7 @@ export function getAllServers(): ServerStatus[] {
|
|
|
91
78
|
if (seen.has(server.id)) continue;
|
|
92
79
|
result.push({
|
|
93
80
|
id: server.id,
|
|
94
|
-
installed: isServerInstalled(server.command
|
|
81
|
+
installed: isServerInstalled(server.command),
|
|
95
82
|
extensions: server.extensions,
|
|
96
83
|
disabled: false,
|
|
97
84
|
source: server.source,
|
|
@@ -105,7 +92,7 @@ export function getAllServers(): ServerStatus[] {
|
|
|
105
92
|
const builtin = BUILTIN_SERVERS[id];
|
|
106
93
|
result.push({
|
|
107
94
|
id,
|
|
108
|
-
installed: builtin ? isServerInstalled(builtin.command
|
|
95
|
+
installed: builtin ? isServerInstalled(builtin.command) : false,
|
|
109
96
|
extensions: builtin?.extensions ?? [],
|
|
110
97
|
disabled: true,
|
|
111
98
|
source: "disabled",
|
|
@@ -37,7 +37,6 @@ export class LspClientTransport {
|
|
|
37
37
|
protected readonly initializeTimeoutMs: number;
|
|
38
38
|
private workspaceApplyEditHandler: WorkspaceApplyEditHandler | null = null;
|
|
39
39
|
private diagnosticPullSupported = false;
|
|
40
|
-
private documentFormattingSupported = false;
|
|
41
40
|
|
|
42
41
|
constructor(
|
|
43
42
|
protected readonly root: string,
|
|
@@ -72,14 +71,6 @@ export class LspClientTransport {
|
|
|
72
71
|
return this.diagnosticPullSupported;
|
|
73
72
|
}
|
|
74
73
|
|
|
75
|
-
protected setDocumentFormattingSupported(supported: boolean): void {
|
|
76
|
-
this.documentFormattingSupported = supported;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
isDocumentFormattingSupported(): boolean {
|
|
80
|
-
return this.documentFormattingSupported;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
74
|
protected handlePublishDiagnostics(params: {
|
|
84
75
|
readonly uri: string;
|
|
85
76
|
readonly diagnostics: readonly Diagnostic[];
|
|
@@ -72,14 +72,6 @@ export interface Diagnostic {
|
|
|
72
72
|
message: string;
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
export interface FormattingOptions {
|
|
76
|
-
tabSize: number;
|
|
77
|
-
insertSpaces: boolean;
|
|
78
|
-
trimTrailingWhitespace?: boolean;
|
|
79
|
-
insertFinalNewline?: boolean;
|
|
80
|
-
trimFinalNewlines?: boolean;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
75
|
export interface TextDocumentIdentifier {
|
|
84
76
|
uri: string;
|
|
85
77
|
}
|
|
@@ -104,18 +104,6 @@ const expectedToolSurface = [
|
|
|
104
104
|
required: ["filePath", "line", "character", "newName"],
|
|
105
105
|
},
|
|
106
106
|
},
|
|
107
|
-
{
|
|
108
|
-
name: "format",
|
|
109
|
-
title: "LSP Format",
|
|
110
|
-
description: "Format a source file with its language server and write the returned edits to disk.",
|
|
111
|
-
inputSchema: {
|
|
112
|
-
type: "object",
|
|
113
|
-
properties: {
|
|
114
|
-
filePath: { type: "string", description: "Source file path to format." },
|
|
115
|
-
},
|
|
116
|
-
required: ["filePath"],
|
|
117
|
-
},
|
|
118
|
-
},
|
|
119
107
|
{
|
|
120
108
|
name: "install_decision",
|
|
121
109
|
title: "LSP Install Decision",
|
|
@@ -140,7 +128,7 @@ const expectedToolSurface = [
|
|
|
140
128
|
];
|
|
141
129
|
|
|
142
130
|
describe("LSP core tool surface", () => {
|
|
143
|
-
test("#given tool descriptors #when listed #then the public
|
|
131
|
+
test("#given tool descriptors #when listed #then the public eight-tool schemas are pinned", () => {
|
|
144
132
|
// given / when
|
|
145
133
|
const surface = LSP_MCP_TOOLS.map((tool) => ({
|
|
146
134
|
name: tool.name,
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { executeLspDiagnostics } from "./diagnostics.js";
|
|
2
|
-
import { executeLspFormat } from "./format.js";
|
|
3
2
|
import { executeLspInstallDecision } from "./install-decision.js";
|
|
4
3
|
import { executeLspFindReferences, executeLspGotoDefinition } from "./navigation.js";
|
|
5
4
|
import { executeLspPrepareRename, executeLspRename } from "./rename.js";
|
|
@@ -117,19 +116,6 @@ export const LSP_MCP_TOOLS: LspMcpTool[] = [
|
|
|
117
116
|
),
|
|
118
117
|
execute: executeLspRename,
|
|
119
118
|
},
|
|
120
|
-
{
|
|
121
|
-
name: "format",
|
|
122
|
-
aliases: ["lsp_format"],
|
|
123
|
-
title: "LSP Format",
|
|
124
|
-
description: "Format a source file with its language server and write the returned edits to disk.",
|
|
125
|
-
inputSchema: objectSchema(
|
|
126
|
-
{
|
|
127
|
-
filePath: { type: "string", description: "Source file path to format." },
|
|
128
|
-
},
|
|
129
|
-
["filePath"],
|
|
130
|
-
),
|
|
131
|
-
execute: executeLspFormat,
|
|
132
|
-
},
|
|
133
119
|
{
|
|
134
120
|
name: "install_decision",
|
|
135
121
|
aliases: ["lsp_install_decision"],
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export { executeLspDiagnostics } from "./diagnostics.js";
|
|
2
2
|
export { LSP_MCP_TOOLS } from "./definitions.js";
|
|
3
|
-
export { executeLspFormat } from "./format.js";
|
|
4
3
|
export { executeLspInstallDecision } from "./install-decision.js";
|
|
5
4
|
export { executeLspFindReferences, executeLspGotoDefinition } from "./navigation.js";
|
|
6
5
|
export { isRecord } from "./parameters.js";
|
|
@@ -93,16 +93,6 @@ export interface LspPrepareRenameDetails {
|
|
|
93
93
|
errorKind?: "missing_dependency";
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
export interface LspFormatDetails {
|
|
97
|
-
filePath: string;
|
|
98
|
-
status: "formatted" | "unchanged" | "unavailable";
|
|
99
|
-
reason?: "capability_not_advertised" | "server_unavailable";
|
|
100
|
-
linesAdded: number;
|
|
101
|
-
linesRemoved: number;
|
|
102
|
-
error?: string;
|
|
103
|
-
errorKind?: "missing_dependency";
|
|
104
|
-
}
|
|
105
|
-
|
|
106
96
|
export interface LspRenameDetails {
|
|
107
97
|
filePath: string;
|
|
108
98
|
line: number;
|