python-delphi-lsp 1.1.1__tar.gz → 2.0.0__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.
Files changed (136) hide show
  1. python_delphi_lsp-2.0.0/PKG-INFO +324 -0
  2. python_delphi_lsp-2.0.0/README.md +285 -0
  3. {python_delphi_lsp-1.1.1/delphiast → python_delphi_lsp-2.0.0/delphi_lsp}/__init__.py +2 -0
  4. python_delphi_lsp-2.0.0/delphi_lsp/_version.py +1 -0
  5. python_delphi_lsp-2.0.0/delphi_lsp/agent_cli.py +242 -0
  6. python_delphi_lsp-2.0.0/delphi_lsp/agent_context.py +2096 -0
  7. {python_delphi_lsp-1.1.1/delphiast → python_delphi_lsp-2.0.0/delphi_lsp}/agent_layers.py +2 -2
  8. python_delphi_lsp-2.0.0/delphi_lsp/agent_protocol.py +390 -0
  9. python_delphi_lsp-2.0.0/delphi_lsp/agent_relations.py +859 -0
  10. python_delphi_lsp-2.0.0/delphi_lsp/agent_templates.py +579 -0
  11. python_delphi_lsp-2.0.0/delphi_lsp/agent_workspace.py +661 -0
  12. {python_delphi_lsp-1.1.1/delphiast → python_delphi_lsp-2.0.0/delphi_lsp}/lsp_server.py +270 -48
  13. {python_delphi_lsp-1.1.1/delphiast → python_delphi_lsp-2.0.0/delphi_lsp}/project_discovery.py +183 -40
  14. {python_delphi_lsp-1.1.1/delphiast → python_delphi_lsp-2.0.0/delphi_lsp}/project_indexer.py +6 -0
  15. python_delphi_lsp-2.0.0/delphi_lsp/source_reader.py +17 -0
  16. {python_delphi_lsp-1.1.1/delphiast → python_delphi_lsp-2.0.0/delphi_lsp}/workspace.py +15 -1
  17. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/opencode.json +1 -6
  18. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/pyproject.toml +5 -5
  19. python_delphi_lsp-2.0.0/python_delphi_lsp.egg-info/PKG-INFO +324 -0
  20. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/python_delphi_lsp.egg-info/SOURCES.txt +31 -21
  21. python_delphi_lsp-2.0.0/python_delphi_lsp.egg-info/entry_points.txt +3 -0
  22. python_delphi_lsp-2.0.0/python_delphi_lsp.egg-info/top_level.txt +1 -0
  23. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/scripts/audit_delphi_language_features.py +3 -3
  24. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/scripts/bootstrap_vllm_codebase_skill_test.py +45 -15
  25. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/scripts/bootstrap_vllm_opencode_test.py +1 -1
  26. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/scripts/generate_release_evidence.py +67 -19
  27. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/scripts/run_opencode_lsp_probe.py +133 -37
  28. python_delphi_lsp-2.0.0/tests/test_agent_codebase.py +910 -0
  29. python_delphi_lsp-2.0.0/tests/test_agent_context.py +1773 -0
  30. python_delphi_lsp-2.0.0/tests/test_agent_protocol.py +666 -0
  31. python_delphi_lsp-2.0.0/tests/test_agent_relations.py +1197 -0
  32. python_delphi_lsp-2.0.0/tests/test_agent_worker.py +446 -0
  33. python_delphi_lsp-2.0.0/tests/test_agent_workspace.py +1280 -0
  34. python_delphi_lsp-2.0.0/tests/test_bootstrap_vllm_codebase_skill.py +152 -0
  35. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/test_bootstrap_vllm_opencode.py +54 -9
  36. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/test_diagnostics.py +1 -1
  37. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/test_legacy_snippets.py +1 -1
  38. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/test_lsp_features.py +3 -3
  39. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/test_lsp_support.py +483 -18
  40. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/test_opencode_probe.py +253 -0
  41. python_delphi_lsp-2.0.0/tests/test_package_metadata.py +124 -0
  42. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/test_parser.py +2 -2
  43. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/test_preprocessor.py +2 -2
  44. python_delphi_lsp-2.0.0/tests/test_project_discovery.py +427 -0
  45. python_delphi_lsp-2.0.0/tests/test_project_indexer.py +398 -0
  46. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/test_release_evidence.py +33 -3
  47. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/test_semantic.py +2 -2
  48. python_delphi_lsp-2.0.0/tests/test_workspace.py +85 -0
  49. python_delphi_lsp-1.1.1/PKG-INFO +0 -434
  50. python_delphi_lsp-1.1.1/README.md +0 -395
  51. python_delphi_lsp-1.1.1/delphiast/agent_cli.py +0 -113
  52. python_delphi_lsp-1.1.1/delphiast/agent_templates.py +0 -180
  53. python_delphi_lsp-1.1.1/delphiast/source_reader.py +0 -15
  54. python_delphi_lsp-1.1.1/python_delphi_lsp.egg-info/PKG-INFO +0 -434
  55. python_delphi_lsp-1.1.1/python_delphi_lsp.egg-info/entry_points.txt +0 -3
  56. python_delphi_lsp-1.1.1/python_delphi_lsp.egg-info/top_level.txt +0 -1
  57. python_delphi_lsp-1.1.1/tests/test_agent_codebase.py +0 -217
  58. python_delphi_lsp-1.1.1/tests/test_bootstrap_vllm_codebase_skill.py +0 -68
  59. python_delphi_lsp-1.1.1/tests/test_package_metadata.py +0 -57
  60. python_delphi_lsp-1.1.1/tests/test_project_discovery.py +0 -174
  61. python_delphi_lsp-1.1.1/tests/test_project_indexer.py +0 -152
  62. python_delphi_lsp-1.1.1/tests/test_workspace.py +0 -31
  63. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/LICENSE +0 -0
  64. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/MANIFEST.in +0 -0
  65. {python_delphi_lsp-1.1.1/delphiast → python_delphi_lsp-2.0.0/delphi_lsp}/binary.py +0 -0
  66. {python_delphi_lsp-1.1.1/delphiast → python_delphi_lsp-2.0.0/delphi_lsp}/comment_builder.py +0 -0
  67. {python_delphi_lsp-1.1.1/delphiast → python_delphi_lsp-2.0.0/delphi_lsp}/consts.py +0 -0
  68. {python_delphi_lsp-1.1.1/delphiast → python_delphi_lsp-2.0.0/delphi_lsp}/grammar.py +0 -0
  69. {python_delphi_lsp-1.1.1/delphiast → python_delphi_lsp-2.0.0/delphi_lsp}/lark_builder.py +0 -0
  70. {python_delphi_lsp-1.1.1/delphiast → python_delphi_lsp-2.0.0/delphi_lsp}/lark_tokens.py +0 -0
  71. {python_delphi_lsp-1.1.1/delphiast → python_delphi_lsp-2.0.0/delphi_lsp}/nodes.py +0 -0
  72. {python_delphi_lsp-1.1.1/delphiast → python_delphi_lsp-2.0.0/delphi_lsp}/parser.py +0 -0
  73. {python_delphi_lsp-1.1.1/delphiast → python_delphi_lsp-2.0.0/delphi_lsp}/preprocessor.py +0 -0
  74. {python_delphi_lsp-1.1.1/delphiast → python_delphi_lsp-2.0.0/delphi_lsp}/semantic.py +0 -0
  75. {python_delphi_lsp-1.1.1/delphiast → python_delphi_lsp-2.0.0/delphi_lsp}/semantic_builder.py +0 -0
  76. {python_delphi_lsp-1.1.1/delphiast → python_delphi_lsp-2.0.0/delphi_lsp}/writer.py +0 -0
  77. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/python_delphi_lsp.egg-info/dependency_links.txt +0 -0
  78. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/python_delphi_lsp.egg-info/requires.txt +0 -0
  79. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/scripts/bootstrap_vllm_opencode_test.ps1 +0 -0
  80. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/scripts/bootstrap_vllm_opencode_test.sh +0 -0
  81. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/scripts/check_ornith_cache.py +0 -0
  82. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/scripts/ollama/ornith-lspctx.Modelfile +0 -0
  83. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/scripts/prepare_ornith_cache.py +0 -0
  84. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/scripts/start_ornith_vllm.sh +0 -0
  85. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/scripts/summarize_opencode_request_payloads.py +0 -0
  86. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/setup.cfg +0 -0
  87. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/legacy_snippets/DeprecatedOnConst.pas +0 -0
  88. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/legacy_snippets/VariantRecordFieldAttributes.pas +0 -0
  89. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/legacy_snippets/alignedrecords.pas +0 -0
  90. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/legacy_snippets/constset.pas +0 -0
  91. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/legacy_snippets/deprecatedtype.pas +0 -0
  92. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/legacy_snippets/dottedtypes.pas +0 -0
  93. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/legacy_snippets/endtoken.pas +0 -0
  94. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/legacy_snippets/experimentals.pas +0 -0
  95. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/legacy_snippets/externalfunction.pas +0 -0
  96. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/legacy_snippets/finalizationinitializationexports.pas +0 -0
  97. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/legacy_snippets/forwardoverloaded.pas +0 -0
  98. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/legacy_snippets/forwardwithoutsemicolon.pas +0 -0
  99. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/legacy_snippets/genericconstraints.pas +0 -0
  100. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/legacy_snippets/genericinterfacemethoddelegation.pas +0 -0
  101. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/legacy_snippets/implementsgenerictype.pas +0 -0
  102. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/legacy_snippets/include file2.inc +0 -0
  103. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/legacy_snippets/includefile.inc +0 -0
  104. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/legacy_snippets/includefile.pas +0 -0
  105. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/legacy_snippets/managedrecords.pas +0 -0
  106. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/legacy_snippets/messagemethod.pas +0 -0
  107. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/legacy_snippets/multiline.pas +0 -0
  108. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/legacy_snippets/nonalignedrecords.pas +0 -0
  109. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/legacy_snippets/numbers.pas +0 -0
  110. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/legacy_snippets/pointerchars.pas +0 -0
  111. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/legacy_snippets/properties.pas +0 -0
  112. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/legacy_snippets/strictvisibility.pas +0 -0
  113. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/legacy_snippets/tryexcept.pas +0 -0
  114. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/legacy_snippets/umlauts.pas +0 -0
  115. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/legacy_snippets/whitespacearoundifdefcondition.pas +0 -0
  116. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/library_demo.dpr +0 -0
  117. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/package_demo.dpk +0 -0
  118. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/program_demo.dpr +0 -0
  119. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/unit_advanced.pas +0 -0
  120. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/unit_attributes.pas +0 -0
  121. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/unit_basic.pas +0 -0
  122. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/unit_consumer.pas +0 -0
  123. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/unit_generics.pas +0 -0
  124. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/unit_inheritance.pas +0 -0
  125. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/unit_math.pas +0 -0
  126. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/unit_properties.pas +0 -0
  127. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/unit_sections.pas +0 -0
  128. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/unit_statements.pas +0 -0
  129. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/unit_types.pas +0 -0
  130. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/unit_unresolved.pas +0 -0
  131. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/fixtures/unit_with.pas +0 -0
  132. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/test_language_feature_matrix.py +0 -0
  133. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/test_opencode_config.py +0 -0
  134. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/test_opencode_request_payloads.py +0 -0
  135. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/test_ornith_cache_prepare.py +0 -0
  136. {python_delphi_lsp-1.1.1 → python_delphi_lsp-2.0.0}/tests/test_vllm_start_script.py +0 -0
@@ -0,0 +1,324 @@
1
+ Metadata-Version: 2.4
2
+ Name: python-delphi-lsp
3
+ Version: 2.0.0
4
+ Summary: Python Delphi/Object Pascal parser, semantic indexer, and language server.
5
+ Author: Dark Light
6
+ License-Expression: MPL-2.0
7
+ Keywords: delphi,object-pascal,pascal,lsp,language-server,parser
8
+ Classifier: Development Status :: 5 - Production/Stable
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Operating System :: MacOS
12
+ Classifier: Operating System :: Microsoft :: Windows
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Programming Language :: Python :: 3.14
19
+ Classifier: Topic :: Software Development :: Compilers
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
+ Requires-Python: >=3.10
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: lark>=1.1.9
25
+ Requires-Dist: pygls<2.0,>=1.3.0
26
+ Requires-Dist: lsprotocol>=2023.0.1
27
+ Provides-Extra: lsp
28
+ Requires-Dist: pygls<2.0,>=1.3.0; extra == "lsp"
29
+ Requires-Dist: lsprotocol>=2023.0.1; extra == "lsp"
30
+ Provides-Extra: test
31
+ Requires-Dist: pytest>=8.0.0; extra == "test"
32
+ Provides-Extra: dev
33
+ Requires-Dist: build>=1.2.0; extra == "dev"
34
+ Requires-Dist: twine>=5.0.0; extra == "dev"
35
+ Requires-Dist: pygls<2.0,>=1.3.0; extra == "dev"
36
+ Requires-Dist: lsprotocol>=2023.0.1; extra == "dev"
37
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
38
+ Dynamic: license-file
39
+
40
+ # Python Delphi LSP
41
+
42
+ `python-delphi-lsp` parses Delphi/Object Pascal, builds semantic and project
43
+ indexes, serves LSP, and provides bounded codebase navigation for agents.
44
+ Version 2.0.0 is authored by Dark Light and supports Windows, macOS, and Linux.
45
+
46
+ ## Install and quick start
47
+
48
+ Install into the Python environment that will run the command:
49
+
50
+ ```bash
51
+ python -m pip install python-delphi-lsp
52
+ ```
53
+
54
+ On Windows, use `py -m pip install python-delphi-lsp` if that is your system
55
+ convention. On macOS and Linux, use `python3 -m pip install python-delphi-lsp`
56
+ when `python` is unavailable. Normal installed use needs neither a checkout
57
+ nor `PYTHONPATH`.
58
+
59
+ ```python
60
+ from delphi_lsp import parse
61
+
62
+ result = parse("unit Unit1; interface implementation end.", "Unit1.pas")
63
+ print(result.root)
64
+ ```
65
+
66
+ For semantic work across units, `build_workspace_semantics` returns per-file
67
+ models and a shared symbol index. `ProjectIndexer` follows a project entry
68
+ with explicit search paths, include paths, and defines.
69
+
70
+ ```python
71
+ from delphi_lsp import ProjectIndexer, build_workspace_semantics
72
+
73
+ workspace = build_workspace_semantics({
74
+ "Unit1.pas": "unit Unit1; interface uses Unit2; implementation end.",
75
+ "Unit2.pas": "unit Unit2; interface implementation end.",
76
+ })
77
+ print(workspace.index.lookup("Unit2"))
78
+
79
+ project = ProjectIndexer(
80
+ search_paths=["src"], include_paths=["include"], defines=["DEBUG"]
81
+ ).index("Main.dpr")
82
+ print(project.parsed_units)
83
+ ```
84
+
85
+ Run the stdio language server with `delphi-lsp`, or equivalently:
86
+
87
+ ```bash
88
+ python -m delphi_lsp.lsp_server
89
+ ```
90
+
91
+ ## OpenCode LSP configuration
92
+
93
+ The root `opencode.json` starts the installed package portably:
94
+
95
+ ```json
96
+ {
97
+ "lsp": {
98
+ "delphi": {
99
+ "command": ["delphi-lsp"],
100
+ "extensions": [".pas", ".dpr", ".dpk", ".inc"],
101
+ "initialization": {"autoDiscoverPaths": true}
102
+ }
103
+ }
104
+ }
105
+ ```
106
+
107
+ `autoDiscoverPaths` is the default. It discovers compiler context without an
108
+ environment section; LSP remains available for normal editor and OpenCode use,
109
+ including large sources.
110
+
111
+ The LSP builds its structural index through the same optimized outline path for
112
+ every source, with no file-size threshold. Definition, hover, references,
113
+ rename, completion, document symbols, workspace symbols, and diagnostics remain
114
+ registered for every file size; source-aware fallbacks keep body-level queries
115
+ available without returning the complete file as agent context.
116
+
117
+ ### Automatic discovery
118
+
119
+ Auto-discovery reads `.dpr`, `.dpk`, `.dproj`, `.cfg`, and `.dof` files.
120
+ Its resolution order is:
121
+
122
+ 1. An explicit project selection takes precedence.
123
+ 2. Otherwise, `.dpr` and `.dpk` candidates are considered.
124
+ 3. `MainSource` in a `.dproj` contributes its entry project.
125
+ 4. A selected entry associates same-stem `.dproj`, `.cfg`, and `.dof`.
126
+ 5. Unit search paths, include paths, and defines are accumulated from explicit
127
+ settings, project metadata, and the associated settings files.
128
+ 6. Direct `Unit in 'path/Unit.pas'` references contribute their parent
129
+ directory to unit search paths.
130
+
131
+ A single discovered project is selected automatically. With no project entry,
132
+ the server uses a synthetic workspace of supported sources. Scans skip build
133
+ and cache directories such as `build`, `dist`, environments, VCS folders,
134
+ `node_modules`, and tool caches. Missing paths and invalid metadata become
135
+ problems; paths are not guessed.
136
+
137
+ ## Agent CLI and Interface/Protocol v2
138
+
139
+ `delphi-lsp-agent` has these subcommands and options:
140
+
141
+ ```text
142
+ delphi-lsp-agent view --root PATH [--project-file FILE] --layer LAYER
143
+ [--query TEXT] [--format markdown|json] [--deep-projects]
144
+ delphi-lsp-agent index --root PATH [--project-file FILE] [--out FILE]
145
+ delphi-lsp-agent skill install [--target PATH] [--force]
146
+ delphi-lsp-agent opencode install [--target PATH] [--python PYTHON]
147
+ [--force] [--write-config]
148
+ delphi-lsp-agent worker --root PATH [--project-file FILE]
149
+ ```
150
+
151
+ `view --layer` accepts `overview`, `projects`, `units`, `unit`,
152
+ `symbols`, `symbol`, `implementation`, `references`, and `problems`.
153
+ `index` materializes overview, projects, and problems JSON. `skill install`
154
+ writes the skill; `opencode install` writes both integration files, while
155
+ `--write-config` additionally writes the restricted agent configuration.
156
+ `worker` serves NDJSON over standard input/output.
157
+
158
+ Protocol v2 actions are `open`, `find`, `inspect`, `trace`, `focus`,
159
+ and `problems`. Detail values are `summary`, `declaration`, `members`,
160
+ `context`, `body`, and `implementations`. Relations are `references`,
161
+ `callers`, `callees`, `uses`, `used_by`, `inherits`, and
162
+ `implements`.
163
+
164
+ A request requires `action` and can include `query`, `target_id`,
165
+ `project_id`, `detail`, `relation`, `cursor`, `max_items`, and
166
+ `max_chars`. Defaults are empty text fields, `detail: "summary"`, no
167
+ relation, `max_items: 12`, and `max_chars: 12000`. Ranges are 1–50 items
168
+ and 256–40000 characters. A successful envelope has `schema: 2`,
169
+ `workspace_revision`, `focus` (project, unit, and target IDs), `result`,
170
+ `page`, and `context`; errors have `schema: 2` and a code/message.
171
+
172
+ Focus preserves the selected project, unit, or target. Cursors bind a workspace
173
+ revision and request fingerprint, so source changes and cross-target or
174
+ cross-detail reuse invalidate them. `max_items` and `max_chars` bound each
175
+ response. A `sound_partial` relation is sound but incomplete: unresolved and
176
+ ambiguous relations are never fabricated.
177
+
178
+ For every source size the navigator builds an outline first, loads source detail
179
+ lazily for a selected target, and returns only selected fragments. Typed source
180
+ chunks are at most 6000 characters and also respect the response budget. This
181
+ optimization does not remove LSP functionality.
182
+
183
+ ## OpenCode semantic navigator
184
+
185
+ Install the generated integration in a worktree:
186
+
187
+ ```bash
188
+ delphi-lsp-agent opencode install --target . --write-config
189
+ ```
190
+
191
+ It writes:
192
+
193
+ ```text
194
+ .agents/skills/delphi-codebase-navigator/SKILL.md
195
+ .opencode/plugins/delphi_codebase.ts
196
+ ```
197
+
198
+ The generated configuration enables only the named
199
+ `delphi-codebase-navigator` skill and `delphi_codebase`. It denies
200
+ `bash`, `read`, `glob`, `grep`, and `lsp`, along with edit/write and
201
+ other raw source tools. The skill is enabled. The installer does not use the
202
+ retired `.opencode/tools` path.
203
+
204
+ The plugin maintains one worker per session/root, reusing focus and indexes.
205
+ During compaction it restores the focus and summary into the new context.
206
+ Transport failure, session deletion, and plugin disposal clean up the worker.
207
+
208
+ A generated OpenCode agent looks like this; providers and unrelated agents stay
209
+ unchanged:
210
+
211
+ ```json
212
+ {
213
+ "agent": {
214
+ "vllm-delphi-codebase": {
215
+ "tools": {
216
+ "delphi_codebase": true, "skill": true, "lsp": false,
217
+ "bash": false, "read": false, "glob": false, "grep": false
218
+ },
219
+ "permission": {
220
+ "delphi_codebase": "allow",
221
+ "skill": {"*": "deny", "delphi-codebase-navigator": "allow"},
222
+ "lsp": "deny"
223
+ }
224
+ }
225
+ }
226
+ }
227
+ ```
228
+
229
+ Select `vllm-delphi-codebase`, ask it to load
230
+ `delphi-codebase-navigator`, then use `delphi_codebase` actions such as
231
+ `open`, `find`, `focus`, and `inspect`. Use semantic tool calls, not raw
232
+ source tools.
233
+
234
+ For the root LSP configuration, a local model can be used as follows:
235
+
236
+ ```bash
237
+ opencode run --dir . --model ollama/ornith-lspctx --agent vllm-lsp \
238
+ "Find the declaration of a Delphi symbol through LSP."
239
+ ```
240
+
241
+ Use `--agent vllm-lsp-edit` only for the separate, focused LSP/edit
242
+ verification workflow; the semantic navigator agent above remains restricted
243
+ to its named skill and tool.
244
+
245
+ That separate verification uses `vllm/ornith-lspctx` and accepts the focused
246
+ LSP result `edit:Edit applied successfully`; it is not the semantic navigator
247
+ workflow and does not grant the navigator any raw source tools.
248
+
249
+ ## Reproducible large-project vLLM proof
250
+
251
+ The proof generates a 117,511-line project. The verifier requires `skill`, `open` (`Main.dpr` evidence), `find`, `focus`, and `inspect`,
252
+ checks `MegaProc02500` and `Value := Value + 40`, and forbids raw `bash`,
253
+ `read`, `glob`, and `grep`. It then waits for the final answer and requires the
254
+ exact body range `src/Mega100kUnit.pas:117464-117509` and the inspected
255
+ statement in that answer. The prompt requires returned range metadata instead
256
+ of a model-calculated line inside the source fragment.
257
+ The proof uses the local Ornith vLLM OpenAI-compatible
258
+ endpoint at `http://127.0.0.1:8001/v1`.
259
+
260
+ Default scripts are offline and must not redownload the model. First check the
261
+ cache:
262
+
263
+ ```bash
264
+ python scripts/check_ornith_cache.py --require-complete
265
+ ```
266
+
267
+ With an already-running endpoint on any supported platform, run:
268
+
269
+ ```bash
270
+ python scripts/bootstrap_vllm_codebase_skill_test.py --use-running-server
271
+ ```
272
+
273
+ On macOS, the offline cached auto-start path is:
274
+
275
+ ```bash
276
+ python scripts/bootstrap_vllm_codebase_skill_test.py --start-vllm
277
+ ```
278
+
279
+ Automatic local vLLM startup is macOS-only. The package and OpenCode plugin are
280
+ supported on Windows. On Windows, start an OpenAI-compatible vLLM endpoint, then
281
+ run the Python bootstrap from PowerShell:
282
+
283
+ ```powershell
284
+ python .\scripts\bootstrap_vllm_codebase_skill_test.py --use-running-server
285
+ ```
286
+
287
+ For an endpoint at another URL, add `--base-url`:
288
+
289
+ ```powershell
290
+ python .\scripts\bootstrap_vllm_codebase_skill_test.py --use-running-server --base-url http://127.0.0.1:9000/v1
291
+ ```
292
+
293
+ `--skip-install` is an optional acceleration for an already prepared `.venv`;
294
+ omit it on a clean checkout so the bootstrap installs `.[dev]`.
295
+ The final-answer verifier defaults to a 420-second probe timeout. On a slower
296
+ local model server, increase it explicitly with `--probe-timeout SECONDS`.
297
+
298
+ The bundled automatic helper is not a cross-platform startup mechanism.
299
+
300
+ ## Migration to 2.0
301
+
302
+ `delphi_lsp` is the only supported import namespace. Update imports directly;
303
+ there is no compatibility import alias.
304
+
305
+ ## Verification and limitations
306
+
307
+ For a checkout:
308
+
309
+ ```bash
310
+ python -m pip install -e ".[dev]"
311
+ python -m pytest
312
+ python -m build
313
+ python -m twine check dist/*
314
+ ```
315
+
316
+ CI tests Ubuntu, macOS, and Windows on Python 3.10 and 3.14, then builds and
317
+ smoke-installs the wheel on Ubuntu/Python 3.14. Results depend on available
318
+ project files, defines, includes, and paths; unsupported compiler behavior and
319
+ unresolvable references are reported as problems. The vLLM proof additionally
320
+ requires OpenCode, a local endpoint, and a complete local cache.
321
+
322
+ ## License
323
+
324
+ Mozilla Public License 2.0. See [LICENSE](LICENSE).
@@ -0,0 +1,285 @@
1
+ # Python Delphi LSP
2
+
3
+ `python-delphi-lsp` parses Delphi/Object Pascal, builds semantic and project
4
+ indexes, serves LSP, and provides bounded codebase navigation for agents.
5
+ Version 2.0.0 is authored by Dark Light and supports Windows, macOS, and Linux.
6
+
7
+ ## Install and quick start
8
+
9
+ Install into the Python environment that will run the command:
10
+
11
+ ```bash
12
+ python -m pip install python-delphi-lsp
13
+ ```
14
+
15
+ On Windows, use `py -m pip install python-delphi-lsp` if that is your system
16
+ convention. On macOS and Linux, use `python3 -m pip install python-delphi-lsp`
17
+ when `python` is unavailable. Normal installed use needs neither a checkout
18
+ nor `PYTHONPATH`.
19
+
20
+ ```python
21
+ from delphi_lsp import parse
22
+
23
+ result = parse("unit Unit1; interface implementation end.", "Unit1.pas")
24
+ print(result.root)
25
+ ```
26
+
27
+ For semantic work across units, `build_workspace_semantics` returns per-file
28
+ models and a shared symbol index. `ProjectIndexer` follows a project entry
29
+ with explicit search paths, include paths, and defines.
30
+
31
+ ```python
32
+ from delphi_lsp import ProjectIndexer, build_workspace_semantics
33
+
34
+ workspace = build_workspace_semantics({
35
+ "Unit1.pas": "unit Unit1; interface uses Unit2; implementation end.",
36
+ "Unit2.pas": "unit Unit2; interface implementation end.",
37
+ })
38
+ print(workspace.index.lookup("Unit2"))
39
+
40
+ project = ProjectIndexer(
41
+ search_paths=["src"], include_paths=["include"], defines=["DEBUG"]
42
+ ).index("Main.dpr")
43
+ print(project.parsed_units)
44
+ ```
45
+
46
+ Run the stdio language server with `delphi-lsp`, or equivalently:
47
+
48
+ ```bash
49
+ python -m delphi_lsp.lsp_server
50
+ ```
51
+
52
+ ## OpenCode LSP configuration
53
+
54
+ The root `opencode.json` starts the installed package portably:
55
+
56
+ ```json
57
+ {
58
+ "lsp": {
59
+ "delphi": {
60
+ "command": ["delphi-lsp"],
61
+ "extensions": [".pas", ".dpr", ".dpk", ".inc"],
62
+ "initialization": {"autoDiscoverPaths": true}
63
+ }
64
+ }
65
+ }
66
+ ```
67
+
68
+ `autoDiscoverPaths` is the default. It discovers compiler context without an
69
+ environment section; LSP remains available for normal editor and OpenCode use,
70
+ including large sources.
71
+
72
+ The LSP builds its structural index through the same optimized outline path for
73
+ every source, with no file-size threshold. Definition, hover, references,
74
+ rename, completion, document symbols, workspace symbols, and diagnostics remain
75
+ registered for every file size; source-aware fallbacks keep body-level queries
76
+ available without returning the complete file as agent context.
77
+
78
+ ### Automatic discovery
79
+
80
+ Auto-discovery reads `.dpr`, `.dpk`, `.dproj`, `.cfg`, and `.dof` files.
81
+ Its resolution order is:
82
+
83
+ 1. An explicit project selection takes precedence.
84
+ 2. Otherwise, `.dpr` and `.dpk` candidates are considered.
85
+ 3. `MainSource` in a `.dproj` contributes its entry project.
86
+ 4. A selected entry associates same-stem `.dproj`, `.cfg`, and `.dof`.
87
+ 5. Unit search paths, include paths, and defines are accumulated from explicit
88
+ settings, project metadata, and the associated settings files.
89
+ 6. Direct `Unit in 'path/Unit.pas'` references contribute their parent
90
+ directory to unit search paths.
91
+
92
+ A single discovered project is selected automatically. With no project entry,
93
+ the server uses a synthetic workspace of supported sources. Scans skip build
94
+ and cache directories such as `build`, `dist`, environments, VCS folders,
95
+ `node_modules`, and tool caches. Missing paths and invalid metadata become
96
+ problems; paths are not guessed.
97
+
98
+ ## Agent CLI and Interface/Protocol v2
99
+
100
+ `delphi-lsp-agent` has these subcommands and options:
101
+
102
+ ```text
103
+ delphi-lsp-agent view --root PATH [--project-file FILE] --layer LAYER
104
+ [--query TEXT] [--format markdown|json] [--deep-projects]
105
+ delphi-lsp-agent index --root PATH [--project-file FILE] [--out FILE]
106
+ delphi-lsp-agent skill install [--target PATH] [--force]
107
+ delphi-lsp-agent opencode install [--target PATH] [--python PYTHON]
108
+ [--force] [--write-config]
109
+ delphi-lsp-agent worker --root PATH [--project-file FILE]
110
+ ```
111
+
112
+ `view --layer` accepts `overview`, `projects`, `units`, `unit`,
113
+ `symbols`, `symbol`, `implementation`, `references`, and `problems`.
114
+ `index` materializes overview, projects, and problems JSON. `skill install`
115
+ writes the skill; `opencode install` writes both integration files, while
116
+ `--write-config` additionally writes the restricted agent configuration.
117
+ `worker` serves NDJSON over standard input/output.
118
+
119
+ Protocol v2 actions are `open`, `find`, `inspect`, `trace`, `focus`,
120
+ and `problems`. Detail values are `summary`, `declaration`, `members`,
121
+ `context`, `body`, and `implementations`. Relations are `references`,
122
+ `callers`, `callees`, `uses`, `used_by`, `inherits`, and
123
+ `implements`.
124
+
125
+ A request requires `action` and can include `query`, `target_id`,
126
+ `project_id`, `detail`, `relation`, `cursor`, `max_items`, and
127
+ `max_chars`. Defaults are empty text fields, `detail: "summary"`, no
128
+ relation, `max_items: 12`, and `max_chars: 12000`. Ranges are 1–50 items
129
+ and 256–40000 characters. A successful envelope has `schema: 2`,
130
+ `workspace_revision`, `focus` (project, unit, and target IDs), `result`,
131
+ `page`, and `context`; errors have `schema: 2` and a code/message.
132
+
133
+ Focus preserves the selected project, unit, or target. Cursors bind a workspace
134
+ revision and request fingerprint, so source changes and cross-target or
135
+ cross-detail reuse invalidate them. `max_items` and `max_chars` bound each
136
+ response. A `sound_partial` relation is sound but incomplete: unresolved and
137
+ ambiguous relations are never fabricated.
138
+
139
+ For every source size the navigator builds an outline first, loads source detail
140
+ lazily for a selected target, and returns only selected fragments. Typed source
141
+ chunks are at most 6000 characters and also respect the response budget. This
142
+ optimization does not remove LSP functionality.
143
+
144
+ ## OpenCode semantic navigator
145
+
146
+ Install the generated integration in a worktree:
147
+
148
+ ```bash
149
+ delphi-lsp-agent opencode install --target . --write-config
150
+ ```
151
+
152
+ It writes:
153
+
154
+ ```text
155
+ .agents/skills/delphi-codebase-navigator/SKILL.md
156
+ .opencode/plugins/delphi_codebase.ts
157
+ ```
158
+
159
+ The generated configuration enables only the named
160
+ `delphi-codebase-navigator` skill and `delphi_codebase`. It denies
161
+ `bash`, `read`, `glob`, `grep`, and `lsp`, along with edit/write and
162
+ other raw source tools. The skill is enabled. The installer does not use the
163
+ retired `.opencode/tools` path.
164
+
165
+ The plugin maintains one worker per session/root, reusing focus and indexes.
166
+ During compaction it restores the focus and summary into the new context.
167
+ Transport failure, session deletion, and plugin disposal clean up the worker.
168
+
169
+ A generated OpenCode agent looks like this; providers and unrelated agents stay
170
+ unchanged:
171
+
172
+ ```json
173
+ {
174
+ "agent": {
175
+ "vllm-delphi-codebase": {
176
+ "tools": {
177
+ "delphi_codebase": true, "skill": true, "lsp": false,
178
+ "bash": false, "read": false, "glob": false, "grep": false
179
+ },
180
+ "permission": {
181
+ "delphi_codebase": "allow",
182
+ "skill": {"*": "deny", "delphi-codebase-navigator": "allow"},
183
+ "lsp": "deny"
184
+ }
185
+ }
186
+ }
187
+ }
188
+ ```
189
+
190
+ Select `vllm-delphi-codebase`, ask it to load
191
+ `delphi-codebase-navigator`, then use `delphi_codebase` actions such as
192
+ `open`, `find`, `focus`, and `inspect`. Use semantic tool calls, not raw
193
+ source tools.
194
+
195
+ For the root LSP configuration, a local model can be used as follows:
196
+
197
+ ```bash
198
+ opencode run --dir . --model ollama/ornith-lspctx --agent vllm-lsp \
199
+ "Find the declaration of a Delphi symbol through LSP."
200
+ ```
201
+
202
+ Use `--agent vllm-lsp-edit` only for the separate, focused LSP/edit
203
+ verification workflow; the semantic navigator agent above remains restricted
204
+ to its named skill and tool.
205
+
206
+ That separate verification uses `vllm/ornith-lspctx` and accepts the focused
207
+ LSP result `edit:Edit applied successfully`; it is not the semantic navigator
208
+ workflow and does not grant the navigator any raw source tools.
209
+
210
+ ## Reproducible large-project vLLM proof
211
+
212
+ The proof generates a 117,511-line project. The verifier requires `skill`, `open` (`Main.dpr` evidence), `find`, `focus`, and `inspect`,
213
+ checks `MegaProc02500` and `Value := Value + 40`, and forbids raw `bash`,
214
+ `read`, `glob`, and `grep`. It then waits for the final answer and requires the
215
+ exact body range `src/Mega100kUnit.pas:117464-117509` and the inspected
216
+ statement in that answer. The prompt requires returned range metadata instead
217
+ of a model-calculated line inside the source fragment.
218
+ The proof uses the local Ornith vLLM OpenAI-compatible
219
+ endpoint at `http://127.0.0.1:8001/v1`.
220
+
221
+ Default scripts are offline and must not redownload the model. First check the
222
+ cache:
223
+
224
+ ```bash
225
+ python scripts/check_ornith_cache.py --require-complete
226
+ ```
227
+
228
+ With an already-running endpoint on any supported platform, run:
229
+
230
+ ```bash
231
+ python scripts/bootstrap_vllm_codebase_skill_test.py --use-running-server
232
+ ```
233
+
234
+ On macOS, the offline cached auto-start path is:
235
+
236
+ ```bash
237
+ python scripts/bootstrap_vllm_codebase_skill_test.py --start-vllm
238
+ ```
239
+
240
+ Automatic local vLLM startup is macOS-only. The package and OpenCode plugin are
241
+ supported on Windows. On Windows, start an OpenAI-compatible vLLM endpoint, then
242
+ run the Python bootstrap from PowerShell:
243
+
244
+ ```powershell
245
+ python .\scripts\bootstrap_vllm_codebase_skill_test.py --use-running-server
246
+ ```
247
+
248
+ For an endpoint at another URL, add `--base-url`:
249
+
250
+ ```powershell
251
+ python .\scripts\bootstrap_vllm_codebase_skill_test.py --use-running-server --base-url http://127.0.0.1:9000/v1
252
+ ```
253
+
254
+ `--skip-install` is an optional acceleration for an already prepared `.venv`;
255
+ omit it on a clean checkout so the bootstrap installs `.[dev]`.
256
+ The final-answer verifier defaults to a 420-second probe timeout. On a slower
257
+ local model server, increase it explicitly with `--probe-timeout SECONDS`.
258
+
259
+ The bundled automatic helper is not a cross-platform startup mechanism.
260
+
261
+ ## Migration to 2.0
262
+
263
+ `delphi_lsp` is the only supported import namespace. Update imports directly;
264
+ there is no compatibility import alias.
265
+
266
+ ## Verification and limitations
267
+
268
+ For a checkout:
269
+
270
+ ```bash
271
+ python -m pip install -e ".[dev]"
272
+ python -m pytest
273
+ python -m build
274
+ python -m twine check dist/*
275
+ ```
276
+
277
+ CI tests Ubuntu, macOS, and Windows on Python 3.10 and 3.14, then builds and
278
+ smoke-installs the wheel on Ubuntu/Python 3.14. Results depend on available
279
+ project files, defines, includes, and paths; unsupported compiler behavior and
280
+ unresolvable references are reported as problems. The vLLM proof additionally
281
+ requires OpenCode, a local endpoint, and a complete local cache.
282
+
283
+ ## License
284
+
285
+ Mozilla Public License 2.0. See [LICENSE](LICENSE).
@@ -1,3 +1,4 @@
1
+ from ._version import __version__
1
2
  from .binary import BinarySerializer, dumps, loads
2
3
  from .consts import AttributeName, SyntaxNodeType
3
4
  from .nodes import (
@@ -60,6 +61,7 @@ from .project_indexer import (
60
61
  )
61
62
 
62
63
  __all__ = [
64
+ '__version__',
63
65
  'AttributeName',
64
66
  'BinarySerializer',
65
67
  'CommentNode',
@@ -0,0 +1 @@
1
+ __version__ = "2.0.0"