python-delphi-lsp 2.0.1__tar.gz → 2.0.2__tar.gz
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.
- {python_delphi_lsp-2.0.1/python_delphi_lsp.egg-info → python_delphi_lsp-2.0.2}/PKG-INFO +30 -31
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/README.md +29 -30
- python_delphi_lsp-2.0.2/delphi_lsp/_version.py +1 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/delphi_lsp/agent_cli.py +12 -5
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/delphi_lsp/agent_templates.py +89 -64
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/pyproject.toml +1 -1
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2/python_delphi_lsp.egg-info}/PKG-INFO +30 -31
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/scripts/bootstrap_vllm_codebase_skill_test.py +5 -6
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/test_agent_codebase.py +152 -61
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/test_bootstrap_vllm_codebase_skill.py +7 -16
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/test_opencode_probe.py +1 -1
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/test_package_metadata.py +5 -4
- python_delphi_lsp-2.0.1/delphi_lsp/_version.py +0 -1
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/LICENSE +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/MANIFEST.in +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/delphi_lsp/__init__.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/delphi_lsp/agent_context.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/delphi_lsp/agent_layers.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/delphi_lsp/agent_metrics.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/delphi_lsp/agent_protocol.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/delphi_lsp/agent_relations.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/delphi_lsp/agent_workspace.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/delphi_lsp/binary.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/delphi_lsp/comment_builder.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/delphi_lsp/consts.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/delphi_lsp/grammar.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/delphi_lsp/lark_builder.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/delphi_lsp/lark_tokens.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/delphi_lsp/lsp_server.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/delphi_lsp/metrics.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/delphi_lsp/nodes.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/delphi_lsp/parser.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/delphi_lsp/preprocessor.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/delphi_lsp/project_discovery.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/delphi_lsp/project_indexer.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/delphi_lsp/semantic.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/delphi_lsp/semantic_builder.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/delphi_lsp/source_reader.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/delphi_lsp/workspace.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/delphi_lsp/writer.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/opencode.json +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/python_delphi_lsp.egg-info/SOURCES.txt +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/python_delphi_lsp.egg-info/dependency_links.txt +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/python_delphi_lsp.egg-info/entry_points.txt +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/python_delphi_lsp.egg-info/requires.txt +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/python_delphi_lsp.egg-info/top_level.txt +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/scripts/audit_delphi_language_features.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/scripts/bootstrap_vllm_opencode_test.ps1 +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/scripts/bootstrap_vllm_opencode_test.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/scripts/bootstrap_vllm_opencode_test.sh +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/scripts/check_ornith_cache.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/scripts/generate_release_evidence.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/scripts/ollama/ornith-lspctx.Modelfile +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/scripts/prepare_ornith_cache.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/scripts/run_opencode_lsp_probe.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/scripts/start_ornith_vllm.sh +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/scripts/summarize_opencode_request_payloads.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/setup.cfg +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/legacy_snippets/DeprecatedOnConst.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/legacy_snippets/VariantRecordFieldAttributes.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/legacy_snippets/alignedrecords.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/legacy_snippets/constset.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/legacy_snippets/deprecatedtype.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/legacy_snippets/dottedtypes.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/legacy_snippets/endtoken.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/legacy_snippets/experimentals.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/legacy_snippets/externalfunction.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/legacy_snippets/finalizationinitializationexports.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/legacy_snippets/forwardoverloaded.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/legacy_snippets/forwardwithoutsemicolon.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/legacy_snippets/genericconstraints.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/legacy_snippets/genericinterfacemethoddelegation.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/legacy_snippets/implementsgenerictype.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/legacy_snippets/include file2.inc +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/legacy_snippets/includefile.inc +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/legacy_snippets/includefile.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/legacy_snippets/managedrecords.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/legacy_snippets/messagemethod.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/legacy_snippets/multiline.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/legacy_snippets/nonalignedrecords.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/legacy_snippets/numbers.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/legacy_snippets/pointerchars.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/legacy_snippets/properties.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/legacy_snippets/strictvisibility.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/legacy_snippets/tryexcept.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/legacy_snippets/umlauts.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/legacy_snippets/whitespacearoundifdefcondition.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/library_demo.dpr +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/package_demo.dpk +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/program_demo.dpr +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/unit_advanced.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/unit_attributes.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/unit_basic.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/unit_consumer.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/unit_generics.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/unit_inheritance.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/unit_math.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/unit_properties.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/unit_sections.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/unit_statements.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/unit_types.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/unit_unresolved.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/fixtures/unit_with.pas +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/test_agent_context.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/test_agent_metrics.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/test_agent_protocol.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/test_agent_relations.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/test_agent_worker.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/test_agent_workspace.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/test_bootstrap_vllm_opencode.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/test_diagnostics.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/test_language_feature_matrix.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/test_legacy_snippets.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/test_lsp_features.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/test_lsp_support.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/test_metrics.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/test_opencode_config.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/test_opencode_request_payloads.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/test_ornith_cache_prepare.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/test_parser.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/test_preprocessor.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/test_project_discovery.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/test_project_indexer.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/test_release_evidence.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/test_semantic.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/test_vllm_start_script.py +0 -0
- {python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/tests/test_workspace.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-delphi-lsp
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.2
|
|
4
4
|
Summary: Python Delphi/Object Pascal parser, semantic indexer, and language server.
|
|
5
5
|
Author: Dark Light
|
|
6
6
|
License-Expression: MPL-2.0
|
|
@@ -41,7 +41,7 @@ Dynamic: license-file
|
|
|
41
41
|
|
|
42
42
|
`python-delphi-lsp` parses Delphi/Object Pascal, builds semantic and project
|
|
43
43
|
indexes, serves LSP, and provides bounded codebase navigation for agents.
|
|
44
|
-
Version 2.0.
|
|
44
|
+
Version 2.0.2 is authored by Dark Light and supports Windows, macOS, and Linux.
|
|
45
45
|
|
|
46
46
|
## Install and quick start
|
|
47
47
|
|
|
@@ -177,7 +177,7 @@ delphi-lsp-agent view --root PATH [--project-file FILE] --layer LAYER
|
|
|
177
177
|
delphi-lsp-agent index --root PATH [--project-file FILE] [--out FILE]
|
|
178
178
|
delphi-lsp-agent skill install [--target PATH] [--force]
|
|
179
179
|
delphi-lsp-agent opencode install [--target PATH] [--python PYTHON]
|
|
180
|
-
[--force] [--write-config]
|
|
180
|
+
[--force] [--write-agent|--write-config]
|
|
181
181
|
delphi-lsp-agent worker --root PATH [--project-file FILE]
|
|
182
182
|
```
|
|
183
183
|
|
|
@@ -187,8 +187,9 @@ delphi-lsp-agent worker --root PATH [--project-file FILE]
|
|
|
187
187
|
returns a project summary and detailed unit metric objects; `--query` filters
|
|
188
188
|
units by name or path.
|
|
189
189
|
`index` materializes overview, projects, and problems JSON. `skill install`
|
|
190
|
-
writes the skill; `opencode install` writes
|
|
191
|
-
|
|
190
|
+
writes the skill; `opencode install` writes the package-named skill, Markdown
|
|
191
|
+
agent, and plugin. The two deprecated write flags are harmless aliases and do
|
|
192
|
+
not change user configuration.
|
|
192
193
|
`worker` serves NDJSON over standard input/output.
|
|
193
194
|
|
|
194
195
|
Protocol v2 actions are `open`, `find`, `inspect`, `trace`, `focus`,
|
|
@@ -225,49 +226,47 @@ optimization does not remove LSP functionality.
|
|
|
225
226
|
Install the generated integration in a worktree:
|
|
226
227
|
|
|
227
228
|
```bash
|
|
228
|
-
delphi-lsp-agent opencode install --target .
|
|
229
|
+
delphi-lsp-agent opencode install --target .
|
|
229
230
|
```
|
|
230
231
|
|
|
231
232
|
It writes:
|
|
232
233
|
|
|
233
234
|
```text
|
|
234
|
-
.agents/skills/delphi-
|
|
235
|
+
.agents/skills/python-delphi-lsp/SKILL.md
|
|
235
236
|
.opencode/plugins/delphi_codebase.ts
|
|
237
|
+
.opencode/agents/python-delphi-lsp.md
|
|
236
238
|
```
|
|
237
239
|
|
|
238
|
-
The
|
|
239
|
-
`delphi-
|
|
240
|
+
The package-named Markdown agent enables only the
|
|
241
|
+
`python-delphi-lsp` skill and `delphi_codebase`. It denies
|
|
240
242
|
`bash`, `read`, `glob`, `grep`, and `lsp`, along with edit/write and
|
|
241
243
|
other raw source tools. The skill is enabled. The installer does not use the
|
|
242
|
-
retired `.opencode/tools` path.
|
|
244
|
+
retired `.opencode/tools` path and never reads or changes `opencode.json`; that
|
|
245
|
+
file remains entirely user-owned. The deprecated `--write-config` and
|
|
246
|
+
`--write-agent` options are accepted harmlessly for compatibility.
|
|
243
247
|
|
|
244
248
|
The plugin maintains one worker per session/root, reusing focus and indexes.
|
|
245
249
|
During compaction it restores the focus and summary into the new context.
|
|
246
250
|
Transport failure, session deletion, and plugin disposal clean up the worker.
|
|
247
251
|
|
|
248
|
-
A generated OpenCode agent
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
"lsp": "deny"
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
}
|
|
252
|
+
A generated OpenCode agent starts with this Markdown frontmatter:
|
|
253
|
+
|
|
254
|
+
```markdown
|
|
255
|
+
---
|
|
256
|
+
description: Inspect Delphi and Object Pascal codebases through python-delphi-lsp.
|
|
257
|
+
mode: subagent
|
|
258
|
+
temperature: 0
|
|
259
|
+
permission:
|
|
260
|
+
"*": deny
|
|
261
|
+
delphi_codebase: allow
|
|
262
|
+
skill:
|
|
263
|
+
"*": deny
|
|
264
|
+
python-delphi-lsp: allow
|
|
265
|
+
---
|
|
267
266
|
```
|
|
268
267
|
|
|
269
|
-
Select `
|
|
270
|
-
|
|
268
|
+
Select `python-delphi-lsp`, ask it to load the `python-delphi-lsp` skill, then
|
|
269
|
+
use `delphi_codebase` actions such as
|
|
271
270
|
`open`, `find`, `focus`, and `inspect`. Use semantic tool calls, not raw
|
|
272
271
|
source tools.
|
|
273
272
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
`python-delphi-lsp` parses Delphi/Object Pascal, builds semantic and project
|
|
4
4
|
indexes, serves LSP, and provides bounded codebase navigation for agents.
|
|
5
|
-
Version 2.0.
|
|
5
|
+
Version 2.0.2 is authored by Dark Light and supports Windows, macOS, and Linux.
|
|
6
6
|
|
|
7
7
|
## Install and quick start
|
|
8
8
|
|
|
@@ -138,7 +138,7 @@ delphi-lsp-agent view --root PATH [--project-file FILE] --layer LAYER
|
|
|
138
138
|
delphi-lsp-agent index --root PATH [--project-file FILE] [--out FILE]
|
|
139
139
|
delphi-lsp-agent skill install [--target PATH] [--force]
|
|
140
140
|
delphi-lsp-agent opencode install [--target PATH] [--python PYTHON]
|
|
141
|
-
[--force] [--write-config]
|
|
141
|
+
[--force] [--write-agent|--write-config]
|
|
142
142
|
delphi-lsp-agent worker --root PATH [--project-file FILE]
|
|
143
143
|
```
|
|
144
144
|
|
|
@@ -148,8 +148,9 @@ delphi-lsp-agent worker --root PATH [--project-file FILE]
|
|
|
148
148
|
returns a project summary and detailed unit metric objects; `--query` filters
|
|
149
149
|
units by name or path.
|
|
150
150
|
`index` materializes overview, projects, and problems JSON. `skill install`
|
|
151
|
-
writes the skill; `opencode install` writes
|
|
152
|
-
|
|
151
|
+
writes the skill; `opencode install` writes the package-named skill, Markdown
|
|
152
|
+
agent, and plugin. The two deprecated write flags are harmless aliases and do
|
|
153
|
+
not change user configuration.
|
|
153
154
|
`worker` serves NDJSON over standard input/output.
|
|
154
155
|
|
|
155
156
|
Protocol v2 actions are `open`, `find`, `inspect`, `trace`, `focus`,
|
|
@@ -186,49 +187,47 @@ optimization does not remove LSP functionality.
|
|
|
186
187
|
Install the generated integration in a worktree:
|
|
187
188
|
|
|
188
189
|
```bash
|
|
189
|
-
delphi-lsp-agent opencode install --target .
|
|
190
|
+
delphi-lsp-agent opencode install --target .
|
|
190
191
|
```
|
|
191
192
|
|
|
192
193
|
It writes:
|
|
193
194
|
|
|
194
195
|
```text
|
|
195
|
-
.agents/skills/delphi-
|
|
196
|
+
.agents/skills/python-delphi-lsp/SKILL.md
|
|
196
197
|
.opencode/plugins/delphi_codebase.ts
|
|
198
|
+
.opencode/agents/python-delphi-lsp.md
|
|
197
199
|
```
|
|
198
200
|
|
|
199
|
-
The
|
|
200
|
-
`delphi-
|
|
201
|
+
The package-named Markdown agent enables only the
|
|
202
|
+
`python-delphi-lsp` skill and `delphi_codebase`. It denies
|
|
201
203
|
`bash`, `read`, `glob`, `grep`, and `lsp`, along with edit/write and
|
|
202
204
|
other raw source tools. The skill is enabled. The installer does not use the
|
|
203
|
-
retired `.opencode/tools` path.
|
|
205
|
+
retired `.opencode/tools` path and never reads or changes `opencode.json`; that
|
|
206
|
+
file remains entirely user-owned. The deprecated `--write-config` and
|
|
207
|
+
`--write-agent` options are accepted harmlessly for compatibility.
|
|
204
208
|
|
|
205
209
|
The plugin maintains one worker per session/root, reusing focus and indexes.
|
|
206
210
|
During compaction it restores the focus and summary into the new context.
|
|
207
211
|
Transport failure, session deletion, and plugin disposal clean up the worker.
|
|
208
212
|
|
|
209
|
-
A generated OpenCode agent
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
"lsp": "deny"
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
}
|
|
213
|
+
A generated OpenCode agent starts with this Markdown frontmatter:
|
|
214
|
+
|
|
215
|
+
```markdown
|
|
216
|
+
---
|
|
217
|
+
description: Inspect Delphi and Object Pascal codebases through python-delphi-lsp.
|
|
218
|
+
mode: subagent
|
|
219
|
+
temperature: 0
|
|
220
|
+
permission:
|
|
221
|
+
"*": deny
|
|
222
|
+
delphi_codebase: allow
|
|
223
|
+
skill:
|
|
224
|
+
"*": deny
|
|
225
|
+
python-delphi-lsp: allow
|
|
226
|
+
---
|
|
228
227
|
```
|
|
229
228
|
|
|
230
|
-
Select `
|
|
231
|
-
|
|
229
|
+
Select `python-delphi-lsp`, ask it to load the `python-delphi-lsp` skill, then
|
|
230
|
+
use `delphi_codebase` actions such as
|
|
232
231
|
`open`, `find`, `focus`, and `inspect`. Use semantic tool calls, not raw
|
|
233
232
|
source tools.
|
|
234
233
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "2.0.2"
|
|
@@ -67,11 +67,19 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
67
67
|
|
|
68
68
|
opencode = subcommands.add_parser("opencode", help="Install opencode integration.")
|
|
69
69
|
opencode_commands = opencode.add_subparsers(dest="opencode_command", required=True)
|
|
70
|
-
opencode_install = opencode_commands.add_parser(
|
|
70
|
+
opencode_install = opencode_commands.add_parser(
|
|
71
|
+
"install", help="Install the package-named skill, Markdown agent, and OpenCode plugin."
|
|
72
|
+
)
|
|
71
73
|
opencode_install.add_argument("--target", type=Path, default=Path("."))
|
|
72
74
|
opencode_install.add_argument("--python", default=sys.executable)
|
|
73
75
|
opencode_install.add_argument("--force", action="store_true")
|
|
74
|
-
opencode_install.add_argument(
|
|
76
|
+
opencode_install.add_argument(
|
|
77
|
+
"--write-agent",
|
|
78
|
+
"--write-config",
|
|
79
|
+
dest="write_config",
|
|
80
|
+
action="store_true",
|
|
81
|
+
help="Deprecated compatibility option; the Markdown agent is always installed and opencode.json is never touched.",
|
|
82
|
+
)
|
|
75
83
|
opencode_install.set_defaults(func=_opencode_install)
|
|
76
84
|
|
|
77
85
|
worker = subcommands.add_parser("worker", help="Serve Protocol v2 NDJSON requests.")
|
|
@@ -139,7 +147,7 @@ def _skill_install(args: argparse.Namespace) -> None:
|
|
|
139
147
|
|
|
140
148
|
|
|
141
149
|
def _opencode_install(args: argparse.Namespace) -> None:
|
|
142
|
-
skill_path, plugin_path,
|
|
150
|
+
skill_path, plugin_path, agent_path = install_opencode_support(
|
|
143
151
|
args.target,
|
|
144
152
|
python_executable=args.python,
|
|
145
153
|
force=args.force,
|
|
@@ -147,8 +155,7 @@ def _opencode_install(args: argparse.Namespace) -> None:
|
|
|
147
155
|
)
|
|
148
156
|
print(skill_path)
|
|
149
157
|
print(plugin_path)
|
|
150
|
-
|
|
151
|
-
print(config_path)
|
|
158
|
+
print(agent_path)
|
|
152
159
|
|
|
153
160
|
|
|
154
161
|
def _worker(args: argparse.Namespace) -> None:
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import hashlib
|
|
3
4
|
from pathlib import Path
|
|
4
5
|
import json
|
|
5
6
|
import os
|
|
@@ -7,14 +8,20 @@ import secrets
|
|
|
7
8
|
import stat
|
|
8
9
|
|
|
9
10
|
|
|
10
|
-
SKILL_NAME = "delphi-
|
|
11
|
+
SKILL_NAME = "python-delphi-lsp"
|
|
12
|
+
AGENT_NAME = "python-delphi-lsp"
|
|
13
|
+
_LEGACY_SKILL_NAME = "delphi-codebase-navigator"
|
|
14
|
+
_LEGACY_SKILL_RELATIVE_PATH = Path(".agents") / "skills" / _LEGACY_SKILL_NAME / "SKILL.md"
|
|
15
|
+
_LEGACY_SKILL_SHA256 = "0843d37bd48431c2b992f191b985175a3c60fe5b56d28e0a46b5e18db6383b28"
|
|
11
16
|
_LEGACY_TOOL_RELATIVE_PATH = Path(".opencode") / "tools" / "delphi_codebase.ts"
|
|
12
17
|
|
|
13
18
|
|
|
14
19
|
def install_skill(target: str | Path, *, force: bool = False) -> Path:
|
|
15
20
|
target_path = Path(target).expanduser().resolve()
|
|
21
|
+
legacy_path = _preflight_legacy_skill(target_path, force=force)
|
|
16
22
|
skill_path = target_path / ".agents" / "skills" / SKILL_NAME / "SKILL.md"
|
|
17
23
|
_write_text(skill_path, _skill_markdown(), force=force)
|
|
24
|
+
_remove_legacy_skill(legacy_path)
|
|
18
25
|
return skill_path
|
|
19
26
|
|
|
20
27
|
|
|
@@ -24,26 +31,30 @@ def install_opencode_support(
|
|
|
24
31
|
python_executable: str,
|
|
25
32
|
force: bool = False,
|
|
26
33
|
write_config: bool = False,
|
|
27
|
-
) -> tuple[Path, Path, Path
|
|
34
|
+
) -> tuple[Path, Path, Path]:
|
|
28
35
|
target_path = Path(target).expanduser().resolve()
|
|
29
36
|
legacy_path = target_path / _LEGACY_TOOL_RELATIVE_PATH
|
|
37
|
+
legacy_skill_path = _preflight_legacy_skill(target_path, force=force)
|
|
30
38
|
skill_path = target_path / ".agents" / "skills" / SKILL_NAME / "SKILL.md"
|
|
31
39
|
plugin_path = target_path / ".opencode" / "plugins" / "delphi_codebase.ts"
|
|
32
|
-
|
|
40
|
+
agent_path = target_path / ".opencode" / "agents" / f"{AGENT_NAME}.md"
|
|
33
41
|
skill_text = _skill_markdown()
|
|
34
42
|
plugin_text = _opencode_plugin(python_executable)
|
|
43
|
+
agent_text = _agent_markdown()
|
|
35
44
|
|
|
36
45
|
legacy_before = _preflight_legacy(legacy_path, force=force)
|
|
37
46
|
snapshots: dict[Path, bytes | None] = {
|
|
38
47
|
legacy_path: legacy_before,
|
|
48
|
+
**(
|
|
49
|
+
{legacy_skill_path: legacy_skill_path.read_bytes()}
|
|
50
|
+
if legacy_skill_path is not None
|
|
51
|
+
else {}
|
|
52
|
+
),
|
|
39
53
|
skill_path: _preflight_destination(skill_path, skill_text, force=force),
|
|
40
54
|
plugin_path: _preflight_destination(plugin_path, plugin_text, force=force),
|
|
55
|
+
agent_path: _preflight_destination(agent_path, agent_text, force=force),
|
|
41
56
|
}
|
|
42
|
-
writes = [(skill_path, skill_text), (plugin_path, plugin_text)]
|
|
43
|
-
if config_path is not None:
|
|
44
|
-
config_before, config_text = _render_opencode_config(config_path)
|
|
45
|
-
snapshots[config_path] = config_before
|
|
46
|
-
writes.append((config_path, config_text))
|
|
57
|
+
writes = [(skill_path, skill_text), (plugin_path, plugin_text), (agent_path, agent_text)]
|
|
47
58
|
|
|
48
59
|
try:
|
|
49
60
|
for path, text in writes:
|
|
@@ -51,11 +62,39 @@ def install_opencode_support(
|
|
|
51
62
|
_write_text(path, text, force=True)
|
|
52
63
|
if legacy_before is not None:
|
|
53
64
|
legacy_path.unlink()
|
|
65
|
+
_remove_legacy_skill(legacy_skill_path)
|
|
54
66
|
except BaseException:
|
|
55
67
|
for path, content in reversed(tuple(snapshots.items())):
|
|
56
68
|
_restore_file(path, content)
|
|
57
69
|
raise
|
|
58
|
-
|
|
70
|
+
_ = write_config # Deprecated compatibility input; user configuration is never touched.
|
|
71
|
+
return skill_path, plugin_path, agent_path
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _preflight_legacy_skill(target: Path, *, force: bool) -> Path | None:
|
|
75
|
+
legacy_path = target / _LEGACY_SKILL_RELATIVE_PATH
|
|
76
|
+
legacy_path.relative_to(target)
|
|
77
|
+
_reject_symbolic_link(legacy_path)
|
|
78
|
+
if not legacy_path.exists():
|
|
79
|
+
return None
|
|
80
|
+
if not legacy_path.is_file():
|
|
81
|
+
raise FileExistsError(f"Legacy skill path is not a file: {legacy_path}")
|
|
82
|
+
digest = hashlib.sha256(legacy_path.read_bytes()).hexdigest()
|
|
83
|
+
if digest != _LEGACY_SKILL_SHA256 and not force:
|
|
84
|
+
raise FileExistsError(
|
|
85
|
+
f"Refusing to remove modified legacy skill without force: {legacy_path}"
|
|
86
|
+
)
|
|
87
|
+
return legacy_path
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def _remove_legacy_skill(path: Path | None) -> None:
|
|
91
|
+
if path is None:
|
|
92
|
+
return
|
|
93
|
+
path.unlink()
|
|
94
|
+
try:
|
|
95
|
+
path.parent.rmdir()
|
|
96
|
+
except OSError:
|
|
97
|
+
pass
|
|
59
98
|
|
|
60
99
|
|
|
61
100
|
def _preflight_legacy(legacy_path: Path, *, force: bool) -> bytes | None:
|
|
@@ -157,13 +196,18 @@ def _write_bytes_atomic(path: Path, content: bytes) -> None:
|
|
|
157
196
|
|
|
158
197
|
|
|
159
198
|
def _reject_symbolic_link(path: Path) -> None:
|
|
160
|
-
|
|
161
|
-
|
|
199
|
+
current = path
|
|
200
|
+
while current != current.parent:
|
|
201
|
+
if current.is_symlink():
|
|
202
|
+
raise FileExistsError(
|
|
203
|
+
f"Generated destination must not contain a symbolic link: {current}"
|
|
204
|
+
)
|
|
205
|
+
current = current.parent
|
|
162
206
|
|
|
163
207
|
|
|
164
208
|
def _skill_markdown() -> str:
|
|
165
209
|
return """---
|
|
166
|
-
name: delphi-
|
|
210
|
+
name: python-delphi-lsp
|
|
167
211
|
description: Inspect Delphi and Object Pascal codebases through the Protocol v2 semantic navigator.
|
|
168
212
|
compatibility: opencode
|
|
169
213
|
metadata:
|
|
@@ -192,6 +236,39 @@ Prefer `summary` and `declaration`, narrow `max_items` and `max_chars`, and requ
|
|
|
192
236
|
"""
|
|
193
237
|
|
|
194
238
|
|
|
239
|
+
def _agent_markdown() -> str:
|
|
240
|
+
return """---
|
|
241
|
+
description: Inspect Delphi and Object Pascal codebases through python-delphi-lsp.
|
|
242
|
+
mode: subagent
|
|
243
|
+
temperature: 0
|
|
244
|
+
tools:
|
|
245
|
+
delphi_codebase: true
|
|
246
|
+
skill: true
|
|
247
|
+
lsp: false
|
|
248
|
+
bash: false
|
|
249
|
+
read: false
|
|
250
|
+
glob: false
|
|
251
|
+
grep: false
|
|
252
|
+
edit: false
|
|
253
|
+
write: false
|
|
254
|
+
task: false
|
|
255
|
+
webfetch: false
|
|
256
|
+
todowrite: false
|
|
257
|
+
permission:
|
|
258
|
+
"*": deny
|
|
259
|
+
delphi_codebase: allow
|
|
260
|
+
skill:
|
|
261
|
+
"*": deny
|
|
262
|
+
python-delphi-lsp: allow
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
Load `python-delphi-lsp` first, then use only `delphi_codebase` for Delphi and
|
|
266
|
+
Object Pascal codebase inspection. Do not use `lsp`, `bash`, `read`, `glob`,
|
|
267
|
+
`grep`, `edit`, `write`, `task`, `webfetch`, or `todowrite`. Preserve returned
|
|
268
|
+
citations exactly and report partial or ambiguous semantic evidence explicitly.
|
|
269
|
+
"""
|
|
270
|
+
|
|
271
|
+
|
|
195
272
|
def _opencode_plugin(python_executable: str) -> str:
|
|
196
273
|
python_json = json.dumps(python_executable)
|
|
197
274
|
template = '''import { tool, type Plugin } from "@opencode-ai/plugin"
|
|
@@ -525,56 +602,4 @@ export const DelphiCodebasePlugin: Plugin = async (_input) => {
|
|
|
525
602
|
return template.replace("__PYTHON_EXECUTABLE__", python_json)
|
|
526
603
|
|
|
527
604
|
|
|
528
|
-
def _render_opencode_config(config_path: Path) -> tuple[bytes | None, str]:
|
|
529
|
-
_reject_symbolic_link(config_path)
|
|
530
|
-
if config_path.exists():
|
|
531
|
-
if not config_path.is_file():
|
|
532
|
-
raise ValueError(f"opencode config path is not a file: {config_path}")
|
|
533
|
-
config_before = config_path.read_bytes()
|
|
534
|
-
config = json.loads(config_before.decode("utf-8"))
|
|
535
|
-
else:
|
|
536
|
-
config_before = None
|
|
537
|
-
config = {"$schema": "https://opencode.ai/config.json"}
|
|
538
|
-
if not isinstance(config, dict):
|
|
539
|
-
raise ValueError("opencode config must be a JSON object")
|
|
540
|
-
if "agent" not in config:
|
|
541
|
-
agents = {}
|
|
542
|
-
config["agent"] = agents
|
|
543
|
-
else:
|
|
544
|
-
agents = config["agent"]
|
|
545
|
-
if not isinstance(agents, dict):
|
|
546
|
-
raise ValueError("opencode config field 'agent' must be a JSON object")
|
|
547
|
-
agents["vllm-delphi-codebase"] = {
|
|
548
|
-
"description": "Use the Delphi codebase navigator skill and plugin without direct filesystem source inspection.",
|
|
549
|
-
"temperature": 0,
|
|
550
|
-
"prompt": (
|
|
551
|
-
"load delphi-codebase-navigator first, then use only delphi_codebase for Delphi/Object Pascal "
|
|
552
|
-
"codebase inspection. Do not use lsp, bash, read, glob, grep, edit, write, task, webfetch, or todowrite."
|
|
553
|
-
),
|
|
554
|
-
"tools": {
|
|
555
|
-
"delphi_codebase": True,
|
|
556
|
-
"skill": True,
|
|
557
|
-
"lsp": False,
|
|
558
|
-
"bash": False,
|
|
559
|
-
"read": False,
|
|
560
|
-
"glob": False,
|
|
561
|
-
"grep": False,
|
|
562
|
-
"edit": False,
|
|
563
|
-
"write": False,
|
|
564
|
-
"task": False,
|
|
565
|
-
"webfetch": False,
|
|
566
|
-
"todowrite": False,
|
|
567
|
-
},
|
|
568
|
-
"permission": {
|
|
569
|
-
"delphi_codebase": "allow",
|
|
570
|
-
"skill": {
|
|
571
|
-
"*": "deny",
|
|
572
|
-
SKILL_NAME: "allow",
|
|
573
|
-
},
|
|
574
|
-
"lsp": "deny",
|
|
575
|
-
},
|
|
576
|
-
}
|
|
577
|
-
return config_before, json.dumps(config, indent=2, sort_keys=True) + "\n"
|
|
578
|
-
|
|
579
|
-
|
|
580
605
|
__all__ = ["SKILL_NAME", "install_opencode_support", "install_skill"]
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "python-delphi-lsp"
|
|
7
|
-
version = "2.0.
|
|
7
|
+
version = "2.0.2"
|
|
8
8
|
description = "Python Delphi/Object Pascal parser, semantic indexer, and language server."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-delphi-lsp
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.2
|
|
4
4
|
Summary: Python Delphi/Object Pascal parser, semantic indexer, and language server.
|
|
5
5
|
Author: Dark Light
|
|
6
6
|
License-Expression: MPL-2.0
|
|
@@ -41,7 +41,7 @@ Dynamic: license-file
|
|
|
41
41
|
|
|
42
42
|
`python-delphi-lsp` parses Delphi/Object Pascal, builds semantic and project
|
|
43
43
|
indexes, serves LSP, and provides bounded codebase navigation for agents.
|
|
44
|
-
Version 2.0.
|
|
44
|
+
Version 2.0.2 is authored by Dark Light and supports Windows, macOS, and Linux.
|
|
45
45
|
|
|
46
46
|
## Install and quick start
|
|
47
47
|
|
|
@@ -177,7 +177,7 @@ delphi-lsp-agent view --root PATH [--project-file FILE] --layer LAYER
|
|
|
177
177
|
delphi-lsp-agent index --root PATH [--project-file FILE] [--out FILE]
|
|
178
178
|
delphi-lsp-agent skill install [--target PATH] [--force]
|
|
179
179
|
delphi-lsp-agent opencode install [--target PATH] [--python PYTHON]
|
|
180
|
-
[--force] [--write-config]
|
|
180
|
+
[--force] [--write-agent|--write-config]
|
|
181
181
|
delphi-lsp-agent worker --root PATH [--project-file FILE]
|
|
182
182
|
```
|
|
183
183
|
|
|
@@ -187,8 +187,9 @@ delphi-lsp-agent worker --root PATH [--project-file FILE]
|
|
|
187
187
|
returns a project summary and detailed unit metric objects; `--query` filters
|
|
188
188
|
units by name or path.
|
|
189
189
|
`index` materializes overview, projects, and problems JSON. `skill install`
|
|
190
|
-
writes the skill; `opencode install` writes
|
|
191
|
-
|
|
190
|
+
writes the skill; `opencode install` writes the package-named skill, Markdown
|
|
191
|
+
agent, and plugin. The two deprecated write flags are harmless aliases and do
|
|
192
|
+
not change user configuration.
|
|
192
193
|
`worker` serves NDJSON over standard input/output.
|
|
193
194
|
|
|
194
195
|
Protocol v2 actions are `open`, `find`, `inspect`, `trace`, `focus`,
|
|
@@ -225,49 +226,47 @@ optimization does not remove LSP functionality.
|
|
|
225
226
|
Install the generated integration in a worktree:
|
|
226
227
|
|
|
227
228
|
```bash
|
|
228
|
-
delphi-lsp-agent opencode install --target .
|
|
229
|
+
delphi-lsp-agent opencode install --target .
|
|
229
230
|
```
|
|
230
231
|
|
|
231
232
|
It writes:
|
|
232
233
|
|
|
233
234
|
```text
|
|
234
|
-
.agents/skills/delphi-
|
|
235
|
+
.agents/skills/python-delphi-lsp/SKILL.md
|
|
235
236
|
.opencode/plugins/delphi_codebase.ts
|
|
237
|
+
.opencode/agents/python-delphi-lsp.md
|
|
236
238
|
```
|
|
237
239
|
|
|
238
|
-
The
|
|
239
|
-
`delphi-
|
|
240
|
+
The package-named Markdown agent enables only the
|
|
241
|
+
`python-delphi-lsp` skill and `delphi_codebase`. It denies
|
|
240
242
|
`bash`, `read`, `glob`, `grep`, and `lsp`, along with edit/write and
|
|
241
243
|
other raw source tools. The skill is enabled. The installer does not use the
|
|
242
|
-
retired `.opencode/tools` path.
|
|
244
|
+
retired `.opencode/tools` path and never reads or changes `opencode.json`; that
|
|
245
|
+
file remains entirely user-owned. The deprecated `--write-config` and
|
|
246
|
+
`--write-agent` options are accepted harmlessly for compatibility.
|
|
243
247
|
|
|
244
248
|
The plugin maintains one worker per session/root, reusing focus and indexes.
|
|
245
249
|
During compaction it restores the focus and summary into the new context.
|
|
246
250
|
Transport failure, session deletion, and plugin disposal clean up the worker.
|
|
247
251
|
|
|
248
|
-
A generated OpenCode agent
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
"lsp": "deny"
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
}
|
|
252
|
+
A generated OpenCode agent starts with this Markdown frontmatter:
|
|
253
|
+
|
|
254
|
+
```markdown
|
|
255
|
+
---
|
|
256
|
+
description: Inspect Delphi and Object Pascal codebases through python-delphi-lsp.
|
|
257
|
+
mode: subagent
|
|
258
|
+
temperature: 0
|
|
259
|
+
permission:
|
|
260
|
+
"*": deny
|
|
261
|
+
delphi_codebase: allow
|
|
262
|
+
skill:
|
|
263
|
+
"*": deny
|
|
264
|
+
python-delphi-lsp: allow
|
|
265
|
+
---
|
|
267
266
|
```
|
|
268
267
|
|
|
269
|
-
Select `
|
|
270
|
-
|
|
268
|
+
Select `python-delphi-lsp`, ask it to load the `python-delphi-lsp` skill, then
|
|
269
|
+
use `delphi_codebase` actions such as
|
|
271
270
|
`open`, `find`, `focus`, and `inspect`. Use semantic tool calls, not raw
|
|
272
271
|
source tools.
|
|
273
272
|
|
{python_delphi_lsp-2.0.1 → python_delphi_lsp-2.0.2}/scripts/bootstrap_vllm_codebase_skill_test.py
RENAMED
|
@@ -35,7 +35,7 @@ from bootstrap_vllm_opencode_test import ( # noqa: E402
|
|
|
35
35
|
|
|
36
36
|
DEFAULT_SANDBOX = Path("output/mega_codebase_skill_project")
|
|
37
37
|
DEFAULT_MODEL = "vllm/ornith-lspctx"
|
|
38
|
-
DEFAULT_AGENT = "
|
|
38
|
+
DEFAULT_AGENT = "python-delphi-lsp"
|
|
39
39
|
DEFAULT_SYMBOL = "MegaProc02500"
|
|
40
40
|
DEFAULT_API_KEY = "vllm"
|
|
41
41
|
DEFAULT_MAX_MODEL_LEN = "32768"
|
|
@@ -208,7 +208,6 @@ def _install_sandbox_support(
|
|
|
208
208
|
sandbox,
|
|
209
209
|
python_executable=str(python_executable),
|
|
210
210
|
force=True,
|
|
211
|
-
write_config=True,
|
|
212
211
|
)
|
|
213
212
|
|
|
214
213
|
|
|
@@ -222,7 +221,7 @@ def build_probe_command(
|
|
|
222
221
|
) -> list[str]:
|
|
223
222
|
output_path = output or sandbox / "bootstrap_vllm_codebase_skill_probe.jsonl"
|
|
224
223
|
prompt = (
|
|
225
|
-
"First load the delphi-
|
|
224
|
+
"First load the python-delphi-lsp skill. Use only delphi_codebase to inspect the Delphi project. "
|
|
226
225
|
"Do not write explanatory text before the required calls. Call action open, then action find with query "
|
|
227
226
|
'"MegaProc02500", focus the returned target with action focus and target_id, then call action inspect '
|
|
228
227
|
"with detail body. In the final answer cite the returned body range as path:start_line-end_line; do not "
|
|
@@ -246,7 +245,7 @@ def build_probe_command(
|
|
|
246
245
|
"--require-tool",
|
|
247
246
|
"delphi_codebase.inspect:Value := Value + 40",
|
|
248
247
|
"--require-tool",
|
|
249
|
-
"skill:delphi-
|
|
248
|
+
"skill:python-delphi-lsp",
|
|
250
249
|
"--require-final",
|
|
251
250
|
"src/Mega100kUnit.pas:117464-117509",
|
|
252
251
|
"--require-final",
|
|
@@ -289,7 +288,7 @@ def build_metrics_probe_command(
|
|
|
289
288
|
) -> list[str]:
|
|
290
289
|
output_path = output or sandbox / "bootstrap_vllm_metrics_probe.jsonl"
|
|
291
290
|
prompt = (
|
|
292
|
-
"First load the delphi-
|
|
291
|
+
"First load the python-delphi-lsp skill. Use only delphi_codebase to inspect the Delphi project. "
|
|
293
292
|
"Do not write explanatory text before the required calls. Call action open, then call action metrics without a query and identify "
|
|
294
293
|
"the unit with the highest cyclomatic maximum. Then call action metrics with that unit's target_id and "
|
|
295
294
|
"detail members. Return exactly these four labeled facts on separate lines: Total LOC, Most complex unit, "
|
|
@@ -311,7 +310,7 @@ def build_metrics_probe_command(
|
|
|
311
310
|
"--require-tool",
|
|
312
311
|
'delphi_codebase.metrics:"routines"',
|
|
313
312
|
"--require-tool",
|
|
314
|
-
"skill:delphi-
|
|
313
|
+
"skill:python-delphi-lsp",
|
|
315
314
|
]
|
|
316
315
|
for required in (
|
|
317
316
|
"Total LOC: 34",
|