contextual-engine 0.9.2__tar.gz → 0.9.4__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 (266) hide show
  1. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/PKG-INFO +1 -1
  2. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/cli/commands/mcp.py +1 -1
  3. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/cli/commands/stats.py +0 -1
  4. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/config/global_/mcp_config.py +9 -0
  5. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/core/models.py +49 -1
  6. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/graph/extractor.py +165 -1
  7. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/graph/integrator.py +25 -0
  8. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/graph/resolver.py +10 -0
  9. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/incremental/file_watcher.py +31 -0
  10. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/incremental/incremental_indexer.py +8 -0
  11. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/indexing/chunker.py +105 -6
  12. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/indexing/symbol_extractor.py +42 -1
  13. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/mcp/access.py +14 -0
  14. contextual_engine-0.9.4/contextual/mcp/memory_monitor.py +294 -0
  15. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/mcp/server.py +93 -4
  16. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/mcp/session_manager.py +45 -0
  17. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/mcp/shim.py +8 -4
  18. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/mcp/tools/graph.py +3 -0
  19. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/mcp/tools/nexus.py +9 -6
  20. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/mcp/tools/semantic.py +1 -1
  21. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/mcp/tools/temporal.py +1 -1
  22. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/retrieval/__init__.py +5 -3
  23. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/retrieval/pipeline.py +32 -7
  24. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/pyproject.toml +1 -1
  25. contextual_engine-0.9.4/scripts/mcp_stress_test.py +482 -0
  26. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/tests/test_graph.py +68 -0
  27. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/tests/test_indexing.py +48 -0
  28. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/.contextualignore +0 -0
  29. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/.cursor/rules/contextual.mdc +0 -0
  30. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/.github/workflows/ci.yml +0 -0
  31. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/.github/workflows/release.yml +0 -0
  32. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/.gitignore +0 -0
  33. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/.mcp.json +0 -0
  34. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/LICENSE +0 -0
  35. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/README.md +0 -0
  36. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/__init__.py +0 -0
  37. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/__main__.py +0 -0
  38. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/cli/__init__.py +0 -0
  39. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/cli/commands/__init__.py +0 -0
  40. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/cli/commands/auth.py +0 -0
  41. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/cli/commands/client.py +0 -0
  42. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/cli/commands/config.py +0 -0
  43. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/cli/commands/doctor.py +0 -0
  44. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/cli/commands/fetch.py +0 -0
  45. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/cli/commands/index.py +0 -0
  46. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/cli/commands/initialisation.py +0 -0
  47. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/cli/commands/install.py +0 -0
  48. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/cli/commands/workspace.py +0 -0
  49. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/cli/core/__init__.py +0 -0
  50. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/cli/core/context.py +0 -0
  51. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/cli/core/decorators.py +0 -0
  52. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/cli/core/editor.py +0 -0
  53. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/cli/core/output.py +0 -0
  54. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/config/__init__.py +0 -0
  55. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/config/base.py +0 -0
  56. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/config/global_/__init__.py +0 -0
  57. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/config/global_/security_config.py +0 -0
  58. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/config/global_/storage_config.py +0 -0
  59. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/config/indexing.py +0 -0
  60. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/config/paths.py +0 -0
  61. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/config/workspace/__init__.py +0 -0
  62. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/config/workspace/cache_config.py +0 -0
  63. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/config/workspace/indexing_config.py +0 -0
  64. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/config/workspace/observability_config.py +0 -0
  65. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/config/workspace/retrieval_config.py +0 -0
  66. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/config/workspace/workspace_config.py +0 -0
  67. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/core/__init__.py +0 -0
  68. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/core/errors.py +0 -0
  69. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/git/__init__.py +0 -0
  70. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/git/blame.py +0 -0
  71. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/git/hooks.py +0 -0
  72. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/git/incremental_git.py +0 -0
  73. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/graph/__init__.py +0 -0
  74. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/graph/dedup.py +0 -0
  75. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/graph/staleness.py +0 -0
  76. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/graph/store.py +0 -0
  77. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/graph/traversal.py +0 -0
  78. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/incremental/__init__.py +0 -0
  79. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/incremental/daemon_embed.py +0 -0
  80. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/indexing/__init__.py +0 -0
  81. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/indexing/_config.py +0 -0
  82. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/indexing/_ignore.py +0 -0
  83. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/indexing/docs_pipeline.py +0 -0
  84. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/indexing/index_writer.py +0 -0
  85. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/indexing/merkle_tree.py +0 -0
  86. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/indexing/pipeline.py +0 -0
  87. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/indexing/processor.py +0 -0
  88. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/integrations/__init__.py +0 -0
  89. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/integrations/client_content.py +0 -0
  90. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/integrations/client_writer.py +0 -0
  91. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/mcp/__init__.py +0 -0
  92. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/mcp/__main__.py +0 -0
  93. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/mcp/_platform.py +0 -0
  94. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/mcp/bootstrap.py +0 -0
  95. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/mcp/config.py +0 -0
  96. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/mcp/daemon.py +0 -0
  97. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/mcp/middleware/__init__.py +0 -0
  98. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/mcp/middleware/audit.py +0 -0
  99. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/mcp/middleware/auth.py +0 -0
  100. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/mcp/middleware/identity.py +0 -0
  101. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/mcp/middleware/ratelimit.py +0 -0
  102. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/mcp/middleware/warmup.py +0 -0
  103. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/mcp/middleware/workspace.py +0 -0
  104. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/mcp/router.py +0 -0
  105. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/mcp/tools/__init__.py +0 -0
  106. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/mcp/tools/system.py +0 -0
  107. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/models/__init__.py +0 -0
  108. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/models/_inference.py +0 -0
  109. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/models/allowlist.py +0 -0
  110. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/models/base_embedder.py +0 -0
  111. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/models/reranker_model.py +0 -0
  112. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/models/unified_embedder.py +0 -0
  113. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/observability/__init__.py +0 -0
  114. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/observability/config.py +0 -0
  115. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/observability/exporters.py +0 -0
  116. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/observability/logging.py +0 -0
  117. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/observability/retention.py +0 -0
  118. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/observability/tracer.py +0 -0
  119. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/retrieval/context_assembler.py +0 -0
  120. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/retrieval/mmr.py +0 -0
  121. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/retrieval/ranker.py +0 -0
  122. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/retrieval/tokenizer.py +0 -0
  123. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/security/__init__.py +0 -0
  124. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/security/paths.py +0 -0
  125. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/security/sanitize.py +0 -0
  126. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/security/workspace.py +0 -0
  127. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/__init__.py +0 -0
  128. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/cache.py +0 -0
  129. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/connection.py +0 -0
  130. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/fts.py +0 -0
  131. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/lancedb_provider.py +0 -0
  132. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/__init__.py +0 -0
  133. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/enterprise/me001_orgs.py +0 -0
  134. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/enterprise/me002_org_members.py +0 -0
  135. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/enterprise/me003_teams.py +0 -0
  136. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/enterprise/me004_team_members.py +0 -0
  137. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/enterprise/me005_org_workspaces.py +0 -0
  138. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/enterprise/me006_workspace_permissions.py +0 -0
  139. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/enterprise/me007_idp_sync_log.py +0 -0
  140. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/enterprise/me008_org_policies.py +0 -0
  141. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/enterprise/me009_api_keys.py +0 -0
  142. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/enterprise/me010_org_audit_log.py +0 -0
  143. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/enterprise/me011_workspace_traceability.py +0 -0
  144. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/m001_global.py +0 -0
  145. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/m002_embeddings.py +0 -0
  146. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/m003_temporal.py +0 -0
  147. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/m004_graph.py +0 -0
  148. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/m005_cache.py +0 -0
  149. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/m006_logs.py +0 -0
  150. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/m007_terminal_sessions.py +0 -0
  151. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/m008_queue.py +0 -0
  152. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/m009_swarm.py +0 -0
  153. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/m010_task_force.py +0 -0
  154. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/m011_reminders.py +0 -0
  155. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/m013_temporal_l2.py +0 -0
  156. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/m014_nexus_foundation.py +0 -0
  157. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/runner.py +0 -0
  158. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/solo/m001_global.py +0 -0
  159. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/solo/m002_embeddings.py +0 -0
  160. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/solo/m003_temporal.py +0 -0
  161. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/solo/m004_graph.py +0 -0
  162. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/solo/m005_cache.py +0 -0
  163. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/solo/m006_logs.py +0 -0
  164. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/solo/m007_terminal_sessions.py +0 -0
  165. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/solo/m008_queue.py +0 -0
  166. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/solo/m009_swarm.py +0 -0
  167. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/solo/m010_task_force.py +0 -0
  168. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/solo/m011_reminders.py +0 -0
  169. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/solo/m012_workspace_metadata.py +0 -0
  170. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/solo/m013_temporal_l2.py +0 -0
  171. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/solo/m014_nexus_foundation.py +0 -0
  172. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/teams/mt001_orgs.py +0 -0
  173. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/teams/mt002_org_members.py +0 -0
  174. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/teams/mt003_teams.py +0 -0
  175. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/teams/mt004_team_members.py +0 -0
  176. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/teams/mt005_team_workspaces.py +0 -0
  177. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/teams/mt006_workspace_permissions.py +0 -0
  178. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/teams/mt007_team_audit_log.py +0 -0
  179. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/migrations/teams/mt008_workspace_traceability.py +0 -0
  180. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/schema.py +0 -0
  181. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/schema_base.py +0 -0
  182. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/schema_ent.py +0 -0
  183. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/storage/schema_team.py +0 -0
  184. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/temporal/__init__.py +0 -0
  185. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/temporal/adr.py +0 -0
  186. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/temporal/blame_pipeline.py +0 -0
  187. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/temporal/context.py +0 -0
  188. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/temporal/query.py +0 -0
  189. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/contextual/temporal/velocity.py +0 -0
  190. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/ADRs/ADR-001-lancedb-over-vec0.md +0 -0
  191. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/ADRs/ADR-002-retry-exponential-backoff.md +0 -0
  192. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/ADRs/ADR-003-blake3-deduplication.md +0 -0
  193. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/ADRs/ADR-004-async-first-architecture.md +0 -0
  194. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/ADRs/ADR-005-model-lineup.md +0 -0
  195. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/ARCHITECTURE.md +0 -0
  196. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/CHANGELOG.md +0 -0
  197. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/DATABASE.md +0 -0
  198. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/DEPLOYMENT.md +0 -0
  199. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/DISTRIBUTIONS.md +0 -0
  200. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/DRs/CHATGPT-DR-mcp-cli-security-testing-distribution.md +0 -0
  201. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/DRs/CHATGPT-DR-web-ui-experience.md +0 -0
  202. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/DRs/CLAUDE-DR-ai-agents-teams.md +0 -0
  203. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/DRs/CLAUDE-DR-competitive-landscape-market-analysis.md +0 -0
  204. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/DRs/CLAUDE-DR-core-architecture.md +0 -0
  205. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/DRs/CLAUDE-DR-mvp-phase0-technical-plan.md +0 -0
  206. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/DRs/CLAUDE-DR-strategic-briefing.md +0 -0
  207. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/DRs/GEMINI-DR-graph-implementation.md +0 -0
  208. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/DRs/GEMINI-DR-hybrid-retrieval-local-optimization.md +0 -0
  209. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/DRs/GEMINI-DR-infrastructure-security.md +0 -0
  210. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/DRs/GEMINI-DR-lance-specs.md +0 -0
  211. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/DRs/GEMINI-DR-nexus-graph-architecture.md +0 -0
  212. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/DRs/GEMINI-DR-nexus-graph-engineering.md +0 -0
  213. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/DRs/GEMINI-DR-vec0-vs-lancedb.md +0 -0
  214. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/DRs/GRAPH_LAYER_OPEN_QUESTIONS_RESOLVED.md +0 -0
  215. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/DRs/KIMI-DR-tech-stack-optimization.md +0 -0
  216. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/DRs/PERPLEXITY-DR-L2-temporal.md +0 -0
  217. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/DRs/PERPLEXITY-DR-client-integration.md +0 -0
  218. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/DRs/PERPLEXITY-DR-indexing-optimisation.md +0 -0
  219. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/DRs/PERPLEXITY-DR-lancedb-implementation.md +0 -0
  220. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/DRs/PERPLEXITY-DR-local-data-infrastructure.md +0 -0
  221. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/DRs/PERPLEXITY-DR-mcp-config.md +0 -0
  222. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/DRs/PERPLEXITY-DR-mcp-security-hardening.md +0 -0
  223. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/DRs/PERPLEXITY-DR-models-pipelines.md +0 -0
  224. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/DRs/PERPLEXITY-DR-python-async-ai-pipelines.md +0 -0
  225. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/DRs/PERPLEXITY-DR-semantic-indexing.md +0 -0
  226. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/FRONTEND.md +0 -0
  227. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/GITHUB.md +0 -0
  228. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/INTEGRATIONS.md +0 -0
  229. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/MCP_TOOLS.md +0 -0
  230. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/MEMORY.md +0 -0
  231. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/PROJECT_MANAGEMENT.md +0 -0
  232. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/PROJECT_PHASES.md +0 -0
  233. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/RESOURCES.md +0 -0
  234. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/ROADMAP.md +0 -0
  235. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/SECURITY.md +0 -0
  236. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/TEAMS.md +0 -0
  237. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/TECHNICAL_SPEC.md +0 -0
  238. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/TESTING.md +0 -0
  239. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/docs/VERSION.MD +0 -0
  240. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/pytest.ini +0 -0
  241. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/tests/README.md +0 -0
  242. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/tests/__init__.py +0 -0
  243. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/tests/conftest.py +0 -0
  244. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/tests/fixtures/__init__.py +0 -0
  245. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/tests/fixtures/sample_code.py +0 -0
  246. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/tests/fixtures/sample_docs.md +0 -0
  247. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/tests/test_accuracy.py +0 -0
  248. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/tests/test_architecture.py +0 -0
  249. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/tests/test_async.py +0 -0
  250. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/tests/test_behaviour.py +0 -0
  251. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/tests/test_cache_stats.py +0 -0
  252. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/tests/test_cli.py +0 -0
  253. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/tests/test_flow.py +0 -0
  254. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/tests/test_git.py +0 -0
  255. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/tests/test_graph_resolution_order.py +0 -0
  256. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/tests/test_incremental.py +0 -0
  257. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/tests/test_latency.py +0 -0
  258. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/tests/test_mcp.py +0 -0
  259. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/tests/test_mcp_hardening.py +0 -0
  260. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/tests/test_observability.py +0 -0
  261. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/tests/test_performance.py +0 -0
  262. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/tests/test_query_cache_roundtrip.py +0 -0
  263. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/tests/test_retrieval.py +0 -0
  264. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/tests/test_retry.py +0 -0
  265. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/tests/test_security.py +0 -0
  266. {contextual_engine-0.9.2 → contextual_engine-0.9.4}/tests/test_storage.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: contextual-engine
3
- Version: 0.9.2
3
+ Version: 0.9.4
4
4
  Summary: Temporal-first local code memory for AI tools via MCP
5
5
  Project-URL: Homepage, https://contextuallabs.dev
6
6
  Project-URL: Documentation, https://contextuallabs.dev/docs
@@ -144,7 +144,7 @@ def mcp_logs(
144
144
  console.print(line, highlight=False, end="")
145
145
  except Exception as e:
146
146
  print_error(f"Failed to read logs: {e}")
147
- return
147
+ raise typer.Exit(1)
148
148
 
149
149
  if follow:
150
150
  try:
@@ -22,7 +22,6 @@ from contextual.security.sanitize import sql_str_literal
22
22
  @require_config
23
23
  @require_index
24
24
  async def stats(
25
- path: str = typer.Option(".", "--path", "-p", help="Repository path"),
26
25
  temporal: bool = typer.Option(False, "--temporal", "-t", help="Show temporal stats"),
27
26
  graph: bool = typer.Option(False, "--graph", "-g", help="Show graph stats"),
28
27
  show_all: bool = typer.Option(False, "--all", "-a", help="Show all stats"),
@@ -50,6 +50,15 @@ class DaemonConfig(BaseModel):
50
50
  compaction_interval_hours: float = 6.0 # How often the background loop runs (0 disables)
51
51
  compaction_retention_hours: float = 1.0 # Prune versions older than this; never 0 (breaks concurrent writes)
52
52
 
53
+ # Heap / memory trimmer
54
+ # When the daemon's physical footprint exceeds heap_trim_threshold_mb a
55
+ # hard trim fires (GC + malloc page return). If the footprint is still over
56
+ # the threshold on the next tick and no sessions are active, models are
57
+ # offloaded to CPU to recover MPS/GPU pages. Set to 0 to disable.
58
+ heap_monitor_enabled: bool = True
59
+ heap_monitor_interval_seconds: int = 30
60
+ heap_trim_threshold_mb: int = 2500
61
+
53
62
  # Logging
54
63
  log_level: str = "INFO"
55
64
 
@@ -98,7 +98,14 @@ class FactSource(StrEnum):
98
98
  class Language(StrEnum):
99
99
  """Supported programming languages for indexing.
100
100
 
101
- Week 1 MVP: Python, TypeScript, JavaScript, Go, Java, Rust, C#
101
+ Each value MUST equal the tree-sitter language name used by
102
+ ``contextual.indexing.chunker.LANGUAGE_MAP`` (the string handed to
103
+ ``tree_sitter_language_pack.get_parser``). The chunker maps a file
104
+ extension to that name; ``_build_chunk`` then does ``Language(name)``.
105
+ Any name present in ``LANGUAGE_MAP`` but absent here silently casts to
106
+ ``Language.PYTHON`` — mislabelling the chunk and breaking language
107
+ filtering. Keep the two in lockstep. ``c_sharp`` is the sole divergence
108
+ (enum value ``csharp``) and is bridged by ``chunker._TS_TO_LANG``.
102
109
  """
103
110
 
104
111
  PYTHON = "python"
@@ -109,12 +116,53 @@ class Language(StrEnum):
109
116
  JAVA = "java"
110
117
  RUST = "rust"
111
118
  CSHARP = "csharp"
119
+ # C family
120
+ C = "c"
121
+ CPP = "cpp"
122
+ # JVM / mobile
123
+ KOTLIN = "kotlin"
124
+ SWIFT = "swift"
125
+ SCALA = "scala"
126
+ DART = "dart"
127
+ # Scripting
128
+ RUBY = "ruby"
129
+ PHP = "php"
130
+ LUA = "lua"
131
+ PERL = "perl"
132
+ R = "r"
133
+ BASH = "bash"
134
+ # Functional / emerging
135
+ HASKELL = "haskell"
136
+ ELIXIR = "elixir"
112
137
  # Config formats (free wins)
113
138
  JSON = "json"
114
139
  YAML = "yaml"
115
140
  TOML = "toml"
116
141
  MARKDOWN = "markdown"
117
142
  DOCKERFILE = "dockerfile"
143
+ # Data / schema / infra
144
+ SQL = "sql"
145
+ HCL = "hcl"
146
+ PROTO = "proto"
147
+ # Web frontend
148
+ HTML = "html"
149
+ CSS = "css"
150
+ SCSS = "scss"
151
+ # JVM / enterprise
152
+ GROOVY = "groovy"
153
+ # Systems / emerging
154
+ NIM = "nim"
155
+ ZIG = "zig"
156
+ V = "v"
157
+ # Functional
158
+ ELM = "elm"
159
+ OCAML = "ocaml"
160
+ ERLANG = "erlang"
161
+ # Scientific
162
+ JULIA = "julia"
163
+ # Platform / Web3
164
+ OBJC = "objc"
165
+ SOLIDITY = "solidity"
118
166
 
119
167
 
120
168
  class ModelType(StrEnum):
@@ -152,6 +152,103 @@ AST_ENTITY_NODES: dict[str, dict[str, set[str]]] = {
152
152
  "enum": {"enum_declaration"},
153
153
  "import": {"using_directive"},
154
154
  },
155
+ "c": {
156
+ "function": {"function_definition"},
157
+ "class": {"struct_specifier"}, # C structs model as class-like
158
+ "enum": {"enum_specifier"},
159
+ "type": {"type_definition"},
160
+ "import": {"preproc_include"},
161
+ },
162
+ "cpp": {
163
+ "function": {"function_definition"},
164
+ "class": {"class_specifier", "struct_specifier"},
165
+ "enum": {"enum_specifier"},
166
+ "import": {"preproc_include"},
167
+ },
168
+ "swift": {
169
+ "class": {"class_declaration"}, # covers class/struct/enum/extension
170
+ "function": {"function_declaration"}, # -> method when nested
171
+ "interface": {"protocol_declaration"},
172
+ },
173
+ "kotlin": {
174
+ "class": {"class_declaration", "object_declaration"},
175
+ "function": {"function_declaration"}, # -> method when nested
176
+ },
177
+ "ruby": {
178
+ "class": {"class", "module"},
179
+ "method": {"method", "singleton_method"},
180
+ },
181
+ "php": {
182
+ "class": {"class_declaration"},
183
+ "function": {"function_definition"},
184
+ "method": {"method_declaration"},
185
+ "interface": {"interface_declaration"},
186
+ "import": {"namespace_use_declaration"},
187
+ },
188
+ "bash": {
189
+ "function": {"function_definition"},
190
+ },
191
+ # ── Data / schema / infra ─────────────────────────────────────────────
192
+ "proto": {
193
+ "class": {"message_declaration"},
194
+ "interface": {"service_declaration"},
195
+ "enum": {"enum_declaration"},
196
+ },
197
+ "hcl": {
198
+ "class": {"block"}, # resource/module/data blocks modelled as class-like
199
+ },
200
+ # ── JVM / enterprise ──────────────────────────────────────────────────
201
+ "groovy": {
202
+ "class": {"class_declaration"},
203
+ "method": {"method_declaration"},
204
+ },
205
+ # ── Systems / emerging ────────────────────────────────────────────────
206
+ "nim": {
207
+ "function": {"proc_declaration", "func_declaration"},
208
+ "type": {"type_declaration"},
209
+ },
210
+ "zig": {
211
+ "function": {"function_declaration"},
212
+ "class": {"container_declaration"},
213
+ },
214
+ "v": {
215
+ "function": {"fn_declaration"},
216
+ "class": {"struct_declaration"},
217
+ "interface": {"interface_declaration"},
218
+ },
219
+ # ── Functional ────────────────────────────────────────────────────────
220
+ "elm": {
221
+ "function": {"value_declaration"},
222
+ "type": {"type_alias_declaration", "type_declaration"},
223
+ },
224
+ "ocaml": {
225
+ "function": {"let_binding"},
226
+ "type": {"type_definition"},
227
+ "module": {"module_definition"},
228
+ },
229
+ "erlang": {
230
+ "function": {"function_clause"},
231
+ "type": {"type_declaration"},
232
+ },
233
+ # ── Scientific ────────────────────────────────────────────────────────
234
+ "julia": {
235
+ "function": {"function_definition"},
236
+ "class": {"struct_definition", "abstract_definition"},
237
+ },
238
+ # ── Platform / Web3 ──────────────────────────────────────────────────
239
+ "objc": {
240
+ "function": {"function_definition"},
241
+ "method": {"method_declaration"},
242
+ "interface": {"objc_interface_declaration"},
243
+ "class": {"objc_implementation_declaration"},
244
+ "import": {"preproc_include"},
245
+ },
246
+ "solidity": {
247
+ "class": {"contract_declaration"},
248
+ "function": {"function_definition"},
249
+ "interface": {"interface_declaration"},
250
+ "enum": {"enum_declaration"},
251
+ },
155
252
  }
156
253
 
157
254
  # Scope boundary node kinds per language — push/pop the FQN scope stack on these.
@@ -164,6 +261,31 @@ SCOPE_BOUNDARY_NODES: dict[str, set[str]] = {
164
261
  "java": {"class_declaration", "interface_declaration", "enum_declaration"},
165
262
  "rust": {"struct_item", "impl_item", "trait_item", "enum_item"},
166
263
  "c_sharp": {"class_declaration", "interface_declaration", "namespace_declaration"},
264
+ "c": {"struct_specifier"},
265
+ "cpp": {"class_specifier", "struct_specifier", "namespace_definition"},
266
+ "swift": {"class_declaration", "protocol_declaration"},
267
+ "kotlin": {"class_declaration", "object_declaration"},
268
+ "ruby": {"class", "module"},
269
+ "php": {"class_declaration", "interface_declaration", "trait_declaration"},
270
+ "bash": set(),
271
+ # ── Data / schema / infra ─────────────────────────────────────────────
272
+ "proto": {"message_declaration", "service_declaration"},
273
+ "hcl": {"block"},
274
+ # ── JVM / enterprise ──────────────────────────────────────────────────
275
+ "groovy": {"class_declaration"},
276
+ # ── Systems / emerging ────────────────────────────────────────────────
277
+ "nim": {"type_declaration"},
278
+ "zig": {"container_declaration"},
279
+ "v": {"struct_declaration", "interface_declaration"},
280
+ # ── Functional ────────────────────────────────────────────────────────
281
+ "elm": set(),
282
+ "ocaml": {"module_definition"},
283
+ "erlang": set(),
284
+ # ── Scientific ────────────────────────────────────────────────────────
285
+ "julia": {"struct_definition", "abstract_definition"},
286
+ # ── Platform / Web3 ──────────────────────────────────────────────────
287
+ "objc": {"objc_interface_declaration", "objc_implementation_declaration"},
288
+ "solidity": {"contract_declaration"},
167
289
  }
168
290
 
169
291
  # Call-expression node kinds per language.
@@ -176,10 +298,32 @@ CALL_NODES: dict[str, set[str]] = {
176
298
  "java": {"method_invocation"},
177
299
  "rust": {"call_expression"},
178
300
  "c_sharp": {"invocation_expression"},
301
+ "c": {"call_expression"},
302
+ "cpp": {"call_expression"},
303
+ "swift": {"call_expression"},
304
+ "kotlin": {"call_expression"},
305
+ "ruby": {"call", "method_call"},
306
+ "php": {"function_call_expression", "member_call_expression", "scoped_call_expression"},
307
+ "bash": {"command"},
308
+ # ── JVM / enterprise ──────────────────────────────────────────────────
309
+ "groovy": {"method_call", "call_expression"},
310
+ # ── Systems / emerging ────────────────────────────────────────────────
311
+ "nim": {"call"},
312
+ "zig": {"call_expression"},
313
+ "v": {"call_expression"},
314
+ # ── Functional ────────────────────────────────────────────────────────
315
+ "elm": {"function_call_expr"},
316
+ "ocaml": {"application_expression"},
317
+ "erlang": {"call"},
318
+ # ── Scientific ────────────────────────────────────────────────────────
319
+ "julia": {"call_expression"},
320
+ # ── Platform / Web3 ──────────────────────────────────────────────────
321
+ "objc": {"call_expression"},
322
+ "solidity": {"call_expression"},
179
323
  }
180
324
 
181
325
  # Languages where a top-level "function" node nested inside a scope is a method.
182
- _METHOD_WHEN_NESTED = {"python", "rust"}
326
+ _METHOD_WHEN_NESTED = {"python", "rust", "swift", "kotlin", "cpp", "groovy", "julia", "solidity"}
183
327
 
184
328
 
185
329
  def init_worker() -> None:
@@ -347,6 +491,26 @@ def _node_name(node: Any, source_bytes: bytes) -> str | None:
347
491
  ):
348
492
  ident = child
349
493
  break
494
+ # C / C++ functions carry the name under a `declarator` field rather than a
495
+ # `name` field: function_definition → function_declarator → identifier. Walk
496
+ # down the declarator chain (handles pointer/reference wrappers too) to find
497
+ # the leaf identifier. Bounded depth to stay safe on pathological trees.
498
+ if ident is None:
499
+ cursor = node.child_by_field_name("declarator")
500
+ for _ in range(6):
501
+ if cursor is None:
502
+ break
503
+ if cursor.kind() in ("identifier", "field_identifier"):
504
+ ident = cursor
505
+ break
506
+ inner = cursor.child_by_field_name("declarator")
507
+ if inner is None:
508
+ for child in _children(cursor):
509
+ if child.kind() in ("identifier", "field_identifier"):
510
+ ident = child
511
+ break
512
+ break
513
+ cursor = inner
350
514
  if ident is None:
351
515
  return None
352
516
  name = _text(ident, source_bytes).lstrip("*") # Go pointer receivers
@@ -32,6 +32,24 @@ GRAPH_CONTEXT_RATIO = 0.15 # 15% graph context, 85% chunk results
32
32
  _MAX_SEED_ENTITIES = 5 # cap seed entities per query for latency
33
33
  _MAX_LABEL_LOOKUP = 200
34
34
 
35
+ # Structural edges followed by default during search-time nexus expansion.
36
+ # co_changes_with is deliberately excluded: it is ~85% of all edges (historical
37
+ # correlation, not a hard dependency) and traversing it explodes the BFS frontier
38
+ # — inflating latency AND diluting the structural context an AI actually needs
39
+ # (callers/callees/imports/inheritance). The dedicated co_change_analysis tool
40
+ # surfaces coupling when it's genuinely wanted. authored_by/supersedes are
41
+ # provenance/version edges, not structure. Mirrors the filter already applied in
42
+ # contextual.mcp.tools.graph.
43
+ STRUCTURAL_PREDICATES: list[str] = [
44
+ "calls",
45
+ "imports",
46
+ "defines",
47
+ "references",
48
+ "inherits_from",
49
+ "implements",
50
+ "uses",
51
+ ]
52
+
35
53
 
36
54
  @dataclass
37
55
  class NexusNode:
@@ -360,6 +378,13 @@ class GraphIntegrator:
360
378
  if not seed_entity_ids:
361
379
  return []
362
380
 
381
+ # Default to structural traversal only. Without this, predicates=None
382
+ # follows every edge type — including co_changes_with (~85% of the graph)
383
+ # — which both slows the BFS and buries real structural context. Callers
384
+ # that genuinely want correlation edges pass an explicit predicate list.
385
+ if predicates is None:
386
+ predicates = STRUCTURAL_PREDICATES
387
+
363
388
  depth = max(1, min(depth, 5)) # clamp to valid range
364
389
  node_budget = _DEPTH_BUDGETS.get(depth, 100)
365
390
 
@@ -284,11 +284,21 @@ def _resolve_inheritance(
284
284
  else as ``inherits_from``.
285
285
  """
286
286
  simple = base.split(".")[-1]
287
+ head = base.split(".")[0]
287
288
  target = local_by_name.get(simple)
288
289
  confidence = 0.90
289
290
  if not target and registry.is_unique(simple):
290
291
  target = registry.lookup_name(simple)[0]
291
292
  confidence = 0.85 if simple in imported_names or base in imported_names else 0.75
293
+ # Ambiguous global fallback (0.55) — only when import-attested, mirroring
294
+ # _resolve_call. Cross-file inheritance from a base whose simple name is not
295
+ # unique (e.g. several `Base`/`Config` classes) was previously dropped
296
+ # entirely; recover it deterministically when the import vouches for it.
297
+ if not target and (head in imported_names or simple in imported_names):
298
+ candidates = [c for c in registry.lookup_name(simple) if c != subject_id]
299
+ if candidates:
300
+ target = candidates[0]
301
+ confidence = CONFIDENCE_FLOOR
292
302
  if not target or target == subject_id:
293
303
  return None
294
304
  predicate = "implements" if entity_type == "interface" else "inherits_from"
@@ -1,6 +1,8 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import asyncio
4
+ import ctypes
5
+ import gc
4
6
  import time
5
7
  from pathlib import Path
6
8
  from threading import Lock
@@ -26,6 +28,31 @@ if TYPE_CHECKING:
26
28
  logger = get_logger(__name__)
27
29
 
28
30
 
31
+ def _post_index_trim() -> None:
32
+ """Reclaim transient allocations after a single-file index job.
33
+
34
+ Each embedding run leaves ~200-600 MB of freed PyArrow/LanceDB pages that
35
+ macOS will not return to the OS without an explicit hint. Calling this after
36
+ every file keeps the footprint flat across a multi-file push event instead
37
+ of letting allocations stack into a multi-GB spike.
38
+ """
39
+ gc.collect()
40
+ try:
41
+ import pyarrow as pa
42
+ pa.default_memory_pool().release_unused()
43
+ except Exception:
44
+ pass
45
+ try:
46
+ ctypes.CDLL("libSystem.B.dylib").malloc_zone_pressure_relief(
47
+ None, ctypes.c_size_t(0)
48
+ )
49
+ except Exception:
50
+ try:
51
+ ctypes.CDLL(None).malloc_trim(0)
52
+ except Exception:
53
+ pass
54
+
55
+
29
56
  class _DocsPipelineProtocol(Protocol):
30
57
  def index_file(self, path: Path) -> None: ...
31
58
 
@@ -152,6 +179,10 @@ class DebouncedFileWatcher(FileSystemEventHandler):
152
179
  duration_ms=duration_ms,
153
180
  )
154
181
 
182
+ # Reclaim transient PyArrow/LanceDB buffers immediately after each
183
+ # file so they don't accumulate across a multi-file push event.
184
+ await asyncio.to_thread(_post_index_trim)
185
+
155
186
  changed = any(abs(v) > 0 for v in stats.values())
156
187
  if changed and self._on_indexed is not None:
157
188
  try:
@@ -191,6 +191,14 @@ class IncrementalIndexer:
191
191
  logger.info("File changed, re-indexing", path=str(file_path))
192
192
  result = await self.pipeline.index_single_file(file_path)
193
193
 
194
+ # Expire the per-workspace FunctionRegistry cache so the next graph
195
+ # resolution pass sees freshly-indexed entities rather than stale ones.
196
+ try:
197
+ from contextual.graph.resolver import invalidate_registry_cache
198
+ invalidate_registry_cache(self.pipeline.workspace_id)
199
+ except Exception:
200
+ pass
201
+
194
202
  if hash_bytes:
195
203
  await self.provider.upsert_file_state(
196
204
  self.pipeline.workspace_id,
@@ -33,6 +33,11 @@ if TYPE_CHECKING:
33
33
 
34
34
  logger = get_logger(__name__)
35
35
 
36
+ # tree-sitter language names that don't match Language enum values
37
+ _TS_TO_LANG: dict[str, Language] = {
38
+ "c_sharp": Language.CSHARP,
39
+ }
40
+
36
41
  # Chunking parameters from TECHNICAL_SPEC §6
37
42
  TARGET_CHUNK_BYTES = 1500
38
43
  MAX_CHUNK_BYTES = 2000
@@ -91,6 +96,34 @@ LANGUAGE_MAP = {
91
96
  "Dockerfile": "dockerfile",
92
97
  # ── Documentation ─────────────────────────────────────────────────────
93
98
  ".md": "markdown",
99
+ # ── Data / schema / infra ─────────────────────────────────────────────
100
+ ".sql": "sql",
101
+ ".tf": "hcl",
102
+ ".hcl": "hcl",
103
+ ".tfvars": "hcl",
104
+ ".proto": "proto",
105
+ # ── Web frontend ──────────────────────────────────────────────────────
106
+ ".html": "html",
107
+ ".htm": "html",
108
+ ".css": "css",
109
+ ".scss": "scss",
110
+ # ── JVM / enterprise ──────────────────────────────────────────────────
111
+ ".groovy": "groovy",
112
+ # ── Systems / emerging ────────────────────────────────────────────────
113
+ ".nim": "nim",
114
+ ".zig": "zig",
115
+ ".v": "v",
116
+ # ── Functional ────────────────────────────────────────────────────────
117
+ ".elm": "elm",
118
+ ".ml": "ocaml",
119
+ ".mli": "ocaml",
120
+ ".erl": "erlang",
121
+ ".hrl": "erlang",
122
+ # ── Scientific ────────────────────────────────────────────────────────
123
+ ".jl": "julia",
124
+ # ── Platform / Web3 ──────────────────────────────────────────────────
125
+ ".m": "objc",
126
+ ".sol": "solidity",
94
127
  }
95
128
 
96
129
  # Top-level node types per language (from TECHNICAL_SPEC §6.1)
@@ -126,6 +159,52 @@ TOP_LEVEL_NODES = {
126
159
  "trait_item",
127
160
  },
128
161
  "c_sharp": {"class_declaration", "method_declaration", "interface_declaration"},
162
+ # ── C family ──────────────────────────────────────────────────────────
163
+ "c": {"function_definition", "struct_specifier", "enum_specifier", "type_definition"},
164
+ "cpp": {
165
+ "function_definition",
166
+ "class_specifier",
167
+ "struct_specifier",
168
+ "namespace_definition",
169
+ "enum_specifier",
170
+ "template_declaration",
171
+ },
172
+ # ── JVM / mobile ──────────────────────────────────────────────────────
173
+ "kotlin": {"function_declaration", "class_declaration", "object_declaration"},
174
+ "swift": {"function_declaration", "class_declaration", "protocol_declaration"},
175
+ # ── Scripting ─────────────────────────────────────────────────────────
176
+ "ruby": {"method", "class", "module", "singleton_method"},
177
+ "php": {
178
+ "function_definition",
179
+ "method_declaration",
180
+ "class_declaration",
181
+ "interface_declaration",
182
+ "trait_declaration",
183
+ },
184
+ "bash": {"function_definition"},
185
+ # ── Data / schema / infra ─────────────────────────────────────────────
186
+ "sql": {"statement"},
187
+ "hcl": {"block", "attribute"},
188
+ "proto": {"message_declaration", "enum_declaration", "service_declaration"},
189
+ # ── Web frontend (no fine-grained AST boundaries needed) ──────────────
190
+ "css": {"rule_set", "keyframes_statement", "at_rule"},
191
+ "scss": {"rule_set", "function_statement", "mixin_statement", "include_statement"},
192
+ # html falls back to line-based splitting — no structural boundary needed
193
+ # ── JVM / enterprise ──────────────────────────────────────────────────
194
+ "groovy": {"method_declaration", "class_declaration"},
195
+ # ── Systems / emerging ────────────────────────────────────────────────
196
+ "nim": {"proc_declaration", "func_declaration", "type_declaration"},
197
+ "zig": {"function_declaration"},
198
+ "v": {"fn_declaration", "struct_declaration"},
199
+ # ── Functional ────────────────────────────────────────────────────────
200
+ "elm": {"value_declaration", "type_alias_declaration", "type_declaration"},
201
+ "ocaml": {"let_binding", "type_definition", "module_definition"},
202
+ "erlang": {"function_clause"},
203
+ # ── Scientific ────────────────────────────────────────────────────────
204
+ "julia": {"function_definition", "struct_definition", "abstract_definition"},
205
+ # ── Platform / Web3 ──────────────────────────────────────────────────
206
+ "objc": {"function_definition", "method_declaration"},
207
+ "solidity": {"contract_declaration", "function_definition", "struct_declaration"},
129
208
  }
130
209
 
131
210
 
@@ -563,6 +642,23 @@ class ASTChunker:
563
642
  )
564
643
  return None
565
644
 
645
+ def _get_decorators(self, node: "Node") -> list[str]:
646
+ """Extract decorator text for a function/class node (Python only)."""
647
+ if self.language != "python":
648
+ return []
649
+ parent = node.parent()
650
+ if parent is None or parent.kind() != "decorated_definition":
651
+ return []
652
+ decorators = []
653
+ for i in range(parent.child_count()):
654
+ child = parent.child(i)
655
+ if child.kind() == "decorator":
656
+ text = self.content[child.start_byte() : child.end_byte()].decode(
657
+ "utf-8", errors="replace"
658
+ ).strip()
659
+ decorators.append(text)
660
+ return decorators
661
+
566
662
  def _build_header(self, header_lines: list[str]) -> str:
567
663
  header = "\n".join(header_lines)
568
664
  if len(header) <= MAX_HEADER_BYTES:
@@ -612,8 +708,11 @@ class ASTChunker:
612
708
  header_lines.append("none")
613
709
 
614
710
  header_lines.append("DECORATORS:")
615
- # TODO: Extract decorators per node
616
- header_lines.append("none")
711
+ decorators = self._get_decorators(parsed_node.node)
712
+ if decorators:
713
+ header_lines.extend(decorators)
714
+ else:
715
+ header_lines.append("none")
617
716
  header_lines.append("-----")
618
717
 
619
718
  header = self._build_header(header_lines)
@@ -630,9 +729,9 @@ class ASTChunker:
630
729
  # Extract symbol name from node
631
730
  symbol_name = self._extract_symbol_name(parsed_node.node)
632
731
 
633
- # Map language to enum
732
+ # Map language to enum (tree-sitter names like "c_sharp" diverge from enum values)
634
733
  try:
635
- language_enum = Language(self.language)
734
+ language_enum = _TS_TO_LANG.get(self.language) or Language(self.language)
636
735
  except ValueError:
637
736
  language_enum = Language.PYTHON # Fallback
638
737
 
@@ -685,9 +784,9 @@ class ASTChunker:
685
784
  full_text = f"{header}\n{body}"
686
785
  content_hash = blake3.blake3(full_text.encode("utf-8")).hexdigest()
687
786
 
688
- # Map language to enum
787
+ # Map language to enum (tree-sitter names like "c_sharp" diverge from enum values)
689
788
  try:
690
- language_enum = Language(self.language)
789
+ language_enum = _TS_TO_LANG.get(self.language) or Language(self.language)
691
790
  except ValueError:
692
791
  language_enum = Language.PYTHON # Fallback
693
792
 
@@ -20,7 +20,11 @@ if TYPE_CHECKING:
20
20
  logger = get_logger(__name__)
21
21
 
22
22
 
23
- # Language to Tree-sitter language name mapping
23
+ # Language to Tree-sitter language name mapping.
24
+ # Languages without a dedicated visitor below route to _extract_generic_symbols
25
+ # (returns []) — they still get full chunking + graph entities, just no entries
26
+ # in the symbols table. Keep the tree-sitter names in sync with
27
+ # chunker.LANGUAGE_MAP so a shared parse can be reused.
24
28
  LANGUAGE_MAPPING = {
25
29
  Language.PYTHON: "python",
26
30
  Language.TYPESCRIPT: "typescript",
@@ -30,6 +34,43 @@ LANGUAGE_MAPPING = {
30
34
  Language.GO: "go",
31
35
  Language.JAVA: "java",
32
36
  Language.CSHARP: "c_sharp",
37
+ Language.C: "c",
38
+ Language.CPP: "cpp",
39
+ Language.KOTLIN: "kotlin",
40
+ Language.SWIFT: "swift",
41
+ Language.SCALA: "scala",
42
+ Language.DART: "dart",
43
+ Language.RUBY: "ruby",
44
+ Language.PHP: "php",
45
+ Language.LUA: "lua",
46
+ Language.PERL: "perl",
47
+ Language.R: "r",
48
+ Language.BASH: "bash",
49
+ Language.HASKELL: "haskell",
50
+ Language.ELIXIR: "elixir",
51
+ # Data / schema / infra
52
+ Language.SQL: "sql",
53
+ Language.HCL: "hcl",
54
+ Language.PROTO: "proto",
55
+ # Web frontend
56
+ Language.HTML: "html",
57
+ Language.CSS: "css",
58
+ Language.SCSS: "scss",
59
+ # JVM / enterprise
60
+ Language.GROOVY: "groovy",
61
+ # Systems / emerging
62
+ Language.NIM: "nim",
63
+ Language.ZIG: "zig",
64
+ Language.V: "v",
65
+ # Functional
66
+ Language.ELM: "elm",
67
+ Language.OCAML: "ocaml",
68
+ Language.ERLANG: "erlang",
69
+ # Scientific
70
+ Language.JULIA: "julia",
71
+ # Platform / Web3
72
+ Language.OBJC: "objc",
73
+ Language.SOLIDITY: "solidity",
33
74
  }
34
75
 
35
76