attocode-code-intel 0.1.0__py3-none-any.whl

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 (345) hide show
  1. attocode_code_intel-0.1.0.dist-info/METADATA +221 -0
  2. attocode_code_intel-0.1.0.dist-info/RECORD +345 -0
  3. attocode_code_intel-0.1.0.dist-info/WHEEL +4 -0
  4. attocode_code_intel-0.1.0.dist-info/entry_points.txt +2 -0
  5. attocode_code_intel-0.1.0.dist-info/licenses/LICENSE +21 -0
  6. attocode_intel/GUIDELINES.md +432 -0
  7. attocode_intel/__init__.py +52 -0
  8. attocode_intel/_internal/__init__.py +1 -0
  9. attocode_intel/_internal/errors/__init__.py +126 -0
  10. attocode_intel/_internal/integrations/__init__.py +1 -0
  11. attocode_intel/_internal/integrations/context/__init__.py +1 -0
  12. attocode_intel/_internal/integrations/context/architecture_drift.py +354 -0
  13. attocode_intel/_internal/integrations/context/ast_chunker.py +202 -0
  14. attocode_intel/_internal/integrations/context/ast_service.py +1483 -0
  15. attocode_intel/_internal/integrations/context/blob_oid.py +423 -0
  16. attocode_intel/_internal/integrations/context/cache_manifest.py +221 -0
  17. attocode_intel/_internal/integrations/context/cas.py +466 -0
  18. attocode_intel/_internal/integrations/context/code_analyzer.py +528 -0
  19. attocode_intel/_internal/integrations/context/codebase_ast.py +1461 -0
  20. attocode_intel/_internal/integrations/context/codebase_context.py +1736 -0
  21. attocode_intel/_internal/integrations/context/cross_mode.py +263 -0
  22. attocode_intel/_internal/integrations/context/cross_references.py +616 -0
  23. attocode_intel/_internal/integrations/context/embedding_rotation.py +597 -0
  24. attocode_intel/_internal/integrations/context/embeddings.py +282 -0
  25. attocode_intel/_internal/integrations/context/frecency.py +427 -0
  26. attocode_intel/_internal/integrations/context/fuzzy.py +320 -0
  27. attocode_intel/_internal/integrations/context/hierarchical_explorer.py +331 -0
  28. attocode_intel/_internal/integrations/context/hydration.py +90 -0
  29. attocode_intel/_internal/integrations/context/index_repair.py +87 -0
  30. attocode_intel/_internal/integrations/context/index_store.py +586 -0
  31. attocode_intel/_internal/integrations/context/memory_store.py +602 -0
  32. attocode_intel/_internal/integrations/context/module_resolution.py +52 -0
  33. attocode_intel/_internal/integrations/context/query_constraints.py +361 -0
  34. attocode_intel/_internal/integrations/context/query_history.py +417 -0
  35. attocode_intel/_internal/integrations/context/reranker.py +351 -0
  36. attocode_intel/_internal/integrations/context/semantic_search.py +2931 -0
  37. attocode_intel/_internal/integrations/context/syntax_evidence.py +94 -0
  38. attocode_intel/_internal/integrations/context/systemone_ranker.py +245 -0
  39. attocode_intel/_internal/integrations/context/temporal_coupling.py +411 -0
  40. attocode_intel/_internal/integrations/context/trigram_index.py +820 -0
  41. attocode_intel/_internal/integrations/context/trigram_regex.py +171 -0
  42. attocode_intel/_internal/integrations/context/ts_parser.py +2199 -0
  43. attocode_intel/_internal/integrations/context/vector_store.py +795 -0
  44. attocode_intel/_internal/integrations/feature_flags/__init__.py +357 -0
  45. attocode_intel/_internal/integrations/lsp/__init__.py +1 -0
  46. attocode_intel/_internal/integrations/lsp/client.py +1140 -0
  47. attocode_intel/_internal/integrations/mcp/__init__.py +1 -0
  48. attocode_intel/_internal/integrations/mcp/client.py +253 -0
  49. attocode_intel/_internal/integrations/security/__init__.py +1 -0
  50. attocode_intel/_internal/integrations/security/custom_rules.py +176 -0
  51. attocode_intel/_internal/integrations/security/dataflow.py +522 -0
  52. attocode_intel/_internal/integrations/security/dependency_audit.py +303 -0
  53. attocode_intel/_internal/integrations/security/matcher.py +44 -0
  54. attocode_intel/_internal/integrations/security/patterns.py +724 -0
  55. attocode_intel/_internal/integrations/security/scanner.py +351 -0
  56. attocode_intel/_internal/integrations/utilities/__init__.py +1 -0
  57. attocode_intel/_internal/integrations/utilities/ignore.py +64 -0
  58. attocode_intel/_internal/integrations/utilities/token_estimate.py +51 -0
  59. attocode_intel/_internal/tricks/__init__.py +1 -0
  60. attocode_intel/_internal/tricks/recursive_context.py +357 -0
  61. attocode_intel/_internal/types/__init__.py +1 -0
  62. attocode_intel/_internal/types/events.py +289 -0
  63. attocode_intel/_internal/types/severity.py +15 -0
  64. attocode_intel/_shared.py +341 -0
  65. attocode_intel/analysis_coverage.py +56 -0
  66. attocode_intel/api/__init__.py +1 -0
  67. attocode_intel/api/access.py +32 -0
  68. attocode_intel/api/app.py +247 -0
  69. attocode_intel/api/auth/__init__.py +128 -0
  70. attocode_intel/api/auth/api_keys.py +61 -0
  71. attocode_intel/api/auth/context.py +34 -0
  72. attocode_intel/api/auth/jwt.py +66 -0
  73. attocode_intel/api/auth/oauth.py +146 -0
  74. attocode_intel/api/auth/passwords.py +15 -0
  75. attocode_intel/api/deps.py +351 -0
  76. attocode_intel/api/knowledge_bridge.py +13 -0
  77. attocode_intel/api/mcp_transport.py +51 -0
  78. attocode_intel/api/middleware.py +411 -0
  79. attocode_intel/api/models.py +698 -0
  80. attocode_intel/api/providers/__init__.py +1 -0
  81. attocode_intel/api/providers/db_provider.py +1106 -0
  82. attocode_intel/api/providers/local_provider.py +476 -0
  83. attocode_intel/api/providers/remote_provider.py +740 -0
  84. attocode_intel/api/repository_source.py +21 -0
  85. attocode_intel/api/routes/__init__.py +1 -0
  86. attocode_intel/api/routes/_pin_helper.py +158 -0
  87. attocode_intel/api/routes/activity.py +148 -0
  88. attocode_intel/api/routes/adr.py +102 -0
  89. attocode_intel/api/routes/analysis.py +515 -0
  90. attocode_intel/api/routes/api_keys.py +170 -0
  91. attocode_intel/api/routes/auth.py +428 -0
  92. attocode_intel/api/routes/branches.py +262 -0
  93. attocode_intel/api/routes/cross_repo_search.py +198 -0
  94. attocode_intel/api/routes/embeddings.py +386 -0
  95. attocode_intel/api/routes/files.py +132 -0
  96. attocode_intel/api/routes/files_v2.py +388 -0
  97. attocode_intel/api/routes/gc.py +322 -0
  98. attocode_intel/api/routes/git_v2.py +433 -0
  99. attocode_intel/api/routes/graph.py +174 -0
  100. attocode_intel/api/routes/graph_viz.py +160 -0
  101. attocode_intel/api/routes/health.py +62 -0
  102. attocode_intel/api/routes/history.py +175 -0
  103. attocode_intel/api/routes/jobs.py +84 -0
  104. attocode_intel/api/routes/learning.py +205 -0
  105. attocode_intel/api/routes/lsp.py +272 -0
  106. attocode_intel/api/routes/notify.py +623 -0
  107. attocode_intel/api/routes/operations.py +27 -0
  108. attocode_intel/api/routes/orgs.py +924 -0
  109. attocode_intel/api/routes/preferences.py +100 -0
  110. attocode_intel/api/routes/presence.py +42 -0
  111. attocode_intel/api/routes/projects.py +116 -0
  112. attocode_intel/api/routes/repos.py +47 -0
  113. attocode_intel/api/routes/search.py +180 -0
  114. attocode_intel/api/routes/snapshots.py +614 -0
  115. attocode_intel/api/routes/webhooks.py +313 -0
  116. attocode_intel/api/routes/websocket.py +116 -0
  117. attocode_intel/api/static/graph.html +239 -0
  118. attocode_intel/api/utils.py +96 -0
  119. attocode_intel/artifacts/__init__.py +45 -0
  120. attocode_intel/artifacts/hashing.py +230 -0
  121. attocode_intel/artifacts/provenance.py +190 -0
  122. attocode_intel/artifacts/retrieval_pin.py +159 -0
  123. attocode_intel/audit.py +59 -0
  124. attocode_intel/bug_finder.py +206 -0
  125. attocode_intel/bundle.py +80 -0
  126. attocode_intel/catalog.py +242 -0
  127. attocode_intel/change_review.py +75 -0
  128. attocode_intel/cli.py +3062 -0
  129. attocode_intel/community.py +63 -0
  130. attocode_intel/confidence/__init__.py +144 -0
  131. attocode_intel/confidence/jev.py +234 -0
  132. attocode_intel/confidence/llm.py +330 -0
  133. attocode_intel/confidence/redact.py +44 -0
  134. attocode_intel/confidence/settings.py +74 -0
  135. attocode_intel/config.py +256 -0
  136. attocode_intel/crypto.py +31 -0
  137. attocode_intel/db/__init__.py +7 -0
  138. attocode_intel/db/base.py +33 -0
  139. attocode_intel/db/engine.py +61 -0
  140. attocode_intel/db/models.py +529 -0
  141. attocode_intel/entrypoint.py +185 -0
  142. attocode_intel/focused_evidence.py +130 -0
  143. attocode_intel/freshness.py +154 -0
  144. attocode_intel/gateway.py +734 -0
  145. attocode_intel/git/__init__.py +7 -0
  146. attocode_intel/git/credentials.py +75 -0
  147. attocode_intel/git/manager.py +493 -0
  148. attocode_intel/git/models.py +96 -0
  149. attocode_intel/git/storage.py +98 -0
  150. attocode_intel/graph_query_parser.py +761 -0
  151. attocode_intel/helpers.py +712 -0
  152. attocode_intel/indexing/__init__.py +29 -0
  153. attocode_intel/indexing/debouncer.py +136 -0
  154. attocode_intel/indexing/delta_indexer.py +151 -0
  155. attocode_intel/indexing/full_indexer.py +323 -0
  156. attocode_intel/indexing/incremental.py +240 -0
  157. attocode_intel/indexing/parser.py +403 -0
  158. attocode_intel/indexing/summarizer.py +264 -0
  159. attocode_intel/installer.py +1896 -0
  160. attocode_intel/knowledge.py +269 -0
  161. attocode_intel/local_knowledge.py +77 -0
  162. attocode_intel/migrations/alembic.ini +36 -0
  163. attocode_intel/migrations/env.py +71 -0
  164. attocode_intel/migrations/script.py.mako +27 -0
  165. attocode_intel/migrations/versions/001_initial_schema.py +219 -0
  166. attocode_intel/migrations/versions/002_branch_version_and_embeddings.py +61 -0
  167. attocode_intel/migrations/versions/003_embedding_uniqueness_and_cascade.py +51 -0
  168. attocode_intel/migrations/versions/004_audit_events.py +38 -0
  169. attocode_intel/migrations/versions/005_user_preferences.py +30 -0
  170. attocode_intel/migrations/versions/006_google_oauth.py +27 -0
  171. attocode_intel/migrations/versions/007_pgvector_embeddings.py +28 -0
  172. attocode_intel/migrations/versions/008_symbol_references.py +37 -0
  173. attocode_intel/migrations/versions/009_webhook_secret_encryption.py +25 -0
  174. attocode_intel/migrations/versions/010_add_commits_table.py +40 -0
  175. attocode_intel/migrations/versions/011_commit_changed_files.py +25 -0
  176. attocode_intel/migrations/versions/012_branch_merged_at.py +25 -0
  177. attocode_intel/migrations/versions/013_revoked_tokens.py +32 -0
  178. attocode_intel/migrations/versions/014_blame_hunks.py +40 -0
  179. attocode_intel/migrations/versions/015_commit_file_stats.py +40 -0
  180. attocode_intel/migrations/versions/016_embedding_provenance_columns.py +179 -0
  181. attocode_intel/migrations/versions/017_provenance_table.py +102 -0
  182. attocode_intel/migrations/versions/018_repo_snapshots.py +178 -0
  183. attocode_intel/migrations/versions/019_symref_caller.py +42 -0
  184. attocode_intel/migrations/versions/020_shared_knowledge.py +29 -0
  185. attocode_intel/onboarding.py +258 -0
  186. attocode_intel/output.py +178 -0
  187. attocode_intel/precision.py +133 -0
  188. attocode_intel/presence.py +160 -0
  189. attocode_intel/probe.py +110 -0
  190. attocode_intel/project_dir.py +97 -0
  191. attocode_intel/pubsub.py +113 -0
  192. attocode_intel/query_ranking.py +242 -0
  193. attocode_intel/readiness.py +972 -0
  194. attocode_intel/redis.py +51 -0
  195. attocode_intel/reference_pages.py +60 -0
  196. attocode_intel/remote.py +131 -0
  197. attocode_intel/repo_ranker.py +246 -0
  198. attocode_intel/request_context.py +82 -0
  199. attocode_intel/rules/__init__.py +28 -0
  200. attocode_intel/rules/ci.py +320 -0
  201. attocode_intel/rules/combinators.py +293 -0
  202. attocode_intel/rules/enricher.py +127 -0
  203. attocode_intel/rules/evolution.py +452 -0
  204. attocode_intel/rules/executor.py +531 -0
  205. attocode_intel/rules/filters/__init__.py +5 -0
  206. attocode_intel/rules/filters/pipeline.py +151 -0
  207. attocode_intel/rules/formatter.py +198 -0
  208. attocode_intel/rules/hygiene.py +242 -0
  209. attocode_intel/rules/importers/__init__.py +1 -0
  210. attocode_intel/rules/importers/semgrep.py +382 -0
  211. attocode_intel/rules/loader.py +292 -0
  212. attocode_intel/rules/marketplace.py +375 -0
  213. attocode_intel/rules/metavar.py +181 -0
  214. attocode_intel/rules/model.py +317 -0
  215. attocode_intel/rules/packs/__init__.py +1 -0
  216. attocode_intel/rules/packs/community/_license_templates/Apache-2.0.txt +176 -0
  217. attocode_intel/rules/packs/community/_license_templates/MIT.txt +21 -0
  218. attocode_intel/rules/packs/community/bandit-python/LICENSE +176 -0
  219. attocode_intel/rules/packs/community/bandit-python/NOTICE +13 -0
  220. attocode_intel/rules/packs/community/bandit-python/PORTING.md +23 -0
  221. attocode_intel/rules/packs/community/bandit-python/manifest.yaml +14 -0
  222. attocode_intel/rules/packs/community/bandit-python/rules/B105-hardcoded-password.yaml +23 -0
  223. attocode_intel/rules/packs/community/bandit-python/rules/B303-weak-md5.yaml +21 -0
  224. attocode_intel/rules/packs/community/bandit-python/rules/B304-weak-des.yaml +20 -0
  225. attocode_intel/rules/packs/community/bandit-python/rules/B307-use-of-eval.yaml +22 -0
  226. attocode_intel/rules/packs/community/bandit-python/rules/B324-weak-sha1.yaml +21 -0
  227. attocode_intel/rules/packs/community/bandit-python/rules/B501-no-cert-validation.yaml +23 -0
  228. attocode_intel/rules/packs/community/bandit-python/rules/B602-shell-true.yaml +22 -0
  229. attocode_intel/rules/packs/community/bandit-python/rules/B608-sqli.yaml +22 -0
  230. attocode_intel/rules/packs/community/eslint-typescript/LICENSE +21 -0
  231. attocode_intel/rules/packs/community/eslint-typescript/NOTICE +13 -0
  232. attocode_intel/rules/packs/community/eslint-typescript/PORTING.md +23 -0
  233. attocode_intel/rules/packs/community/eslint-typescript/manifest.yaml +14 -0
  234. attocode_intel/rules/packs/community/eslint-typescript/rules/eqeqeq.yaml +20 -0
  235. attocode_intel/rules/packs/community/eslint-typescript/rules/no-eval.yaml +22 -0
  236. attocode_intel/rules/packs/community/eslint-typescript/rules/no-implied-eval.yaml +20 -0
  237. attocode_intel/rules/packs/community/eslint-typescript/rules/no-new-func.yaml +21 -0
  238. attocode_intel/rules/packs/community/eslint-typescript/rules/no-throw-literal.yaml +19 -0
  239. attocode_intel/rules/packs/community/eslint-typescript/rules/no-var.yaml +20 -0
  240. attocode_intel/rules/packs/community/eslint-typescript/rules/no-with.yaml +18 -0
  241. attocode_intel/rules/packs/community/gosec-go/LICENSE +176 -0
  242. attocode_intel/rules/packs/community/gosec-go/NOTICE +13 -0
  243. attocode_intel/rules/packs/community/gosec-go/PORTING.md +23 -0
  244. attocode_intel/rules/packs/community/gosec-go/manifest.yaml +14 -0
  245. attocode_intel/rules/packs/community/gosec-go/rules/G101-hardcoded-credentials.yaml +22 -0
  246. attocode_intel/rules/packs/community/gosec-go/rules/G102-bind-all-interfaces.yaml +21 -0
  247. attocode_intel/rules/packs/community/gosec-go/rules/G103-unsafe-block.yaml +21 -0
  248. attocode_intel/rules/packs/community/gosec-go/rules/G201-sql-format.yaml +21 -0
  249. attocode_intel/rules/packs/community/gosec-go/rules/G304-file-inclusion.yaml +23 -0
  250. attocode_intel/rules/packs/community/gosec-go/rules/G401-weak-cipher.yaml +20 -0
  251. attocode_intel/rules/packs/community/gosec-go/rules/G402-tls-min-version.yaml +20 -0
  252. attocode_intel/rules/packs/community/gosec-go/rules/G501-md5-import.yaml +21 -0
  253. attocode_intel/rules/packs/examples/cpp/manifest.yaml +4 -0
  254. attocode_intel/rules/packs/examples/cpp/rules/security.yaml +90 -0
  255. attocode_intel/rules/packs/examples/cpp/rules/structural.yaml +42 -0
  256. attocode_intel/rules/packs/examples/csharp/manifest.yaml +4 -0
  257. attocode_intel/rules/packs/examples/csharp/rules/security.yaml +69 -0
  258. attocode_intel/rules/packs/examples/csharp/rules/structural.yaml +42 -0
  259. attocode_intel/rules/packs/examples/go/manifest.yaml +4 -0
  260. attocode_intel/rules/packs/examples/go/rules/performance.yaml +136 -0
  261. attocode_intel/rules/packs/examples/go/rules/security.yaml +48 -0
  262. attocode_intel/rules/packs/examples/go/rules/structural.yaml +58 -0
  263. attocode_intel/rules/packs/examples/go/taint/sanitizers.yaml +24 -0
  264. attocode_intel/rules/packs/examples/go/taint/sinks.yaml +51 -0
  265. attocode_intel/rules/packs/examples/go/taint/sources.yaml +26 -0
  266. attocode_intel/rules/packs/examples/java/manifest.yaml +4 -0
  267. attocode_intel/rules/packs/examples/java/rules/correctness.yaml +55 -0
  268. attocode_intel/rules/packs/examples/java/rules/structural.yaml +48 -0
  269. attocode_intel/rules/packs/examples/java/taint/sinks.yaml +37 -0
  270. attocode_intel/rules/packs/examples/java/taint/sources.yaml +21 -0
  271. attocode_intel/rules/packs/examples/kotlin/manifest.yaml +4 -0
  272. attocode_intel/rules/packs/examples/kotlin/rules/correctness.yaml +50 -0
  273. attocode_intel/rules/packs/examples/kotlin/rules/structural.yaml +38 -0
  274. attocode_intel/rules/packs/examples/php/manifest.yaml +4 -0
  275. attocode_intel/rules/packs/examples/php/rules/security.yaml +66 -0
  276. attocode_intel/rules/packs/examples/php/rules/structural.yaml +41 -0
  277. attocode_intel/rules/packs/examples/python/manifest.yaml +4 -0
  278. attocode_intel/rules/packs/examples/python/rules/performance.yaml +90 -0
  279. attocode_intel/rules/packs/examples/python/rules/structural.yaml +55 -0
  280. attocode_intel/rules/packs/examples/ruby/manifest.yaml +4 -0
  281. attocode_intel/rules/packs/examples/ruby/rules/security.yaml +73 -0
  282. attocode_intel/rules/packs/examples/ruby/rules/structural.yaml +41 -0
  283. attocode_intel/rules/packs/examples/rust/manifest.yaml +4 -0
  284. attocode_intel/rules/packs/examples/rust/rules/correctness.yaml +51 -0
  285. attocode_intel/rules/packs/examples/rust/rules/structural.yaml +49 -0
  286. attocode_intel/rules/packs/examples/typescript/manifest.yaml +4 -0
  287. attocode_intel/rules/packs/examples/typescript/rules/performance.yaml +70 -0
  288. attocode_intel/rules/packs/examples/typescript/rules/structural.yaml +48 -0
  289. attocode_intel/rules/packs/pack_loader.py +244 -0
  290. attocode_intel/rules/plugins/__init__.py +1 -0
  291. attocode_intel/rules/plugins/plugin_loader.py +132 -0
  292. attocode_intel/rules/profiling.py +332 -0
  293. attocode_intel/rules/registry.py +213 -0
  294. attocode_intel/rules/sarif.py +187 -0
  295. attocode_intel/rules/synthesis.py +420 -0
  296. attocode_intel/rules/testing.py +326 -0
  297. attocode_intel/server.py +734 -0
  298. attocode_intel/service.py +3416 -0
  299. attocode_intel/sharing.py +57 -0
  300. attocode_intel/storage/__init__.py +6 -0
  301. attocode_intel/storage/branch_overlay.py +352 -0
  302. attocode_intel/storage/content_store.py +220 -0
  303. attocode_intel/storage/dependency_store.py +143 -0
  304. attocode_intel/storage/diff_engine.py +187 -0
  305. attocode_intel/storage/embedding_store.py +594 -0
  306. attocode_intel/storage/provenance_store.py +137 -0
  307. attocode_intel/storage/security_scanner_db.py +164 -0
  308. attocode_intel/storage/symbol_store.py +160 -0
  309. attocode_intel/structural_evidence.py +144 -0
  310. attocode_intel/symbol_inspection.py +141 -0
  311. attocode_intel/symbol_links.py +167 -0
  312. attocode_intel/telemetry.py +42 -0
  313. attocode_intel/test_ranking.py +73 -0
  314. attocode_intel/testing/__init__.py +43 -0
  315. attocode_intel/testing/fixtures.py +122 -0
  316. attocode_intel/testing/helpers.py +75 -0
  317. attocode_intel/testing/mocks.py +99 -0
  318. attocode_intel/tools/__init__.py +2 -0
  319. attocode_intel/tools/adr_tools.py +628 -0
  320. attocode_intel/tools/analysis_tools.py +382 -0
  321. attocode_intel/tools/composite_tools.py +695 -0
  322. attocode_intel/tools/cross_mode_tools.py +173 -0
  323. attocode_intel/tools/dead_code_tools.py +582 -0
  324. attocode_intel/tools/distill_tools.py +353 -0
  325. attocode_intel/tools/frecency_tools.py +220 -0
  326. attocode_intel/tools/fuzzy_tools.py +255 -0
  327. attocode_intel/tools/history_tools.py +486 -0
  328. attocode_intel/tools/learning_tools.py +222 -0
  329. attocode_intel/tools/lsp_tools.py +218 -0
  330. attocode_intel/tools/maintenance_tools.py +1662 -0
  331. attocode_intel/tools/navigation_tools.py +220 -0
  332. attocode_intel/tools/overlay_tools.py +540 -0
  333. attocode_intel/tools/pin_store.py +432 -0
  334. attocode_intel/tools/pin_tools.py +266 -0
  335. attocode_intel/tools/query_constraints_tools.py +262 -0
  336. attocode_intel/tools/query_history_tools.py +158 -0
  337. attocode_intel/tools/readiness_tools.py +44 -0
  338. attocode_intel/tools/rule_tools.py +992 -0
  339. attocode_intel/tools/search_tools.py +770 -0
  340. attocode_intel/tools/snapshot_tools.py +624 -0
  341. attocode_intel/workers/__init__.py +1 -0
  342. attocode_intel/workers/job_utils.py +111 -0
  343. attocode_intel/workers/jobs.py +573 -0
  344. attocode_intel/workers/run.py +30 -0
  345. attocode_intel/workers/settings.py +61 -0
@@ -0,0 +1,262 @@
1
+ """Query constraints MCP tools.
2
+
3
+ Supports fff-style query constraints for filtering search results:
4
+ - git:modified, git:staged, git:deleted, git:renamed, git:untracked, git:ignored
5
+ - !pattern - exclude files matching pattern
6
+ - path/ - filter by directory
7
+ - ./**/*.py - glob patterns
8
+ - *.py - extension filters
9
+
10
+ Example queries:
11
+ "git:modified *.py" - Modified Python files
12
+ "!test/ src/**/*.rs" - Rust files not in test directories
13
+ "git:staged !vendor/" - Staged files excluding vendor
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ import subprocess
19
+ from typing import TYPE_CHECKING
20
+
21
+ from attocode_intel._shared import _get_project_dir, mcp
22
+
23
+ if TYPE_CHECKING:
24
+ from attocode_intel._internal.integrations.context.query_constraints import QueryConstraintProcessor
25
+
26
+
27
+ def _get_constraint_processor() -> QueryConstraintProcessor:
28
+ """Get the constraint processor."""
29
+ from attocode_intel._internal.integrations.context.query_constraints import (
30
+ QueryConstraintProcessor,
31
+ )
32
+
33
+ project_dir = _get_project_dir()
34
+ return QueryConstraintProcessor(project_dir=project_dir)
35
+
36
+
37
+ def _run_git_status() -> dict[str, str]:
38
+ """Run git status --porcelain to get all file statuses.
39
+
40
+ Returns:
41
+ Dict mapping file path to status code.
42
+ """
43
+ project_dir = _get_project_dir()
44
+
45
+ try:
46
+ result = subprocess.run(
47
+ ["git", "status", "--porcelain"],
48
+ cwd=project_dir,
49
+ capture_output=True,
50
+ text=True,
51
+ timeout=30,
52
+ )
53
+
54
+ statuses: dict[str, str] = {}
55
+ for line in result.stdout.splitlines():
56
+ if len(line) < 3:
57
+ continue
58
+ x_status = line[0] # index (staging area)
59
+ y_status = line[1] # worktree
60
+ file_path = line[3:].strip()
61
+ # Prefer index status if meaningful, otherwise use worktree
62
+ if x_status not in (" ", "?"):
63
+ statuses[file_path] = x_status
64
+ elif y_status != " ":
65
+ statuses[file_path] = y_status
66
+ else:
67
+ statuses[file_path] = x_status # handles '??' etc.
68
+
69
+ return statuses
70
+
71
+ except (subprocess.TimeoutExpired, FileNotFoundError, OSError):
72
+ return {}
73
+
74
+
75
+ @mcp.tool()
76
+ def parse_query_with_constraints(query: str) -> str:
77
+ """Parse a query with fff-style constraints.
78
+
79
+ Shows how the query is decomposed into the main search term
80
+ and any constraints.
81
+
82
+ Supported constraints:
83
+ - git:modified, git:staged, git:deleted, git:renamed, git:untracked, git:ignored
84
+ - !pattern - exclude files matching pattern
85
+ - path/ - filter by directory
86
+ - ./**/*.py - glob patterns
87
+ - *.py - extension filters
88
+
89
+ Args:
90
+ query: Query string to parse.
91
+
92
+ Returns:
93
+ Parsed constraint breakdown.
94
+ """
95
+ from attocode_intel._internal.integrations.context.query_constraints import parse_query_constraints
96
+
97
+ parsed = parse_query_constraints(query)
98
+
99
+ lines = [
100
+ f"Query: '{query}'",
101
+ "\nParsed components:",
102
+ f" Main query: '{parsed.query}'" if parsed.query else " Main query: (empty)",
103
+ f"\n Constraints ({len(parsed.constraints)}):",
104
+ ]
105
+
106
+ if not parsed.constraints:
107
+ lines.append(" (none)")
108
+ else:
109
+ for i, c in enumerate(parsed.constraints, 1):
110
+ neg_str = " (negated)" if c.negated else ""
111
+ lines.append(f" {i}. [{c.type}] '{c.value}'{neg_str}")
112
+
113
+ lines.append("\nExamples of valid queries:")
114
+ lines.append(' "git:modified *.py" - Find modified Python files')
115
+ lines.append(' "!test/ src/**/*.rs" - Rust files not in test/')
116
+ lines.append(' "git:staged !vendor/" - Staged files except vendor')
117
+
118
+ return "\n".join(lines)
119
+
120
+
121
+ @mcp.tool()
122
+ def filter_files_with_constraints(
123
+ query: str,
124
+ files: str,
125
+ ) -> str:
126
+ """Filter a list of files using query constraints.
127
+
128
+ Takes a query with constraints and a list of files, then returns
129
+ only the files that match all constraints.
130
+
131
+ Args:
132
+ query: Query with constraints (e.g., "git:modified *.py")
133
+ files: Newline-separated list of file paths to filter.
134
+
135
+ Returns:
136
+ Filtered list of files.
137
+ """
138
+ from attocode_intel._internal.integrations.context.query_constraints import (
139
+ GitStatus,
140
+ matches_constraints,
141
+ parse_query_constraints,
142
+ )
143
+
144
+ file_list = [f.strip() for f in files.splitlines() if f.strip()]
145
+
146
+ if not file_list:
147
+ return "No files provided."
148
+
149
+ parsed = parse_query_constraints(query)
150
+
151
+ if not parsed.constraints:
152
+ return f"No constraints found in query '{query}'."
153
+
154
+ # Get git statuses
155
+ git_statuses_raw = _run_git_status()
156
+ git_statuses: dict[str, GitStatus] = {}
157
+
158
+ status_map = {
159
+ "M": GitStatus.MODIFIED,
160
+ "A": GitStatus.STAGED,
161
+ "D": GitStatus.DELETED,
162
+ "R": GitStatus.RENAMED,
163
+ "?": GitStatus.UNTRACKED,
164
+ "!": GitStatus.IGNORED,
165
+ }
166
+
167
+ for file_path, status_char in git_statuses_raw.items():
168
+ git_statuses[file_path] = status_map.get(status_char, GitStatus.MODIFIED)
169
+
170
+ # Filter files
171
+ filtered = []
172
+ for file_path in file_list:
173
+ git_status = git_statuses.get(file_path)
174
+ if matches_constraints(file_path, parsed.constraints, git_status):
175
+ filtered.append(file_path)
176
+
177
+ if not filtered:
178
+ return (
179
+ f"No files matched constraints from query '{query}'.\n"
180
+ f"Tried to filter {len(file_list)} files."
181
+ )
182
+
183
+ lines = [
184
+ f"Filtered {len(filtered)} files (from {len(file_list)} input files):",
185
+ f"Query: '{query}'\n",
186
+ ]
187
+ lines.extend(filtered)
188
+
189
+ return "\n".join(lines)
190
+
191
+
192
+ @mcp.tool()
193
+ def list_modified_files() -> str:
194
+ """List all git-modified files in the project.
195
+
196
+ Returns:
197
+ List of modified files with their status.
198
+ """
199
+ project_dir = _get_project_dir()
200
+
201
+ try:
202
+ result = subprocess.run(
203
+ ["git", "status", "--porcelain"],
204
+ cwd=project_dir,
205
+ capture_output=True,
206
+ text=True,
207
+ timeout=30,
208
+ )
209
+
210
+ files_by_status: dict[str, list[str]] = {}
211
+
212
+ status_map = {
213
+ "M": "modified",
214
+ "A": "staged",
215
+ "D": "deleted",
216
+ "R": "renamed",
217
+ "?": "untracked",
218
+ "!": "ignored",
219
+ }
220
+
221
+ for line in result.stdout.splitlines():
222
+ if len(line) < 3:
223
+ continue
224
+
225
+ x_status = line[0] # index (staging area)
226
+ y_status = line[1] # worktree
227
+ file_path = line[3:].strip()
228
+
229
+ # Add file under each applicable status
230
+ statuses_to_add: list[str] = []
231
+ if x_status not in (" ", "?", "!"):
232
+ statuses_to_add.append(
233
+ status_map.get(x_status, f"unknown({x_status})")
234
+ )
235
+ if y_status not in (" ", "?", "!"):
236
+ name = status_map.get(y_status, f"unknown({y_status})")
237
+ if name not in statuses_to_add:
238
+ statuses_to_add.append(name)
239
+ # Handle untracked/ignored (both columns are the same char)
240
+ if x_status == "?":
241
+ statuses_to_add.append("untracked")
242
+ elif x_status == "!":
243
+ statuses_to_add.append("ignored")
244
+
245
+ for status_name in statuses_to_add:
246
+ if status_name not in files_by_status:
247
+ files_by_status[status_name] = []
248
+ files_by_status[status_name].append(file_path)
249
+
250
+ if not files_by_status:
251
+ return "No modified files."
252
+
253
+ lines = ["Modified files:"]
254
+ for status_name, files in files_by_status.items():
255
+ lines.append(f"\n{status_name.upper()}:")
256
+ for f in sorted(files):
257
+ lines.append(f" {f}")
258
+
259
+ return "\n".join(lines)
260
+
261
+ except (subprocess.TimeoutExpired, FileNotFoundError, OSError) as e:
262
+ return f"Error running git: {e}"
@@ -0,0 +1,158 @@
1
+ """Query history MCP tools for tracking search-result selections.
2
+
3
+ Tracks which files are selected after which queries, enabling
4
+ combo boosting to prioritize commonly co-occurring results.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from pathlib import Path
10
+ from typing import TYPE_CHECKING
11
+
12
+ from attocode_intel._shared import _get_project_dir, mcp
13
+ from attocode_intel.tools.pin_tools import pin_stamped
14
+
15
+ if TYPE_CHECKING:
16
+ from attocode_intel._internal.integrations.context.query_history import QueryHistoryTracker
17
+
18
+
19
+ def _get_query_tracker() -> QueryHistoryTracker:
20
+ """Get the query history tracker instance."""
21
+ from attocode_intel._internal.integrations.context.query_history import get_query_tracker
22
+
23
+ project_dir = _get_project_dir()
24
+ db_path = Path(project_dir) / ".attocode" / "query_history"
25
+ return get_query_tracker(db_path=db_path)
26
+
27
+
28
+ @mcp.tool()
29
+ def track_query_result(query: str, file_path: str) -> str:
30
+ """Track that a user selected a file after searching.
31
+
32
+ Call this whenever a user searches for something and then opens
33
+ a file from the results. This builds up combo boosting to help
34
+ prioritize commonly selected files for future searches.
35
+
36
+ Args:
37
+ query: The search query that led to the selection.
38
+ file_path: The file that was selected/opened.
39
+
40
+ Returns:
41
+ Confirmation message.
42
+ """
43
+ tracker = _get_query_tracker()
44
+ tracker.track_selection(query, file_path)
45
+
46
+ # Check if this triggers combo boost
47
+ boost = tracker.get_combo_boost(query, file_path)
48
+ if boost > 0:
49
+ return (
50
+ f"Tracked: '{query}' -> {file_path}\n"
51
+ f"Combo boost activated: +{boost:.0f}"
52
+ )
53
+ return f"Tracked: '{query}' -> {file_path}"
54
+
55
+
56
+ @mcp.tool()
57
+ def get_query_combo_boost(query: str, file_path: str) -> str:
58
+ """Get the combo boost score for a query+file pair.
59
+
60
+ Args:
61
+ query: The search query.
62
+ file_path: The file path to check.
63
+
64
+ Returns:
65
+ Combo boost score and metadata.
66
+ """
67
+ tracker = _get_query_tracker()
68
+ boost = tracker.get_combo_boost(query, file_path)
69
+
70
+ if boost == 0:
71
+ return (
72
+ f"No combo boost for '{query}' -> {file_path}\n"
73
+ f"(Need 3+ selections to activate boost)"
74
+ )
75
+
76
+ return (
77
+ f"Combo boost: +{boost:.0f}\n"
78
+ f"Query: '{query}'\n"
79
+ f"File: {file_path}"
80
+ )
81
+
82
+
83
+ @mcp.tool()
84
+ @pin_stamped
85
+ def get_top_results_for_query(query: str, limit: int = 10) -> str:
86
+ """Get the top files commonly selected for a query.
87
+
88
+ Args:
89
+ query: The search query.
90
+ limit: Maximum number of results to return.
91
+
92
+ Returns:
93
+ Top files for this query with selection counts.
94
+ """
95
+ tracker = _get_query_tracker()
96
+ top_files = tracker.get_top_files_for_query(query, limit=limit)
97
+
98
+ if not top_files:
99
+ return f"No history for query: '{query}'"
100
+
101
+ lines = [
102
+ f"Top results for: '{query}'",
103
+ f"(Based on {limit} historical selections)\n",
104
+ ]
105
+
106
+ for i, (file_path, count, combo_score) in enumerate(top_files, 1):
107
+ boost_str = f" (+{combo_score:.0f} boost)" if combo_score > 0 else ""
108
+ lines.append(f"{i}. [{count}x] {file_path}{boost_str}")
109
+
110
+ return "\n".join(lines)
111
+
112
+
113
+ @mcp.tool()
114
+ def get_query_history_stats() -> str:
115
+ """Get overall query history statistics.
116
+
117
+ Returns:
118
+ Statistics about tracked queries and selections.
119
+ """
120
+ tracker = _get_query_tracker()
121
+ stats = tracker.get_stats()
122
+
123
+ lines = [
124
+ "Query History Statistics",
125
+ "=" * 40,
126
+ f"Total selections tracked: {stats.total_selections}",
127
+ f"Total query entries: {stats.total_queries}",
128
+ f"Unique queries: {stats.unique_queries}",
129
+ f"Unique files: {stats.unique_files}",
130
+ f"Files with combo boost: {stats.combo_boosts}",
131
+ ]
132
+
133
+ return "\n".join(lines)
134
+
135
+
136
+ @mcp.tool()
137
+ def clear_query_history(query: str | None = None, file_path: str | None = None) -> str:
138
+ """Clear query history.
139
+
140
+ Args:
141
+ query: Optional specific query to clear. If None, clears all.
142
+ file_path: Optional specific file to clear (requires query).
143
+
144
+ Returns:
145
+ Confirmation message.
146
+ """
147
+ tracker = _get_query_tracker()
148
+
149
+ if query is None:
150
+ tracker.clear()
151
+ return "All query history cleared."
152
+
153
+ count = tracker.clear(query, file_path)
154
+ if count > 0:
155
+ if file_path:
156
+ return f"Cleared history for '{query}' -> {file_path}"
157
+ return f"Cleared {count} entries for query: '{query}'"
158
+ return f"No history found for query: '{query}'"
@@ -0,0 +1,44 @@
1
+ """Readiness report tool for the code-intel MCP server.
2
+
3
+ Tools: readiness_report.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from attocode_intel._shared import (
9
+ _get_service,
10
+ mcp,
11
+ )
12
+
13
+
14
+ @mcp.tool()
15
+ def readiness_report(
16
+ phases: list[int] | None = None,
17
+ scope: str = "",
18
+ tracer_bullets: bool = True,
19
+ min_severity: str = "info",
20
+ ) -> str:
21
+ """Run a comprehensive readiness audit of the codebase.
22
+
23
+ Executes 8 analysis phases covering baseline health, API completeness,
24
+ frontend flows, data layer, test coverage, security, observability,
25
+ and deployability. Orchestrates existing tools (security_scan, dead_code,
26
+ hotspots, conventions, etc.) plus new phase-specific analysis.
27
+
28
+ Returns severity-tagged findings with file:line evidence and an overall
29
+ readiness grade (A-F).
30
+
31
+ Args:
32
+ phases: List of phase numbers to run (0-7). None = all phases.
33
+ 0=Baseline, 1=API/Logic, 2=Frontend, 3=Data, 4=Tests,
34
+ 5=Security, 6=Observability, 7=Deployability.
35
+ scope: Restrict analysis to files under this directory prefix.
36
+ tracer_bullets: Whether to run tracer bullet analysis (default True).
37
+ min_severity: Minimum severity to include: "pass", "info", "warning", "critical".
38
+ """
39
+ return _get_service().readiness_report(
40
+ phases=phases,
41
+ scope=scope,
42
+ tracer_bullets=tracer_bullets,
43
+ min_severity=min_severity,
44
+ )