@octocodeai/octocode-engine 16.6.0 → 16.7.0
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 +190 -249
- package/dist/lsp/client.d.ts +18 -9
- package/dist/lsp/client.js +35 -25
- package/dist/lsp/config.d.ts +29 -1
- package/dist/lsp/config.js +156 -1
- package/dist/lsp/ideContext.d.ts +18 -0
- package/dist/lsp/ideContext.js +29 -0
- package/dist/lsp/index.d.ts +8 -3
- package/dist/lsp/index.js +7 -2
- package/dist/lsp/lspClientPool.d.ts +2 -0
- package/dist/lsp/lspClientPool.js +9 -4
- package/dist/lsp/manager.d.ts +11 -0
- package/dist/lsp/manager.js +72 -25
- package/dist/lsp/native.d.ts +2 -1
- package/dist/lsp/platform.d.ts +20 -0
- package/dist/lsp/platform.js +64 -0
- package/dist/lsp/resolver.js +10 -4
- package/dist/lsp/serverDiscovery.d.ts +63 -0
- package/dist/lsp/serverDiscovery.js +226 -0
- package/dist/lsp/serverManifest.d.ts +71 -0
- package/dist/lsp/serverManifest.js +116 -0
- package/dist/lsp/serverManifestData.d.ts +2 -0
- package/dist/lsp/serverManifestData.js +96 -0
- package/dist/lsp/serverProvisioner.d.ts +19 -0
- package/dist/lsp/serverProvisioner.js +262 -0
- package/dist/lsp/types.d.ts +18 -0
- package/dist/security/commandValidator.js +74 -10
- package/dist/security/contentSanitizer.js +4 -3
- package/dist/security/discoveryFilter.js +10 -0
- package/dist/security/filePatterns.js +6 -0
- package/dist/security/ignoredPathFilter.js +10 -2
- package/dist/security/mask.js +5 -22
- package/dist/security/maskUtils.d.ts +6 -0
- package/dist/security/maskUtils.js +22 -0
- package/dist/security/native.js +5 -22
- package/dist/security/pathPatterns.js +5 -0
- package/dist/security/pathValidator.js +38 -37
- package/dist/security/registry.js +27 -9
- package/dist/security/securityConstants.d.ts +1 -1
- package/dist/security/securityConstants.js +22 -1
- package/dist/security/withSecurityValidation.js +18 -3
- package/docs/LSP_SERVER_LIFECYCLE.md +258 -0
- package/index.d.ts +8 -2
- package/package.json +54 -10
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
# LSP in Octocode — Lifecycle, Provisioning, and the No-Fallback Contract
|
|
2
|
+
|
|
3
|
+
Companion: `docs/context/LSP_GUIDE.md` (protocol primer + platformized resolution ladder).
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Two layers, two different jobs
|
|
8
|
+
|
|
9
|
+
| Layer | What it is | Speed | Answers |
|
|
10
|
+
|---|---|---|---|
|
|
11
|
+
| **Tree-sitter / OXC** | parser compiled into the engine | sub-ms/file | *"what does this code look like?"* — outlines, shapes, calls, imports (`structural/`, `signatures/`, `grammar.rs`) |
|
|
12
|
+
| **LSP** | a real language server, spawned over stdio | cold 1–120s, warm <100ms | *"what does this symbol mean?"* — cross-file definition identity, all references, call/type graph (`lsp/client.rs`, `manager.ts`, tools-core `semantic_content/execution.ts`) |
|
|
13
|
+
|
|
14
|
+
These are **not** interchangeable. Tree-sitter cannot resolve a symbol across files, infer a type, or follow an import — that needs a language server.
|
|
15
|
+
|
|
16
|
+
## The no-fallback contract (the rule that matters)
|
|
17
|
+
|
|
18
|
+
When a semantic operation needs a language server and **no server is available**, octocode **throws** — it does *not* fabricate a syntactic or same-file approximation. A faked answer is worse than an honest failure, because the calling agent would trust it.
|
|
19
|
+
|
|
20
|
+
- The thrown error is the standard typed envelope: `status:"error"`, `errorCode:"lspServerUnavailable"`. In bulk it lands under `errors[]`.
|
|
21
|
+
- The message names the language, says no server is available, gives the install hint, and **directs the agent to `localSearchCode` (text/structural search) + `localGetFileContent`** instead.
|
|
22
|
+
- octocode never returns a same-file-only `references` result, or a tree-sitter guess, dressed up as a semantic answer.
|
|
23
|
+
|
|
24
|
+
**Throws when no server:** `definition`, `references`, `hover`, `callers`, `callees`, `callHierarchy`, `typeDefinition`, `implementation`, `workspaceSymbol`, `supertypes`, `subtypes`, `diagnostic`.
|
|
25
|
+
|
|
26
|
+
**Never throws (genuine tree-sitter features, server-free):** `documentSymbols` (native OXC for JS/TS, Markdown heading outline, or LSP when present) and structural/AST search via `localSearchCode`. These are real syntactic capabilities, not LSP stand-ins. `documentSymbols` only throws for a non-JS/TS language with no server *and* no outline.
|
|
27
|
+
|
|
28
|
+
> A server that *is* running but lacks a capability, or returns zero results, still yields an honest *empty* (`unsupportedOperation` / `noReferences` / …) — that is an accurate answer ("none"), not a missing-server failure.
|
|
29
|
+
|
|
30
|
+
## Provisioning — three classes (how a server becomes available)
|
|
31
|
+
|
|
32
|
+
octocode maximizes the chance a real server answers via the resolution ladder (override → PATH → bundled → ecosystem discovery → managed cache; see `LSP_GUIDE.md` §13). Use `npx octocode lsp-server list` to see all servers and their current status, `npx octocode lsp-server status <file>` to check resolution for a specific file, and `npx octocode lsp-server install <name>` to trigger an auto-download. Servers fall into:
|
|
33
|
+
|
|
34
|
+
- **Bundled (npm dep, offline)** — pure-JS servers launched with the current Node; zero install. TS/JS, Python (pyright), Shell (bash-language-server), PHP (intelephense), YAML, JSON/HTML/CSS.
|
|
35
|
+
- **Auto-download (managed cache)** — portable single-binary servers fetched from a pinned release into `~/.octocode/lsp/<server>/<tag>/` (prompt-by-default, SHA-verified). rust-analyzer (all platforms), clangd (no linux-arm64 asset). Set `OCTOCODE_LSP_AUTO_INSTALL=auto` to skip the prompt or `=off` to disable downloads entirely.
|
|
36
|
+
- **Detect-and-instruct (host toolchain)** — need a runtime octocode won't auto-install: gopls (Go), jdtls (JDK 21+), sourcekit-lsp (Xcode/CLI tools on macOS), csharp-ls (.NET SDK). The status/hint tells you how to install; semantic ops throw until you do.
|
|
37
|
+
|
|
38
|
+
## Supported language servers
|
|
39
|
+
|
|
40
|
+
Scope is the **main languages**. Niche/long-tail servers were intentionally removed from
|
|
41
|
+
LSP routing (their tree-sitter grammars remain for structural/AST search). A file type not
|
|
42
|
+
listed below has no server config: semantic ops return `lspServerUnavailable` and the agent
|
|
43
|
+
falls back to text search.
|
|
44
|
+
|
|
45
|
+
| Language | Extensions | Server | Provisioning |
|
|
46
|
+
|---|---|---|---|
|
|
47
|
+
| TypeScript / JS (+ TSX/JSX) | `.ts .mts .cts .tsx .js .mjs .cjs .jsx` | typescript-language-server (`tsgo`/override aware) | **bundled** |
|
|
48
|
+
| Python | `.py .pyi` | pyright (`pylsp` via override) | **bundled** |
|
|
49
|
+
| Shell | `.sh` | bash-language-server | **bundled** |
|
|
50
|
+
| PHP | `.php` | intelephense | **bundled** |
|
|
51
|
+
| YAML | `.yaml .yml` | yaml-language-server | **bundled** |
|
|
52
|
+
| JSON | `.json .jsonc` | vscode-json-language-server | **bundled** |
|
|
53
|
+
| HTML | `.html .htm` | vscode-html-language-server | **bundled** |
|
|
54
|
+
| CSS / SCSS / LESS | `.css .scss .less` | vscode-css-language-server | **bundled** |
|
|
55
|
+
| Rust | `.rs` | rust-analyzer | **auto-download** |
|
|
56
|
+
| C / C++ | `.c .h .cpp .cc .cxx .hpp` | clangd | **auto-download** (no linux-arm64 asset) |
|
|
57
|
+
| Go | `.go` | gopls | **detect-and-instruct** (needs Go toolchain) |
|
|
58
|
+
| Java | `.java` | jdtls | **detect-and-instruct** (needs JDK 21+) |
|
|
59
|
+
| Swift | `.swift` | sourcekit-lsp | **detect-and-instruct** (needs Xcode or `xcode-select --install`) |
|
|
60
|
+
| C# | `.cs` | csharp-ls | **detect-and-instruct** (needs .NET SDK + `dotnet tool install -g csharp-ls`) |
|
|
61
|
+
| SQL | `.sql` | sqls | **PATH / override only** |
|
|
62
|
+
|
|
63
|
+
Any built-in server can be overridden with `OCTOCODE_<LANG>_SERVER_PATH` or `.octocode/lsp-servers.json`.
|
|
64
|
+
PATH/override-only servers resolve only if already on `PATH` / in an ecosystem dir; otherwise
|
|
65
|
+
semantic ops throw with an install hint.
|
|
66
|
+
|
|
67
|
+
**Removed from LSP routing** (use text/structural search instead): TOML, Ruby, Kotlin,
|
|
68
|
+
Elixir, Terraform, Lua, Proto, OCaml, Zig, Julia, Erlang, R, GDScript. Their tree-sitter
|
|
69
|
+
grammars stay available for `localSearchCode` structural/AST queries.
|
|
70
|
+
|
|
71
|
+
### Custom / bring-your-own LSP (any language)
|
|
72
|
+
|
|
73
|
+
A language with **no built-in spec** (e.g. Scala, Kotlin, Ruby) gets full semantic support by
|
|
74
|
+
registering a server in a JSON config — no rebuild, no code change. This is also how you swap a
|
|
75
|
+
built-in server for a different one. Resolution reads, in order (`config.rs::user_config_paths`):
|
|
76
|
+
|
|
77
|
+
1. `$OCTOCODE_LSP_CONFIG` (explicit file path)
|
|
78
|
+
2. `<workspace>/.octocode/lsp-servers.json` (per-project, checked in or local)
|
|
79
|
+
3. `~/.octocode/lsp-servers.json` (per-user, all projects)
|
|
80
|
+
|
|
81
|
+
The file maps a **file extension** to a launch spec. A custom entry takes precedence over the
|
|
82
|
+
built-in spec for that extension:
|
|
83
|
+
|
|
84
|
+
```jsonc
|
|
85
|
+
// .octocode/lsp-servers.json — register Scala (metals)
|
|
86
|
+
{
|
|
87
|
+
"languageServers": {
|
|
88
|
+
".scala": { "command": "metals", "args": ["stdio"], "languageId": "scala" },
|
|
89
|
+
".sc": { "command": "metals", "args": ["stdio"], "languageId": "scala" }
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
| Field | Required | Meaning |
|
|
95
|
+
|---|---|---|
|
|
96
|
+
| `command` | yes | Executable name (resolved on `PATH`) or absolute path. Shell wrappers are rejected. |
|
|
97
|
+
| `languageId` | yes | LSP `languageId` sent on `textDocument/didOpen` (e.g. `scala`, `ruby`). |
|
|
98
|
+
| `args` | no | Launch args (default `[]`). |
|
|
99
|
+
| `initializationOptions` | no | Passed verbatim in the LSP `initialize` request. |
|
|
100
|
+
|
|
101
|
+
With the config present, semantic ops (`definition`, `references`, `hover`, call hierarchy, …)
|
|
102
|
+
work for that language exactly like a built-in one. **Without it, the extension stays unsupported:
|
|
103
|
+
the engine resolves no server and the no-fallback contract applies** — semantic ops throw
|
|
104
|
+
`lspServerUnavailable` and the agent falls back to `localSearchCode` + `localGetFileContent`.
|
|
105
|
+
Both halves of this contract are asserted by the benchmark (`benchmark/lsp/check-lsp.mjs`,
|
|
106
|
+
"Custom LSP — bring-your-own server (Scala / metals)"), and verified **live against a real
|
|
107
|
+
server** by `benchmark/lsp/check-custom-lsp.mjs` (`yarn lsp:custom`) — which registers
|
|
108
|
+
`bash-language-server` (a language with no built-in spec) and runs real `documentSymbols` /
|
|
109
|
+
`references` / `hover` through it.
|
|
110
|
+
|
|
111
|
+
### Markup & docs: what's LSP vs minify
|
|
112
|
+
|
|
113
|
+
- **HTML / CSS / SCSS / LESS / JSON / YAML are LSP** — served by the bundled
|
|
114
|
+
`vscode-*-language-server` / `yaml-language-server` (markup/data, offline-ready). They're
|
|
115
|
+
not "code" languages but they do have real language servers.
|
|
116
|
+
- **Markdown / MDX are NOT LSP.** They are handled by the **minifier** using heading-section
|
|
117
|
+
heuristics (ATX `#`/`##` and setext headings → `minify/strategies/markdown.rs`; `md`,
|
|
118
|
+
`markdown`, `mdx` all map to the markdown strategy in `minify/config.rs`). There is no
|
|
119
|
+
markdown language server in octocode — `documentSymbols` on a `.md` file uses the native
|
|
120
|
+
heading-outline path, and structure/compression comes from the minifier, not a server.
|
|
121
|
+
|
|
122
|
+
## Full format support matrix
|
|
123
|
+
|
|
124
|
+
Per-extension capabilities across all four axes — minify strategy, structural AST,
|
|
125
|
+
signature outline, and LSP server — machine-generated from the shipped napi binary.
|
|
126
|
+
The LSP column here is the per-extension view of the [Supported language servers](#supported-language-servers)
|
|
127
|
+
table above.
|
|
128
|
+
|
|
129
|
+
<!-- BEGIN GENERATED: support-matrix (yarn matrix:check --write) — do not edit between these markers -->
|
|
130
|
+
|
|
131
|
+
_Generated by `yarn matrix:check --write` (benchmark/check-matrix.mjs) — every cell probed live against the shipped napi binary. Do not edit between the markers; run `yarn matrix:check` to re-verify._
|
|
132
|
+
|
|
133
|
+
> **Note:** The matrix queries the native layer (`config.rs`) only. Two servers injected at the TS layer (`config.ts`) are not reflected: **bash-language-server** for `.sh` (languageId `shellscript`) and **intelephense** for `.php` (the native spec emits `intelephense` as command — both bundled and active). Their LSP cells show `—` in the matrix below but the servers are bundled and resolve correctly (`npx octocode lsp-server status <file>` will show `resolved: bundled`).
|
|
134
|
+
|
|
135
|
+
**151 extensions** known to the engine — 61 with structural AST, 47 with a signature outline, 32 with an LSP server, 90 minify-only.
|
|
136
|
+
|
|
137
|
+
### Rich formats — AST + signature + LSP
|
|
138
|
+
|
|
139
|
+
Extensions with a wired tree-sitter grammar (and, where configured, a language server). The minify column is the configured strategy.
|
|
140
|
+
|
|
141
|
+
| Extension | Minify | Structural AST | Signature outline | LSP (server → language-id) |
|
|
142
|
+
|-----------|--------|:--------------:|-------------------|----------------------------|
|
|
143
|
+
| `.bash` | `conservative` | ✅ | ✅ tree-sitter | — |
|
|
144
|
+
| `.c` | `conservative` | ✅ | ✅ tree-sitter | `clangd` → `c` |
|
|
145
|
+
| `.cc` | `conservative` | ✅ | ✅ tree-sitter | `clangd` → `cpp` |
|
|
146
|
+
| `.cjs` | `terser` | ✅ | ✅ tree-sitter | `typescript-language-server` → `javascript` |
|
|
147
|
+
| `.cpp` | `conservative` | ✅ | ✅ tree-sitter | `clangd` → `cpp` |
|
|
148
|
+
| `.cs` | `conservative` | ✅ | ✅ tree-sitter | `csharp-ls` → `csharp` |
|
|
149
|
+
| `.css` | `aggressive` | ✅ | — | `vscode-css-language-server` → `css` |
|
|
150
|
+
| `.cts` | `conservative` | ✅ | ✅ tree-sitter | `typescript-language-server` → `typescript` |
|
|
151
|
+
| `.cxx` | `conservative` | ✅ | ✅ tree-sitter | `clangd` → `cpp` |
|
|
152
|
+
| `.erl` | `aggressive` | ✅ | ✅ tree-sitter | — |
|
|
153
|
+
| `.ex` | `aggressive` | ✅ | ✅ tree-sitter | — |
|
|
154
|
+
| `.exs` | `aggressive` | ✅ | ✅ tree-sitter | — |
|
|
155
|
+
| `.gemspec` | `conservative` | ✅ | ✅ tree-sitter | — |
|
|
156
|
+
| `.go` | `conservative` | ✅ | ✅ tree-sitter | `gopls` → `go` |
|
|
157
|
+
| `.h` | `conservative` | ✅ | ✅ tree-sitter | `clangd` → `c` |
|
|
158
|
+
| `.hcl` | `conservative` | ✅ | ✅ tree-sitter | — |
|
|
159
|
+
| `.hh` | `conservative` | ✅ | ✅ tree-sitter | — |
|
|
160
|
+
| `.hpp` | `conservative` | ✅ | ✅ tree-sitter | `clangd` → `cpp` |
|
|
161
|
+
| `.hrl` | `aggressive` | ✅ | ✅ tree-sitter | — |
|
|
162
|
+
| `.htm` | `aggressive` | ✅ | — | `vscode-html-language-server` → `html` |
|
|
163
|
+
| `.html` | `aggressive` | ✅ | — | `vscode-html-language-server` → `html` |
|
|
164
|
+
| `.hxx` | `conservative` | ✅ | ✅ tree-sitter | — |
|
|
165
|
+
| `.java` | `conservative` | ✅ | ✅ tree-sitter | `jdtls` → `java` |
|
|
166
|
+
| `.jl` | `conservative` | ✅ | — | — |
|
|
167
|
+
| `.js` | `terser` | ✅ | ✅ tree-sitter | `typescript-language-server` → `javascript` |
|
|
168
|
+
| `.json` | `json` | ✅ | — | `vscode-json-language-server` → `json` |
|
|
169
|
+
| `.jsonc` | `json` | ✅ | — | `vscode-json-language-server` → `json` |
|
|
170
|
+
| `.jsx` | `terser` | ✅ | ✅ tree-sitter | `typescript-language-server` → `javascriptreact` |
|
|
171
|
+
| `.kt` | `conservative` | ✅ | ✅ tree-sitter | — |
|
|
172
|
+
| `.kts` | `conservative` | ✅ | ✅ tree-sitter | — |
|
|
173
|
+
| `.less` | `aggressive` | ✅ | — | `vscode-css-language-server` → `less` |
|
|
174
|
+
| `.lua` | `aggressive` | ✅ | ✅ tree-sitter | — |
|
|
175
|
+
| `.mjs` | `terser` | ✅ | ✅ tree-sitter | `typescript-language-server` → `javascript` |
|
|
176
|
+
| `.ml` | `conservative` | ✅ | — | — |
|
|
177
|
+
| `.mli` | `conservative` | ✅ | — | — |
|
|
178
|
+
| `.mts` | `conservative` | ✅ | ✅ tree-sitter | `typescript-language-server` → `typescript` |
|
|
179
|
+
| `.php` | `conservative` | ✅ | ✅ tree-sitter | `intelephense` → `php` |
|
|
180
|
+
| `.proto` | `conservative` | ✅ | ✅ tree-sitter | — |
|
|
181
|
+
| `.py` | `conservative` | ✅ | ✅ tree-sitter | `pylsp` → `python` |
|
|
182
|
+
| `.pyi` | `conservative` | ✅ | ✅ tree-sitter | `pylsp` → `python` |
|
|
183
|
+
| `.r` | `aggressive` | ✅ | ✅ tree-sitter | — |
|
|
184
|
+
| `.rake` | `conservative` | ✅ | ✅ tree-sitter | — |
|
|
185
|
+
| `.rb` | `conservative` | ✅ | ✅ tree-sitter | — |
|
|
186
|
+
| `.rs` | `conservative` | ✅ | ✅ tree-sitter | `rust-analyzer` → `rust` |
|
|
187
|
+
| `.ru` | `conservative` | ✅ | ✅ tree-sitter | — |
|
|
188
|
+
| `.sbt` | — | ✅ | ✅ tree-sitter | — |
|
|
189
|
+
| `.sc` | — | ✅ | ✅ tree-sitter | — |
|
|
190
|
+
| `.scala` | `conservative` | ✅ | ✅ tree-sitter | — |
|
|
191
|
+
| `.scss` | `aggressive` | ✅ | — | `vscode-css-language-server` → `scss` |
|
|
192
|
+
| `.sh` | `conservative` | ✅ | ✅ tree-sitter | — |
|
|
193
|
+
| `.sql` | `conservative` | ✅ | — | `sqls` → `sql` |
|
|
194
|
+
| `.swift` | `conservative` | ✅ | ✅ tree-sitter | `sourcekit-lsp` → `swift` |
|
|
195
|
+
| `.tf` | `conservative` | ✅ | ✅ tree-sitter | — |
|
|
196
|
+
| `.tfvars` | `conservative` | ✅ | ✅ tree-sitter | — |
|
|
197
|
+
| `.toml` | `conservative` | ✅ | — | — |
|
|
198
|
+
| `.ts` | `conservative` | ✅ | ✅ tree-sitter | `typescript-language-server` → `typescript` |
|
|
199
|
+
| `.tsx` | `conservative` | ✅ | ✅ tree-sitter | `typescript-language-server` → `typescriptreact` |
|
|
200
|
+
| `.yaml` | `conservative` | ✅ | — | `yaml-language-server` → `yaml` |
|
|
201
|
+
| `.yml` | `conservative` | ✅ | — | `yaml-language-server` → `yaml` |
|
|
202
|
+
| `.zig` | `conservative` | ✅ | ✅ tree-sitter | — |
|
|
203
|
+
| `.zsh` | `conservative` | ✅ | ✅ tree-sitter | — |
|
|
204
|
+
|
|
205
|
+
Notes:
|
|
206
|
+
- **Signature outline is tree-sitter only** — markup/style/config grammars (HTML/CSS/SCSS/LESS/Scala/JSON/YAML/TOML) parse for structural `rule` queries but have no function body, so no skeleton. There is **no** regex/heuristic fallback.
|
|
207
|
+
- **`.jsx`** resolves the LSP server as `javascriptreact` (to enable JSX) even though its tree-sitter grammar registry id is `javascript` (shared JS grammar). `.tsx` has its own grammar, so both ids are `typescriptreact`.
|
|
208
|
+
- **`.hh` / `.hxx`** have the C++ grammar + signatures but **no clangd server config** (only `.cpp/.cc/.cxx/.hpp` are mapped).
|
|
209
|
+
- **C/C++**: structural `rule` queries (e.g. `kind: call_expression`) work fully; a bare call-shaped `pattern` can hit tree-sitter's declaration-vs-call ambiguity — prefer a `rule` with `kind`. JS/TS also have a native (oxc) symbol/in-file-reference path that needs **no server installed**.
|
|
210
|
+
|
|
211
|
+
### Minify-only formats
|
|
212
|
+
|
|
213
|
+
Native comment/whitespace stripping; no AST/LSP. (90 extensions, grouped by strategy.)
|
|
214
|
+
|
|
215
|
+
**`aggressive`** (18): `clj` `cljs` `ejs` `erb` `handlebars` `hbs` `jinja` `jinja2` `mustache` `pl` `pm` `svelte` `svg` `twig` `vue` `xml` `xsl` `xslt`
|
|
216
|
+
|
|
217
|
+
**`conservative`** (66): `adb` `ads` `asm` `awk` `bzl` `cfg` `cmake` `coffee` `conf` `config` `csv` `dart` `dockerignore` `elm` `env` `f` `f03` `f08` `f90` `f95` `fish` `for` `fs` `fsx` `gitignore` `gql` `gradle` `graphql` `groovy` `haml` `hs` `ini` `jade` `kotlin` `lhs` `lisp` `lsp` `mm` `nasm` `nim` `nix` `pas` `perl` `plsql` `pp` `properties` `ps1` `psd1` `psm1` `pug` `rkt` `rst` `rust` `sass` `scm` `slim` `star` `styl` `tsql` `v` `vb` `vbs` `vhd` `vhdl` `wast` `wat`
|
|
218
|
+
|
|
219
|
+
**`general`** (2): `log` `txt`
|
|
220
|
+
|
|
221
|
+
**`json`** (1): `json5`
|
|
222
|
+
|
|
223
|
+
**`markdown`** (3): `markdown` `md` `mdx`
|
|
224
|
+
|
|
225
|
+
### Verify
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
yarn matrix:check # this matrix, live
|
|
229
|
+
yarn ast:check # structural search + signatures on real samples
|
|
230
|
+
yarn lsp:check # language-id + server resolution + native semantics
|
|
231
|
+
yarn lsp:live # spawn a real server, exercise every LSP operation type
|
|
232
|
+
yarn minify:check # minifier over every configured format
|
|
233
|
+
yarn benchmark # all of the above
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
<!-- END GENERATED: support-matrix -->
|
|
237
|
+
|
|
238
|
+
## Lifecycle — pool, cold start, indexing
|
|
239
|
+
|
|
240
|
+
- **Pool** (`lspClientPool.ts`): one warm `LSPClient` per (server × workspace), 60s idle timeout (`OCTOCODE_LSP_POOL_IDLE_MS`). A long-lived MCP session reuses warm servers across tool calls; one-shot CLI invocations don't share a pool.
|
|
241
|
+
- **Cold start / indexing**: a server reads the project and builds its model before answering correctly. Costs vary — typescript-language-server <1s, gopls 3–15s, rust-analyzer 5–60s (multiple `$/progress` waves), jdtls 30–120s.
|
|
242
|
+
- **Readiness** (`manager.ts` + `json_rpc.rs`): for servers that emit `$/progress` (go, rust, java, csharp, swift) the pool factory calls `waitForReady` with a per-language cap before the first query; servers without `$/progress` (TS/JS, Python, clangd, data formats) skip the wait to avoid a fixed 2s settle penalty.
|
|
243
|
+
- **Spawn gate**: every resolved command passes `validateLSPServerPath` (rejects shell wrappers / nonexistent / non-executable) in `LSPClient.start()` before the process is spawned.
|
|
244
|
+
- **Discovery caching** (`serverDiscovery.ts`): ecosystem-dir lookup results are memoised per `(command, workspaceRoot)` for the process lifetime. Ecosystem dirs are pre-filtered to existing ones once, cutting stat calls from ~15-per-server to ~5. Call `clearDiscoveryCache()` (or restart) after installing a server mid-session.
|
|
245
|
+
|
|
246
|
+
## Open / future (non-blocking)
|
|
247
|
+
|
|
248
|
+
Progress streaming to the caller (`lsp.indexingStatus`), an opt-in `waitForIndexingMs`, tree-sitter symbol extraction for compiled-language `documentSymbols`, and a SCIP precomputed index — all deferred; none change the no-fallback contract above.
|
|
249
|
+
|
|
250
|
+
> **Known issue — cold `references` under-reports.** On a one-shot CLI invocation,
|
|
251
|
+
> `references` (and other project-wide ops) can return incomplete results
|
|
252
|
+
> *labelled* `complete=true`, because `typescript-language-server` emits no
|
|
253
|
+
> `$/progress` and the project isn't indexed yet when queried. This is the one
|
|
254
|
+
> behaviour that can make an agent wrong rather than just slow — analysis and the
|
|
255
|
+
> proposed fix (honest `complete=false` + cross-check hint, with an opt-in
|
|
256
|
+
> `waitForIndexingMs`) are in
|
|
257
|
+
> [`LSP_REFERENCES_INDEXING_RFC.md`](https://github.com/bgauryy/octocode/blob/main/docs/context/LSP_REFERENCES_INDEXING_RFC.md). Meanwhile,
|
|
258
|
+
> prefer `--op callers` or `localSearchCode` to confirm "who uses this".
|
package/index.d.ts
CHANGED
|
@@ -4,7 +4,8 @@ export declare class NativeLspClient {
|
|
|
4
4
|
constructor(config: JsLanguageServerConfig)
|
|
5
5
|
start(): Promise<void>
|
|
6
6
|
stop(): Promise<void>
|
|
7
|
-
|
|
7
|
+
/** Readiness after post-`initialized` indexing: `progressIdle` = a `$/progress` cycle drained to idle; `settledFallback` = no progress seen, only the settle window elapsed; `timeout` = progress still active at the deadline. */
|
|
8
|
+
waitForReady(timeoutMs?: number | undefined | null): Promise<'progressIdle' | 'settledFallback' | 'timeout'>
|
|
8
9
|
hasCapability(capability: string): boolean
|
|
9
10
|
/** Server-selected LSP `positionEncoding` (utf-16 unless the server is non-conformant); null if omitted/not started. */
|
|
10
11
|
positionEncoding(): string | null
|
|
@@ -943,8 +944,13 @@ export interface StructuralQueryExplanation {
|
|
|
943
944
|
|
|
944
945
|
export interface StructuralDetailedMatch extends StructuralMatch {
|
|
945
946
|
id: string
|
|
947
|
+
/** tree-sitter `kind` of the matched node (e.g. `call_expression`). */
|
|
946
948
|
nodeKind?: string
|
|
947
|
-
|
|
949
|
+
/**
|
|
950
|
+
* The octo matcher is a precise AST matcher, so every match is an exact
|
|
951
|
+
* tree-sitter node match — there is no partial/fallback tier.
|
|
952
|
+
*/
|
|
953
|
+
confidence: 'exact-ast'
|
|
948
954
|
}
|
|
949
955
|
|
|
950
956
|
export interface StructuralSearchDetailedResult {
|
package/package.json
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@octocodeai/octocode-engine",
|
|
3
|
-
"version": "16.
|
|
3
|
+
"version": "16.7.0",
|
|
4
4
|
"description": "Rust native Octocode engine for context compression, structural search, and LSP semantic navigation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.cjs",
|
|
7
7
|
"types": "index.d.ts",
|
|
8
8
|
"license": "MIT",
|
|
9
9
|
"author": "Guy Bary <bgauryy@octocodeai.com>",
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"access": "public"
|
|
12
|
+
},
|
|
10
13
|
"repository": {
|
|
11
14
|
"type": "git",
|
|
12
15
|
"url": "https://github.com/bgauryy/octocode-mcp.git",
|
|
@@ -109,6 +112,26 @@
|
|
|
109
112
|
"import": "./dist/lsp/manager.js",
|
|
110
113
|
"default": "./dist/lsp/manager.js"
|
|
111
114
|
},
|
|
115
|
+
"./lsp/platform": {
|
|
116
|
+
"types": "./dist/lsp/platform.d.ts",
|
|
117
|
+
"import": "./dist/lsp/platform.js",
|
|
118
|
+
"default": "./dist/lsp/platform.js"
|
|
119
|
+
},
|
|
120
|
+
"./lsp/serverDiscovery": {
|
|
121
|
+
"types": "./dist/lsp/serverDiscovery.d.ts",
|
|
122
|
+
"import": "./dist/lsp/serverDiscovery.js",
|
|
123
|
+
"default": "./dist/lsp/serverDiscovery.js"
|
|
124
|
+
},
|
|
125
|
+
"./lsp/serverManifest": {
|
|
126
|
+
"types": "./dist/lsp/serverManifest.d.ts",
|
|
127
|
+
"import": "./dist/lsp/serverManifest.js",
|
|
128
|
+
"default": "./dist/lsp/serverManifest.js"
|
|
129
|
+
},
|
|
130
|
+
"./lsp/serverProvisioner": {
|
|
131
|
+
"types": "./dist/lsp/serverProvisioner.d.ts",
|
|
132
|
+
"import": "./dist/lsp/serverProvisioner.js",
|
|
133
|
+
"default": "./dist/lsp/serverProvisioner.js"
|
|
134
|
+
},
|
|
112
135
|
"./lsp/resolver": {
|
|
113
136
|
"types": "./dist/lsp/resolver.d.ts",
|
|
114
137
|
"import": "./dist/lsp/resolver.js",
|
|
@@ -196,6 +219,18 @@
|
|
|
196
219
|
"lsp/manager": [
|
|
197
220
|
"./dist/lsp/manager.d.ts"
|
|
198
221
|
],
|
|
222
|
+
"lsp/platform": [
|
|
223
|
+
"./dist/lsp/platform.d.ts"
|
|
224
|
+
],
|
|
225
|
+
"lsp/serverDiscovery": [
|
|
226
|
+
"./dist/lsp/serverDiscovery.d.ts"
|
|
227
|
+
],
|
|
228
|
+
"lsp/serverManifest": [
|
|
229
|
+
"./dist/lsp/serverManifest.d.ts"
|
|
230
|
+
],
|
|
231
|
+
"lsp/serverProvisioner": [
|
|
232
|
+
"./dist/lsp/serverProvisioner.d.ts"
|
|
233
|
+
],
|
|
199
234
|
"lsp/resolver": [
|
|
200
235
|
"./dist/lsp/resolver.d.ts"
|
|
201
236
|
],
|
|
@@ -221,18 +256,19 @@
|
|
|
221
256
|
},
|
|
222
257
|
"files": [
|
|
223
258
|
"dist",
|
|
259
|
+
"docs/**",
|
|
224
260
|
"index.cjs",
|
|
225
261
|
"index.js",
|
|
226
262
|
"index.d.ts",
|
|
227
263
|
"README.md"
|
|
228
264
|
],
|
|
229
265
|
"optionalDependencies": {
|
|
230
|
-
"@octocodeai/octocode-engine-darwin-arm64": "16.
|
|
231
|
-
"@octocodeai/octocode-engine-darwin-x64": "16.
|
|
232
|
-
"@octocodeai/octocode-engine-linux-arm64-gnu": "16.
|
|
233
|
-
"@octocodeai/octocode-engine-linux-x64-gnu": "16.
|
|
234
|
-
"@octocodeai/octocode-engine-linux-x64-musl": "16.
|
|
235
|
-
"@octocodeai/octocode-engine-win32-x64-msvc": "16.
|
|
266
|
+
"@octocodeai/octocode-engine-darwin-arm64": "16.7.0",
|
|
267
|
+
"@octocodeai/octocode-engine-darwin-x64": "16.7.0",
|
|
268
|
+
"@octocodeai/octocode-engine-linux-arm64-gnu": "16.7.0",
|
|
269
|
+
"@octocodeai/octocode-engine-linux-x64-gnu": "16.7.0",
|
|
270
|
+
"@octocodeai/octocode-engine-linux-x64-musl": "16.7.0",
|
|
271
|
+
"@octocodeai/octocode-engine-win32-x64-msvc": "16.7.0"
|
|
236
272
|
},
|
|
237
273
|
"engines": {
|
|
238
274
|
"node": ">=20.0.0"
|
|
@@ -256,18 +292,21 @@
|
|
|
256
292
|
"build:linux-x64-musl": "node scripts/prebuild.cjs && napi build --platform --release --cross-compile --target x86_64-unknown-linux-musl && node scripts/postbuild.cjs",
|
|
257
293
|
"build:linux-arm64-gnu": "node scripts/prebuild.cjs && napi build --platform --release --cross-compile --target aarch64-unknown-linux-gnu && node scripts/postbuild.cjs",
|
|
258
294
|
"build:windows-x64": "node scripts/prebuild.cjs && napi build --platform --release --cross-compile --target x86_64-pc-windows-msvc && node scripts/postbuild.cjs",
|
|
259
|
-
"build:all": "yarn build:darwin-arm64 && yarn build:darwin-x64 && yarn build:linux-x64-gnu && yarn build:linux-x64-musl && yarn build:linux-arm64-gnu && yarn build:windows-x64 && yarn build:ts",
|
|
295
|
+
"build:all": "yarn clean:binaries && yarn build:darwin-arm64 && yarn build:darwin-x64 && yarn build:linux-x64-gnu && yarn build:linux-x64-musl && yarn build:linux-arm64-gnu && yarn build:windows-x64 && yarn build:ts",
|
|
260
296
|
"build:dev": "yarn readme:sync && node scripts/prebuild.cjs && napi build --platform && node scripts/postbuild.cjs && tsc -p tsconfig.build.json",
|
|
261
297
|
"build:ts": "yarn readme:sync && rm -rf dist && tsc -p tsconfig.build.json",
|
|
262
298
|
"clean": "rm -rf dist/ && rm -f *.node",
|
|
299
|
+
"clean:binaries": "rm -f *.node && find npm -name '*.node' -delete",
|
|
263
300
|
"gen": "node scripts/gen-patterns.mjs",
|
|
264
301
|
"verify:patterns": "node scripts/gen-patterns.mjs && git diff --exit-code src/security/patterns.rs || (echo 'ERROR: src/security/patterns.rs is out of sync with the TS source — run yarn gen and commit the result' && exit 1)",
|
|
265
302
|
"pack:check": "node scripts/check-pack-size.cjs",
|
|
266
303
|
"platforms:check": "node scripts/check-platform-binaries.cjs",
|
|
267
304
|
"version:check": "node scripts/check-version-consistency.cjs",
|
|
268
305
|
"version:sync": "node scripts/sync-versions.cjs",
|
|
306
|
+
"manifest:gen": "node scripts/gen-server-manifest.mjs",
|
|
307
|
+
"verify:manifest": "node scripts/gen-server-manifest.mjs && git diff --exit-code src/lsp/serverManifestData.ts || (echo 'ERROR: src/lsp/serverManifestData.ts is out of sync with serverManifest.json — run yarn manifest:gen and commit the result' && exit 1)",
|
|
269
308
|
"loader:check": "node scripts/check-loader-entries.cjs",
|
|
270
|
-
"prepublish:verify": "yarn version:check && yarn loader:check && yarn pack:check && yarn platforms:check",
|
|
309
|
+
"prepublish:verify": "yarn version:check && yarn loader:check && yarn verify:manifest && yarn pack:check && yarn platforms:check",
|
|
271
310
|
"binary-size:check": "node scripts/check-binary-size.cjs",
|
|
272
311
|
"ast:check": "yarn workspace @octocodeai/octocode-benchmark ast:check",
|
|
273
312
|
"lsp:check": "yarn workspace @octocodeai/octocode-benchmark lsp:check",
|
|
@@ -296,14 +335,19 @@
|
|
|
296
335
|
"audit:rust": "cargo audit -D unmaintained -D unsound -D yanked",
|
|
297
336
|
"audit": "yarn audit:rust",
|
|
298
337
|
"verify:rust": "yarn check:rust && yarn fmt:rust:check && yarn lint:rust && yarn test:rust && yarn deps:rust && yarn udeps:rust && yarn audit:rust",
|
|
299
|
-
"verify": "yarn verify:patterns && yarn typecheck && yarn verify:rust && yarn test && yarn benchmark && yarn pack:check && yarn version:check && yarn loader:check && yarn binary-size:check",
|
|
338
|
+
"verify": "yarn verify:patterns && yarn verify:manifest && yarn typecheck && yarn verify:rust && yarn test && yarn benchmark && yarn pack:check && yarn version:check && yarn loader:check && yarn binary-size:check",
|
|
300
339
|
"readme:sync": "node ../../scripts/sync-package-readmes.mjs .",
|
|
301
340
|
"prepack": "yarn readme:sync",
|
|
302
341
|
"prepublishOnly": "yarn version:sync"
|
|
303
342
|
},
|
|
304
343
|
"dependencies": {
|
|
344
|
+
"bash-language-server": "^5.6.0",
|
|
345
|
+
"intelephense": "^1.14.1",
|
|
346
|
+
"pyright": "^1.1.411",
|
|
305
347
|
"typescript": "^5.9.3",
|
|
306
348
|
"typescript-language-server": "^4.4.0",
|
|
349
|
+
"vscode-langservers-extracted": "^4.10.0",
|
|
350
|
+
"yaml-language-server": "^1.23.0",
|
|
307
351
|
"zod": "^4.4.3"
|
|
308
352
|
},
|
|
309
353
|
"devDependencies": {
|