python-delphi-lsp 3.0.0__tar.gz → 3.1.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 (160) hide show
  1. {python_delphi_lsp-3.0.0/python_delphi_lsp.egg-info → python_delphi_lsp-3.1.0}/PKG-INFO +40 -3
  2. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/README.md +39 -2
  3. python_delphi_lsp-3.1.0/delphi_lsp/_version.py +1 -0
  4. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/agent_cli.py +32 -0
  5. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/agent_layers.py +1 -1
  6. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/agent_metrics.py +110 -1
  7. python_delphi_lsp-3.1.0/delphi_lsp/agent_wiki.py +1084 -0
  8. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/pyproject.toml +1 -1
  9. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0/python_delphi_lsp.egg-info}/PKG-INFO +40 -3
  10. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/python_delphi_lsp.egg-info/SOURCES.txt +2 -0
  11. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_agent_codebase.py +31 -0
  12. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_agent_metrics.py +32 -0
  13. python_delphi_lsp-3.1.0/tests/test_agent_wiki.py +347 -0
  14. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_package_metadata.py +15 -3
  15. python_delphi_lsp-3.0.0/delphi_lsp/_version.py +0 -1
  16. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/.github/workflows/ci.yml +0 -0
  17. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/LICENSE +0 -0
  18. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/MANIFEST.in +0 -0
  19. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/__init__.py +0 -0
  20. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/agent_cache.py +0 -0
  21. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/agent_context.py +0 -0
  22. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/agent_cpg.py +0 -0
  23. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/agent_cpg_builder.py +0 -0
  24. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/agent_protocol.py +0 -0
  25. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/agent_relations.py +0 -0
  26. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/agent_templates.py +0 -0
  27. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/agent_workspace.py +0 -0
  28. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/binary.py +0 -0
  29. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/comment_builder.py +0 -0
  30. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/consts.py +0 -0
  31. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/delphiast_lexer.py +0 -0
  32. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/delphiast_parser.py +0 -0
  33. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/delphiast_tokens.py +0 -0
  34. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/grammar.py +0 -0
  35. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/lark_builder.py +0 -0
  36. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/lark_tokens.py +0 -0
  37. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/lsp_server.py +0 -0
  38. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/metrics.py +0 -0
  39. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/navigation_cache.py +0 -0
  40. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/nodes.py +0 -0
  41. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/parallel_outline.py +0 -0
  42. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/parser.py +0 -0
  43. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/parser_backend.py +0 -0
  44. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/preprocessor.py +0 -0
  45. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/progress.py +0 -0
  46. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/project_discovery.py +0 -0
  47. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/project_indexer.py +0 -0
  48. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/semantic.py +0 -0
  49. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/semantic_builder.py +0 -0
  50. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/source_reader.py +0 -0
  51. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/workspace.py +0 -0
  52. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/delphi_lsp/writer.py +0 -0
  53. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/opencode.json +0 -0
  54. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/python_delphi_lsp.egg-info/dependency_links.txt +0 -0
  55. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/python_delphi_lsp.egg-info/entry_points.txt +0 -0
  56. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/python_delphi_lsp.egg-info/requires.txt +0 -0
  57. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/python_delphi_lsp.egg-info/top_level.txt +0 -0
  58. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/scripts/audit_delphi_language_features.py +0 -0
  59. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/scripts/benchmark_cpg.py +0 -0
  60. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/scripts/benchmark_github_corpus.py +0 -0
  61. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/scripts/benchmark_parallel_cache.py +0 -0
  62. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/scripts/bootstrap_vllm_codebase_skill_test.py +0 -0
  63. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/scripts/bootstrap_vllm_opencode_test.ps1 +0 -0
  64. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/scripts/bootstrap_vllm_opencode_test.py +0 -0
  65. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/scripts/bootstrap_vllm_opencode_test.sh +0 -0
  66. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/scripts/build_github_performance_corpus.py +0 -0
  67. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/scripts/check_ornith_cache.py +0 -0
  68. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/scripts/generate_progress_pdf.py +0 -0
  69. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/scripts/generate_release_evidence.py +0 -0
  70. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/scripts/ollama/ornith-lspctx.Modelfile +0 -0
  71. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/scripts/prepare_ornith_cache.py +0 -0
  72. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/scripts/run_opencode_lsp_probe.py +0 -0
  73. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/scripts/run_openrouter_github_e2e.py +0 -0
  74. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/scripts/start_ornith_vllm.sh +0 -0
  75. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/scripts/summarize_opencode_request_payloads.py +0 -0
  76. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/setup.cfg +0 -0
  77. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/corpora.performance.lock.json +0 -0
  78. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/legacy_snippets/DeprecatedOnConst.pas +0 -0
  79. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/legacy_snippets/VariantRecordFieldAttributes.pas +0 -0
  80. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/legacy_snippets/alignedrecords.pas +0 -0
  81. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/legacy_snippets/constset.pas +0 -0
  82. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/legacy_snippets/deprecatedtype.pas +0 -0
  83. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/legacy_snippets/dottedtypes.pas +0 -0
  84. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/legacy_snippets/endtoken.pas +0 -0
  85. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/legacy_snippets/experimentals.pas +0 -0
  86. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/legacy_snippets/externalfunction.pas +0 -0
  87. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/legacy_snippets/finalizationinitializationexports.pas +0 -0
  88. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/legacy_snippets/forwardoverloaded.pas +0 -0
  89. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/legacy_snippets/forwardwithoutsemicolon.pas +0 -0
  90. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/legacy_snippets/genericconstraints.pas +0 -0
  91. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/legacy_snippets/genericinterfacemethoddelegation.pas +0 -0
  92. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/legacy_snippets/implementsgenerictype.pas +0 -0
  93. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/legacy_snippets/include file2.inc +0 -0
  94. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/legacy_snippets/includefile.inc +0 -0
  95. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/legacy_snippets/includefile.pas +0 -0
  96. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/legacy_snippets/managedrecords.pas +0 -0
  97. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/legacy_snippets/messagemethod.pas +0 -0
  98. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/legacy_snippets/multiline.pas +0 -0
  99. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/legacy_snippets/nonalignedrecords.pas +0 -0
  100. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/legacy_snippets/numbers.pas +0 -0
  101. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/legacy_snippets/pointerchars.pas +0 -0
  102. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/legacy_snippets/properties.pas +0 -0
  103. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/legacy_snippets/strictvisibility.pas +0 -0
  104. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/legacy_snippets/tryexcept.pas +0 -0
  105. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/legacy_snippets/umlauts.pas +0 -0
  106. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/legacy_snippets/whitespacearoundifdefcondition.pas +0 -0
  107. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/library_demo.dpr +0 -0
  108. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/package_demo.dpk +0 -0
  109. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/program_demo.dpr +0 -0
  110. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/unit_advanced.pas +0 -0
  111. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/unit_attributes.pas +0 -0
  112. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/unit_basic.pas +0 -0
  113. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/unit_consumer.pas +0 -0
  114. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/unit_generics.pas +0 -0
  115. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/unit_inheritance.pas +0 -0
  116. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/unit_math.pas +0 -0
  117. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/unit_properties.pas +0 -0
  118. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/unit_sections.pas +0 -0
  119. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/unit_statements.pas +0 -0
  120. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/unit_types.pas +0 -0
  121. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/unit_unresolved.pas +0 -0
  122. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/fixtures/unit_with.pas +0 -0
  123. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_agent_cache.py +0 -0
  124. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_agent_cli_errors.py +0 -0
  125. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_agent_context.py +0 -0
  126. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_agent_cpg.py +0 -0
  127. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_agent_protocol.py +0 -0
  128. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_agent_relations.py +0 -0
  129. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_agent_worker.py +0 -0
  130. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_agent_workspace.py +0 -0
  131. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_bootstrap_vllm_codebase_skill.py +0 -0
  132. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_bootstrap_vllm_opencode.py +0 -0
  133. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_delphiast_lexer.py +0 -0
  134. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_delphiast_native_compatibility.py +0 -0
  135. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_delphiast_parser.py +0 -0
  136. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_delphiast_semantic_compatibility.py +0 -0
  137. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_diagnostics.py +0 -0
  138. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_github_performance_corpus.py +0 -0
  139. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_language_feature_matrix.py +0 -0
  140. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_legacy_snippets.py +0 -0
  141. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_lsp_features.py +0 -0
  142. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_lsp_support.py +0 -0
  143. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_metrics.py +0 -0
  144. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_navigation_cache.py +0 -0
  145. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_opencode_config.py +0 -0
  146. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_opencode_probe.py +0 -0
  147. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_opencode_request_payloads.py +0 -0
  148. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_openrouter_github_e2e.py +0 -0
  149. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_ornith_cache_prepare.py +0 -0
  150. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_parallel_outline.py +0 -0
  151. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_parser.py +0 -0
  152. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_parser_backends.py +0 -0
  153. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_preprocessor.py +0 -0
  154. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_progress.py +0 -0
  155. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_project_discovery.py +0 -0
  156. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_project_indexer.py +0 -0
  157. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_release_evidence.py +0 -0
  158. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_semantic.py +0 -0
  159. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_vllm_start_script.py +0 -0
  160. {python_delphi_lsp-3.0.0 → python_delphi_lsp-3.1.0}/tests/test_workspace.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-delphi-lsp
3
- Version: 3.0.0
3
+ Version: 3.1.0
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
@@ -42,7 +42,7 @@ Dynamic: license-file
42
42
 
43
43
  `python-delphi-lsp` parses Delphi/Object Pascal, builds semantic and project
44
44
  indexes, serves LSP, and provides bounded codebase navigation for agents.
45
- Version 3.0.0 is authored by Dark Light and supports Windows, macOS, and Linux.
45
+ Version 3.1.0 is authored by Dark Light and supports Windows, macOS, and Linux.
46
46
 
47
47
  ## Install and quick start
48
48
 
@@ -199,6 +199,8 @@ delphi-lsp-agent view --root PATH [--project-file FILE] --layer LAYER
199
199
  [--workers auto|N]
200
200
  delphi-lsp-agent index --root PATH [--project-file FILE] [--out FILE]
201
201
  [--workers auto|N]
202
+ delphi-lsp-agent wiki export --root PATH [--project-file FILE] [--out DIRECTORY]
203
+ [--workers auto|N] [--force]
202
204
  delphi-lsp-agent query --root PATH ACTION [VALUE]
203
205
  [--project-id ID] [--detail summary|declaration|members|context|body|implementations]
204
206
  [--relation references|callers|callees|uses|used_by|inherits|implements]
@@ -224,6 +226,40 @@ delphi-lsp-agent cache stop --root PATH
224
226
  `cache stop` outputs stop status JSON and may include warnings on stderr.
225
227
  `query` outputs Protocol v3 JSON responses and writes warnings to stderr.
226
228
 
229
+ ### Open Knowledge Format wiki export
230
+
231
+ Export the complete unique knowledge represented by the layered codebase views
232
+ as a portable Markdown wiki:
233
+
234
+ ```bash
235
+ delphi-lsp-agent wiki export --root PATH --out codebase-wiki
236
+ ```
237
+
238
+ When `--out` is relative, it is resolved below `--root`; the default is
239
+ `.delphi-lsp/wiki`. The command builds the semantic index once, deep-indexes
240
+ discovered projects, calculates workspace and unit metrics, and writes:
241
+
242
+ - an OKF 0.2 root `index.md`;
243
+ - linked project, unit, and symbol concepts;
244
+ - declaration and implementation source fragments;
245
+ - resolved and unresolved semantic references;
246
+ - discovery/project problems and complete metric records;
247
+ - Protocol v3, relation, CPG, cache, and layer-mapping reference concepts.
248
+
249
+ Every non-index concept is UTF-8 Markdown with YAML frontmatter and a non-empty
250
+ `type`. Readable filenames include a stable digest, so overloads and equal names
251
+ from different units remain distinct even on case-insensitive filesystems.
252
+ Output order and content are deterministic. The finished bundle replaces the
253
+ destination only after generation succeeds; an existing non-empty destination
254
+ requires `--force`, and unsafe root/ancestor/symlink targets are rejected.
255
+
256
+ Pages are streamed to disk, decoded source retention is bounded, and metrics
257
+ process source paths without materializing the entire source corpus. Lazy CPG
258
+ subgraphs are documented rather than eagerly multiplied across all possible
259
+ targets; a focused live `cpg` query remains the bounded way to obtain one graph.
260
+ The bundle structure follows the
261
+ [Open Knowledge Format 0.2 specification](https://github.com/GoogleCloudPlatform/knowledge-catalog/blob/main/okf/SPEC.md).
262
+
227
263
  ```bash
228
264
  delphi-lsp-agent query --root PATH find TCustomer
229
265
  delphi-lsp-agent query --root PATH focus TARGET_ID
@@ -330,7 +366,8 @@ outside the root workspace.
330
366
  `metrics`. For example, `delphi-lsp-agent view --layer metrics --format json`
331
367
  returns a project summary and detailed unit metric objects; `--query` filters
332
368
  units by name or path.
333
- `index` materializes overview, projects, and problems JSON. `skill install`
369
+ `index` materializes overview, projects, and problems JSON. `wiki export`
370
+ materializes the same navigational knowledge as a linked OKF Markdown bundle. `skill install`
334
371
  writes the skill; `opencode install` writes the package-named skill, Markdown
335
372
  agent, and plugin. The two deprecated write flags are harmless aliases and do
336
373
  not change user configuration.
@@ -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 3.0.0 is authored by Dark Light and supports Windows, macOS, and Linux.
5
+ Version 3.1.0 is authored by Dark Light and supports Windows, macOS, and Linux.
6
6
 
7
7
  ## Install and quick start
8
8
 
@@ -159,6 +159,8 @@ delphi-lsp-agent view --root PATH [--project-file FILE] --layer LAYER
159
159
  [--workers auto|N]
160
160
  delphi-lsp-agent index --root PATH [--project-file FILE] [--out FILE]
161
161
  [--workers auto|N]
162
+ delphi-lsp-agent wiki export --root PATH [--project-file FILE] [--out DIRECTORY]
163
+ [--workers auto|N] [--force]
162
164
  delphi-lsp-agent query --root PATH ACTION [VALUE]
163
165
  [--project-id ID] [--detail summary|declaration|members|context|body|implementations]
164
166
  [--relation references|callers|callees|uses|used_by|inherits|implements]
@@ -184,6 +186,40 @@ delphi-lsp-agent cache stop --root PATH
184
186
  `cache stop` outputs stop status JSON and may include warnings on stderr.
185
187
  `query` outputs Protocol v3 JSON responses and writes warnings to stderr.
186
188
 
189
+ ### Open Knowledge Format wiki export
190
+
191
+ Export the complete unique knowledge represented by the layered codebase views
192
+ as a portable Markdown wiki:
193
+
194
+ ```bash
195
+ delphi-lsp-agent wiki export --root PATH --out codebase-wiki
196
+ ```
197
+
198
+ When `--out` is relative, it is resolved below `--root`; the default is
199
+ `.delphi-lsp/wiki`. The command builds the semantic index once, deep-indexes
200
+ discovered projects, calculates workspace and unit metrics, and writes:
201
+
202
+ - an OKF 0.2 root `index.md`;
203
+ - linked project, unit, and symbol concepts;
204
+ - declaration and implementation source fragments;
205
+ - resolved and unresolved semantic references;
206
+ - discovery/project problems and complete metric records;
207
+ - Protocol v3, relation, CPG, cache, and layer-mapping reference concepts.
208
+
209
+ Every non-index concept is UTF-8 Markdown with YAML frontmatter and a non-empty
210
+ `type`. Readable filenames include a stable digest, so overloads and equal names
211
+ from different units remain distinct even on case-insensitive filesystems.
212
+ Output order and content are deterministic. The finished bundle replaces the
213
+ destination only after generation succeeds; an existing non-empty destination
214
+ requires `--force`, and unsafe root/ancestor/symlink targets are rejected.
215
+
216
+ Pages are streamed to disk, decoded source retention is bounded, and metrics
217
+ process source paths without materializing the entire source corpus. Lazy CPG
218
+ subgraphs are documented rather than eagerly multiplied across all possible
219
+ targets; a focused live `cpg` query remains the bounded way to obtain one graph.
220
+ The bundle structure follows the
221
+ [Open Knowledge Format 0.2 specification](https://github.com/GoogleCloudPlatform/knowledge-catalog/blob/main/okf/SPEC.md).
222
+
187
223
  ```bash
188
224
  delphi-lsp-agent query --root PATH find TCustomer
189
225
  delphi-lsp-agent query --root PATH focus TARGET_ID
@@ -290,7 +326,8 @@ outside the root workspace.
290
326
  `metrics`. For example, `delphi-lsp-agent view --layer metrics --format json`
291
327
  returns a project summary and detailed unit metric objects; `--query` filters
292
328
  units by name or path.
293
- `index` materializes overview, projects, and problems JSON. `skill install`
329
+ `index` materializes overview, projects, and problems JSON. `wiki export`
330
+ materializes the same navigational knowledge as a linked OKF Markdown bundle. `skill install`
294
331
  writes the skill; `opencode install` writes the package-named skill, Markdown
295
332
  agent, and plugin. The two deprecated write flags are harmless aliases and do
296
333
  not change user configuration.
@@ -0,0 +1 @@
1
+ __version__ = "3.1.0"
@@ -34,6 +34,7 @@ from .agent_protocol import (
34
34
  SUPPORTED_RELATIONS,
35
35
  )
36
36
  from .agent_templates import install_opencode_support, install_skill
37
+ from .agent_wiki import WikiExportError, export_okf_wiki
37
38
  from .parallel_outline import ParallelOutlineError, parse_worker_setting
38
39
 
39
40
 
@@ -92,6 +93,19 @@ def build_parser() -> argparse.ArgumentParser:
92
93
  index.add_argument("--workers", type=parse_worker_setting, default=0)
93
94
  index.set_defaults(func=_index)
94
95
 
96
+ wiki = subcommands.add_parser("wiki", help="Export a portable Markdown knowledge wiki.")
97
+ wiki_commands = wiki.add_subparsers(dest="wiki_command", required=True)
98
+ wiki_export = wiki_commands.add_parser(
99
+ "export",
100
+ help="Export all indexed codebase knowledge as an Open Knowledge Format bundle.",
101
+ )
102
+ wiki_export.add_argument("--root", type=Path, default=Path("."))
103
+ wiki_export.add_argument("--project-file", type=Path)
104
+ wiki_export.add_argument("--out", type=Path, default=Path(".delphi-lsp") / "wiki")
105
+ wiki_export.add_argument("--workers", type=parse_worker_setting, default=0)
106
+ wiki_export.add_argument("--force", action="store_true")
107
+ wiki_export.set_defaults(func=_wiki_export)
108
+
95
109
  skill = subcommands.add_parser("skill", help="Install agent skill templates.")
96
110
  skill_commands = skill.add_subparsers(dest="skill_command", required=True)
97
111
  skill_install = skill_commands.add_parser("install", help="Install .agents skill.")
@@ -288,6 +302,24 @@ def _index(args: argparse.Namespace) -> None:
288
302
  print(args.out)
289
303
 
290
304
 
305
+ def _wiki_export(args: argparse.Namespace) -> None:
306
+ args.root = _workspace_root(args.root)
307
+ output = args.out
308
+ if not output.is_absolute():
309
+ output = args.root / output
310
+ try:
311
+ result = export_okf_wiki(
312
+ args.root,
313
+ output,
314
+ project_file=args.project_file,
315
+ workers=args.workers,
316
+ force=args.force,
317
+ )
318
+ except WikiExportError as error:
319
+ raise _CliError("wiki_export_failed", str(error)) from None
320
+ _write_json(result.to_mapping())
321
+
322
+
291
323
  def _skill_install(args: argparse.Namespace) -> None:
292
324
  _require_install_directory(args.target)
293
325
  try:
@@ -315,7 +315,7 @@ def _symbols_payload(index: CodebaseIndex, *, query: str) -> dict[str, Any]:
315
315
  continue
316
316
  symbols.append(_symbol_item(symbol))
317
317
  symbols.sort(key=lambda item: (item["name"].casefold(), item["path"].casefold(), item["line"]))
318
- return {"layer": "symbols", "root": index.root, "query": query, "items": symbols[:200]}
318
+ return {"layer": "symbols", "root": index.root, "query": query, "items": symbols}
319
319
 
320
320
 
321
321
  def _symbol_payload(index: CodebaseIndex, *, query: str) -> dict[str, Any]:
@@ -3,6 +3,7 @@ from __future__ import annotations
3
3
  from dataclasses import dataclass
4
4
  from dataclasses import replace
5
5
  from pathlib import Path
6
+ from typing import Iterable
6
7
 
7
8
  from .agent_workspace import (
8
9
  AgentWorkspace,
@@ -161,6 +162,102 @@ def build_workspace_metrics(
161
162
  return metrics
162
163
 
163
164
 
165
+ def build_path_metrics(
166
+ root: str | Path,
167
+ source_files: Iterable[str | Path],
168
+ *,
169
+ defines: Iterable[str] = (),
170
+ include_paths: Iterable[str | Path] = (),
171
+ project_name: str = "",
172
+ workers: int = 0,
173
+ ) -> ProjectMetrics:
174
+ """Analyze file paths without retaining the complete source corpus in RAM."""
175
+
176
+ root_path = Path(root).expanduser().resolve()
177
+ unique_paths: dict[str, Path] = {}
178
+ for value in source_files:
179
+ path = Path(value).expanduser()
180
+ if not path.is_absolute():
181
+ path = root_path / path
182
+ path = path.resolve()
183
+ unique_paths.setdefault(str(path).replace("\\", "/").casefold(), path)
184
+ unit_paths = [
185
+ path for path in unique_paths.values() if path.suffix.casefold() in {".pas", ".dpr", ".dpk"}
186
+ ]
187
+ include_files = [
188
+ path for path in unique_paths.values() if path.suffix.casefold() == ".inc"
189
+ ]
190
+ source_bytes = 0
191
+ for path in unit_paths:
192
+ try:
193
+ source_bytes += path.stat().st_size
194
+ except OSError:
195
+ continue
196
+ parser_mode = (
197
+ ParserMode.TOLERANT
198
+ if len(unit_paths) >= _LARGE_PROJECT_UNIT_THRESHOLD
199
+ or source_bytes >= _LARGE_PROJECT_BYTE_THRESHOLD
200
+ else ParserMode.STRICT
201
+ )
202
+ define_values = tuple(defines)
203
+ include_path_values = tuple(str(Path(value)) for value in include_paths)
204
+ analyzed_units: list[UnitMetrics] = []
205
+ problems: list[MetricProblem] = []
206
+
207
+ def consume_result(result: _MetricResult) -> None:
208
+ if result.metrics is not None:
209
+ analyzed_units.append(result.metrics)
210
+ if result.problem is not None:
211
+ problems.append(result.problem)
212
+
213
+ run_outline_tasks(
214
+ (
215
+ _MetricTask(
216
+ ordinal,
217
+ str(path),
218
+ _display_path(path, root_path),
219
+ "",
220
+ define_values,
221
+ include_path_values,
222
+ parser_mode,
223
+ )
224
+ for ordinal, path in enumerate(unit_paths)
225
+ ),
226
+ configured_workers=workers,
227
+ on_complete=consume_result,
228
+ retain_results=False,
229
+ task_runner=_analyze_metric_task,
230
+ )
231
+
232
+ include_loc = 0
233
+ for path in include_files:
234
+ try:
235
+ source = read_source_text(path)
236
+ include_loc += len(source.splitlines()) if source else 0
237
+ except (OSError, UnicodeError):
238
+ problems.append(
239
+ MetricProblem(
240
+ kind="include_unavailable",
241
+ path=_display_path(path, root_path),
242
+ message="Could not read include file.",
243
+ )
244
+ )
245
+ metrics = aggregate_project_metrics(
246
+ analyzed_units,
247
+ include_loc=include_loc,
248
+ project_name=project_name,
249
+ )
250
+ if problems:
251
+ metrics = replace(
252
+ metrics,
253
+ problems=(
254
+ *metrics.problems,
255
+ *sorted(problems, key=lambda item: (item.path.casefold(), item.kind)),
256
+ ),
257
+ )
258
+ return metrics
259
+
260
+
164
261
  def project_metric_item(metrics: ProjectMetrics) -> dict[str, object]:
165
262
  return {"item_type": "project_metrics", **metrics.to_mapping()}
166
263
 
@@ -176,4 +273,16 @@ def _workspace_path(root: Path, value: str) -> Path:
176
273
  return path.resolve()
177
274
 
178
275
 
179
- __all__ = ["build_workspace_metrics", "project_metric_item", "unit_metric_item"]
276
+ def _display_path(path: Path, root: Path) -> str:
277
+ try:
278
+ return path.relative_to(root).as_posix()
279
+ except ValueError:
280
+ return path.as_posix()
281
+
282
+
283
+ __all__ = [
284
+ "build_path_metrics",
285
+ "build_workspace_metrics",
286
+ "project_metric_item",
287
+ "unit_metric_item",
288
+ ]