python-delphi-lsp 2.0.3__tar.gz → 2.0.5__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 (139) hide show
  1. {python_delphi_lsp-2.0.3/python_delphi_lsp.egg-info → python_delphi_lsp-2.0.5}/PKG-INFO +73 -3
  2. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/README.md +72 -2
  3. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/delphi_lsp/__init__.py +3 -0
  4. python_delphi_lsp-2.0.5/delphi_lsp/_version.py +1 -0
  5. python_delphi_lsp-2.0.5/delphi_lsp/agent_cache.py +710 -0
  6. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/delphi_lsp/agent_cli.py +145 -3
  7. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/delphi_lsp/agent_context.py +30 -1
  8. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/delphi_lsp/agent_layers.py +115 -6
  9. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/delphi_lsp/agent_relations.py +0 -1
  10. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/delphi_lsp/agent_workspace.py +7 -0
  11. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/delphi_lsp/binary.py +0 -1
  12. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/delphi_lsp/lsp_server.py +195 -35
  13. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/delphi_lsp/preprocessor.py +32 -10
  14. python_delphi_lsp-2.0.5/delphi_lsp/progress.py +26 -0
  15. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/delphi_lsp/project_discovery.py +125 -16
  16. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/delphi_lsp/project_indexer.py +43 -1
  17. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/delphi_lsp/semantic.py +1 -1
  18. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/pyproject.toml +1 -1
  19. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5/python_delphi_lsp.egg-info}/PKG-INFO +73 -3
  20. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/python_delphi_lsp.egg-info/SOURCES.txt +4 -0
  21. python_delphi_lsp-2.0.5/tests/test_agent_cache.py +621 -0
  22. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/test_agent_codebase.py +104 -0
  23. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/test_agent_relations.py +15 -14
  24. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/test_agent_worker.py +174 -0
  25. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/test_lsp_features.py +0 -2
  26. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/test_lsp_support.py +243 -18
  27. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/test_package_metadata.py +3 -3
  28. python_delphi_lsp-2.0.5/tests/test_progress.py +56 -0
  29. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/test_project_discovery.py +77 -5
  30. python_delphi_lsp-2.0.3/delphi_lsp/_version.py +0 -1
  31. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/.github/workflows/ci.yml +0 -0
  32. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/LICENSE +0 -0
  33. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/MANIFEST.in +0 -0
  34. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/delphi_lsp/agent_metrics.py +0 -0
  35. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/delphi_lsp/agent_protocol.py +0 -0
  36. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/delphi_lsp/agent_templates.py +0 -0
  37. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/delphi_lsp/comment_builder.py +0 -0
  38. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/delphi_lsp/consts.py +0 -0
  39. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/delphi_lsp/grammar.py +0 -0
  40. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/delphi_lsp/lark_builder.py +0 -0
  41. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/delphi_lsp/lark_tokens.py +0 -0
  42. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/delphi_lsp/metrics.py +0 -0
  43. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/delphi_lsp/nodes.py +0 -0
  44. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/delphi_lsp/parser.py +0 -0
  45. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/delphi_lsp/semantic_builder.py +0 -0
  46. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/delphi_lsp/source_reader.py +0 -0
  47. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/delphi_lsp/workspace.py +0 -0
  48. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/delphi_lsp/writer.py +0 -0
  49. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/opencode.json +0 -0
  50. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/python_delphi_lsp.egg-info/dependency_links.txt +0 -0
  51. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/python_delphi_lsp.egg-info/entry_points.txt +0 -0
  52. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/python_delphi_lsp.egg-info/requires.txt +0 -0
  53. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/python_delphi_lsp.egg-info/top_level.txt +0 -0
  54. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/scripts/audit_delphi_language_features.py +0 -0
  55. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/scripts/benchmark_github_corpus.py +0 -0
  56. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/scripts/bootstrap_vllm_codebase_skill_test.py +0 -0
  57. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/scripts/bootstrap_vllm_opencode_test.ps1 +0 -0
  58. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/scripts/bootstrap_vllm_opencode_test.py +0 -0
  59. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/scripts/bootstrap_vllm_opencode_test.sh +0 -0
  60. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/scripts/build_github_performance_corpus.py +0 -0
  61. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/scripts/check_ornith_cache.py +0 -0
  62. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/scripts/generate_progress_pdf.py +0 -0
  63. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/scripts/generate_release_evidence.py +0 -0
  64. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/scripts/ollama/ornith-lspctx.Modelfile +0 -0
  65. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/scripts/prepare_ornith_cache.py +0 -0
  66. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/scripts/run_opencode_lsp_probe.py +0 -0
  67. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/scripts/run_openrouter_github_e2e.py +0 -0
  68. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/scripts/start_ornith_vllm.sh +0 -0
  69. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/scripts/summarize_opencode_request_payloads.py +0 -0
  70. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/setup.cfg +0 -0
  71. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/corpora.performance.lock.json +0 -0
  72. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/legacy_snippets/DeprecatedOnConst.pas +0 -0
  73. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/legacy_snippets/VariantRecordFieldAttributes.pas +0 -0
  74. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/legacy_snippets/alignedrecords.pas +0 -0
  75. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/legacy_snippets/constset.pas +0 -0
  76. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/legacy_snippets/deprecatedtype.pas +0 -0
  77. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/legacy_snippets/dottedtypes.pas +0 -0
  78. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/legacy_snippets/endtoken.pas +0 -0
  79. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/legacy_snippets/experimentals.pas +0 -0
  80. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/legacy_snippets/externalfunction.pas +0 -0
  81. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/legacy_snippets/finalizationinitializationexports.pas +0 -0
  82. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/legacy_snippets/forwardoverloaded.pas +0 -0
  83. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/legacy_snippets/forwardwithoutsemicolon.pas +0 -0
  84. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/legacy_snippets/genericconstraints.pas +0 -0
  85. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/legacy_snippets/genericinterfacemethoddelegation.pas +0 -0
  86. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/legacy_snippets/implementsgenerictype.pas +0 -0
  87. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/legacy_snippets/include file2.inc +0 -0
  88. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/legacy_snippets/includefile.inc +0 -0
  89. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/legacy_snippets/includefile.pas +0 -0
  90. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/legacy_snippets/managedrecords.pas +0 -0
  91. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/legacy_snippets/messagemethod.pas +0 -0
  92. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/legacy_snippets/multiline.pas +0 -0
  93. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/legacy_snippets/nonalignedrecords.pas +0 -0
  94. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/legacy_snippets/numbers.pas +0 -0
  95. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/legacy_snippets/pointerchars.pas +0 -0
  96. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/legacy_snippets/properties.pas +0 -0
  97. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/legacy_snippets/strictvisibility.pas +0 -0
  98. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/legacy_snippets/tryexcept.pas +0 -0
  99. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/legacy_snippets/umlauts.pas +0 -0
  100. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/legacy_snippets/whitespacearoundifdefcondition.pas +0 -0
  101. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/library_demo.dpr +0 -0
  102. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/package_demo.dpk +0 -0
  103. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/program_demo.dpr +0 -0
  104. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/unit_advanced.pas +0 -0
  105. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/unit_attributes.pas +0 -0
  106. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/unit_basic.pas +0 -0
  107. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/unit_consumer.pas +0 -0
  108. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/unit_generics.pas +0 -0
  109. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/unit_inheritance.pas +0 -0
  110. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/unit_math.pas +0 -0
  111. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/unit_properties.pas +0 -0
  112. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/unit_sections.pas +0 -0
  113. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/unit_statements.pas +0 -0
  114. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/unit_types.pas +0 -0
  115. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/unit_unresolved.pas +0 -0
  116. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/fixtures/unit_with.pas +0 -0
  117. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/test_agent_context.py +0 -0
  118. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/test_agent_metrics.py +0 -0
  119. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/test_agent_protocol.py +0 -0
  120. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/test_agent_workspace.py +0 -0
  121. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/test_bootstrap_vllm_codebase_skill.py +0 -0
  122. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/test_bootstrap_vllm_opencode.py +0 -0
  123. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/test_diagnostics.py +0 -0
  124. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/test_github_performance_corpus.py +0 -0
  125. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/test_language_feature_matrix.py +0 -0
  126. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/test_legacy_snippets.py +0 -0
  127. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/test_metrics.py +0 -0
  128. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/test_opencode_config.py +0 -0
  129. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/test_opencode_probe.py +0 -0
  130. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/test_opencode_request_payloads.py +0 -0
  131. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/test_openrouter_github_e2e.py +0 -0
  132. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/test_ornith_cache_prepare.py +0 -0
  133. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/test_parser.py +0 -0
  134. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/test_preprocessor.py +0 -0
  135. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/test_project_indexer.py +0 -0
  136. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/test_release_evidence.py +0 -0
  137. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/test_semantic.py +0 -0
  138. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/tests/test_vllm_start_script.py +0 -0
  139. {python_delphi_lsp-2.0.3 → python_delphi_lsp-2.0.5}/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
3
+ Version: 2.0.5
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.3 is authored by Dark Light and supports Windows, macOS, and Linux.
44
+ Version 2.0.5 is authored by Dark Light and supports Windows, macOS, and Linux.
45
45
 
46
46
  ## Install and quick start
47
47
 
@@ -82,6 +82,19 @@ project = ProjectIndexer(
82
82
  print(project.parsed_units)
83
83
  ```
84
84
 
85
+ Long-running discovery and indexing accept a keyword-only `on_progress`
86
+ callback. It receives an immutable `ProgressEvent` with package-controlled
87
+ phase, path, and monotonic counters; callback exceptions are not suppressed.
88
+
89
+ ```python
90
+ from delphi_lsp import ProjectIndexer, ProgressEvent
91
+
92
+ def report(event: ProgressEvent) -> None:
93
+ print(event.phase, event.files_completed, event.path)
94
+
95
+ ProjectIndexer(on_progress=report).index("Main.dpr")
96
+ ```
97
+
85
98
  ## Architecture metrics
86
99
 
87
100
  The public metrics API analyzes a single unit or aggregates a complete project:
@@ -172,15 +185,67 @@ problems; paths are not guessed.
172
185
  `delphi-lsp-agent` has these subcommands and options:
173
186
 
174
187
  ```text
188
+ delphi-lsp-agent cache start --root PATH [--project-file FILE] [--max-memory 512M]
189
+ [--idle-timeout 1800]
190
+ delphi-lsp-agent cache status --root PATH [--format text|json]
191
+ delphi-lsp-agent cache stop --root PATH
175
192
  delphi-lsp-agent view --root PATH [--project-file FILE] --layer LAYER
176
193
  [--query TEXT] [--format markdown|json] [--deep-projects]
177
194
  delphi-lsp-agent index --root PATH [--project-file FILE] [--out FILE]
195
+ delphi-lsp-agent query --root PATH ACTION [VALUE]
196
+ [--project-id FILE] [--detail summary|declaration|members|context|body|implementations]
197
+ [--relation references|callers|callees|uses|used_by|inherits|implements]
198
+ [--cursor TEXT] [--max-items INT] [--max-chars INT]
178
199
  delphi-lsp-agent skill install [--target PATH] [--force]
179
200
  delphi-lsp-agent opencode install [--target PATH] [--python PYTHON]
180
201
  [--force] [--write-agent|--write-config]
181
202
  delphi-lsp-agent worker --root PATH [--project-file FILE]
182
203
  ```
183
204
 
205
+ The `cache` commands manage one daemon per canonical root. Use these:
206
+
207
+ ```bash
208
+ delphi-lsp-agent cache start --root PATH
209
+ delphi-lsp-agent cache status --root PATH
210
+ delphi-lsp-agent cache stop --root PATH
211
+ ```
212
+
213
+ `cache start` outputs cache lifecycle JSON; runtime warnings are still on stderr.
214
+ `cache status --format json` outputs status JSON to stdout and the same warning stream on stderr.
215
+ `cache stop` outputs stop status JSON and may include warnings on stderr.
216
+ `query` outputs Protocol v2 JSON responses and writes warnings to stderr.
217
+
218
+ ```bash
219
+ delphi-lsp-agent query --root PATH find TCustomer
220
+ delphi-lsp-agent query --root PATH focus TARGET_ID
221
+ delphi-lsp-agent query --root PATH inspect
222
+ delphi-lsp-agent query --root PATH trace TARGET_ID --relation callers
223
+ delphi-lsp-agent query --root PATH metrics
224
+ delphi-lsp-agent query --root PATH metrics UNIT_QUERY
225
+ delphi-lsp-agent cache status --root PATH --format json
226
+ ```
227
+
228
+ `inspect` uses the currently focused target, so call `focus TARGET_ID` before
229
+ `inspect` unless a previous request already selected it.
230
+
231
+ The cache daemon prewarms the navigation cache at startup so first `find` requests are
232
+ fast. The cache retained-cache budget is `512 MiB` by default and tracks retained
233
+ cache usage only, not a hard RSS/parse peak. Warnings are emitted on stderr at or
234
+ above 80 percent.
235
+
236
+ Eviction is ordered: auxiliary caches are evicted first, navigation caches second.
237
+ If compaction removes navigable data, the daemon rebuilds the navigation state on demand
238
+ while preserving focus state for the next request.
239
+
240
+ The daemon tracks a 30-minute idle timeout; idle state shows in JSON status (`cache status`).
241
+ `source revision` changes on source edits and invalidate reused request caches.
242
+ Workspace state appears in status as `requests`, `warm_hits`, `rebuilds`, `invalidations`,
243
+ `evictions`, and `cache_state`.
244
+
245
+ Metadata is stored in `.delphi-lsp/agent-cache/daemon.json` with owner-only token and
246
+ permissions (`daemon.json` mode 600 and parent 700). Do not copy or share this token
247
+ outside the root workspace.
248
+
184
249
  `view --layer` accepts `overview`, `projects`, `units`, `unit`,
185
250
  `symbols`, `symbol`, `implementation`, `references`, `problems`, and
186
251
  `metrics`. For example, `delphi-lsp-agent view --layer metrics --format json`
@@ -214,7 +279,7 @@ Focus preserves the selected project, unit, or target. Cursors bind a workspace
214
279
  revision and request fingerprint, so source changes and cross-target or
215
280
  cross-detail reuse invalidate them. `max_items` and `max_chars` bound each
216
281
  response. A `sound_partial` relation is sound but incomplete: unresolved and
217
- ambiguous relations are never fabricated.
282
+ ambiguous relations are never fabricated. Unsupported relations are rejected.
218
283
 
219
284
  For every source size the navigator builds an outline first, loads source detail
220
285
  lazily for a selected target, and returns only selected fragments. Typed source
@@ -249,6 +314,11 @@ The plugin maintains one worker per session/root, reusing focus and indexes.
249
314
  During compaction it restores the focus and summary into the new context.
250
315
  Transport failure, session deletion, and plugin disposal clean up the worker.
251
316
 
317
+ OpenCode history: 1.1.0 and 1.1.1 used a spawned view per call model.
318
+ Persistent session/root worker support first shipped in 2.0.0.
319
+ This is the same persistent session/root worker boundary.
320
+ The OpenCode worker stays separate from CLI daemon, and current plugin behavior is unchanged.
321
+
252
322
  A generated OpenCode agent starts with this Markdown frontmatter:
253
323
 
254
324
  ```markdown
@@ -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.3 is authored by Dark Light and supports Windows, macOS, and Linux.
5
+ Version 2.0.5 is authored by Dark Light and supports Windows, macOS, and Linux.
6
6
 
7
7
  ## Install and quick start
8
8
 
@@ -43,6 +43,19 @@ project = ProjectIndexer(
43
43
  print(project.parsed_units)
44
44
  ```
45
45
 
46
+ Long-running discovery and indexing accept a keyword-only `on_progress`
47
+ callback. It receives an immutable `ProgressEvent` with package-controlled
48
+ phase, path, and monotonic counters; callback exceptions are not suppressed.
49
+
50
+ ```python
51
+ from delphi_lsp import ProjectIndexer, ProgressEvent
52
+
53
+ def report(event: ProgressEvent) -> None:
54
+ print(event.phase, event.files_completed, event.path)
55
+
56
+ ProjectIndexer(on_progress=report).index("Main.dpr")
57
+ ```
58
+
46
59
  ## Architecture metrics
47
60
 
48
61
  The public metrics API analyzes a single unit or aggregates a complete project:
@@ -133,15 +146,67 @@ problems; paths are not guessed.
133
146
  `delphi-lsp-agent` has these subcommands and options:
134
147
 
135
148
  ```text
149
+ delphi-lsp-agent cache start --root PATH [--project-file FILE] [--max-memory 512M]
150
+ [--idle-timeout 1800]
151
+ delphi-lsp-agent cache status --root PATH [--format text|json]
152
+ delphi-lsp-agent cache stop --root PATH
136
153
  delphi-lsp-agent view --root PATH [--project-file FILE] --layer LAYER
137
154
  [--query TEXT] [--format markdown|json] [--deep-projects]
138
155
  delphi-lsp-agent index --root PATH [--project-file FILE] [--out FILE]
156
+ delphi-lsp-agent query --root PATH ACTION [VALUE]
157
+ [--project-id FILE] [--detail summary|declaration|members|context|body|implementations]
158
+ [--relation references|callers|callees|uses|used_by|inherits|implements]
159
+ [--cursor TEXT] [--max-items INT] [--max-chars INT]
139
160
  delphi-lsp-agent skill install [--target PATH] [--force]
140
161
  delphi-lsp-agent opencode install [--target PATH] [--python PYTHON]
141
162
  [--force] [--write-agent|--write-config]
142
163
  delphi-lsp-agent worker --root PATH [--project-file FILE]
143
164
  ```
144
165
 
166
+ The `cache` commands manage one daemon per canonical root. Use these:
167
+
168
+ ```bash
169
+ delphi-lsp-agent cache start --root PATH
170
+ delphi-lsp-agent cache status --root PATH
171
+ delphi-lsp-agent cache stop --root PATH
172
+ ```
173
+
174
+ `cache start` outputs cache lifecycle JSON; runtime warnings are still on stderr.
175
+ `cache status --format json` outputs status JSON to stdout and the same warning stream on stderr.
176
+ `cache stop` outputs stop status JSON and may include warnings on stderr.
177
+ `query` outputs Protocol v2 JSON responses and writes warnings to stderr.
178
+
179
+ ```bash
180
+ delphi-lsp-agent query --root PATH find TCustomer
181
+ delphi-lsp-agent query --root PATH focus TARGET_ID
182
+ delphi-lsp-agent query --root PATH inspect
183
+ delphi-lsp-agent query --root PATH trace TARGET_ID --relation callers
184
+ delphi-lsp-agent query --root PATH metrics
185
+ delphi-lsp-agent query --root PATH metrics UNIT_QUERY
186
+ delphi-lsp-agent cache status --root PATH --format json
187
+ ```
188
+
189
+ `inspect` uses the currently focused target, so call `focus TARGET_ID` before
190
+ `inspect` unless a previous request already selected it.
191
+
192
+ The cache daemon prewarms the navigation cache at startup so first `find` requests are
193
+ fast. The cache retained-cache budget is `512 MiB` by default and tracks retained
194
+ cache usage only, not a hard RSS/parse peak. Warnings are emitted on stderr at or
195
+ above 80 percent.
196
+
197
+ Eviction is ordered: auxiliary caches are evicted first, navigation caches second.
198
+ If compaction removes navigable data, the daemon rebuilds the navigation state on demand
199
+ while preserving focus state for the next request.
200
+
201
+ The daemon tracks a 30-minute idle timeout; idle state shows in JSON status (`cache status`).
202
+ `source revision` changes on source edits and invalidate reused request caches.
203
+ Workspace state appears in status as `requests`, `warm_hits`, `rebuilds`, `invalidations`,
204
+ `evictions`, and `cache_state`.
205
+
206
+ Metadata is stored in `.delphi-lsp/agent-cache/daemon.json` with owner-only token and
207
+ permissions (`daemon.json` mode 600 and parent 700). Do not copy or share this token
208
+ outside the root workspace.
209
+
145
210
  `view --layer` accepts `overview`, `projects`, `units`, `unit`,
146
211
  `symbols`, `symbol`, `implementation`, `references`, `problems`, and
147
212
  `metrics`. For example, `delphi-lsp-agent view --layer metrics --format json`
@@ -175,7 +240,7 @@ Focus preserves the selected project, unit, or target. Cursors bind a workspace
175
240
  revision and request fingerprint, so source changes and cross-target or
176
241
  cross-detail reuse invalidate them. `max_items` and `max_chars` bound each
177
242
  response. A `sound_partial` relation is sound but incomplete: unresolved and
178
- ambiguous relations are never fabricated.
243
+ ambiguous relations are never fabricated. Unsupported relations are rejected.
179
244
 
180
245
  For every source size the navigator builds an outline first, loads source detail
181
246
  lazily for a selected target, and returns only selected fragments. Typed source
@@ -210,6 +275,11 @@ The plugin maintains one worker per session/root, reusing focus and indexes.
210
275
  During compaction it restores the focus and summary into the new context.
211
276
  Transport failure, session deletion, and plugin disposal clean up the worker.
212
277
 
278
+ OpenCode history: 1.1.0 and 1.1.1 used a spawned view per call model.
279
+ Persistent session/root worker support first shipped in 2.0.0.
280
+ This is the same persistent session/root worker boundary.
281
+ The OpenCode worker stays separate from CLI daemon, and current plugin behavior is unchanged.
282
+
213
283
  A generated OpenCode agent starts with this Markdown frontmatter:
214
284
 
215
285
  ```markdown
@@ -48,6 +48,7 @@ from .semantic_builder import SemanticBuilder, SemanticModel, SemanticProblem
48
48
  from .workspace import WorkspaceSemanticResult, build_workspace_semantics
49
49
  from .lsp_server import LspWorkspaceState, create_server
50
50
  from .project_discovery import DelphiProjectDiscovery, DiscoveryProblem, discover_delphi_project
51
+ from .progress import ProgressCallback, ProgressEvent
51
52
  from .project_indexer import (
52
53
  GetUnitSyntaxHook,
53
54
  IncludeFileInfo,
@@ -136,6 +137,8 @@ __all__ = [
136
137
  'DelphiProjectDiscovery',
137
138
  'DiscoveryProblem',
138
139
  'discover_delphi_project',
140
+ 'ProgressCallback',
141
+ 'ProgressEvent',
139
142
  'ProjectIndexer',
140
143
  'ProjectIndexResult',
141
144
  'ProjectProblemType',
@@ -0,0 +1 @@
1
+ __version__ = "2.0.5"