dotscope 1.2.1__tar.gz → 1.3.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 (467) hide show
  1. dotscope-1.3.0/.claude/settings.local.json +7 -0
  2. {dotscope-1.2.1 → dotscope-1.3.0}/.github/workflows/python-publish.yml +1 -1
  3. dotscope-1.3.0/.mcp.json +8 -0
  4. dotscope-1.3.0/.virtual/isolated-hubs.scope +14 -0
  5. dotscope-1.3.0/CLAUDE.md +10 -0
  6. {dotscope-1.2.1 → dotscope-1.3.0}/PKG-INFO +3 -3
  7. {dotscope-1.2.1 → dotscope-1.3.0}/docs/mcp-setup.md +80 -2
  8. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/__init__.py +1 -1
  9. dotscope-1.3.0/dotscope/cli/__init__.py +320 -0
  10. dotscope-1.3.0/dotscope/cli/core.py +214 -0
  11. dotscope-1.3.0/dotscope/cli/hooks.py +491 -0
  12. dotscope-1.3.0/dotscope/cli/ingest.py +243 -0
  13. dotscope-1.3.0/dotscope/cli/observability.py +342 -0
  14. {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/composer.py +3 -1
  15. {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/discovery.py +0 -21
  16. dotscope-1.3.0/dotscope/explain.py +189 -0
  17. {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/formatter.py +13 -1
  18. {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/health.py +76 -12
  19. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/help.py +2 -0
  20. {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/ingest.py +3 -1
  21. dotscope-1.3.0/dotscope/mcp/__init__.py +139 -0
  22. dotscope-1.3.0/dotscope/mcp/core.py +459 -0
  23. dotscope-1.3.0/dotscope/mcp/hooks.py +8 -0
  24. dotscope-1.3.0/dotscope/mcp/ingest.py +99 -0
  25. dotscope-1.3.0/dotscope/mcp/observability.py +188 -0
  26. {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/models/core.py +4 -0
  27. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/models/intent.py +2 -0
  28. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/models/state.py +1 -0
  29. {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/passes/convention_discovery.py +40 -0
  30. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/sentinel/checks/antipattern.py +2 -0
  31. {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/passes/sentinel/checks/boundary.py +2 -0
  32. {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/passes/sentinel/checks/contracts.py +4 -0
  33. {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/passes/sentinel/checks/convention.py +2 -0
  34. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/sentinel/checks/direction.py +2 -0
  35. {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/passes/sentinel/checks/intent.py +8 -0
  36. {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/passes/sentinel/checks/network.py +2 -0
  37. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/sentinel/checks/spatial.py +2 -0
  38. {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/passes/sentinel/checks/stability.py +2 -0
  39. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/sentinel/checks/voice.py +4 -0
  40. {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/passes/virtual.py +1 -1
  41. dotscope-1.3.0/dotscope/paths/repo.py +24 -0
  42. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/refresh.py +135 -4
  43. {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/resolver.py +2 -2
  44. {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/runtime_overlay.py +1 -1
  45. {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/search/synthesizer.py +17 -7
  46. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/storage/claude_hooks.py +47 -0
  47. dotscope-1.3.0/dotscope/storage/mcp_config.py +216 -0
  48. {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/tokens.py +1 -1
  49. dotscope-1.3.0/epic.yaml +75 -0
  50. dotscope-1.3.0/intent.yaml +42 -0
  51. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/pyproject.toml +3 -3
  52. dotscope-1.3.0/run_epic.py +108 -0
  53. {dotscope-1.2.1 → dotscope-1.3.0}/tests/test_health.py +1 -1
  54. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_ingest.py +1 -1
  55. dotscope-1.3.0/tests/test_mcp_config.py +153 -0
  56. dotscope-1.3.0/tests/test_mcp_server.py +67 -0
  57. {dotscope-1.2.1 → dotscope-1.3.0}/tests/test_parser.py +1 -1
  58. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_virtual.py +1 -1
  59. dotscope-1.3.0/virtual/_treesitter_lifecycle/.scope +23 -0
  60. dotscope-1.3.0/virtual/absorber_lifecycle/.scope +33 -0
  61. dotscope-1.3.0/virtual/acknowledge_lifecycle/.scope +52 -0
  62. dotscope-1.3.0/virtual/ast_analyzer_lifecycle/.scope +30 -0
  63. dotscope-1.3.0/virtual/budget_lifecycle/.scope +25 -0
  64. dotscope-1.3.0/virtual/constants_lifecycle/.scope +32 -0
  65. dotscope-1.3.0/virtual/constraints_lifecycle/.scope +64 -0
  66. dotscope-1.3.0/virtual/context_lifecycle/.scope +79 -0
  67. dotscope-1.3.0/virtual/core_lifecycle/.scope +55 -0
  68. dotscope-1.3.0/virtual/counterfactual_lifecycle/.scope +27 -0
  69. dotscope-1.3.0/virtual/go_lifecycle/.scope +23 -0
  70. dotscope-1.3.0/virtual/harness_lifecycle/.scope +25 -0
  71. dotscope-1.3.0/virtual/history_lifecycle/.scope +51 -0
  72. dotscope-1.3.0/virtual/ignore_lifecycle/.scope +21 -0
  73. dotscope-1.3.0/virtual/incremental_lifecycle/.scope +43 -0
  74. dotscope-1.3.0/virtual/incremental_state_lifecycle/.scope +47 -0
  75. dotscope-1.3.0/virtual/intent_lifecycle/.scope +106 -0
  76. dotscope-1.3.0/virtual/line_filter_lifecycle/.scope +22 -0
  77. dotscope-1.3.0/virtual/matcher_lifecycle/.scope +53 -0
  78. dotscope-1.3.0/virtual/merge_lifecycle/.scope +40 -0
  79. dotscope-1.3.0/virtual/models_lifecycle/.scope +64 -0
  80. dotscope-1.3.0/virtual/parser_lifecycle/.scope +103 -0
  81. dotscope-1.3.0/virtual/refresh_lifecycle/.scope +73 -0
  82. dotscope-1.3.0/virtual/resolver_lifecycle/.scope +44 -0
  83. dotscope-1.3.0/virtual/runtime_overlay_lifecycle/.scope +41 -0
  84. dotscope-1.3.0/virtual/sessions_lifecycle/.scope +30 -0
  85. dotscope-1.3.0/virtual/state_lifecycle/.scope +50 -0
  86. dotscope-1.3.0/virtual/textio_lifecycle/.scope +53 -0
  87. dotscope-1.3.0/virtual/utility_lifecycle/.scope +80 -0
  88. dotscope-1.2.1/.claude/settings.local.json +0 -35
  89. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/.claude/hooks/pre-commit-check.sh +0 -41
  90. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/.claude/settings.json +0 -15
  91. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/.claude/settings.local.json +0 -52
  92. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/.git +0 -1
  93. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/README.md +0 -90
  94. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/docs/mcp-setup.md +0 -255
  95. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/cli.py +0 -1561
  96. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/composer.py +0 -229
  97. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/constants.py +0 -45
  98. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/discovery.py +0 -138
  99. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/formatter.py +0 -157
  100. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/generate/engine.py +0 -189
  101. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/health.py +0 -272
  102. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/ingest.py +0 -972
  103. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/mcp_server.py +0 -1457
  104. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/models/core.py +0 -328
  105. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/models.py +0 -9
  106. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/passes/convention_discovery.py +0 -345
  107. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/passes/graph_builder.py +0 -437
  108. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/passes/sentinel/checks/boundary.py +0 -46
  109. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/passes/sentinel/checks/contracts.py +0 -148
  110. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/passes/sentinel/checks/convention.py +0 -54
  111. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/passes/sentinel/checks/intent.py +0 -207
  112. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/passes/sentinel/checks/network.py +0 -91
  113. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/passes/sentinel/checks/stability.py +0 -66
  114. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/passes/virtual.py +0 -247
  115. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/resolver.py +0 -198
  116. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/runtime_overlay.py +0 -403
  117. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/scanner.py +0 -246
  118. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/search/retriever.py +0 -368
  119. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/search/synthesizer.py +0 -292
  120. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/storage/mcp_config.py +0 -98
  121. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/tokens.py +0 -53
  122. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/tests/test_health.py +0 -142
  123. dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/tests/test_parser.py +0 -180
  124. dotscope-1.2.1/.gitignore +0 -10
  125. dotscope-1.2.1/.mcp.json +0 -9
  126. dotscope-1.2.1/.scopes +0 -28
  127. dotscope-1.2.1/AGENT_INSTRUCTIONS.md +0 -129
  128. dotscope-1.2.1/LICENSE +0 -21
  129. dotscope-1.2.1/docs/architecture.md +0 -72
  130. dotscope-1.2.1/docs/cli-reference.md +0 -67
  131. dotscope-1.2.1/docs/how-it-works.md +0 -146
  132. dotscope-1.2.1/docs/scope-file.md +0 -285
  133. dotscope-1.2.1/dotscope/.scope +0 -82
  134. dotscope-1.2.1/dotscope/__init__.py +0 -3
  135. dotscope-1.2.1/dotscope/absorber.py +0 -390
  136. dotscope-1.2.1/dotscope/assertions.py +0 -127
  137. dotscope-1.2.1/dotscope/ast_analyzer.py +0 -2
  138. dotscope-1.2.1/dotscope/backtest.py +0 -2
  139. dotscope-1.2.1/dotscope/bench.py +0 -141
  140. dotscope-1.2.1/dotscope/budget.py +0 -3
  141. dotscope-1.2.1/dotscope/cache.py +0 -2
  142. dotscope-1.2.1/dotscope/check/__init__.py +0 -1
  143. dotscope-1.2.1/dotscope/check/acknowledge.py +0 -2
  144. dotscope-1.2.1/dotscope/check/checker.py +0 -3
  145. dotscope-1.2.1/dotscope/check/checks/__init__.py +0 -1
  146. dotscope-1.2.1/dotscope/check/checks/antipattern.py +0 -2
  147. dotscope-1.2.1/dotscope/check/checks/boundary.py +0 -2
  148. dotscope-1.2.1/dotscope/check/checks/contracts.py +0 -3
  149. dotscope-1.2.1/dotscope/check/checks/direction.py +0 -2
  150. dotscope-1.2.1/dotscope/check/checks/intent.py +0 -2
  151. dotscope-1.2.1/dotscope/check/checks/stability.py +0 -2
  152. dotscope-1.2.1/dotscope/check/constraints.py +0 -2
  153. dotscope-1.2.1/dotscope/check/models.py +0 -15
  154. dotscope-1.2.1/dotscope/cli.py +0 -1561
  155. dotscope-1.2.1/dotscope/context.py +0 -60
  156. dotscope-1.2.1/dotscope/counterfactual.py +0 -180
  157. dotscope-1.2.1/dotscope/debug.py +0 -220
  158. dotscope-1.2.1/dotscope/eval/.scope +0 -27
  159. dotscope-1.2.1/dotscope/eval/__init__.py +0 -18
  160. dotscope-1.2.1/dotscope/eval/bootstrap.py +0 -231
  161. dotscope-1.2.1/dotscope/eval/compare.py +0 -147
  162. dotscope-1.2.1/dotscope/eval/corpus.py +0 -214
  163. dotscope-1.2.1/dotscope/eval/harness.py +0 -310
  164. dotscope-1.2.1/dotscope/eval/replay.py +0 -356
  165. dotscope-1.2.1/dotscope/generate/.scope +0 -24
  166. dotscope-1.2.1/dotscope/generate/__init__.py +0 -1
  167. dotscope-1.2.1/dotscope/generate/atlas.py +0 -341
  168. dotscope-1.2.1/dotscope/generate/contracts.py +0 -296
  169. dotscope-1.2.1/dotscope/generate/models.py +0 -27
  170. dotscope-1.2.1/dotscope/generate/network.py +0 -284
  171. dotscope-1.2.1/dotscope/graph.py +0 -3
  172. dotscope-1.2.1/dotscope/help.py +0 -218
  173. dotscope-1.2.1/dotscope/history.py +0 -6
  174. dotscope-1.2.1/dotscope/hooks.py +0 -2
  175. dotscope-1.2.1/dotscope/intent.py +0 -614
  176. dotscope-1.2.1/dotscope/lessons.py +0 -223
  177. dotscope-1.2.1/dotscope/matcher.py +0 -104
  178. dotscope-1.2.1/dotscope/mcp_server.py +0 -1457
  179. dotscope-1.2.1/dotscope/merge/.scope +0 -34
  180. dotscope-1.2.1/dotscope/merge/__init__.py +0 -1
  181. dotscope-1.2.1/dotscope/merge/classifier.py +0 -83
  182. dotscope-1.2.1/dotscope/merge/composer.py +0 -210
  183. dotscope-1.2.1/dotscope/merge/differ.py +0 -178
  184. dotscope-1.2.1/dotscope/merge/driver.py +0 -147
  185. dotscope-1.2.1/dotscope/merge/imports.py +0 -114
  186. dotscope-1.2.1/dotscope/merge/models.py +0 -62
  187. dotscope-1.2.1/dotscope/merge/swarm.py +0 -336
  188. dotscope-1.2.1/dotscope/models/.scope +0 -45
  189. dotscope-1.2.1/dotscope/models/__init__.py +0 -8
  190. dotscope-1.2.1/dotscope/models/eval.py +0 -96
  191. dotscope-1.2.1/dotscope/models/history.py +0 -73
  192. dotscope-1.2.1/dotscope/models/intent.py +0 -214
  193. dotscope-1.2.1/dotscope/models/passes.py +0 -58
  194. dotscope-1.2.1/dotscope/models/state.py +0 -251
  195. dotscope-1.2.1/dotscope/models.py +0 -9
  196. dotscope-1.2.1/dotscope/near_miss.py +0 -3
  197. dotscope-1.2.1/dotscope/onboarding.py +0 -2
  198. dotscope-1.2.1/dotscope/parser.py +0 -395
  199. dotscope-1.2.1/dotscope/passes/.scope +0 -105
  200. dotscope-1.2.1/dotscope/passes/__init__.py +0 -1
  201. dotscope-1.2.1/dotscope/passes/ast_analyzer.py +0 -757
  202. dotscope-1.2.1/dotscope/passes/backtest.py +0 -198
  203. dotscope-1.2.1/dotscope/passes/budget_allocator.py +0 -343
  204. dotscope-1.2.1/dotscope/passes/convention_compliance.py +0 -40
  205. dotscope-1.2.1/dotscope/passes/convention_parser.py +0 -235
  206. dotscope-1.2.1/dotscope/passes/hint_generator.py +0 -128
  207. dotscope-1.2.1/dotscope/passes/history_miner.py +0 -336
  208. dotscope-1.2.1/dotscope/passes/incremental.py +0 -221
  209. dotscope-1.2.1/dotscope/passes/lang/__init__.py +0 -38
  210. dotscope-1.2.1/dotscope/passes/lang/_base.py +0 -20
  211. dotscope-1.2.1/dotscope/passes/lang/_treesitter.py +0 -93
  212. dotscope-1.2.1/dotscope/passes/lang/go.py +0 -334
  213. dotscope-1.2.1/dotscope/passes/lang/javascript.py +0 -431
  214. dotscope-1.2.1/dotscope/passes/lazy.py +0 -177
  215. dotscope-1.2.1/dotscope/passes/preflight.py +0 -117
  216. dotscope-1.2.1/dotscope/passes/semantic_diff.py +0 -160
  217. dotscope-1.2.1/dotscope/passes/sentinel/__init__.py +0 -1
  218. dotscope-1.2.1/dotscope/passes/sentinel/acknowledge.py +0 -222
  219. dotscope-1.2.1/dotscope/passes/sentinel/checker.py +0 -428
  220. dotscope-1.2.1/dotscope/passes/sentinel/checks/__init__.py +0 -1
  221. dotscope-1.2.1/dotscope/passes/sentinel/checks/antipattern.py +0 -84
  222. dotscope-1.2.1/dotscope/passes/sentinel/checks/direction.py +0 -71
  223. dotscope-1.2.1/dotscope/passes/sentinel/checks/spatial.py +0 -115
  224. dotscope-1.2.1/dotscope/passes/sentinel/checks/voice.py +0 -108
  225. dotscope-1.2.1/dotscope/passes/sentinel/constraints.py +0 -472
  226. dotscope-1.2.1/dotscope/passes/sentinel/line_filter.py +0 -88
  227. dotscope-1.2.1/dotscope/passes/sentinel/models.py +0 -15
  228. dotscope-1.2.1/dotscope/passes/spatial_autofix.py +0 -206
  229. dotscope-1.2.1/dotscope/passes/voice.py +0 -161
  230. dotscope-1.2.1/dotscope/passes/voice_defaults.py +0 -68
  231. dotscope-1.2.1/dotscope/passes/voice_discovery.py +0 -245
  232. dotscope-1.2.1/dotscope/paths.py +0 -83
  233. dotscope-1.2.1/dotscope/progress.py +0 -44
  234. dotscope-1.2.1/dotscope/refresh.py +0 -543
  235. dotscope-1.2.1/dotscope/regression.py +0 -147
  236. dotscope-1.2.1/dotscope/search/.scope +0 -29
  237. dotscope-1.2.1/dotscope/search/__init__.py +0 -1
  238. dotscope-1.2.1/dotscope/search/chunker.py +0 -343
  239. dotscope-1.2.1/dotscope/search/expander.py +0 -129
  240. dotscope-1.2.1/dotscope/search/flattener.py +0 -187
  241. dotscope-1.2.1/dotscope/search/models.py +0 -70
  242. dotscope-1.2.1/dotscope/search/observation.py +0 -279
  243. dotscope-1.2.1/dotscope/search/reranker.py +0 -85
  244. dotscope-1.2.1/dotscope/sessions.py +0 -2
  245. dotscope-1.2.1/dotscope/storage/.scope +0 -64
  246. dotscope-1.2.1/dotscope/storage/__init__.py +0 -1
  247. dotscope-1.2.1/dotscope/storage/cache.py +0 -177
  248. dotscope-1.2.1/dotscope/storage/claude_hooks.py +0 -119
  249. dotscope-1.2.1/dotscope/storage/git_hooks.py +0 -500
  250. dotscope-1.2.1/dotscope/storage/incremental_state.py +0 -124
  251. dotscope-1.2.1/dotscope/storage/mcp_config.py +0 -98
  252. dotscope-1.2.1/dotscope/storage/near_miss.py +0 -183
  253. dotscope-1.2.1/dotscope/storage/onboarding.py +0 -150
  254. dotscope-1.2.1/dotscope/storage/session_manager.py +0 -195
  255. dotscope-1.2.1/dotscope/storage/swarm_state.py +0 -144
  256. dotscope-1.2.1/dotscope/storage/timing.py +0 -84
  257. dotscope-1.2.1/dotscope/textio.py +0 -122
  258. dotscope-1.2.1/dotscope/timing.py +0 -2
  259. dotscope-1.2.1/dotscope/utility.py +0 -123
  260. dotscope-1.2.1/dotscope/virtual.py +0 -3
  261. dotscope-1.2.1/dotscope/visibility.py +0 -687
  262. dotscope-1.2.1/logo.png +0 -0
  263. dotscope-1.2.1/pyproject.toml +0 -45
  264. dotscope-1.2.1/tests/.scope +0 -29
  265. dotscope-1.2.1/tests/__init__.py +0 -0
  266. dotscope-1.2.1/tests/conftest.py +0 -152
  267. dotscope-1.2.1/tests/test_absorber.py +0 -91
  268. dotscope-1.2.1/tests/test_ast_analyzer.py +0 -168
  269. dotscope-1.2.1/tests/test_backtest.py +0 -114
  270. dotscope-1.2.1/tests/test_budget.py +0 -124
  271. dotscope-1.2.1/tests/test_canonical_snippet.py +0 -70
  272. dotscope-1.2.1/tests/test_cli.py +0 -122
  273. dotscope-1.2.1/tests/test_composer.py +0 -125
  274. dotscope-1.2.1/tests/test_context.py +0 -52
  275. dotscope-1.2.1/tests/test_enforcement.py +0 -423
  276. dotscope-1.2.1/tests/test_eval_harness.py +0 -376
  277. dotscope-1.2.1/tests/test_experience.py +0 -237
  278. dotscope-1.2.1/tests/test_graph.py +0 -78
  279. dotscope-1.2.1/tests/test_history.py +0 -71
  280. dotscope-1.2.1/tests/test_ingest.py +0 -319
  281. dotscope-1.2.1/tests/test_lessons.py +0 -91
  282. dotscope-1.2.1/tests/test_line_filter.py +0 -67
  283. dotscope-1.2.1/tests/test_loop.py +0 -384
  284. dotscope-1.2.1/tests/test_matcher.py +0 -47
  285. dotscope-1.2.1/tests/test_near_miss.py +0 -161
  286. dotscope-1.2.1/tests/test_refresh.py +0 -251
  287. dotscope-1.2.1/tests/test_resolver.py +0 -100
  288. dotscope-1.2.1/tests/test_rigor.py +0 -223
  289. dotscope-1.2.1/tests/test_routing.py +0 -207
  290. dotscope-1.2.1/tests/test_scanner.py +0 -54
  291. dotscope-1.2.1/tests/test_sessions.py +0 -122
  292. dotscope-1.2.1/tests/test_textio.py +0 -85
  293. dotscope-1.2.1/tests/test_treesitter.py +0 -359
  294. dotscope-1.2.1/tests/test_utility.py +0 -48
  295. dotscope-1.2.1/tests/test_virtual.py +0 -95
  296. dotscope-1.2.1/tests/test_visibility.py +0 -417
  297. dotscope-1.2.1/tests/test_voice_check.py +0 -123
  298. dotscope-1.2.1/tests/test_voice_discovery.py +0 -143
  299. dotscope-1.2.1/uv.lock +0 -2375
  300. {dotscope-1.2.1 → dotscope-1.3.0}/.claude/hooks/pre-commit-check.sh +0 -0
  301. {dotscope-1.2.1 → dotscope-1.3.0}/.claude/settings.json +0 -0
  302. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/.gitignore +0 -0
  303. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/.scopes +0 -0
  304. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/AGENT_INSTRUCTIONS.md +0 -0
  305. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/LICENSE +0 -0
  306. {dotscope-1.2.1 → dotscope-1.3.0}/README.md +0 -0
  307. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/docs/architecture.md +0 -0
  308. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/docs/cli-reference.md +0 -0
  309. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/docs/how-it-works.md +0 -0
  310. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/docs/scope-file.md +0 -0
  311. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/.scope +0 -0
  312. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/absorber.py +0 -0
  313. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/assertions.py +0 -0
  314. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/ast_analyzer.py +0 -0
  315. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/backtest.py +0 -0
  316. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/bench.py +0 -0
  317. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/budget.py +0 -0
  318. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/cache.py +0 -0
  319. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/check/__init__.py +0 -0
  320. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/check/acknowledge.py +0 -0
  321. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/check/checker.py +0 -0
  322. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/check/checks/__init__.py +0 -0
  323. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/check/checks/antipattern.py +0 -0
  324. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/check/checks/boundary.py +0 -0
  325. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/check/checks/contracts.py +0 -0
  326. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/check/checks/direction.py +0 -0
  327. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/check/checks/intent.py +0 -0
  328. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/check/checks/stability.py +0 -0
  329. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/check/constraints.py +0 -0
  330. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/check/models.py +0 -0
  331. {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/constants.py +0 -0
  332. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/context.py +0 -0
  333. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/counterfactual.py +0 -0
  334. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/debug.py +0 -0
  335. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/eval/.scope +0 -0
  336. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/eval/__init__.py +0 -0
  337. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/eval/bootstrap.py +0 -0
  338. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/eval/compare.py +0 -0
  339. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/eval/corpus.py +0 -0
  340. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/eval/harness.py +0 -0
  341. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/eval/replay.py +0 -0
  342. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/generate/.scope +0 -0
  343. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/generate/__init__.py +0 -0
  344. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/generate/atlas.py +0 -0
  345. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/generate/contracts.py +0 -0
  346. {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/generate/engine.py +0 -0
  347. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/generate/models.py +0 -0
  348. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/generate/network.py +0 -0
  349. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/graph.py +0 -0
  350. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/history.py +0 -0
  351. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/hooks.py +0 -0
  352. {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/ignore.py +0 -0
  353. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/intent.py +0 -0
  354. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/lessons.py +0 -0
  355. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/matcher.py +0 -0
  356. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/merge/.scope +0 -0
  357. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/merge/__init__.py +0 -0
  358. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/merge/classifier.py +0 -0
  359. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/merge/composer.py +0 -0
  360. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/merge/differ.py +0 -0
  361. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/merge/driver.py +0 -0
  362. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/merge/imports.py +0 -0
  363. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/merge/models.py +0 -0
  364. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/merge/swarm.py +0 -0
  365. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/models/.scope +0 -0
  366. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/models/__init__.py +0 -0
  367. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/models/eval.py +0 -0
  368. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/models/history.py +0 -0
  369. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/models/passes.py +0 -0
  370. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/near_miss.py +0 -0
  371. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/onboarding.py +0 -0
  372. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/parser.py +0 -0
  373. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/.scope +0 -0
  374. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/__init__.py +0 -0
  375. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/ast_analyzer.py +0 -0
  376. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/backtest.py +0 -0
  377. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/budget_allocator.py +0 -0
  378. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/convention_compliance.py +0 -0
  379. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/convention_parser.py +0 -0
  380. {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/passes/graph_builder.py +0 -0
  381. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/hint_generator.py +0 -0
  382. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/history_miner.py +0 -0
  383. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/incremental.py +0 -0
  384. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/lang/__init__.py +0 -0
  385. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/lang/_base.py +0 -0
  386. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/lang/_treesitter.py +0 -0
  387. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/lang/go.py +0 -0
  388. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/lang/javascript.py +0 -0
  389. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/lazy.py +0 -0
  390. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/preflight.py +0 -0
  391. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/semantic_diff.py +0 -0
  392. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/sentinel/__init__.py +0 -0
  393. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/sentinel/acknowledge.py +0 -0
  394. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/sentinel/checker.py +0 -0
  395. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/sentinel/checks/__init__.py +0 -0
  396. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/sentinel/constraints.py +0 -0
  397. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/sentinel/line_filter.py +0 -0
  398. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/sentinel/models.py +0 -0
  399. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/spatial_autofix.py +0 -0
  400. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/voice.py +0 -0
  401. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/voice_defaults.py +0 -0
  402. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/voice_discovery.py +0 -0
  403. /dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/paths.py → /dotscope-1.3.0/dotscope/paths/__init__.py +0 -0
  404. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/progress.py +0 -0
  405. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/regression.py +0 -0
  406. {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/scanner.py +0 -0
  407. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/search/.scope +0 -0
  408. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/search/__init__.py +0 -0
  409. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/search/chunker.py +0 -0
  410. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/search/expander.py +0 -0
  411. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/search/flattener.py +0 -0
  412. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/search/models.py +0 -0
  413. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/search/observation.py +0 -0
  414. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/search/reranker.py +0 -0
  415. {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/search/retriever.py +0 -0
  416. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/sessions.py +0 -0
  417. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/storage/.scope +0 -0
  418. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/storage/__init__.py +0 -0
  419. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/storage/cache.py +0 -0
  420. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/storage/git_hooks.py +0 -0
  421. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/storage/incremental_state.py +0 -0
  422. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/storage/near_miss.py +0 -0
  423. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/storage/onboarding.py +0 -0
  424. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/storage/session_manager.py +0 -0
  425. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/storage/swarm_state.py +0 -0
  426. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/storage/timing.py +0 -0
  427. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/textio.py +0 -0
  428. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/timing.py +0 -0
  429. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/utility.py +0 -0
  430. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/virtual.py +0 -0
  431. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/visibility.py +0 -0
  432. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/logo.png +0 -0
  433. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/.scope +0 -0
  434. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/__init__.py +0 -0
  435. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/conftest.py +0 -0
  436. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_absorber.py +0 -0
  437. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_ast_analyzer.py +0 -0
  438. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_backtest.py +0 -0
  439. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_budget.py +0 -0
  440. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_canonical_snippet.py +0 -0
  441. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_cli.py +0 -0
  442. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_composer.py +0 -0
  443. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_context.py +0 -0
  444. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_enforcement.py +0 -0
  445. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_eval_harness.py +0 -0
  446. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_experience.py +0 -0
  447. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_graph.py +0 -0
  448. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_history.py +0 -0
  449. {dotscope-1.2.1 → dotscope-1.3.0}/tests/test_ignore.py +0 -0
  450. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_lessons.py +0 -0
  451. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_line_filter.py +0 -0
  452. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_loop.py +0 -0
  453. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_matcher.py +0 -0
  454. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_near_miss.py +0 -0
  455. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_refresh.py +0 -0
  456. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_resolver.py +0 -0
  457. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_rigor.py +0 -0
  458. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_routing.py +0 -0
  459. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_scanner.py +0 -0
  460. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_sessions.py +0 -0
  461. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_textio.py +0 -0
  462. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_treesitter.py +0 -0
  463. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_utility.py +0 -0
  464. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_visibility.py +0 -0
  465. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_voice_check.py +0 -0
  466. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_voice_discovery.py +0 -0
  467. {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/uv.lock +0 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(python -m pytest tests/test_mcp_config.py tests/test_mcp_server.py -v)"
5
+ ]
6
+ }
7
+ }
@@ -49,7 +49,7 @@ jobs:
49
49
  # Dedicated environments with protections for publishing are strongly recommended.
50
50
  # For more information, see: https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment#deployment-protection-rules
51
51
  environment:
52
- name: pypi
52
+ name: dotscope environment
53
53
  # OPTIONAL: uncomment and update to include your PyPI project URL in the deployment status:
54
54
  # url: https://pypi.org/p/YOURPROJECT
55
55
  #
@@ -0,0 +1,8 @@
1
+ {
2
+ "mcpServers": {
3
+ "dotscope": {
4
+ "type": "stdio",
5
+ "command": "dotscope-mcp"
6
+ }
7
+ }
8
+ }
@@ -0,0 +1,14 @@
1
+ description: Detected dense God-Objects. Emitting directive to isolate hubs.
2
+ includes:
3
+ - dotscope/discovery.py
4
+ - dotscope/models.py
5
+ - dotscope/parser.py
6
+ context: |
7
+ ## Cloud Directive
8
+ This virtual scope isolates objects that cross the semantic failure threshold for AI context.
9
+
10
+ ### Constraints
11
+ - prohibited_imports: *
12
+ tags:
13
+ - virtual
14
+ - federated-directive
@@ -0,0 +1,10 @@
1
+ # CLAUDE.md
2
+
3
+ This repo uses dotscope. Before touching code:
4
+
5
+ 1. `codebase_search("your task description")` — not manual file reads
6
+ 2. `dotscope_check` before every commit
7
+ 3. If check returns HOLDs, fix them before committing
8
+
9
+ dotscope provides: dependency graph, implicit contracts, conventions,
10
+ and file locks. Use its tools instead of guessing.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dotscope
3
- Version: 1.2.1
3
+ Version: 1.3.0
4
4
  Summary: Agents see files. You see architecture. dotscope gives agents the architecture.
5
5
  Author: Supremum
6
6
  License-Expression: MIT
@@ -17,7 +17,7 @@ Requires-Dist: tree-sitter-javascript>=0.23.0
17
17
  Requires-Dist: tree-sitter-typescript>=0.23.0
18
18
  Requires-Dist: tree-sitter>=0.23.0
19
19
  Provides-Extra: all
20
- Requires-Dist: mcp>=1.2.0; extra == 'all'
20
+ Requires-Dist: mcp<3,>=1.2.0; extra == 'all'
21
21
  Requires-Dist: numpy; extra == 'all'
22
22
  Requires-Dist: sentence-transformers; extra == 'all'
23
23
  Requires-Dist: tiktoken; extra == 'all'
@@ -27,7 +27,7 @@ Requires-Dist: ruff; extra == 'dev'
27
27
  Provides-Extra: embeddings
28
28
  Requires-Dist: sentence-transformers; extra == 'embeddings'
29
29
  Provides-Extra: mcp
30
- Requires-Dist: mcp>=1.2.0; extra == 'mcp'
30
+ Requires-Dist: mcp<3,>=1.2.0; extra == 'mcp'
31
31
  Provides-Extra: search
32
32
  Requires-Dist: numpy; extra == 'search'
33
33
  Requires-Dist: sentence-transformers; extra == 'search'
@@ -2,18 +2,25 @@
2
2
 
3
3
  dotscope's primary interface for agents is an MCP server. The agent calls `resolve_scope` to get files, context, and constraints. dotscope tracks every call for the feedback loop.
4
4
 
5
+ **Supported clients:** Claude Desktop, Claude Code, Cursor, Windsurf, VS Code Copilot, OpenAI Codex CLI, JetBrains AI, Zed
6
+
5
7
  ## Install
6
8
 
7
9
  ```bash
8
10
  pip install dotscope[mcp]
9
11
  ```
10
12
 
13
+ ## Quick Setup
14
+
15
+ Run `dotscope init` in your project root. It auto-detects installed editors and writes config for each one.
16
+
11
17
  ## Claude Desktop
12
18
 
13
19
  Edit your config file:
14
20
 
15
21
  **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
16
22
  **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
23
+ **Linux:** `~/.config/Claude/claude_desktop_config.json`
17
24
 
18
25
  ```json
19
26
  {
@@ -30,12 +37,13 @@ Omit `--root` to use the current working directory. Restart Claude Desktop after
30
37
 
31
38
  ## Claude Code
32
39
 
33
- Add to your project's `.claude/settings.json` or the global settings:
40
+ Add a `.mcp.json` file to your project root (preferred):
34
41
 
35
42
  ```json
36
43
  {
37
44
  "mcpServers": {
38
45
  "dotscope": {
46
+ "type": "stdio",
39
47
  "command": "dotscope-mcp"
40
48
  }
41
49
  }
@@ -46,7 +54,7 @@ No `--root` needed. Claude Code launches from the project directory.
46
54
 
47
55
  ## Cursor
48
56
 
49
- Settings > MCP Servers:
57
+ Add to `.cursor/mcp.json` in your project root:
50
58
 
51
59
  ```json
52
60
  {
@@ -57,6 +65,76 @@ Settings > MCP Servers:
57
65
  }
58
66
  ```
59
67
 
68
+ Note: Cursor uses a flat structure (no `mcpServers` wrapper).
69
+
70
+ ## Windsurf
71
+
72
+ Edit `~/.codeium/windsurf/mcp_config.json` (global config):
73
+
74
+ ```json
75
+ {
76
+ "mcpServers": {
77
+ "dotscope": {
78
+ "command": "dotscope-mcp",
79
+ "args": ["--root", "/path/to/your/project"]
80
+ }
81
+ }
82
+ }
83
+ ```
84
+
85
+ ## VS Code Copilot
86
+
87
+ Add to `.vscode/mcp.json` in your project root:
88
+
89
+ ```json
90
+ {
91
+ "servers": {
92
+ "dotscope": {
93
+ "command": "dotscope-mcp"
94
+ }
95
+ }
96
+ }
97
+ ```
98
+
99
+ Note: VS Code uses `servers` as the top-level key (not `mcpServers`).
100
+
101
+ ## OpenAI Codex CLI
102
+
103
+ Add to `.codex/config.toml` in your project root (or `~/.codex/config.toml` for global):
104
+
105
+ ```toml
106
+ [mcp_servers.dotscope]
107
+ command = "dotscope-mcp"
108
+ ```
109
+
110
+ ## JetBrains AI
111
+
112
+ Configure manually via the IDE:
113
+
114
+ 1. Open **Settings > Tools > AI Assistant > Model Context Protocol (MCP)**
115
+ 2. Add a new local server:
116
+ - **Command:** `dotscope-mcp`
117
+ - **Arguments:** `--root /path/to/your/project`
118
+ 3. Click OK and restart the AI Assistant
119
+
120
+ ## Zed
121
+
122
+ Add to `~/.config/zed/settings.json`:
123
+
124
+ ```json
125
+ {
126
+ "context_servers": {
127
+ "dotscope": {
128
+ "source": "custom",
129
+ "command": "dotscope-mcp",
130
+ "args": ["--root", "/path/to/your/project"]
131
+ }
132
+ }
133
+ }
134
+ ```
135
+
136
+ Or use Agent Panel (Cmd+Shift+A) > Settings > "Add Custom Server".
137
+
60
138
  ## Verifying
61
139
 
62
140
  Ask your agent: "What scopes are available?" It should call `list_scopes` and show what dotscope generated during ingest.
@@ -1,3 +1,3 @@
1
1
  """dotscope — Directory-scoped context boundaries for AI coding agents."""
2
2
 
3
- __version__ = "0.1.0"
3
+ __version__ = "1.3.0"
@@ -0,0 +1,320 @@
1
+ from .core import _cmd_resolve, _cmd_context, _cmd_match, _cmd_init, _cmd_intent, _cmd_utility
2
+ from .observability import _cmd_stats, _cmd_tree, _cmd_health, _cmd_validate, _cmd_virtual, _cmd_lessons, _cmd_invariants, _cmd_rebuild, _cmd_test_compiler, _cmd_bench, _cmd_debug
3
+ from .ingest import _cmd_ingest, _cmd_impact, _cmd_backtest, _cmd_conventions, _cmd_diff
4
+ from .hooks import _cmd_observe, _cmd_incremental, _cmd_hook, _cmd_refresh, _cmd_check, _cmd_check_backtest, _cmd_voice
5
+
6
+
7
+ """CLI entry point for dotscope."""
8
+
9
+ import argparse
10
+
11
+ import os
12
+
13
+ import sys
14
+
15
+ def _safe_print(text, **kwargs):
16
+ """Print with ASCII fallback for Windows cp1252 terminals."""
17
+ try:
18
+ print(text, **kwargs)
19
+ except UnicodeEncodeError:
20
+ print(text.encode("ascii", errors="replace").decode("ascii"), **kwargs)
21
+
22
+ def main(argv=None):
23
+ from ..textio import consume_decode_warnings
24
+
25
+ consume_decode_warnings()
26
+
27
+ # Intercept help before argparse touches it
28
+ args_list = argv if argv is not None else sys.argv[1:]
29
+ if not args_list or args_list == ["help"] or args_list == ["--help"] or args_list == ["-h"]:
30
+ from ..help import print_help
31
+ print_help()
32
+ return
33
+ if len(args_list) >= 2 and args_list[1] in ("--help", "-h"):
34
+ from ..help import print_help, HELP_COMMANDS
35
+ cmd = args_list[0]
36
+ if cmd in HELP_COMMANDS:
37
+ print_help(cmd)
38
+ return
39
+ # Fall through to argparse for unknown commands
40
+
41
+ parser = argparse.ArgumentParser(
42
+ prog="dotscope",
43
+ description="Directory-scoped context boundaries for AI coding agents",
44
+ add_help=False,
45
+ )
46
+ parser.add_argument("--version", action="version", version=f"%(prog)s {_version()}")
47
+ parser.add_argument("-h", "--help", action="store_true", dest="show_help")
48
+
49
+ sub = parser.add_subparsers(dest="command")
50
+
51
+ # --- resolve ---
52
+ p_resolve = sub.add_parser("resolve", help="Resolve a scope expression to files")
53
+ p_resolve.add_argument("scope", help="Scope name, path, or expression (e.g., auth+payments)")
54
+ p_resolve.add_argument("--budget", type=int, default=None, help="Max tokens (context + files)")
55
+ p_resolve.add_argument("--tokens", action="store_true", help="Show per-file token counts")
56
+ p_resolve.add_argument("--json", action="store_true", help="Output as JSON")
57
+ p_resolve.add_argument("--cursor", action="store_true", help="Output as .cursorrules format")
58
+ p_resolve.add_argument("--no-related", action="store_true", help="Don't follow related scopes")
59
+ p_resolve.add_argument("--task", default=None, help="Task description for relevance ranking")
60
+
61
+ # --- context ---
62
+ p_context = sub.add_parser("context", help="Print context for a scope")
63
+ p_context.add_argument("scope", help="Scope name or path")
64
+ p_context.add_argument("--section", default=None, help="Filter to a named section")
65
+
66
+ # --- match ---
67
+ p_match = sub.add_parser("match", help="Match a task description to scope(s)")
68
+ p_match.add_argument("task", help="Task description string")
69
+
70
+ # --- init ---
71
+ p_init = sub.add_parser("init", help="One command: ingest, install hooks, configure agents")
72
+ p_init.add_argument("path", nargs="?", default=".", help="Repository root")
73
+ p_init.add_argument("--quiet", action="store_true", help="Suppress progress (for CI)")
74
+
75
+ # --- validate ---
76
+ sub.add_parser("validate", help="Check all .scope files for broken paths")
77
+
78
+ # --- stats ---
79
+ sub.add_parser("stats", help="Token savings report across all scopes")
80
+
81
+ # --- tree ---
82
+ sub.add_parser("tree", help="Visual tree of all scopes and relationships")
83
+
84
+ # --- health ---
85
+ sub.add_parser("health", help="Scope health: staleness, coverage, drift")
86
+
87
+ # --- ingest ---
88
+ p_ingest = sub.add_parser("ingest", help="Reverse-engineer .scope files from an existing codebase")
89
+ p_ingest.add_argument("--dir", default=".", help="Repository root to ingest")
90
+ p_ingest.add_argument("--no-history", action="store_true", help="Skip git history mining")
91
+ p_ingest.add_argument("--no-docs", action="store_true", help="Skip doc absorption")
92
+ p_ingest.add_argument("--dry-run", action="store_true", help="Plan only, don't write files")
93
+ p_ingest.add_argument("--max-commits", type=int, default=500, help="Max git commits to analyze")
94
+ p_ingest.add_argument("--quiet", action="store_true", help="Suppress progress output (for CI)")
95
+ p_ingest.add_argument("--voice", choices=["prescriptive", "adaptive"], default=None,
96
+ help="Override voice mode (prescriptive for new, adaptive for existing)")
97
+
98
+ # --- voice ---
99
+ p_voice = sub.add_parser("voice", help="View and manage code voice")
100
+ p_voice.add_argument("--upgrade", metavar="RULE", help="Upgrade enforcement for a rule (typing, bare_excepts)")
101
+ p_voice.add_argument("--reset", action="store_true", help="Reset voice to defaults")
102
+ p_voice.add_argument("--json", action="store_true", help="Machine-readable output")
103
+
104
+ # --- impact ---
105
+ p_impact = sub.add_parser("impact", help="Predict blast radius of changes to a file")
106
+ p_impact.add_argument("file", help="File path to analyze impact for")
107
+
108
+ # --- backtest ---
109
+ p_backtest = sub.add_parser("backtest", help="Validate scopes against git history")
110
+ p_backtest.add_argument("--commits", type=int, default=50, help="Number of commits to test against")
111
+
112
+ # --- observe ---
113
+ p_observe = sub.add_parser("observe", help="Record observation for a commit (called by post-commit hook)")
114
+ p_observe.add_argument("commit", help="Commit hash to observe")
115
+
116
+ # --- incremental ---
117
+ p_incremental = sub.add_parser("incremental", help="Incremental scope update (called by post-commit hook)")
118
+ p_incremental.add_argument("commit", help="Commit hash")
119
+
120
+ # --- hook ---
121
+ p_hook = sub.add_parser("hook", help="Manage git hooks")
122
+ hook_sub = p_hook.add_subparsers(dest="hook_action")
123
+ hook_sub.add_parser("install", help="Install post-commit observer hook")
124
+ hook_sub.add_parser("uninstall", help="Remove post-commit observer hook")
125
+ hook_sub.add_parser("status", help="Check if hook is installed")
126
+ hook_sub.add_parser("claude", help="Install Claude Code pre-commit enforcement")
127
+
128
+ # --- refresh ---
129
+ p_refresh = sub.add_parser("refresh", help="Refresh scopes (synchronous by default)")
130
+ p_refresh.add_argument("scopes", nargs="*", help="Scope names to refresh (omit for full repo)")
131
+ p_refresh.add_argument("--repo", action="store_true", help="Force full repo refresh")
132
+ p_refresh.add_argument("--async", dest="run_async", action="store_true", help="Queue and return (legacy async mode)")
133
+ refresh_sub = p_refresh.add_subparsers(dest="refresh_action")
134
+ p_refresh_enqueue = refresh_sub.add_parser("enqueue", help="Queue runtime refresh work")
135
+ p_refresh_enqueue.add_argument("scopes", nargs="*", help="Scope names to refresh")
136
+ p_refresh_enqueue.add_argument("--commit", default=None, help="Classify a commit into refresh work")
137
+ p_refresh_enqueue.add_argument("--repo", action="store_true", help="Enqueue a full repo runtime refresh")
138
+ p_refresh_enqueue.add_argument("--reason", default="", help="Reason stored with the queued job")
139
+ p_refresh_run = refresh_sub.add_parser("run", help="Run queued refresh work")
140
+ p_refresh_run.add_argument("--drain", action="store_true", help="Drain the entire queue")
141
+ refresh_sub.add_parser("status", help="Show refresh worker and queue status")
142
+
143
+ # --- utility ---
144
+ p_utility = sub.add_parser("utility", help="Show utility scores for a scope")
145
+ p_utility.add_argument("scope", help="Scope name")
146
+
147
+ # --- virtual ---
148
+ sub.add_parser("virtual", help="Detect and show virtual (cross-cutting) scopes")
149
+
150
+ # --- lessons ---
151
+ p_lessons = sub.add_parser("lessons", help="Show lessons for a scope")
152
+ p_lessons.add_argument("scope", help="Scope name")
153
+
154
+ # --- invariants ---
155
+ p_invariants = sub.add_parser("invariants", help="Show observed invariants for a scope")
156
+ p_invariants.add_argument("scope", help="Scope name")
157
+
158
+ # --- rebuild ---
159
+ sub.add_parser("rebuild", help="Rebuild derived state from event logs")
160
+
161
+ # --- check ---
162
+ p_check = sub.add_parser("check", help="Validate a diff against codebase rules")
163
+ p_check.add_argument("--diff", default=None, help="Path to diff file (default: staged changes)")
164
+ p_check.add_argument("--session", default=None, help="Session ID for boundary checking")
165
+ p_check.add_argument("--acknowledge", action="append", default=[], help="Acknowledge a hold by ID")
166
+ p_check.add_argument("--backtest", action="store_true", help="Replay recent commits against checks")
167
+ p_check.add_argument("--commits", type=int, default=10, help="Commits to replay in backtest mode")
168
+ p_check.add_argument("--json", dest="json_output", action="store_true", help="Output as JSON")
169
+ p_check.add_argument("--explain", action="store_true", help="Show full provenance for each finding")
170
+
171
+ # --- intent ---
172
+ p_intent = sub.add_parser("intent", help="Manage architectural intents")
173
+ intent_sub = p_intent.add_subparsers(dest="intent_action")
174
+ p_intent_add = intent_sub.add_parser("add", help="Add an architectural intent")
175
+ p_intent_add.add_argument("directive", choices=["decouple", "deprecate", "freeze", "consolidate"])
176
+ p_intent_add.add_argument("targets", nargs="+", help="Modules or files")
177
+ p_intent_add.add_argument("--reason", default="", help="Why this intent exists")
178
+ p_intent_add.add_argument("--replacement", default=None, help="Replacement (for deprecate)")
179
+ p_intent_add.add_argument("--target", default=None, help="Consolidation target")
180
+ p_intent_list = intent_sub.add_parser("list", help="List all intents")
181
+ p_intent_rm = intent_sub.add_parser("remove", help="Remove an intent by ID")
182
+ p_intent_rm.add_argument("id", help="Intent ID to remove")
183
+
184
+ # --- conventions ---
185
+ p_conv = sub.add_parser("conventions", help="List or discover conventions")
186
+ p_conv.add_argument("--discover", action="store_true", help="Discover conventions from codebase")
187
+ p_conv.add_argument("--accept", action="store_true", help="Accept discovered conventions")
188
+ p_conv.add_argument("--json", dest="json_output", action="store_true", help="Output as JSON")
189
+
190
+ # --- diff ---
191
+ p_diff = sub.add_parser("diff", help="Semantic diff against conventions")
192
+ p_diff.add_argument("ref", nargs="?", default=None, help="Git ref to diff against")
193
+ p_diff.add_argument("--staged", action="store_true", help="Diff staged changes")
194
+ p_diff.add_argument("--json", dest="json_output", action="store_true", help="Output as JSON")
195
+
196
+ # --- test-compiler ---
197
+ p_tc = sub.add_parser("test-compiler", help="Replay frozen sessions as regression tests")
198
+ p_tc.add_argument("--scope", default=None, help="Filter to a specific scope")
199
+
200
+ # --- bench ---
201
+ p_bench = sub.add_parser("bench", help="Performance and accuracy benchmarks")
202
+ p_bench.add_argument("--json", dest="json_output", action="store_true", help="JSON output")
203
+
204
+ # --- debug ---
205
+ p_debug = sub.add_parser("debug", help="Bisect a bad session to find root cause")
206
+ p_debug.add_argument("session_id", nargs="?", default=None, help="Session ID to debug")
207
+ p_debug.add_argument("--last", action="store_true", help="Debug most recent bad session")
208
+ p_debug.add_argument("--list", dest="list_bad", action="store_true", help="List bad sessions")
209
+
210
+ args = parser.parse_args(argv)
211
+
212
+ if args.command is None or getattr(args, "show_help", False):
213
+ from ..help import print_help
214
+ print_help()
215
+ return
216
+
217
+ try:
218
+ handler = {
219
+ "resolve": _cmd_resolve,
220
+ "context": _cmd_context,
221
+ "match": _cmd_match,
222
+ "init": _cmd_init,
223
+ "validate": _cmd_validate,
224
+ "stats": _cmd_stats,
225
+ "tree": _cmd_tree,
226
+ "health": _cmd_health,
227
+ "ingest": _cmd_ingest,
228
+ "impact": _cmd_impact,
229
+ "backtest": _cmd_backtest,
230
+ "observe": _cmd_observe,
231
+ "incremental": _cmd_incremental,
232
+ "hook": _cmd_hook,
233
+ "refresh": _cmd_refresh,
234
+ "utility": _cmd_utility,
235
+ "virtual": _cmd_virtual,
236
+ "lessons": _cmd_lessons,
237
+ "invariants": _cmd_invariants,
238
+ "rebuild": _cmd_rebuild,
239
+ "check": _cmd_check,
240
+ "intent": _cmd_intent,
241
+ "conventions": _cmd_conventions,
242
+ "diff": _cmd_diff,
243
+ "voice": _cmd_voice,
244
+ "test-compiler": _cmd_test_compiler,
245
+ "bench": _cmd_bench,
246
+ "debug": _cmd_debug,
247
+ }[args.command]
248
+ handler(args)
249
+ except (ValueError, FileNotFoundError) as e:
250
+ print(f"Error: {e}", file=sys.stderr)
251
+ sys.exit(1)
252
+ finally:
253
+ warnings = consume_decode_warnings()
254
+ if warnings:
255
+ count = len(warnings)
256
+ noun = "file" if count == 1 else "files"
257
+ _safe_print(
258
+ f"dotscope: decoded {count} repo {noun} with replacement; "
259
+ "run `dotscope health` for details",
260
+ file=sys.stderr,
261
+ )
262
+
263
+ def _print_counterfactual(ingest_result, backtest, violations):
264
+ """Format init output as a counterfactual story."""
265
+ scopes = ingest_result.get("scopes_written", 0) if isinstance(ingest_result, dict) else 0
266
+ contracts = ingest_result.get("contracts_found", 0) if isinstance(ingest_result, dict) else 0
267
+ conventions = ingest_result.get("conventions_found", 0) if isinstance(ingest_result, dict) else 0
268
+
269
+ recall = backtest.get("overall_recall", 0)
270
+
271
+ lines = [""]
272
+ lines.append(f" {scopes} scopes, {contracts} contracts, {conventions} conventions, {recall:.0%} recall")
273
+ lines.append("")
274
+
275
+ if violations > 0:
276
+ lines.append(f" What dotscope would have caught in your last 50 commits:")
277
+ lines.append(f" {violations} files that agents would have missed")
278
+ lines.append("")
279
+ lines.append(" Your agents are ready.")
280
+ lines.append("")
281
+
282
+ print("\n".join(lines), file=sys.stderr)
283
+
284
+ def _write_agent_instructions(root: str, quiet: bool = False):
285
+ """Write AGENT_INSTRUCTIONS.md to the target repo if it doesn't exist."""
286
+ target = os.path.join(root, "AGENT_INSTRUCTIONS.md")
287
+ if os.path.exists(target):
288
+ if not quiet:
289
+ print("dotscope: AGENT_INSTRUCTIONS.md already exists, skipping", file=sys.stderr)
290
+ return
291
+
292
+ # Load the template from the dotscope package
293
+ package_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
294
+ template = os.path.join(package_dir, "AGENT_INSTRUCTIONS.md")
295
+
296
+ if os.path.isfile(template):
297
+ import shutil
298
+ shutil.copy2(template, target)
299
+ else:
300
+ # Fallback: write a minimal version
301
+ with open(target, "w", encoding="utf-8") as f:
302
+ f.write("# dotscope Agent Instructions\n\n")
303
+ f.write("Start every task with `codebase_search`. Run `dotscope_check` before every commit.\n\n")
304
+ f.write("See https://github.com/nxrobins/dotscope for full documentation.\n")
305
+
306
+ if not quiet:
307
+ print("dotscope: AGENT_INSTRUCTIONS.md written", file=sys.stderr)
308
+
309
+ def _print_summary(ingest_result):
310
+ """Fallback when backtest isn't available."""
311
+ print("", file=sys.stderr)
312
+ print(" Your agents are ready.", file=sys.stderr)
313
+ print("", file=sys.stderr)
314
+
315
+ def _version():
316
+ from .. import __version__
317
+ return __version__
318
+
319
+ if __name__ == "__main__":
320
+ main()