loom-tool 0.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 (218) hide show
  1. loom_tool-0.1.0/.env.example +34 -0
  2. loom_tool-0.1.0/.gitattributes +22 -0
  3. loom_tool-0.1.0/.github/ISSUE_TEMPLATE/bug_report.md +25 -0
  4. loom_tool-0.1.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
  5. loom_tool-0.1.0/.github/ISSUE_TEMPLATE/feature_request.md +14 -0
  6. loom_tool-0.1.0/.github/pull_request_template.md +7 -0
  7. loom_tool-0.1.0/.github/workflows/ci.yml +58 -0
  8. loom_tool-0.1.0/.github/workflows/loom-full-index.yml +34 -0
  9. loom_tool-0.1.0/.github/workflows/loom-index.yml +37 -0
  10. loom_tool-0.1.0/.github/workflows/publish-pypi.yml +41 -0
  11. loom_tool-0.1.0/.gitignore +11 -0
  12. loom_tool-0.1.0/.mcp.json +12 -0
  13. loom_tool-0.1.0/.python-version +1 -0
  14. loom_tool-0.1.0/CHANGELOG.md +48 -0
  15. loom_tool-0.1.0/CLAUDE.md +224 -0
  16. loom_tool-0.1.0/CODE_OF_CONDUCT.md +26 -0
  17. loom_tool-0.1.0/CONTRIBUTING.md +44 -0
  18. loom_tool-0.1.0/LICENSE +21 -0
  19. loom_tool-0.1.0/PKG-INFO +371 -0
  20. loom_tool-0.1.0/README.md +335 -0
  21. loom_tool-0.1.0/SECURITY.md +19 -0
  22. loom_tool-0.1.0/docker-compose.yml +13 -0
  23. loom_tool-0.1.0/docs/ARCHITECTURE.md +412 -0
  24. loom_tool-0.1.0/docs/MANUAL_INTERVENTION_ERRORS.md +61 -0
  25. loom_tool-0.1.0/docs/TECHNICAL_CAPABILITIES.md +224 -0
  26. loom_tool-0.1.0/docs/USAGE.md +355 -0
  27. loom_tool-0.1.0/pyproject.toml +103 -0
  28. loom_tool-0.1.0/pytest.ini +5 -0
  29. loom_tool-0.1.0/scripts/check_deps.py +142 -0
  30. loom_tool-0.1.0/scripts/check_env.py +46 -0
  31. loom_tool-0.1.0/scripts/diagnose_vector_query.py +64 -0
  32. loom_tool-0.1.0/src/loom/__init__.py +32 -0
  33. loom_tool-0.1.0/src/loom/analysis/__init__.py +0 -0
  34. loom_tool-0.1.0/src/loom/analysis/code/__init__.py +1 -0
  35. loom_tool-0.1.0/src/loom/analysis/code/calls.py +232 -0
  36. loom_tool-0.1.0/src/loom/analysis/code/calls_java.py +132 -0
  37. loom_tool-0.1.0/src/loom/analysis/code/calls_ts.py +136 -0
  38. loom_tool-0.1.0/src/loom/analysis/code/communities.py +261 -0
  39. loom_tool-0.1.0/src/loom/analysis/code/coupling.py +205 -0
  40. loom_tool-0.1.0/src/loom/analysis/code/extractor.py +78 -0
  41. loom_tool-0.1.0/src/loom/analysis/code/noise_filter.py +251 -0
  42. loom_tool-0.1.0/src/loom/analysis/code/parser.py +58 -0
  43. loom_tool-0.1.0/src/loom/cli.py +1157 -0
  44. loom_tool-0.1.0/src/loom/config.py +86 -0
  45. loom_tool-0.1.0/src/loom/core/__init__.py +13 -0
  46. loom_tool-0.1.0/src/loom/core/content_hash.py +20 -0
  47. loom_tool-0.1.0/src/loom/core/edge.py +88 -0
  48. loom_tool-0.1.0/src/loom/core/falkor/__init__.py +3 -0
  49. loom_tool-0.1.0/src/loom/core/falkor/cypher.py +92 -0
  50. loom_tool-0.1.0/src/loom/core/falkor/edge_type_adapter.py +91 -0
  51. loom_tool-0.1.0/src/loom/core/falkor/gateway.py +107 -0
  52. loom_tool-0.1.0/src/loom/core/falkor/mappers.py +119 -0
  53. loom_tool-0.1.0/src/loom/core/falkor/repositories.py +306 -0
  54. loom_tool-0.1.0/src/loom/core/falkor/schema.py +87 -0
  55. loom_tool-0.1.0/src/loom/core/graph.py +145 -0
  56. loom_tool-0.1.0/src/loom/core/node.py +98 -0
  57. loom_tool-0.1.0/src/loom/core/protocols.py +32 -0
  58. loom_tool-0.1.0/src/loom/devtools.py +123 -0
  59. loom_tool-0.1.0/src/loom/drift/__init__.py +0 -0
  60. loom_tool-0.1.0/src/loom/drift/detector.py +160 -0
  61. loom_tool-0.1.0/src/loom/embed/__init__.py +0 -0
  62. loom_tool-0.1.0/src/loom/embed/embedder.py +150 -0
  63. loom_tool-0.1.0/src/loom/ingest/__init__.py +0 -0
  64. loom_tool-0.1.0/src/loom/ingest/code/__init__.py +1 -0
  65. loom_tool-0.1.0/src/loom/ingest/code/languages/__init__.py +1 -0
  66. loom_tool-0.1.0/src/loom/ingest/code/languages/_ts_utils.py +27 -0
  67. loom_tool-0.1.0/src/loom/ingest/code/languages/constants.py +224 -0
  68. loom_tool-0.1.0/src/loom/ingest/code/languages/go_lang.py +185 -0
  69. loom_tool-0.1.0/src/loom/ingest/code/languages/java.py +344 -0
  70. loom_tool-0.1.0/src/loom/ingest/code/languages/javascript.py +242 -0
  71. loom_tool-0.1.0/src/loom/ingest/code/languages/markup.py +601 -0
  72. loom_tool-0.1.0/src/loom/ingest/code/languages/python.py +399 -0
  73. loom_tool-0.1.0/src/loom/ingest/code/languages/ruby.py +214 -0
  74. loom_tool-0.1.0/src/loom/ingest/code/languages/rust.py +178 -0
  75. loom_tool-0.1.0/src/loom/ingest/code/languages/typescript.py +442 -0
  76. loom_tool-0.1.0/src/loom/ingest/code/registry.py +290 -0
  77. loom_tool-0.1.0/src/loom/ingest/code/walker.py +104 -0
  78. loom_tool-0.1.0/src/loom/ingest/differ.py +53 -0
  79. loom_tool-0.1.0/src/loom/ingest/docs/__init__.py +1 -0
  80. loom_tool-0.1.0/src/loom/ingest/docs/base.py +121 -0
  81. loom_tool-0.1.0/src/loom/ingest/docs/markdown.py +87 -0
  82. loom_tool-0.1.0/src/loom/ingest/docs/pdf.py +41 -0
  83. loom_tool-0.1.0/src/loom/ingest/git.py +102 -0
  84. loom_tool-0.1.0/src/loom/ingest/helpers.py +36 -0
  85. loom_tool-0.1.0/src/loom/ingest/incremental.py +606 -0
  86. loom_tool-0.1.0/src/loom/ingest/integrations/__init__.py +1 -0
  87. loom_tool-0.1.0/src/loom/ingest/integrations/jira.py +224 -0
  88. loom_tool-0.1.0/src/loom/ingest/pipeline.py +677 -0
  89. loom_tool-0.1.0/src/loom/ingest/result.py +56 -0
  90. loom_tool-0.1.0/src/loom/ingest/utils.py +158 -0
  91. loom_tool-0.1.0/src/loom/linker/__init__.py +0 -0
  92. loom_tool-0.1.0/src/loom/linker/_text_utils.py +15 -0
  93. loom_tool-0.1.0/src/loom/linker/embed_match.py +100 -0
  94. loom_tool-0.1.0/src/loom/linker/linker.py +92 -0
  95. loom_tool-0.1.0/src/loom/linker/llm_match.py +104 -0
  96. loom_tool-0.1.0/src/loom/linker/name_match.py +60 -0
  97. loom_tool-0.1.0/src/loom/linker/prompts.py +20 -0
  98. loom_tool-0.1.0/src/loom/linker/reranker.py +84 -0
  99. loom_tool-0.1.0/src/loom/llm/__init__.py +0 -0
  100. loom_tool-0.1.0/src/loom/llm/client.py +35 -0
  101. loom_tool-0.1.0/src/loom/mcp/__init__.py +1 -0
  102. loom_tool-0.1.0/src/loom/mcp/server.py +301 -0
  103. loom_tool-0.1.0/src/loom/py.typed +0 -0
  104. loom_tool-0.1.0/src/loom/query/__init__.py +1 -0
  105. loom_tool-0.1.0/src/loom/query/blast_radius.py +109 -0
  106. loom_tool-0.1.0/src/loom/query/node_lookup.py +66 -0
  107. loom_tool-0.1.0/src/loom/query/traceability.py +176 -0
  108. loom_tool-0.1.0/src/loom/search/__init__.py +1 -0
  109. loom_tool-0.1.0/src/loom/search/searcher.py +156 -0
  110. loom_tool-0.1.0/src/loom/watch/__init__.py +1 -0
  111. loom_tool-0.1.0/src/loom/watch/watcher.py +105 -0
  112. loom_tool-0.1.0/tests/__init__.py +1 -0
  113. loom_tool-0.1.0/tests/fixtures/__init__.py +1 -0
  114. loom_tool-0.1.0/tests/fixtures/java_springboot/src/main/java/com/example/payment/controller/PaymentController.java +48 -0
  115. loom_tool-0.1.0/tests/fixtures/java_springboot/src/main/java/com/example/payment/domain/BankTransferPayment.java +31 -0
  116. loom_tool-0.1.0/tests/fixtures/java_springboot/src/main/java/com/example/payment/domain/CreditCardPayment.java +53 -0
  117. loom_tool-0.1.0/tests/fixtures/java_springboot/src/main/java/com/example/payment/domain/Payment.java +46 -0
  118. loom_tool-0.1.0/tests/fixtures/java_springboot/src/main/java/com/example/payment/domain/PaymentStatus.java +9 -0
  119. loom_tool-0.1.0/tests/fixtures/java_springboot/src/main/java/com/example/payment/domain/PaymentType.java +9 -0
  120. loom_tool-0.1.0/tests/fixtures/java_springboot/src/main/java/com/example/payment/dto/PaymentRequest.java +39 -0
  121. loom_tool-0.1.0/tests/fixtures/java_springboot/src/main/java/com/example/payment/dto/PaymentResponse.java +33 -0
  122. loom_tool-0.1.0/tests/fixtures/java_springboot/src/main/java/com/example/payment/repository/InMemoryPaymentRepository.java +33 -0
  123. loom_tool-0.1.0/tests/fixtures/java_springboot/src/main/java/com/example/payment/repository/PaymentRepository.java +15 -0
  124. loom_tool-0.1.0/tests/fixtures/java_springboot/src/main/java/com/example/payment/service/CreditCardProcessor.java +41 -0
  125. loom_tool-0.1.0/tests/fixtures/java_springboot/src/main/java/com/example/payment/service/PaymentProcessor.java +11 -0
  126. loom_tool-0.1.0/tests/fixtures/java_springboot/src/main/java/com/example/payment/service/PaymentService.java +46 -0
  127. loom_tool-0.1.0/tests/fixtures/java_springboot/src/main/java/com/example/payment/util/ReflectionExample.java +46 -0
  128. loom_tool-0.1.0/tests/fixtures/java_springboot/src/main/resources/application.properties +31 -0
  129. loom_tool-0.1.0/tests/fixtures/python_flask_app/.env.example +33 -0
  130. loom_tool-0.1.0/tests/fixtures/python_flask_app/app.py +160 -0
  131. loom_tool-0.1.0/tests/fixtures/python_flask_app/models.py +88 -0
  132. loom_tool-0.1.0/tests/fixtures/python_flask_app/reflection_example.py +72 -0
  133. loom_tool-0.1.0/tests/fixtures/python_flask_app/utils.py +125 -0
  134. loom_tool-0.1.0/tests/fixtures/sample_graph.py +179 -0
  135. loom_tool-0.1.0/tests/fixtures/sample_repo/auth.py +45 -0
  136. loom_tool-0.1.0/tests/fixtures/sample_repo/flask_app.py +24 -0
  137. loom_tool-0.1.0/tests/fixtures/vue_tsx_app/.env.example +23 -0
  138. loom_tool-0.1.0/tests/fixtures/vue_tsx_app/src/components/TaskCard.tsx +113 -0
  139. loom_tool-0.1.0/tests/fixtures/vue_tsx_app/src/components/TaskList.tsx +66 -0
  140. loom_tool-0.1.0/tests/fixtures/vue_tsx_app/src/composables/useTaskManager.ts +95 -0
  141. loom_tool-0.1.0/tests/fixtures/vue_tsx_app/src/types/Task.ts +36 -0
  142. loom_tool-0.1.0/tests/fixtures/vue_tsx_app/src/utils/dynamicPatterns.ts +82 -0
  143. loom_tool-0.1.0/tests/fixtures/vue_tsx_app/src/utils/taskHelpers.ts +62 -0
  144. loom_tool-0.1.0/tests/integration/__init__.py +0 -0
  145. loom_tool-0.1.0/tests/integration/test_communities.py +196 -0
  146. loom_tool-0.1.0/tests/integration/test_edge_type_storage.py +269 -0
  147. loom_tool-0.1.0/tests/integration/test_graph_crud_and_neighbors.py +66 -0
  148. loom_tool-0.1.0/tests/integration/test_graph_e2e.py +99 -0
  149. loom_tool-0.1.0/tests/integration/test_graph_upsert_metadata_edges.py +169 -0
  150. loom_tool-0.1.0/tests/integration/test_incremental.py +326 -0
  151. loom_tool-0.1.0/tests/integration/test_java_springboot_e2e.py +364 -0
  152. loom_tool-0.1.0/tests/integration/test_markup_config_e2e.py +419 -0
  153. loom_tool-0.1.0/tests/integration/test_python_flask_e2e.py +253 -0
  154. loom_tool-0.1.0/tests/integration/test_schema_init.py +41 -0
  155. loom_tool-0.1.0/tests/integration/test_search_query_e2e.py +89 -0
  156. loom_tool-0.1.0/tests/integration/test_semantic_linker_rerank_e2e.py +69 -0
  157. loom_tool-0.1.0/tests/integration/test_vue_tsx_e2e.py +267 -0
  158. loom_tool-0.1.0/tests/unit/test_calls.py +293 -0
  159. loom_tool-0.1.0/tests/unit/test_calls_ts_java.py +43 -0
  160. loom_tool-0.1.0/tests/unit/test_cli_accuracy.py +288 -0
  161. loom_tool-0.1.0/tests/unit/test_cli_analyze.py +254 -0
  162. loom_tool-0.1.0/tests/unit/test_cli_calls.py +133 -0
  163. loom_tool-0.1.0/tests/unit/test_cli_entrypoints.py +42 -0
  164. loom_tool-0.1.0/tests/unit/test_cli_help_query.py +14 -0
  165. loom_tool-0.1.0/tests/unit/test_cli_query.py +40 -0
  166. loom_tool-0.1.0/tests/unit/test_cli_sync.py +94 -0
  167. loom_tool-0.1.0/tests/unit/test_cli_trace.py +63 -0
  168. loom_tool-0.1.0/tests/unit/test_communities.py +141 -0
  169. loom_tool-0.1.0/tests/unit/test_content_hash.py +69 -0
  170. loom_tool-0.1.0/tests/unit/test_coupling.py +379 -0
  171. loom_tool-0.1.0/tests/unit/test_differ.py +58 -0
  172. loom_tool-0.1.0/tests/unit/test_docs_markdown.py +88 -0
  173. loom_tool-0.1.0/tests/unit/test_drift_detector.py +116 -0
  174. loom_tool-0.1.0/tests/unit/test_edge.py +113 -0
  175. loom_tool-0.1.0/tests/unit/test_edge_more_cases.py +31 -0
  176. loom_tool-0.1.0/tests/unit/test_edge_origin_mapper.py +25 -0
  177. loom_tool-0.1.0/tests/unit/test_edge_type_adapter.py +153 -0
  178. loom_tool-0.1.0/tests/unit/test_embed_match.py +111 -0
  179. loom_tool-0.1.0/tests/unit/test_embedder.py +45 -0
  180. loom_tool-0.1.0/tests/unit/test_gateway_config.py +27 -0
  181. loom_tool-0.1.0/tests/unit/test_git.py +115 -0
  182. loom_tool-0.1.0/tests/unit/test_imports.py +12 -0
  183. loom_tool-0.1.0/tests/unit/test_incremental_sync.py +1010 -0
  184. loom_tool-0.1.0/tests/unit/test_index_repo_docs.py +112 -0
  185. loom_tool-0.1.0/tests/unit/test_index_repo_incremental.py +227 -0
  186. loom_tool-0.1.0/tests/unit/test_index_repo_semantic_linker.py +94 -0
  187. loom_tool-0.1.0/tests/unit/test_ingest_utils.py +34 -0
  188. loom_tool-0.1.0/tests/unit/test_jira_connector.py +104 -0
  189. loom_tool-0.1.0/tests/unit/test_linker.py +64 -0
  190. loom_tool-0.1.0/tests/unit/test_llm_match.py +76 -0
  191. loom_tool-0.1.0/tests/unit/test_mappers.py +111 -0
  192. loom_tool-0.1.0/tests/unit/test_markup_parser.py +281 -0
  193. loom_tool-0.1.0/tests/unit/test_mcp_server.py +183 -0
  194. loom_tool-0.1.0/tests/unit/test_mcp_tools.py +48 -0
  195. loom_tool-0.1.0/tests/unit/test_multilang_parser.py +468 -0
  196. loom_tool-0.1.0/tests/unit/test_name_match.py +83 -0
  197. loom_tool-0.1.0/tests/unit/test_neighbors_kind_lookup.py +116 -0
  198. loom_tool-0.1.0/tests/unit/test_node.py +116 -0
  199. loom_tool-0.1.0/tests/unit/test_node_lookup.py +99 -0
  200. loom_tool-0.1.0/tests/unit/test_node_repository.py +98 -0
  201. loom_tool-0.1.0/tests/unit/test_noise_filter.py +28 -0
  202. loom_tool-0.1.0/tests/unit/test_parser.py +346 -0
  203. loom_tool-0.1.0/tests/unit/test_parser_metadata.py +59 -0
  204. loom_tool-0.1.0/tests/unit/test_pipeline_jira.py +100 -0
  205. loom_tool-0.1.0/tests/unit/test_registry.py +16 -0
  206. loom_tool-0.1.0/tests/unit/test_repositories.py +28 -0
  207. loom_tool-0.1.0/tests/unit/test_reranker.py +87 -0
  208. loom_tool-0.1.0/tests/unit/test_searcher.py +196 -0
  209. loom_tool-0.1.0/tests/unit/test_semantic_linker.py +238 -0
  210. loom_tool-0.1.0/tests/unit/test_semantic_linker_rerank.py +53 -0
  211. loom_tool-0.1.0/tests/unit/test_smoke.py +2 -0
  212. loom_tool-0.1.0/tests/unit/test_traceability.py +235 -0
  213. loom_tool-0.1.0/tests/unit/test_traversal_ppr.py +140 -0
  214. loom_tool-0.1.0/tests/unit/test_vector_embedding_storage.py +93 -0
  215. loom_tool-0.1.0/tests/unit/test_vector_index_fix.py +142 -0
  216. loom_tool-0.1.0/tests/unit/test_walk_repo.py +133 -0
  217. loom_tool-0.1.0/tests/unit/test_watcher.py +181 -0
  218. loom_tool-0.1.0/uv.lock +3651 -0
@@ -0,0 +1,34 @@
1
+ # Loom Configuration
2
+ # Copy this file to .env and fill in your values
3
+
4
+ # ============================================================================
5
+ # Required
6
+ # ============================================================================
7
+
8
+ # Database configuration
9
+ LOOM_DB_HOST=localhost
10
+ LOOM_DB_PORT=6379
11
+
12
+ # Embedding model (must match LOOM_EMBED_DIM)
13
+ LOOM_EMBED_MODEL=nomic-ai/nomic-embed-text-v1.5
14
+ LOOM_EMBED_DIM=768
15
+ LOOM_EMBED_BATCH_SIZE=64
16
+
17
+ # ============================================================================
18
+ # Optional — enables LLM-assisted semantic linking (higher quality IMPLEMENTS edges)
19
+ # Leave unset to use static extraction only (recommended for getting started)
20
+ # ============================================================================
21
+
22
+ # Examples:
23
+ # LOOM_LLM_MODEL=ollama/llama3.2
24
+ # LOOM_LLM_MODEL=openai/gpt-4o-mini
25
+ # LOOM_LLM_MODEL=anthropic/claude-3-haiku-20240307
26
+ LOOM_LLM_MODEL=
27
+
28
+ # ============================================================================
29
+ # Optional — Jira integration
30
+ # ============================================================================
31
+
32
+ LOOM_JIRA_URL=
33
+ LOOM_JIRA_EMAIL=
34
+ LOOM_JIRA_API_TOKEN=
@@ -0,0 +1,22 @@
1
+ # Enforce LF line endings to keep ruff format --check consistent across OS
2
+
3
+ # Default to LF for all text
4
+ * text=auto eol=lf
5
+
6
+ # Explicit common text formats
7
+ *.py text eol=lf
8
+ *.pyi text eol=lf
9
+ *.md text eol=lf
10
+ *.yml text eol=lf
11
+ *.yaml text eol=lf
12
+ *.toml text eol=lf
13
+ *.ini text eol=lf
14
+ *.cfg text eol=lf
15
+ *.txt text eol=lf
16
+ *.json text eol=lf
17
+ *.sh text eol=lf
18
+
19
+ # Keep Windows scripts with CRLF if you add them later
20
+ *.bat text eol=crlf
21
+ *.cmd text eol=crlf
22
+ *.ps1 text eol=crlf
@@ -0,0 +1,25 @@
1
+ ---
2
+ name: Bug report
3
+ about: Report a problem in Loom
4
+ title: "bug: "
5
+ labels: [bug]
6
+ ---
7
+
8
+ ## What happened
9
+
10
+ ## What you expected
11
+
12
+ ## Steps to reproduce
13
+
14
+ ## Environment
15
+
16
+ - OS:
17
+ - Python version:
18
+ - uv version:
19
+ - FalkorDB image/tag:
20
+
21
+ ## Logs / output
22
+
23
+ ```text
24
+ (paste relevant output here)
25
+ ```
@@ -0,0 +1,5 @@
1
+ blank_issues_enabled: false
2
+ contact_links:
3
+ - name: Questions / Discussions
4
+ url: https://github.com/ddevilz/loom/discussions
5
+ about: Please ask and answer questions here.
@@ -0,0 +1,14 @@
1
+ ---
2
+ name: Feature request
3
+ about: Suggest an improvement
4
+ title: "feat: "
5
+ labels: [enhancement]
6
+ ---
7
+
8
+ ## Problem
9
+
10
+ ## Proposed solution
11
+
12
+ ## Alternatives considered
13
+
14
+ ## Additional context
@@ -0,0 +1,7 @@
1
+ ## Summary
2
+
3
+ ## Changes
4
+
5
+ ## Testing
6
+
7
+ ## Notes
@@ -0,0 +1,58 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [ main, develop ]
6
+ pull_request:
7
+ branches: [ main ]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ${{ matrix.os }}
12
+ timeout-minutes: 10
13
+ strategy:
14
+ matrix:
15
+ os: [ubuntu-latest, windows-latest, macos-latest]
16
+ python-version: ['3.12']
17
+
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+
21
+ - name: Set up Python ${{ matrix.python-version }}
22
+ uses: actions/setup-python@v4
23
+ with:
24
+ python-version: ${{ matrix.python-version }}
25
+
26
+ - name: Install uv
27
+ uses: astral-sh/setup-uv@v3
28
+ with:
29
+ version: "latest"
30
+
31
+ - name: Install dependencies
32
+ run: |
33
+ uv sync --dev
34
+
35
+ - name: Run linting
36
+ run: |
37
+ uv run ruff check .
38
+ uv run mypy src/
39
+
40
+ - name: Check formatting
41
+ run: |
42
+ uv run ruff format --check .
43
+
44
+ - name: Run tests
45
+ run: |
46
+ if [ "${{ matrix.os }}" = "windows-latest" ]; then
47
+ uv run pytest tests/unit/ -v --tb=short
48
+ else
49
+ uv run pytest -v --tb=short
50
+ fi
51
+ shell: bash
52
+
53
+ - name: Test package build
54
+ run: |
55
+ uv build --wheel
56
+ uv pip install dist/*.whl
57
+ uv run loom --version
58
+ shell: bash
@@ -0,0 +1,34 @@
1
+ name: Loom Full Index
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ push:
6
+ branches: [main]
7
+
8
+ jobs:
9
+ loom-full-index:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+
14
+ - name: Set up Python
15
+ uses: actions/setup-python@v5
16
+ with:
17
+ python-version: "3.12"
18
+
19
+ - name: Install uv
20
+ uses: astral-sh/setup-uv@v5
21
+
22
+ - name: Install Loom
23
+ run: |
24
+ uv sync
25
+
26
+ - name: Start FalkorDB
27
+ run: |
28
+ docker run -d -p 6379:6379 --name loom-db falkordb/falkordb
29
+
30
+ - name: Loom full index
31
+ run: |
32
+ uv run loom analyze . \
33
+ --graph-name "${{ github.repository }}" \
34
+ --force
@@ -0,0 +1,37 @@
1
+ name: Loom Incremental Sync
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+
7
+ jobs:
8
+ loom-sync:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v4
12
+ with:
13
+ fetch-depth: 2
14
+
15
+ - name: Set up Python
16
+ uses: actions/setup-python@v5
17
+ with:
18
+ python-version: "3.12"
19
+
20
+ - name: Install uv
21
+ uses: astral-sh/setup-uv@v5
22
+
23
+ - name: Install Loom
24
+ run: |
25
+ uv sync
26
+
27
+ - name: Start FalkorDB
28
+ run: |
29
+ docker run -d -p 6379:6379 --name loom-db falkordb/falkordb
30
+
31
+ - name: Loom incremental sync
32
+ run: |
33
+ uv run loom sync \
34
+ --old-sha "${{ github.event.before }}" \
35
+ --new-sha "${{ github.sha }}" \
36
+ --graph-name "${{ github.repository }}" \
37
+ --repo-path .
@@ -0,0 +1,41 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+ push:
7
+ tags:
8
+ - 'v*'
9
+
10
+ jobs:
11
+ build:
12
+ runs-on: ubuntu-latest
13
+ permissions:
14
+ id-token: write
15
+ contents: read
16
+
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+
20
+ - name: Set up Python
21
+ uses: actions/setup-python@v4
22
+ with:
23
+ python-version: '3.12'
24
+
25
+ - name: Install uv
26
+ uses: astral-sh/setup-uv@v3
27
+ with:
28
+ version: "latest"
29
+
30
+ - name: Build package
31
+ run: |
32
+ uv build
33
+
34
+ - name: Check package
35
+ run: |
36
+ python -m pip install --upgrade pip
37
+ python -m pip install twine
38
+ python -m twine check dist/*
39
+
40
+ - name: Publish to PyPI
41
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,11 @@
1
+ .loom/
2
+ .venv/
3
+ __pycache__/
4
+ .env
5
+ .mypy_cache
6
+ .pytest_cache
7
+ .ruff_cache
8
+ .claude/
9
+ docs/New folder/
10
+ scripts/audit_graph_coverage.py
11
+ scripts/spotcheck_blast_radius.py
@@ -0,0 +1,12 @@
1
+ {
2
+ "mcpServers": {
3
+ "loom": {
4
+ "command": "/Users/devashish/Desktop/loom/.venv/bin/loom",
5
+ "args": ["serve", "--graph-name", "loom_repo"],
6
+ "env": {
7
+ "LOOM_DB_HOST": "localhost",
8
+ "LOOM_DB_PORT": "6379"
9
+ }
10
+ }
11
+ }
12
+ }
@@ -0,0 +1 @@
1
+ 3.12
@@ -0,0 +1,48 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Added
11
+ - Vector index DDL correctness and schema init error visibility
12
+ - Embedding persistence via `vecf32()` for FalkorDB `VECTOR` type
13
+ - Lexical context in `loom calls` (parents/children via `CONTAINS` edges)
14
+ - Graph expansion includes `CONTAINS` edges in search
15
+ - CLI ambiguity handling for `loom calls` target resolution
16
+ - Comprehensive unit tests for vector indexing and embedding storage
17
+ - QA diagnostic script for DB-level vector query validation
18
+ - Open-source readiness: LICENSE (MIT), CONTRIBUTING, CODE_OF_CONDUCT, SECURITY, GitHub templates, CI
19
+
20
+ ### Fixed
21
+ - Vector index never created due to DDL syntax errors
22
+ - `loom query` always falling back to brute-force vector search
23
+ - Ambiguous names in `loom calls` failing with generic “Target not found”
24
+
25
+ ## [0.1.0] - 2026-03-09
26
+
27
+ ### Added
28
+ - Initial release of Loom
29
+ - Repository indexing into FalkorDB graph
30
+ - Multi-language code understanding (Python, TS/JS, Java, Go, Rust, Ruby, markup)
31
+ - Call graph extraction
32
+ - Document ingestion (Markdown, PDF)
33
+ - Jira and traceability workflows
34
+ - Semantic linking (name match, embedding match, LLM match)
35
+ - Incremental sync and watch mode
36
+ - Semantic search with query-time graph expansion
37
+ - MCP server for editor/agent integration
38
+ - CLI commands: analyze, enrich, query, trace, calls, entrypoints, watch, sync, serve
39
+
40
+ ---
41
+
42
+ ## Release process
43
+
44
+ 1. Update version in `pyproject.toml`
45
+ 2. Add a new section to `CHANGELOG.md` under `[Unreleased]`
46
+ 3. Commit and push
47
+ 4. Create a GitHub Release with the changelog for that version
48
+ 5. Tag the release: `git tag v0.1.0 && git push --tags`
@@ -0,0 +1,224 @@
1
+ # Loom — Claude Code Context
2
+
3
+ This file tells Claude Code everything it needs to know to work effectively in this repo.
4
+ Read this before touching any file.
5
+
6
+ ---
7
+
8
+ ## What this project is
9
+
10
+ Loom is a **unified code + document knowledge graph**. It reads a codebase (via tree-sitter AST parsing) and documentation files (PDFs, DOCX, Markdown, Confluence) and stores everything as nodes and edges in FalkorDB — a graph database.
11
+
12
+ The key innovation: **code symbols and document sections are the same node type**, connected by semantic edges (`IMPLEMENTS`, `SPECIFIES`, `VIOLATES`). This enables queries like "does checkout_flow() satisfy PCI-DSS §3.4?" — something no existing tool can answer.
13
+
14
+ ---
15
+
16
+ ## Architecture — read this first
17
+
18
+ ```
19
+ src/loom/
20
+ ├── core/ ← START HERE. Node, Edge, Graph. Every module uses these.
21
+ ├── ingest/ ← Source connectors. Code repos + doc files → raw data.
22
+ ├── analysis/ ← Intelligence. AST parsing, call tracing, communities, summaries.
23
+ ├── embed/ ← nomic-embed-text (unified embedding space for code AND docs).
24
+ ├── linker/ ← THE CORE INNOVATION. Creates IMPLEMENTS edges between code+docs.
25
+ ├── search/ ← Dual-traversal search across code graph + doc tree.
26
+ ├── watch/ ← watchfiles-based incremental re-indexer.
27
+ ├── drift/ ← Detects spec violations when code changes.
28
+ ├── llm/ ← LiteLLM wrapper. Routes to Ollama, OpenAI, Groq etc.
29
+ └── mcp/ ← FastMCP server. 5 tools for Claude Code/Cursor/Copilot.
30
+ ```
31
+
32
+ **Dependency flow:** `core` ← `ingest` ← `analysis` ← `embed` ← `linker` ← `search/watch/drift` ← `mcp`
33
+
34
+ Never import from a downstream module into an upstream one. `core` has zero internal imports.
35
+
36
+ ---
37
+
38
+ ## The data model — understand this deeply
39
+
40
+ Everything is a `Node` or an `Edge`. That's it.
41
+
42
+ ```python
43
+ # A function in code:
44
+ Node(id="function:src/auth.py:validate_user", kind=NodeKind.FUNCTION, source=NodeSource.CODE, ...)
45
+
46
+ # A section in a spec document:
47
+ Node(id="doc:specs/auth.pdf:3.2.4", kind=NodeKind.SECTION, source=NodeSource.DOC, ...)
48
+
49
+ # The link between them (created by SemanticLinker):
50
+ Edge(from_id="function:src/auth.py:validate_user",
51
+ to_id="doc:specs/auth.pdf:3.2.4",
52
+ kind=EdgeType.LOOM_IMPLEMENTS,
53
+ confidence=0.87,
54
+ link_method="embed_match")
55
+ ```
56
+
57
+ **Node ID convention — never break this:**
58
+ - Code: `"{kind}:{file_path}:{symbol_name}"` → `"function:src/auth.py:validate_user"`
59
+ - Doc: `"doc:{doc_path}:{section_id}"` → `"doc:specs/auth.pdf:chapter_3.2.4"`
60
+
61
+ ---
62
+
63
+ ## Tech stack — key decisions
64
+
65
+ | What | Tool | Why it matters |
66
+ |---|---|---|
67
+ | Graph DB | FalkorDB | Redis-based. Run: `docker compose up -d`. Port 6379. |
68
+ | Embeddings | fastembed + nomic-embed-text-v1.5 | Local ONNX, no API key, 768-dim, works for both code and prose |
69
+ | LLM | LiteLLM | `LOOM_LLM_MODEL=ollama/llama3.2` for local/free, `gpt-4o-mini` for fast |
70
+ | Code parsing | tree-sitter | AST-based. Never use regex to parse code. |
71
+ | Async | asyncio + winloop (Windows) / uvloop (Linux/Mac) | See platform check in `src/loom/__init__.py` |
72
+ | Communities | igraph + leidenalg | Leiden algorithm on the call graph |
73
+ | File watching | watchfiles | Rust-based, 500ms debounce |
74
+ | MCP | FastMCP | `@mcp.tool()` decorator pattern |
75
+
76
+ **Windows note:** uvloop doesn't support Windows. We use winloop instead. The platform check in `config.py` handles this automatically — don't remove it.
77
+
78
+ ---
79
+
80
+ ## Environment setup
81
+
82
+ ```bash
83
+ # 1. Install dependencies
84
+ uv sync
85
+
86
+ # 2. Start FalkorDB
87
+ docker compose up -d
88
+
89
+ # 3. Copy env file
90
+ cp .env.example .env
91
+
92
+ # 4. Set your LLM (use Ollama for free local inference):
93
+ # LOOM_LLM_MODEL=ollama/llama3.2
94
+ # or:
95
+ # LOOM_LLM_MODEL=gpt-4o-mini
96
+ # LOOM_LLM_API_KEY=sk-...
97
+
98
+ # 5. Run tests
99
+ uv run pytest
100
+
101
+ # 6. Verify graph connection
102
+ uv run python scripts/check_env.py
103
+ ```
104
+
105
+ ---
106
+
107
+ ## Running Loom
108
+
109
+ ```bash
110
+ # Index a repo
111
+ uv run loom analyze /path/to/repo --docs /path/to/docs
112
+
113
+ # Query
114
+ uv run loom query "how does authentication work?"
115
+
116
+ # Start MCP server
117
+ uv run loom serve
118
+
119
+ # Watch mode
120
+ uv run loom watch /path/to/repo
121
+ ```
122
+
123
+ ---
124
+
125
+ ## Coding conventions
126
+
127
+ **Async everywhere.** All I/O — graph queries, LLM calls, file reads — must be async. Use `asyncio.gather()` for concurrent operations. Never `time.sleep()` — always `await asyncio.sleep()`.
128
+
129
+ **Semaphore for LLM calls.** Always wrap concurrent LLM calls with a semaphore:
130
+ ```python
131
+ sem = asyncio.Semaphore(10)
132
+ async def call_with_limit(prompt):
133
+ async with sem:
134
+ return await llm.complete(prompt)
135
+ results = await asyncio.gather(*[call_with_limit(p) for p in prompts])
136
+ ```
137
+
138
+ **MERGE not CREATE in FalkorDB.** Re-indexing must be idempotent. Always:
139
+ ```cypher
140
+ MERGE (n:Node {id: $id}) SET n += $props
141
+ ```
142
+ Never `CREATE` a node directly — it will create duplicates on re-index.
143
+
144
+ **Bulk over N+1.** Never loop individual FalkorDB inserts. Always `UNWIND`:
145
+ ```python
146
+ graph.query("UNWIND $nodes AS n MERGE (node:Node {id: n.id}) SET node += n",
147
+ {"nodes": [n.model_dump() for n in nodes]})
148
+ ```
149
+
150
+ **LiteLLM for all LLM calls.** Never call OpenAI/Anthropic SDKs directly. Always go through `src/loom/llm/client.py` which wraps LiteLLM. This ensures Ollama/Groq/OpenAI all work with one config change.
151
+
152
+ **Pydantic v2.** All data models use Pydantic v2 `BaseModel`. Use `model_dump()` and `model_validate()`. Never use `.dict()` (v1 API).
153
+
154
+ **Type hints everywhere.** Every function must have complete type hints. `mypy --strict` must pass.
155
+
156
+ ---
157
+
158
+ ## Testing
159
+
160
+ ```bash
161
+ uv run pytest # all tests
162
+ uv run pytest tests/unit/ # unit tests only (no DB needed)
163
+ uv run pytest tests/integration/ # integration tests (requires Docker)
164
+ uv run pytest --cov=loom # with coverage
165
+ uv run pytest -k "test_node" # specific test
166
+ ```
167
+
168
+ **Test fixtures are in `tests/fixtures/`.**
169
+ - `sample_graph.py` — 15 nodes, 20 edges, a realistic auth module. Reuse this everywhere.
170
+ - `sample_repo/auth.py` — the Python file the parser tests run against.
171
+ - `sample_docs/sample_spec.pdf` — the PDF the doc pipeline tests run against.
172
+
173
+ **Integration tests require FalkorDB running.** They're marked with `@pytest.mark.integration` and skipped if the DB is unreachable.
174
+
175
+ ---
176
+
177
+ ## Current sprint: Sprint 1 — Graph Foundation
178
+
179
+ **What we're building right now:**
180
+
181
+ | Ticket | File | Status |
182
+ |---|---|---|
183
+ | LOOM-001 | Project init | ✅ Done |
184
+ | LOOM-002 | Dependencies + env | ✅ Done |
185
+ | LOOM-003 | `src/loom/core/node.py` | 🔄 In progress |
186
+ | LOOM-004 | `src/loom/core/edge.py` | ⬜ Todo |
187
+ | LOOM-005 | `src/loom/core/graph.py` | ⬜ Todo |
188
+ | LOOM-006 | `src/loom/core/schema.py` | ⬜ Todo |
189
+ | LOOM-007 | E2E test | ⬜ Todo |
190
+
191
+ **Sprint goal:** `pytest tests/integration/test_graph_e2e.py` passes cleanly.
192
+
193
+ ---
194
+
195
+ ## What NOT to do
196
+
197
+ - **Don't use regex to parse code.** tree-sitter exists for this. Regex breaks on nested structures.
198
+ - **Don't call LLM APIs directly.** Always use `src/loom/llm/client.py`.
199
+ - **Don't touch FalkorDB directly** outside of `src/loom/core/graph.py`. All DB access through `LoomGraph`.
200
+ - **Don't create duplicate node IDs.** The ID convention is strict — use `MERGE`.
201
+ - **Don't add uvloop directly on Windows.** Use the platform check in config.
202
+ - **Don't run LLM calls sequentially in a loop.** Always `asyncio.gather()` with semaphore.
203
+ - **Don't hardcode the LLM model.** Always read from config/env.
204
+
205
+ ---
206
+
207
+ ## Key algorithms (planned for v0.2+)
208
+
209
+ These are NOT implemented yet but are planned. Don't implement them in v0.1:
210
+
211
+ - **Personalized PageRank** (igraph) — for impact scoring instead of BFS
212
+ - **Cross-encoder reranking** (sentence-transformers) — for better linker precision
213
+ - **GumTree AST diffing** — for precise drift detection
214
+ - **RAPTOR hierarchical summaries** — for multi-level doc intelligence
215
+ - **HippoRAG search** — PPR-based retrieval over the unified graph
216
+
217
+ ---
218
+
219
+ ## Getting help
220
+
221
+ - Architecture decisions → see `docs/architecture.md`
222
+ - Ticket details → GitHub Issues (LOOM-XXX labels)
223
+ - Graph queries → see `docs/cypher-examples.md`
224
+ - LLM prompts used in the linker → see `src/loom/linker/prompts.py`
@@ -0,0 +1,26 @@
1
+ # Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We pledge to make participation in this project a harassment-free experience for everyone.
6
+
7
+ ## Our Standards
8
+
9
+ Examples of behavior that contributes to a positive environment include:
10
+
11
+ - Using welcoming and inclusive language
12
+ - Being respectful of differing viewpoints and experiences
13
+ - Gracefully accepting constructive criticism
14
+
15
+ Examples of unacceptable behavior include:
16
+
17
+ - Harassment, discrimination, or insulting/derogatory comments
18
+ - Trolling or personal attacks
19
+
20
+ ## Enforcement
21
+
22
+ Project maintainers are responsible for clarifying standards and taking appropriate action.
23
+
24
+ ## Scope
25
+
26
+ This Code of Conduct applies within project spaces and in public spaces when representing the project.
@@ -0,0 +1,44 @@
1
+ # Contributing
2
+
3
+ Thanks for your interest in contributing to Loom.
4
+
5
+ ## Development setup
6
+
7
+ ### Requirements
8
+
9
+ - Python 3.12+
10
+ - uv
11
+ - Docker (for FalkorDB)
12
+
13
+ ### Setup
14
+
15
+ ```bash
16
+ uv sync
17
+ ```
18
+
19
+ Start FalkorDB:
20
+
21
+ ```bash
22
+ docker run -d -p 6379:6379 --name loom-db falkordb/falkordb
23
+ ```
24
+
25
+ Run tests:
26
+
27
+ ```bash
28
+ uv run pytest -q
29
+ ```
30
+
31
+ ## Pull requests
32
+
33
+ - Keep changes focused and incremental.
34
+ - Add or update tests for behavioral changes.
35
+ - Run the test suite before submitting.
36
+
37
+ ## Reporting bugs
38
+
39
+ Please include:
40
+
41
+ - What you expected vs what happened
42
+ - Your OS and Python version
43
+ - Loom commands run (and relevant logs)
44
+ - FalkorDB version (Docker image tag)
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Devashish
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.