python-delphi-lsp 3.6.0__cp310-abi3-win_amd64.whl
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.
- delphi_lsp/__init__.py +184 -0
- delphi_lsp/_version.py +1 -0
- delphi_lsp/agent_cache.py +1574 -0
- delphi_lsp/agent_cli.py +902 -0
- delphi_lsp/agent_context.py +3907 -0
- delphi_lsp/agent_cpg.py +349 -0
- delphi_lsp/agent_cpg_builder.py +666 -0
- delphi_lsp/agent_layers.py +1410 -0
- delphi_lsp/agent_metrics.py +526 -0
- delphi_lsp/agent_protocol.py +445 -0
- delphi_lsp/agent_relations.py +1881 -0
- delphi_lsp/agent_templates.py +614 -0
- delphi_lsp/agent_wiki.py +2853 -0
- delphi_lsp/agent_workspace.py +860 -0
- delphi_lsp/ast_serialize.py +126 -0
- delphi_lsp/binary.py +250 -0
- delphi_lsp/comment_builder.py +28 -0
- delphi_lsp/consts.py +345 -0
- delphi_lsp/delphi_lsp_native.pyd +0 -0
- delphi_lsp/delphiast_lexer.py +399 -0
- delphi_lsp/delphiast_parser.py +2189 -0
- delphi_lsp/delphiast_tokens.py +41 -0
- delphi_lsp/grammar.py +459 -0
- delphi_lsp/incremental.py +1139 -0
- delphi_lsp/lark_builder.py +2684 -0
- delphi_lsp/lark_tokens.py +236 -0
- delphi_lsp/lexical_scanner.py +30 -0
- delphi_lsp/lsp_server.py +6698 -0
- delphi_lsp/metrics.py +1452 -0
- delphi_lsp/native_bridge.py +300 -0
- delphi_lsp/navigation_cache.py +189 -0
- delphi_lsp/nodes.py +462 -0
- delphi_lsp/parallel_outline.py +662 -0
- delphi_lsp/parse_artifacts.py +969 -0
- delphi_lsp/parser.py +342 -0
- delphi_lsp/parser_backend.py +139 -0
- delphi_lsp/preprocessor.py +1122 -0
- delphi_lsp/progress.py +26 -0
- delphi_lsp/project_config.py +285 -0
- delphi_lsp/project_discovery.py +932 -0
- delphi_lsp/project_indexer.py +470 -0
- delphi_lsp/py.typed +1 -0
- delphi_lsp/response_cache.py +465 -0
- delphi_lsp/semantic.py +394 -0
- delphi_lsp/semantic_builder.py +2302 -0
- delphi_lsp/source_reader.py +17 -0
- delphi_lsp/wiki_external_sort.py +392 -0
- delphi_lsp/wiki_memory.py +548 -0
- delphi_lsp/workspace.py +83 -0
- delphi_lsp/writer.py +73 -0
- python_delphi_lsp-3.6.0.dist-info/METADATA +766 -0
- python_delphi_lsp-3.6.0.dist-info/RECORD +56 -0
- python_delphi_lsp-3.6.0.dist-info/WHEEL +4 -0
- python_delphi_lsp-3.6.0.dist-info/entry_points.txt +3 -0
- python_delphi_lsp-3.6.0.dist-info/licenses/LICENSE +373 -0
- python_delphi_lsp-3.6.0.dist-info/sboms/python-delphi-lsp.cyclonedx.json +770 -0
|
@@ -0,0 +1,766 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: python-delphi-lsp
|
|
3
|
+
Version: 3.6.0
|
|
4
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
5
|
+
Classifier: Intended Audience :: Developers
|
|
6
|
+
Classifier: Operating System :: OS Independent
|
|
7
|
+
Classifier: Operating System :: MacOS
|
|
8
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
15
|
+
Classifier: Topic :: Software Development :: Compilers
|
|
16
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
17
|
+
Requires-Dist: lark>=1.1.9
|
|
18
|
+
Requires-Dist: pygls>=1.3.0,<2.0
|
|
19
|
+
Requires-Dist: lsprotocol>=2023.0.1
|
|
20
|
+
Requires-Dist: tomli>=2.0.1 ; python_full_version < '3.11'
|
|
21
|
+
Requires-Dist: watchfiles>=1.2,<2.0
|
|
22
|
+
Requires-Dist: build>=1.2.0 ; extra == 'dev'
|
|
23
|
+
Requires-Dist: maturin>=1.5,<2.0 ; extra == 'dev'
|
|
24
|
+
Requires-Dist: twine>=5.0.0 ; extra == 'dev'
|
|
25
|
+
Requires-Dist: pygls>=1.3.0,<2.0 ; extra == 'dev'
|
|
26
|
+
Requires-Dist: lsprotocol>=2023.0.1 ; extra == 'dev'
|
|
27
|
+
Requires-Dist: pytest>=8.0.0 ; extra == 'dev'
|
|
28
|
+
Requires-Dist: pytest-timeout>=2.3.0 ; extra == 'dev'
|
|
29
|
+
Requires-Dist: pygls>=1.3.0,<2.0 ; extra == 'lsp'
|
|
30
|
+
Requires-Dist: lsprotocol>=2023.0.1 ; extra == 'lsp'
|
|
31
|
+
Requires-Dist: pytest>=8.0.0 ; extra == 'test'
|
|
32
|
+
Requires-Dist: pytest-timeout>=2.3.0 ; extra == 'test'
|
|
33
|
+
Provides-Extra: dev
|
|
34
|
+
Provides-Extra: lsp
|
|
35
|
+
Provides-Extra: test
|
|
36
|
+
License-File: LICENSE
|
|
37
|
+
Summary: Python Delphi/Object Pascal parser, semantic indexer, and language server.
|
|
38
|
+
Keywords: delphi,object-pascal,pascal,lsp,language-server,parser
|
|
39
|
+
Author: Dark Light
|
|
40
|
+
License-Expression: MPL-2.0
|
|
41
|
+
Requires-Python: >=3.10
|
|
42
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
43
|
+
|
|
44
|
+
# Python Delphi LSP
|
|
45
|
+
|
|
46
|
+
`python-delphi-lsp` parses Delphi/Object Pascal, builds semantic and project
|
|
47
|
+
indexes, serves LSP, and provides bounded codebase navigation for agents.
|
|
48
|
+
Version 3.5.0 is authored by Dark Light and supports Windows, macOS, and Linux.
|
|
49
|
+
|
|
50
|
+
## Install and quick start
|
|
51
|
+
|
|
52
|
+
Install into the Python environment that will run the command:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
python -m pip install python-delphi-lsp
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
On Windows, use `py -m pip install python-delphi-lsp` if that is your system
|
|
59
|
+
convention. On macOS and Linux, use `python3 -m pip install python-delphi-lsp`
|
|
60
|
+
when `python` is unavailable. Normal installed use needs neither a checkout
|
|
61
|
+
nor `PYTHONPATH`.
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
from delphi_lsp import parse
|
|
65
|
+
|
|
66
|
+
result = parse("unit Unit1; interface implementation end.", "Unit1.pas")
|
|
67
|
+
print(result.root)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
For semantic work across units, `build_workspace_semantics` returns per-file
|
|
71
|
+
models and a shared symbol index. `ProjectIndexer` follows a project entry
|
|
72
|
+
with explicit search paths, include paths, and defines.
|
|
73
|
+
|
|
74
|
+
```python
|
|
75
|
+
from delphi_lsp import ProjectIndexer, build_workspace_semantics
|
|
76
|
+
|
|
77
|
+
workspace = build_workspace_semantics({
|
|
78
|
+
"Unit1.pas": "unit Unit1; interface uses Unit2; implementation end.",
|
|
79
|
+
"Unit2.pas": "unit Unit2; interface implementation end.",
|
|
80
|
+
})
|
|
81
|
+
print(workspace.index.lookup("Unit2"))
|
|
82
|
+
|
|
83
|
+
project = ProjectIndexer(
|
|
84
|
+
search_paths=["src"], include_paths=["include"], defines=["DEBUG"]
|
|
85
|
+
).index("Main.dpr")
|
|
86
|
+
print(project.parsed_units)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Long-running discovery and indexing accept a keyword-only `on_progress`
|
|
90
|
+
callback. It receives an immutable `ProgressEvent` with package-controlled
|
|
91
|
+
phase, path, and monotonic counters; callback exceptions are not suppressed.
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
from delphi_lsp import ProjectIndexer, ProgressEvent
|
|
95
|
+
|
|
96
|
+
def report(event: ProgressEvent) -> None:
|
|
97
|
+
print(event.phase, event.files_completed, event.path)
|
|
98
|
+
|
|
99
|
+
ProjectIndexer(on_progress=report).index("Main.dpr")
|
|
100
|
+
```
|
|
101
|
+
## Integrated Rust parser
|
|
102
|
+
|
|
103
|
+
On Windows x64, the distribution includes the Rust-native parser in the same
|
|
104
|
+
wheel:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
pip install python-delphi-lsp
|
|
108
|
+
DELPHI_LSP_PARSER=python … # force the Python parser
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
The extension is an `abi3` module built with maturin and lives inside the
|
|
112
|
+
`delphi_lsp` package. There is no separate native distribution or `rust` extra.
|
|
113
|
+
Other operating systems and Windows on ARM receive the universal Python wheel;
|
|
114
|
+
the native backend is hard-disabled there and the Python parser is used.
|
|
115
|
+
Set `DELPHI_LSP_PARSER=python` to force the Python parser. Set
|
|
116
|
+
`DELPHI_LSP_PARSER=rust` to force Rust and fail immediately if the compiled
|
|
117
|
+
module is unavailable. The default `auto` selects Rust when the module loads,
|
|
118
|
+
otherwise falls back to Python.
|
|
119
|
+
|
|
120
|
+
Parity between the two parsers is tracked via
|
|
121
|
+
`scripts/parser_differential.py --stage 1..5` (see
|
|
122
|
+
[docs/rust-backend.md](docs/rust-backend.md) for details).
|
|
123
|
+
|
|
124
|
+
## Architecture metrics
|
|
125
|
+
|
|
126
|
+
The public metrics API analyzes a single unit or aggregates a complete project:
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
from delphi_lsp import analyze_project, analyze_unit
|
|
130
|
+
|
|
131
|
+
unit = analyze_unit(
|
|
132
|
+
"unit Alpha; interface implementation procedure Run; begin end; end.",
|
|
133
|
+
"Alpha.pas",
|
|
134
|
+
)
|
|
135
|
+
print(unit.lines.total_lines, unit.cyclomatic.maximum)
|
|
136
|
+
|
|
137
|
+
project = analyze_project({
|
|
138
|
+
"Main.dpr": "program Main; uses Alpha; begin end.",
|
|
139
|
+
"Alpha.pas": "unit Alpha; interface implementation end.",
|
|
140
|
+
})
|
|
141
|
+
print(project.total_loc)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Line results distinguish total, source, blank, comment-only, mixed-comment, and
|
|
145
|
+
compiler-directive lines. Project `total_loc` counts each `.dpr`, `.dpk`, and
|
|
146
|
+
`.pas` source once; `include_loc` counts unique `.inc` inputs separately, and
|
|
147
|
+
`total_loc_with_includes` combines both totals.
|
|
148
|
+
|
|
149
|
+
Cyclomatic complexity is reported per routine and as unit/project aggregates.
|
|
150
|
+
The result also includes complete Halstead counts and derived values, a
|
|
151
|
+
normalized 0–100 maintainability index, symbol counts, dependency edges,
|
|
152
|
+
afferent coupling (fan-in), efferent coupling (fan-out), instability,
|
|
153
|
+
abstractness, and distance from the main sequence. Coupling detail separates
|
|
154
|
+
internal from external dependencies. Empty or partial inputs produce finite
|
|
155
|
+
JSON values; unreadable agent-workspace inputs are reported as metric problems.
|
|
156
|
+
|
|
157
|
+
Run the stdio language server with `delphi-lsp`, or equivalently:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
python -m delphi_lsp.lsp_server
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## OpenCode LSP configuration
|
|
164
|
+
|
|
165
|
+
The root `opencode.json` starts the installed package portably:
|
|
166
|
+
|
|
167
|
+
```json
|
|
168
|
+
{
|
|
169
|
+
"lsp": {
|
|
170
|
+
"delphi": {
|
|
171
|
+
"command": ["delphi-lsp"],
|
|
172
|
+
"extensions": [".pas", ".dpr", ".dpk", ".inc"],
|
|
173
|
+
"initialization": {
|
|
174
|
+
"autoDiscoverPaths": true,
|
|
175
|
+
"semanticCacheSize": 512
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
`autoDiscoverPaths` is the default. It discovers compiler context without an
|
|
183
|
+
environment section; LSP remains available for normal editor and OpenCode use,
|
|
184
|
+
including large sources.
|
|
185
|
+
|
|
186
|
+
`semanticCacheSize` limits retained per-file outline models while keeping
|
|
187
|
+
source text available. Its default is 512; set it to zero to disable retained
|
|
188
|
+
snapshot models. The value is preserved when workspace folders change.
|
|
189
|
+
|
|
190
|
+
The LSP builds its structural index through the same optimized outline path for
|
|
191
|
+
every source, with no file-size threshold. Definition, hover, references,
|
|
192
|
+
rename, completion, document symbols, workspace symbols, and diagnostics remain
|
|
193
|
+
registered for every file size; source-aware fallbacks keep body-level queries
|
|
194
|
+
available without returning the complete file as agent context.
|
|
195
|
+
|
|
196
|
+
### Automatic discovery
|
|
197
|
+
|
|
198
|
+
Auto-discovery reads `.dpr`, `.dpk`, `.dproj`, `.cfg`, and `.dof` files.
|
|
199
|
+
Its resolution order is:
|
|
200
|
+
|
|
201
|
+
1. An explicit `.dproj`, `.dpr`, or `.dpk` selection takes precedence. An
|
|
202
|
+
explicit `.dproj` resolves its `MainSource`.
|
|
203
|
+
2. Otherwise, `.dpr` and `.dpk` candidates are considered.
|
|
204
|
+
3. `MainSource` in a `.dproj` contributes its entry project.
|
|
205
|
+
4. A selected entry associates same-stem `.dproj`, `.cfg`, and `.dof`.
|
|
206
|
+
5. Unit search paths, include paths, and defines are accumulated from explicit
|
|
207
|
+
settings, project metadata, and the associated settings files.
|
|
208
|
+
6. Direct `Unit in 'path/Unit.pas'` references contribute their parent
|
|
209
|
+
directory to unit search paths.
|
|
210
|
+
|
|
211
|
+
A single discovered project is selected automatically. With multiple project
|
|
212
|
+
entries, a synthetic repository workspace containing every supported source is
|
|
213
|
+
selected automatically while the concrete projects remain available. With no
|
|
214
|
+
project entry, the same workspace model is used. Scans skip build and cache
|
|
215
|
+
directories such as `build`, `dist`, environments, VCS folders, `node_modules`,
|
|
216
|
+
and tool caches. Missing paths and invalid metadata become problems; paths are
|
|
217
|
+
not guessed.
|
|
218
|
+
|
|
219
|
+
## Agent CLI and Interface/Protocol v3
|
|
220
|
+
|
|
221
|
+
`delphi-lsp-agent` has these subcommands and options:
|
|
222
|
+
|
|
223
|
+
```text
|
|
224
|
+
delphi-lsp-agent cache start --root PATH [--project-file FILE] [--max-memory 512M]
|
|
225
|
+
[--max-disk-cache 512M]
|
|
226
|
+
[--workers auto|N] [--startup-timeout 120]
|
|
227
|
+
[--idle-timeout 1800]
|
|
228
|
+
delphi-lsp-agent cache status --root PATH [--format text|json]
|
|
229
|
+
delphi-lsp-agent cache stop --root PATH
|
|
230
|
+
delphi-lsp-agent cache clear --root PATH
|
|
231
|
+
delphi-lsp-agent view --root PATH [--project-file FILE] --layer LAYER
|
|
232
|
+
[--query TEXT] [--format markdown|json] [--deep-projects]
|
|
233
|
+
[--workers auto|N]
|
|
234
|
+
delphi-lsp-agent index --root PATH [--project-file FILE] [--out FILE]
|
|
235
|
+
[--workers auto|N] [--deep-projects]
|
|
236
|
+
delphi-lsp-agent wiki export --root PATH [--project-file FILE] [--out DIRECTORY]
|
|
237
|
+
[--workers auto|N] [--force] [--quiet]
|
|
238
|
+
delphi-lsp-agent query --root PATH ACTION [VALUE]
|
|
239
|
+
[--project-id ID] [--detail summary|declaration|members|context|body|implementations]
|
|
240
|
+
[--relation references|callers|callees|uses|used_by|inherits|implements]
|
|
241
|
+
[--graph ast|cfg|dfg|call|full] [--direction out|in|both]
|
|
242
|
+
[--depth 1..16]
|
|
243
|
+
[--cursor TEXT] [--max-items INT] [--max-chars INT]
|
|
244
|
+
delphi-lsp-agent skill install [--target PATH] [--force]
|
|
245
|
+
delphi-lsp-agent opencode install [--target PATH] [--python PYTHON]
|
|
246
|
+
[--force] [--write-agent|--write-config]
|
|
247
|
+
delphi-lsp-agent worker --root PATH [--project-file FILE] [--workers auto|N]
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
`--deep-projects` opts into per-project dependency parsing for the `projects`
|
|
251
|
+
and `problems` layers. It is off by default because it dominates run time on
|
|
252
|
+
real repositories:
|
|
253
|
+
on a 60-project corpus it cost 36.9 s against 1.0 s for the same index, and it
|
|
254
|
+
adds nothing to the unit model set. Without it the `projects` and `problems`
|
|
255
|
+
layers report `deep_indexed: false`, and `index` records `deep_projects` at the
|
|
256
|
+
top level of its JSON, so a shallow index is never mistaken for a complete one.
|
|
257
|
+
|
|
258
|
+
The `cache` commands manage one daemon per canonical root. Use these:
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
delphi-lsp-agent cache start --root PATH
|
|
262
|
+
delphi-lsp-agent cache status --root PATH
|
|
263
|
+
delphi-lsp-agent cache stop --root PATH
|
|
264
|
+
delphi-lsp-agent cache clear --root PATH
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
`cache start` outputs cache lifecycle JSON; runtime warnings are still on stderr.
|
|
268
|
+
`cache status --format json` outputs status JSON to stdout and the same warning stream on stderr.
|
|
269
|
+
`cache stop` outputs stop status JSON and may include warnings on stderr.
|
|
270
|
+
`cache clear` stops the daemon and removes persistent navigation shards.
|
|
271
|
+
`query` outputs Protocol v3 JSON responses and writes warnings to stderr.
|
|
272
|
+
For `index`, a relative `--out` is resolved below `--root`; the default is
|
|
273
|
+
`.delphi-lsp/agent-index/index.json`.
|
|
274
|
+
|
|
275
|
+
### Open Knowledge Format wiki export
|
|
276
|
+
|
|
277
|
+
Export the complete unique knowledge represented by the layered codebase views
|
|
278
|
+
as a portable Markdown wiki:
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
delphi-lsp-agent wiki export --root PATH --out codebase-wiki
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
When `--out` is relative, it is resolved below `--root`; the default is
|
|
285
|
+
`.delphi-lsp/wiki`. The command builds the semantic index once, deep-indexes
|
|
286
|
+
main projects, calculates workspace and unit metrics, and writes:
|
|
287
|
+
|
|
288
|
+
- an OKF 0.2 root `index.md`;
|
|
289
|
+
- linked project, unit, and symbol concepts;
|
|
290
|
+
- declaration and implementation source fragments;
|
|
291
|
+
- resolved and unresolved semantic references;
|
|
292
|
+
- discovery/project problems and complete metric records;
|
|
293
|
+
- Protocol v3, relation, CPG, cache, and layer-mapping reference concepts.
|
|
294
|
+
|
|
295
|
+
Without `--project-file`, the exporter selects repository main projects:
|
|
296
|
+
non-example project entries in the repository root, or, when none exist, the
|
|
297
|
+
shallowest configured `.dproj` entries. Recursively discovered example,
|
|
298
|
+
sample, test, benchmark, and vendor projects are not promoted to project
|
|
299
|
+
pages. A repository `.delphi-lsp.toml` can replace this heuristic with the
|
|
300
|
+
explicit monorepo selection described below. With `--project-file`, only that
|
|
301
|
+
explicit entry is selected. Project
|
|
302
|
+
dependency traversal and include loading are confined to the repository root,
|
|
303
|
+
so Delphi SDK and other external standard units are recorded as unresolved
|
|
304
|
+
dependencies instead of being parsed. If no main project can be identified,
|
|
305
|
+
the exporter falls back to the repository source inventory without inventing
|
|
306
|
+
project pages.
|
|
307
|
+
|
|
308
|
+
Every non-index concept is UTF-8 Markdown with YAML frontmatter and a non-empty
|
|
309
|
+
`type`. Readable filenames include a stable digest, so overloads and equal names
|
|
310
|
+
from different units remain distinct even on case-insensitive filesystems.
|
|
311
|
+
Output order and content are deterministic. The finished bundle replaces the
|
|
312
|
+
destination only after generation succeeds; an existing non-empty destination
|
|
313
|
+
requires `--force`, and unsafe root/ancestor/symlink targets are rejected.
|
|
314
|
+
|
|
315
|
+
Pages are streamed to disk, decoded source retention is bounded, and metrics
|
|
316
|
+
process source paths without materializing the entire source corpus. Lazy CPG
|
|
317
|
+
subgraphs are documented rather than eagerly multiplied across all possible
|
|
318
|
+
targets; a focused live `cpg` query remains the bounded way to obtain one graph.
|
|
319
|
+
The bundle structure follows the
|
|
320
|
+
[Open Knowledge Format 0.2 specification](https://github.com/GoogleCloudPlatform/knowledge-catalog/blob/main/okf/SPEC.md).
|
|
321
|
+
|
|
322
|
+
Progress is shown on `stderr` while the final machine-readable JSON summary
|
|
323
|
+
remains the only record on `stdout`. Redirected progress is throttled to
|
|
324
|
+
milestones; pass `--quiet` to suppress it completely.
|
|
325
|
+
|
|
326
|
+
```bash
|
|
327
|
+
delphi-lsp-agent query --root PATH find TCustomer
|
|
328
|
+
delphi-lsp-agent query --root PATH focus TARGET_ID
|
|
329
|
+
delphi-lsp-agent query --root PATH inspect
|
|
330
|
+
delphi-lsp-agent query --root PATH trace TARGET_ID --relation callers
|
|
331
|
+
delphi-lsp-agent query --root PATH cpg TARGET_ID --graph full --direction out --depth 4
|
|
332
|
+
delphi-lsp-agent query --root PATH metrics
|
|
333
|
+
delphi-lsp-agent query --root PATH metrics UNIT_QUERY
|
|
334
|
+
delphi-lsp-agent query --root PATH metrics --target-id UNIT_TARGET_ID
|
|
335
|
+
delphi-lsp-agent cache status --root PATH --format json
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
A `target_v2_...` positional value for `metrics` is also recognized as a unit
|
|
339
|
+
target ID; other positional values remain case-insensitive unit-name or path
|
|
340
|
+
queries.
|
|
341
|
+
|
|
342
|
+
The repository root is sufficient even when it contains many projects:
|
|
343
|
+
|
|
344
|
+
```bash
|
|
345
|
+
delphi-lsp-agent cache start --root PATH
|
|
346
|
+
delphi-lsp-agent query --root PATH find TCustomer
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
This prewarms one bounded repository navigation index and requires no project
|
|
350
|
+
selection. A `.dproj` is optional. For repeatable monorepo selection, add a
|
|
351
|
+
`.delphi-lsp.toml` file as described below. Pass one project explicitly when
|
|
352
|
+
its project-specific compiler
|
|
353
|
+
settings and `MainSource` should define the index:
|
|
354
|
+
|
|
355
|
+
```bash
|
|
356
|
+
delphi-lsp-agent cache start --root PATH --project-file relative/path/Main.dproj
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
An explicit `.dpr` or `.dpk` remains supported. To switch an already running
|
|
360
|
+
repository cache to one of its concrete project views, list the projects and
|
|
361
|
+
focus one by its returned `project_id`:
|
|
362
|
+
|
|
363
|
+
```bash
|
|
364
|
+
delphi-lsp-agent query --root PATH open
|
|
365
|
+
delphi-lsp-agent query --root PATH focus --project-id PROJECT_ID
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
Selecting a project this way also prewarms its navigation cache.
|
|
369
|
+
|
|
370
|
+
### TOML project selection for monorepos
|
|
371
|
+
|
|
372
|
+
Place `.delphi-lsp.toml` in the repository root to define which `.dpr`,
|
|
373
|
+
`.dpk`, or companion `.dproj` projects belong to the codebase:
|
|
374
|
+
|
|
375
|
+
```toml
|
|
376
|
+
[projects]
|
|
377
|
+
include = [
|
|
378
|
+
"apps/**",
|
|
379
|
+
"services/Api/ApiServer.dproj",
|
|
380
|
+
"packages/*/Runtime.dpk",
|
|
381
|
+
]
|
|
382
|
+
exclude = [
|
|
383
|
+
"**/examples/**",
|
|
384
|
+
"**/tests/**",
|
|
385
|
+
]
|
|
386
|
+
|
|
387
|
+
[workspace]
|
|
388
|
+
exclude = [
|
|
389
|
+
"vendor",
|
|
390
|
+
"generated/**",
|
|
391
|
+
"thirdparty/legacy",
|
|
392
|
+
]
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
Paths are relative to the repository root, case-insensitive, and use `/` on
|
|
396
|
+
every operating system. An exact directory name covers all descendants. `*`
|
|
397
|
+
matches within one path segment, while `**` crosses directory boundaries.
|
|
398
|
+
Absolute paths and `..` traversal are rejected.
|
|
399
|
+
|
|
400
|
+
When `include` is non-empty, only matching project entries remain. Matching a
|
|
401
|
+
`.dproj` selects the `.dpr` or `.dpk` from its `MainSource`. The `exclude`
|
|
402
|
+
list is applied afterward, so `exclude` always wins. With active TOML filters,
|
|
403
|
+
all remaining matches are main projects even when they occur at different
|
|
404
|
+
directory depths; the built-in shallow-project and example-name heuristic is
|
|
405
|
+
not applied.
|
|
406
|
+
|
|
407
|
+
Use `projects.exclude` when a directory may still contain shared units but its
|
|
408
|
+
project entries must not become selectable projects. Use `workspace.exclude`
|
|
409
|
+
for a hard boundary. Matching directories are never traversed or parsed, and
|
|
410
|
+
neither is any file below them. They cannot be reintroduced by
|
|
411
|
+
`projects.include` or an explicit `--project-file`. Unit dependencies and
|
|
412
|
+
include directives resolving into those directories are reported as
|
|
413
|
+
unavailable without reading the files.
|
|
414
|
+
For complete directory pruning, an exact entry such as `"vendor"` is enough;
|
|
415
|
+
`"generated/**"` also excludes the `generated` directory itself.
|
|
416
|
+
|
|
417
|
+
The same selection is used by `cache`, `worker`, `query`, `view`, `index`,
|
|
418
|
+
wiki export, and language-server discovery. An explicit `--project-file`
|
|
419
|
+
bypasses `projects.include` and `projects.exclude` for that invocation, but
|
|
420
|
+
never bypasses `workspace.exclude`. If no project remains, the command reports
|
|
421
|
+
that the configured filters matched no Delphi projects and stops instead of
|
|
422
|
+
silently parsing every source file in the repository. Restart an already
|
|
423
|
+
running cache daemon after changing the path configuration.
|
|
424
|
+
|
|
425
|
+
`inspect` uses the currently focused target, so call `focus TARGET_ID` before
|
|
426
|
+
`inspect` unless a previous request already selected it.
|
|
427
|
+
|
|
428
|
+
The cache daemon prewarms the navigation cache at startup so first `find` requests are
|
|
429
|
+
fast. The cache retained-cache budget is `512 MiB` by default and tracks retained
|
|
430
|
+
cache usage only, not a hard RSS/parse peak. Warnings are emitted on stderr at or
|
|
431
|
+
above 80 percent.
|
|
432
|
+
|
|
433
|
+
Cold builds parse independent source units in short-lived processes created with
|
|
434
|
+
the cross-platform `spawn` method. `--workers auto|N` defaults to `auto`.
|
|
435
|
+
Automatic selection uses at most eight worker processes, leaves one detected CPU
|
|
436
|
+
free, never exceeds the source task count, and—for the cache daemon—allows one
|
|
437
|
+
worker per `64 MiB` of retained-cache budget. `view` and `index` use the same
|
|
438
|
+
task, CPU, and eight-worker caps without the cache-budget term. An explicit value
|
|
439
|
+
from 1 through 32 overrides the automatic CPU and memory caps but is still
|
|
440
|
+
limited by the number of tasks.
|
|
441
|
+
|
|
442
|
+
Standalone `view` and `index` commands cache their exact completed response
|
|
443
|
+
bytes under `.delphi-lsp/response-cache`. A strong content revision covers the
|
|
444
|
+
selected source, include, project, and configuration files, so any relevant
|
|
445
|
+
content change produces a miss. Records are content-addressed, owner-only,
|
|
446
|
+
atomically replaced, size-bounded, and never use pickle. Batch commands bypass
|
|
447
|
+
the older per-unit artifact shards; an unchanged request can therefore return
|
|
448
|
+
the validated response without rebuilding semantic models. To reproduce the
|
|
449
|
+
large-corpus cold/warm gate, run:
|
|
450
|
+
|
|
451
|
+
```bash
|
|
452
|
+
python scripts/benchmark_response_cache.py \
|
|
453
|
+
--fpc-root /path/to/fpc-corpus \
|
|
454
|
+
--delphi-root /path/to/delphi-corpus
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
Worker processes build compact, detached navigation shards and exit before
|
|
458
|
+
retained-cache accounting. Full semantic object graphs and source text are not
|
|
459
|
+
retained in the parent. Tokenized source documents are loaded only for source
|
|
460
|
+
evidence requests such as `inspect`, and a byte-bounded LRU evicts older
|
|
461
|
+
documents. The transient worker memory remains separate from retained navigation
|
|
462
|
+
structures and the existing 80-percent warning. Retained bytes are maintained
|
|
463
|
+
incrementally; requests never traverse the complete cache object graph merely
|
|
464
|
+
to measure it. If an automatic pool fails before accepting a result, one
|
|
465
|
+
automatic serial fallback is attempted; explicit worker counts fail instead of
|
|
466
|
+
silently changing the requested configuration.
|
|
467
|
+
|
|
468
|
+
Detached navigation shards are also stored as versioned, content-addressed JSON
|
|
469
|
+
under `.delphi-lsp/agent-cache/navigation-v1`. A restarted CLI or OpenCode cache
|
|
470
|
+
daemon reuses unchanged units without parsing them again. Source content,
|
|
471
|
+
conditional defines, or a shard-schema change produces a cache miss; malformed
|
|
472
|
+
or incompatible JSON is ignored and rebuilt. The disk cache contains no pickle
|
|
473
|
+
payloads and does not count against the retained-RAM budget. Each completed
|
|
474
|
+
navigation build removes superseded shards and enforces the
|
|
475
|
+
`--max-disk-cache` byte budget, which defaults to 512 MiB.
|
|
476
|
+
|
|
477
|
+
Cache prewarming builds the navigation registry directly without constructing
|
|
478
|
+
an empty-query result, symbol cards, pagination, or JSON payloads. Up to sixteen
|
|
479
|
+
recent ranked queries are retained in a small LRU so alternating CLI and
|
|
480
|
+
OpenCode searches remain warm.
|
|
481
|
+
|
|
482
|
+
`cache start` waits up to `--startup-timeout 120` seconds for the child process
|
|
483
|
+
to bind and publish readiness metadata, not for the large workspace to finish
|
|
484
|
+
prewarming. Workspace discovery and prewarming continue in the daemon while
|
|
485
|
+
status reports `warming`. If bootstrap fails, the CLI reports whether it timed
|
|
486
|
+
out or exited, the exit code, Python executable, workspace, and a sanitized
|
|
487
|
+
tail of child stderr. Starting a live root with a different worker
|
|
488
|
+
configuration reports a configuration conflict.
|
|
489
|
+
|
|
490
|
+
Eviction is ordered: auxiliary caches are evicted first, navigation caches second.
|
|
491
|
+
If compaction removes navigable data, the daemon rebuilds the navigation state on demand
|
|
492
|
+
while preserving focus state for the next request.
|
|
493
|
+
|
|
494
|
+
The daemon tracks a 30-minute idle timeout; idle state shows in JSON status (`cache status`).
|
|
495
|
+
`source revision` changes on source edits and invalidate reused request caches.
|
|
496
|
+
Workspace state appears in status as `requests`, `warm_hits`, `rebuilds`, `invalidations`,
|
|
497
|
+
`evictions`, and `cache_state`. Parallel prewarm status adds
|
|
498
|
+
`workers_configured`, `workers_effective`, `parallel_files_completed`,
|
|
499
|
+
`prewarm_seconds`, `parallel_seconds`, `parallel_fallbacks`,
|
|
500
|
+
`navigation_disk_hits`, and `navigation_disk_misses`.
|
|
501
|
+
|
|
502
|
+
Metadata is stored in `.delphi-lsp/agent-cache/daemon.json` with owner-only token and
|
|
503
|
+
permissions (`daemon.json` mode 600 and parent 700). Do not copy or share this token
|
|
504
|
+
outside the root workspace.
|
|
505
|
+
|
|
506
|
+
`view --layer` accepts `overview`, `projects`, `units`, `unit`,
|
|
507
|
+
`symbols`, `symbol`, `implementation`, `references`, `problems`, and
|
|
508
|
+
`metrics`. For example, `delphi-lsp-agent view --layer metrics --format json`
|
|
509
|
+
returns a project summary and detailed unit metric objects; `--query` filters
|
|
510
|
+
units by name or path.
|
|
511
|
+
`index` materializes overview, projects, and problems JSON. `wiki export`
|
|
512
|
+
materializes the same navigational knowledge as a linked OKF Markdown bundle. `skill install`
|
|
513
|
+
writes the skill; `opencode install` writes the package-named skill, Markdown
|
|
514
|
+
agent, and plugin. The two deprecated write flags are harmless aliases and do
|
|
515
|
+
not change user configuration.
|
|
516
|
+
`worker` serves NDJSON over standard input/output.
|
|
517
|
+
|
|
518
|
+
Protocol v3 actions are `open`, `find`, `inspect`, `trace`, `focus`,
|
|
519
|
+
`problems`, `metrics`, and `cpg`. A `metrics` request without a query returns the
|
|
520
|
+
project summary followed by unit cards. A query filters units, while a unit
|
|
521
|
+
`target_id` from `open` selects one unit; `detail: "members"` adds routine,
|
|
522
|
+
Halstead, dependency, and symbol-count detail without returning source text.
|
|
523
|
+
Detail values are `summary`, `declaration`, `members`,
|
|
524
|
+
`context`, `body`, and `implementations`. Relations are `references`,
|
|
525
|
+
`callers`, `callees`, `uses`, `used_by`, `inherits`, and
|
|
526
|
+
`implements`.
|
|
527
|
+
|
|
528
|
+
A request requires `action` and can include `query`, `target_id`,
|
|
529
|
+
`project_id`, `detail`, `relation`, `graph`, `direction`, `depth`, `cursor`,
|
|
530
|
+
`max_items`, and `max_chars`. Defaults are empty text fields,
|
|
531
|
+
`detail: "summary"`, no relation, `graph: "full"`, `direction: "out"`,
|
|
532
|
+
`depth: 4`, `max_items: 12`, and `max_chars: 12000`. Depth is 1–16;
|
|
533
|
+
response ranges are 1–50 items and 256–40000 characters. A successful envelope
|
|
534
|
+
has `schema: 3`,
|
|
535
|
+
`workspace_revision`, `focus` (project, unit, and target IDs), `result`,
|
|
536
|
+
`page`, and `context`; errors have `schema: 3` and a code/message. Existing
|
|
537
|
+
target IDs remain unchanged across the protocol upgrade.
|
|
538
|
+
|
|
539
|
+
Focus preserves the selected project, unit, or target. Cursors bind a workspace
|
|
540
|
+
revision and request fingerprint, so source changes and cross-target or
|
|
541
|
+
cross-detail reuse invalidate them. `max_items` and `max_chars` bound each
|
|
542
|
+
response. A `sound_partial` relation is sound but incomplete: unresolved and
|
|
543
|
+
ambiguous relations are never fabricated. Unsupported relations are rejected.
|
|
544
|
+
|
|
545
|
+
### Lazy code property graph
|
|
546
|
+
|
|
547
|
+
The `cpg` action translates one selected unit, type, or routine into a bounded
|
|
548
|
+
code property graph. Graph selectors are `ast`, `cfg`, `dfg`, `call`, and `full`;
|
|
549
|
+
`direction` accepts `out`, `in`, or `both`, and `depth` limits traversal
|
|
550
|
+
from the selected target. Together, `graph`, `direction`, and `depth` select
|
|
551
|
+
the returned subgraph. Results contain stable CPG node and edge IDs,
|
|
552
|
+
location and symbol properties, graph metadata, and explicit problems.
|
|
553
|
+
|
|
554
|
+
AST edges preserve syntax containment. CFG edges include routine entry/exit,
|
|
555
|
+
sequence, conditional branches, loop back-edges, and conservative structured
|
|
556
|
+
control flow. Local DFG edges distinguish definitions, uses, and reaching
|
|
557
|
+
definitions. CALL edges are emitted only for a uniquely resolved explicit
|
|
558
|
+
callee. Ambiguous or unsupported semantics increase the unresolved count and
|
|
559
|
+
are reported as `sound_partial`; the navigator does not fabricate certainty.
|
|
560
|
+
|
|
561
|
+
CPG construction is lazy: navigation prewarming creates no graph. The first
|
|
562
|
+
request parses only the selected source, and identical requests reuse an
|
|
563
|
+
in-memory LRU keyed by workspace revision, target, `graph`, `direction`, and
|
|
564
|
+
`depth`. The CPG LRU receives 20 percent of the configured retained-cache
|
|
565
|
+
budget, capped at 128 MiB. Source text and full parser trees are not retained
|
|
566
|
+
inside graph records, and normal navigation keeps its existing cache path.
|
|
567
|
+
|
|
568
|
+
The release gate used the pinned 8,549-file FPC corpus with 4,021,192 physical
|
|
569
|
+
lines on an Apple-silicon Mac with Python 3.14 and eight workers. Navigation
|
|
570
|
+
prewarming took 22.62 seconds. The first focused CPG query took 0.0166 seconds;
|
|
571
|
+
the cached query took 0.000069 seconds and retained 4,007 bytes. Exactly one
|
|
572
|
+
source was parsed for CPG. Legacy navigation retained 98.43 percent of its
|
|
573
|
+
in-run control throughput, above the 95-percent release floor. Reproduce it
|
|
574
|
+
with `python scripts/benchmark_cpg.py --root CORPUS --query Run --workers 8`.
|
|
575
|
+
|
|
576
|
+
Separate reproducible performance profiles cover the coherent FPC compiler
|
|
577
|
+
tree and a project-file-dense Delphi corpus. The Delphi profile can add a
|
|
578
|
+
deterministic `__history`/recovery/build/search-path overlay without changing
|
|
579
|
+
the pinned base corpus. See [the FPC benchmark](docs/performance-fpc.md) and
|
|
580
|
+
[the Delphi discovery benchmark](docs/performance-delphi.md).
|
|
581
|
+
|
|
582
|
+
For every source size the navigator builds an outline first, loads source detail
|
|
583
|
+
lazily for a selected target, and returns only selected fragments. Typed source
|
|
584
|
+
chunks are at most 6000 characters and also respect the response budget. This
|
|
585
|
+
optimization does not remove LSP functionality.
|
|
586
|
+
|
|
587
|
+
## OpenCode semantic navigator
|
|
588
|
+
|
|
589
|
+
Install the generated integration in a worktree:
|
|
590
|
+
|
|
591
|
+
```bash
|
|
592
|
+
delphi-lsp-agent opencode install --target .
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
It writes:
|
|
596
|
+
|
|
597
|
+
```text
|
|
598
|
+
.agents/skills/python-delphi-lsp/SKILL.md
|
|
599
|
+
.opencode/plugins/delphi_codebase.ts
|
|
600
|
+
.opencode/agents/python-delphi-lsp.md
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
The package-named Markdown agent enables only the
|
|
604
|
+
`python-delphi-lsp` skill and `delphi_codebase`. It denies
|
|
605
|
+
`bash`, `read`, `glob`, `grep`, and `lsp`, along with edit/write and
|
|
606
|
+
other raw source tools. The skill is enabled. The installer does not use the
|
|
607
|
+
retired `.opencode/tools` path and never reads or changes `opencode.json`; that
|
|
608
|
+
file remains entirely user-owned. The deprecated `--write-config` and
|
|
609
|
+
`--write-agent` options are accepted harmlessly for compatibility.
|
|
610
|
+
|
|
611
|
+
The plugin maintains one worker per session/root, reusing focus, indexes, and
|
|
612
|
+
lazy CPG subgraphs.
|
|
613
|
+
During compaction it restores the focus and summary into the new context.
|
|
614
|
+
Transport failure, session deletion, and plugin disposal clean up the worker.
|
|
615
|
+
|
|
616
|
+
OpenCode history: 1.1.0 and 1.1.1 used a spawned view per call model.
|
|
617
|
+
Persistent session/root worker support first shipped in 2.0.0.
|
|
618
|
+
This is the same persistent session/root worker boundary.
|
|
619
|
+
The OpenCode worker stays separate from CLI daemon. Protocol v3 adds CPG
|
|
620
|
+
arguments without changing the persistent session/root boundary.
|
|
621
|
+
|
|
622
|
+
A generated OpenCode agent starts with this Markdown frontmatter:
|
|
623
|
+
|
|
624
|
+
```markdown
|
|
625
|
+
---
|
|
626
|
+
description: Inspect Delphi and Object Pascal codebases through python-delphi-lsp.
|
|
627
|
+
mode: all
|
|
628
|
+
temperature: 0
|
|
629
|
+
permission:
|
|
630
|
+
delphi_codebase: allow
|
|
631
|
+
skill:
|
|
632
|
+
"*": deny
|
|
633
|
+
python-delphi-lsp: allow
|
|
634
|
+
lsp: deny
|
|
635
|
+
bash: deny
|
|
636
|
+
read: deny
|
|
637
|
+
glob: deny
|
|
638
|
+
grep: deny
|
|
639
|
+
list: deny
|
|
640
|
+
edit: deny
|
|
641
|
+
write: deny
|
|
642
|
+
patch: deny
|
|
643
|
+
task: deny
|
|
644
|
+
webfetch: deny
|
|
645
|
+
websearch: deny
|
|
646
|
+
question: deny
|
|
647
|
+
todowrite: deny
|
|
648
|
+
todoread: deny
|
|
649
|
+
codebase_map: deny
|
|
650
|
+
code_guidelines: deny
|
|
651
|
+
---
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
Select `python-delphi-lsp`, ask it to load the `python-delphi-lsp` skill, then
|
|
655
|
+
use `delphi_codebase` actions such as
|
|
656
|
+
`open`, `find`, `focus`, `inspect`, and `cpg`. Use semantic tool calls, not raw
|
|
657
|
+
source tools.
|
|
658
|
+
|
|
659
|
+
For architecture questions, call `metrics` without a query to compare unit
|
|
660
|
+
cards and read project LOC. Then select a returned unit ID with another
|
|
661
|
+
`metrics` call and `detail: "members"` to inspect its routines and coupling.
|
|
662
|
+
|
|
663
|
+
For the root LSP configuration, a local model can be used as follows:
|
|
664
|
+
|
|
665
|
+
```bash
|
|
666
|
+
opencode run --dir . --model ollama/ornith-lspctx --agent vllm-lsp \
|
|
667
|
+
"Find the declaration of a Delphi symbol through LSP."
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
Use `--agent vllm-lsp-edit` only for the separate, focused LSP/edit
|
|
671
|
+
verification workflow; the semantic navigator agent above remains restricted
|
|
672
|
+
to its named skill and tool.
|
|
673
|
+
|
|
674
|
+
That separate verification uses `vllm/ornith-lspctx` and accepts the focused
|
|
675
|
+
LSP result `edit:Edit applied successfully`; it is not the semantic navigator
|
|
676
|
+
workflow and does not grant the navigator any raw source tools.
|
|
677
|
+
|
|
678
|
+
## Reproducible large-project vLLM proof
|
|
679
|
+
|
|
680
|
+
The proof generates a 117,511-line project. The verifier requires `skill`, `open` (`Main.dpr` evidence), `find`, `focus`, and `inspect`,
|
|
681
|
+
checks `MegaProc02500` and `Value := Value + 40`, and forbids raw `bash`,
|
|
682
|
+
`read`, `glob`, and `grep`. It then waits for the final answer and requires the
|
|
683
|
+
exact body range `src/Mega100kUnit.pas:117464-117509` and the inspected
|
|
684
|
+
statement in that answer. The prompt requires returned range metadata instead
|
|
685
|
+
of a model-calculated line inside the source fragment.
|
|
686
|
+
The proof uses the local Ornith vLLM OpenAI-compatible
|
|
687
|
+
endpoint at `http://127.0.0.1:8001/v1`.
|
|
688
|
+
|
|
689
|
+
Default scripts are offline and must not redownload the model. First check the
|
|
690
|
+
cache:
|
|
691
|
+
|
|
692
|
+
```bash
|
|
693
|
+
python scripts/check_ornith_cache.py --require-complete
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
With an already-running endpoint on any supported platform, run:
|
|
697
|
+
|
|
698
|
+
```bash
|
|
699
|
+
python scripts/bootstrap_vllm_codebase_skill_test.py --use-running-server
|
|
700
|
+
```
|
|
701
|
+
|
|
702
|
+
On macOS, the offline cached auto-start path is:
|
|
703
|
+
|
|
704
|
+
```bash
|
|
705
|
+
python scripts/bootstrap_vllm_codebase_skill_test.py --start-vllm
|
|
706
|
+
```
|
|
707
|
+
|
|
708
|
+
Automatic local vLLM startup is macOS-only. The package and OpenCode plugin are
|
|
709
|
+
supported on Windows. On Windows, start an OpenAI-compatible vLLM endpoint, then
|
|
710
|
+
run the Python bootstrap from PowerShell:
|
|
711
|
+
|
|
712
|
+
```powershell
|
|
713
|
+
python .\scripts\bootstrap_vllm_codebase_skill_test.py --use-running-server
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
For an endpoint at another URL, add `--base-url`:
|
|
717
|
+
|
|
718
|
+
```powershell
|
|
719
|
+
python .\scripts\bootstrap_vllm_codebase_skill_test.py --use-running-server --base-url http://127.0.0.1:9000/v1
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
`--skip-install` is an optional acceleration for an already prepared `.venv`;
|
|
723
|
+
omit it on a clean checkout so the bootstrap installs `.[dev]`.
|
|
724
|
+
The final-answer verifier defaults to a 420-second probe timeout. On a slower
|
|
725
|
+
local model server, increase it explicitly with `--probe-timeout SECONDS`.
|
|
726
|
+
|
|
727
|
+
The bundled automatic helper is not a cross-platform startup mechanism.
|
|
728
|
+
|
|
729
|
+
The architecture-metrics proof uses a separate deterministic 34-LOC project.
|
|
730
|
+
It requires the restricted model to load the skill, call `metrics` for the
|
|
731
|
+
project and most-complex unit, and report exact LOC, cyclomatic maximum, and
|
|
732
|
+
instability values. Raw source, search, shell, and write tools remain forbidden:
|
|
733
|
+
|
|
734
|
+
```bash
|
|
735
|
+
python scripts/bootstrap_vllm_codebase_skill_test.py --probe metrics --use-running-server
|
|
736
|
+
```
|
|
737
|
+
|
|
738
|
+
Use `--probe metrics --start-vllm --max-model-len 24576` for the cached macOS
|
|
739
|
+
auto-start path when no endpoint is already running.
|
|
740
|
+
|
|
741
|
+
## Migration to 2.0
|
|
742
|
+
|
|
743
|
+
`delphi_lsp` is the only supported import namespace. Update imports directly;
|
|
744
|
+
there is no compatibility import alias.
|
|
745
|
+
|
|
746
|
+
## Verification and limitations
|
|
747
|
+
|
|
748
|
+
For a checkout:
|
|
749
|
+
|
|
750
|
+
```bash
|
|
751
|
+
python -m pip install -e ".[dev]"
|
|
752
|
+
python -m pytest
|
|
753
|
+
python -m build
|
|
754
|
+
python -m twine check dist/*
|
|
755
|
+
```
|
|
756
|
+
|
|
757
|
+
CI tests Ubuntu, macOS, and Windows on Python 3.10 and 3.14, then builds and
|
|
758
|
+
smoke-installs the wheel on Ubuntu/Python 3.14. Results depend on available
|
|
759
|
+
project files, defines, includes, and paths; unsupported compiler behavior and
|
|
760
|
+
unresolvable references are reported as problems. The vLLM proof additionally
|
|
761
|
+
requires OpenCode, a local endpoint, and a complete local cache.
|
|
762
|
+
|
|
763
|
+
## License
|
|
764
|
+
|
|
765
|
+
Mozilla Public License 2.0. See [LICENSE](LICENSE).
|
|
766
|
+
|