dotscope 1.2.0__tar.gz → 1.2.1__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 (418) hide show
  1. dotscope-1.2.1/PKG-INFO +83 -0
  2. dotscope-1.2.1/README.md +46 -0
  3. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/__init__.py +1 -1
  4. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/constants.py +26 -2
  5. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/generate/engine.py +2 -2
  6. dotscope-1.2.1/dotscope/ignore.py +59 -0
  7. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/ingest.py +51 -3
  8. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/graph_builder.py +13 -2
  9. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/scanner.py +18 -1
  10. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/search/retriever.py +21 -3
  11. {dotscope-1.2.0 → dotscope-1.2.1}/pyproject.toml +1 -1
  12. dotscope-1.2.1/tests/test_ignore.py +64 -0
  13. dotscope-1.2.0/PKG-INFO +0 -127
  14. dotscope-1.2.0/README.md +0 -90
  15. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/hooks/pre-commit-check.sh +0 -0
  16. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/settings.json +0 -0
  17. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/settings.local.json +0 -0
  18. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/.claude/hooks/pre-commit-check.sh +0 -0
  19. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/.claude/settings.json +0 -0
  20. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/.claude/settings.local.json +0 -0
  21. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/.git +0 -0
  22. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/.gitignore +0 -0
  23. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/.scopes +0 -0
  24. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/AGENT_INSTRUCTIONS.md +0 -0
  25. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/LICENSE +0 -0
  26. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/README.md +0 -0
  27. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/docs/architecture.md +0 -0
  28. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/docs/cli-reference.md +0 -0
  29. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/docs/how-it-works.md +0 -0
  30. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/docs/mcp-setup.md +0 -0
  31. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/docs/scope-file.md +0 -0
  32. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/.scope +0 -0
  33. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/__init__.py +0 -0
  34. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/absorber.py +0 -0
  35. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/assertions.py +0 -0
  36. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/ast_analyzer.py +0 -0
  37. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/backtest.py +0 -0
  38. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/bench.py +0 -0
  39. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/budget.py +0 -0
  40. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/cache.py +0 -0
  41. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/check/__init__.py +0 -0
  42. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/check/acknowledge.py +0 -0
  43. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/check/checker.py +0 -0
  44. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/check/checks/__init__.py +0 -0
  45. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/check/checks/antipattern.py +0 -0
  46. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/check/checks/boundary.py +0 -0
  47. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/check/checks/contracts.py +0 -0
  48. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/check/checks/direction.py +0 -0
  49. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/check/checks/intent.py +0 -0
  50. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/check/checks/stability.py +0 -0
  51. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/check/constraints.py +0 -0
  52. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/check/models.py +0 -0
  53. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/cli.py +0 -0
  54. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/composer.py +0 -0
  55. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/constants.py +0 -0
  56. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/context.py +0 -0
  57. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/counterfactual.py +0 -0
  58. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/debug.py +0 -0
  59. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/discovery.py +0 -0
  60. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/eval/.scope +0 -0
  61. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/eval/__init__.py +0 -0
  62. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/eval/bootstrap.py +0 -0
  63. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/eval/compare.py +0 -0
  64. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/eval/corpus.py +0 -0
  65. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/eval/harness.py +0 -0
  66. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/eval/replay.py +0 -0
  67. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/formatter.py +0 -0
  68. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/generate/.scope +0 -0
  69. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/generate/__init__.py +0 -0
  70. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/generate/atlas.py +0 -0
  71. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/generate/contracts.py +0 -0
  72. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/generate/engine.py +0 -0
  73. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/generate/models.py +0 -0
  74. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/generate/network.py +0 -0
  75. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/graph.py +0 -0
  76. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/health.py +0 -0
  77. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/help.py +0 -0
  78. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/history.py +0 -0
  79. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/hooks.py +0 -0
  80. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/ingest.py +0 -0
  81. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/intent.py +0 -0
  82. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/lessons.py +0 -0
  83. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/matcher.py +0 -0
  84. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/mcp_server.py +0 -0
  85. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/merge/.scope +0 -0
  86. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/merge/__init__.py +0 -0
  87. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/merge/classifier.py +0 -0
  88. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/merge/composer.py +0 -0
  89. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/merge/differ.py +0 -0
  90. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/merge/driver.py +0 -0
  91. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/merge/imports.py +0 -0
  92. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/merge/models.py +0 -0
  93. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/merge/swarm.py +0 -0
  94. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/models/.scope +0 -0
  95. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/models/__init__.py +0 -0
  96. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/models/core.py +0 -0
  97. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/models/eval.py +0 -0
  98. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/models/history.py +0 -0
  99. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/models/intent.py +0 -0
  100. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/models/passes.py +0 -0
  101. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/models/state.py +0 -0
  102. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/models.py +0 -0
  103. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/near_miss.py +0 -0
  104. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/onboarding.py +0 -0
  105. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/parser.py +0 -0
  106. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/.scope +0 -0
  107. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/__init__.py +0 -0
  108. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/ast_analyzer.py +0 -0
  109. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/backtest.py +0 -0
  110. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/budget_allocator.py +0 -0
  111. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/convention_compliance.py +0 -0
  112. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/convention_discovery.py +0 -0
  113. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/convention_parser.py +0 -0
  114. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/graph_builder.py +0 -0
  115. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/hint_generator.py +0 -0
  116. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/history_miner.py +0 -0
  117. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/incremental.py +0 -0
  118. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/lang/__init__.py +0 -0
  119. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/lang/_base.py +0 -0
  120. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/lang/_treesitter.py +0 -0
  121. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/lang/go.py +0 -0
  122. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/lang/javascript.py +0 -0
  123. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/lazy.py +0 -0
  124. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/preflight.py +0 -0
  125. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/semantic_diff.py +0 -0
  126. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/sentinel/__init__.py +0 -0
  127. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/sentinel/acknowledge.py +0 -0
  128. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/sentinel/checker.py +0 -0
  129. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/sentinel/checks/__init__.py +0 -0
  130. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/sentinel/checks/antipattern.py +0 -0
  131. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/sentinel/checks/boundary.py +0 -0
  132. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/sentinel/checks/contracts.py +0 -0
  133. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/sentinel/checks/convention.py +0 -0
  134. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/sentinel/checks/direction.py +0 -0
  135. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/sentinel/checks/intent.py +0 -0
  136. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/sentinel/checks/network.py +0 -0
  137. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/sentinel/checks/spatial.py +0 -0
  138. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/sentinel/checks/stability.py +0 -0
  139. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/sentinel/checks/voice.py +0 -0
  140. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/sentinel/constraints.py +0 -0
  141. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/sentinel/line_filter.py +0 -0
  142. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/sentinel/models.py +0 -0
  143. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/spatial_autofix.py +0 -0
  144. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/virtual.py +0 -0
  145. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/voice.py +0 -0
  146. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/voice_defaults.py +0 -0
  147. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/passes/voice_discovery.py +0 -0
  148. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/paths.py +0 -0
  149. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/progress.py +0 -0
  150. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/refresh.py +0 -0
  151. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/regression.py +0 -0
  152. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/resolver.py +0 -0
  153. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/runtime_overlay.py +0 -0
  154. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/scanner.py +0 -0
  155. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/search/.scope +0 -0
  156. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/search/__init__.py +0 -0
  157. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/search/chunker.py +0 -0
  158. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/search/expander.py +0 -0
  159. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/search/flattener.py +0 -0
  160. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/search/models.py +0 -0
  161. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/search/observation.py +0 -0
  162. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/search/reranker.py +0 -0
  163. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/search/retriever.py +0 -0
  164. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/search/synthesizer.py +0 -0
  165. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/sessions.py +0 -0
  166. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/storage/.scope +0 -0
  167. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/storage/__init__.py +0 -0
  168. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/storage/cache.py +0 -0
  169. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/storage/claude_hooks.py +0 -0
  170. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/storage/git_hooks.py +0 -0
  171. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/storage/incremental_state.py +0 -0
  172. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/storage/mcp_config.py +0 -0
  173. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/storage/near_miss.py +0 -0
  174. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/storage/onboarding.py +0 -0
  175. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/storage/session_manager.py +0 -0
  176. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/storage/swarm_state.py +0 -0
  177. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/storage/timing.py +0 -0
  178. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/textio.py +0 -0
  179. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/timing.py +0 -0
  180. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/tokens.py +0 -0
  181. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/utility.py +0 -0
  182. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/virtual.py +0 -0
  183. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/dotscope/visibility.py +0 -0
  184. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/logo.png +0 -0
  185. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/pyproject.toml +0 -0
  186. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/.scope +0 -0
  187. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/__init__.py +0 -0
  188. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/conftest.py +0 -0
  189. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_absorber.py +0 -0
  190. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_ast_analyzer.py +0 -0
  191. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_backtest.py +0 -0
  192. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_budget.py +0 -0
  193. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_canonical_snippet.py +0 -0
  194. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_cli.py +0 -0
  195. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_composer.py +0 -0
  196. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_context.py +0 -0
  197. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_enforcement.py +0 -0
  198. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_eval_harness.py +0 -0
  199. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_experience.py +0 -0
  200. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_graph.py +0 -0
  201. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_health.py +0 -0
  202. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_history.py +0 -0
  203. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_ingest.py +0 -0
  204. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_lessons.py +0 -0
  205. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_line_filter.py +0 -0
  206. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_loop.py +0 -0
  207. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_matcher.py +0 -0
  208. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_near_miss.py +0 -0
  209. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_parser.py +0 -0
  210. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_refresh.py +0 -0
  211. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_resolver.py +0 -0
  212. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_rigor.py +0 -0
  213. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_routing.py +0 -0
  214. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_scanner.py +0 -0
  215. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_sessions.py +0 -0
  216. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_textio.py +0 -0
  217. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_treesitter.py +0 -0
  218. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_utility.py +0 -0
  219. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_virtual.py +0 -0
  220. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_visibility.py +0 -0
  221. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_voice_check.py +0 -0
  222. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/tests/test_voice_discovery.py +0 -0
  223. {dotscope-1.2.0 → dotscope-1.2.1}/.claude/worktrees/hopeful-chatelet/uv.lock +0 -0
  224. {dotscope-1.2.0 → dotscope-1.2.1}/.github/workflows/python-publish.yml +0 -0
  225. {dotscope-1.2.0 → dotscope-1.2.1}/.gitignore +0 -0
  226. {dotscope-1.2.0 → dotscope-1.2.1}/.mcp.json +0 -0
  227. {dotscope-1.2.0 → dotscope-1.2.1}/.scopes +0 -0
  228. {dotscope-1.2.0 → dotscope-1.2.1}/AGENT_INSTRUCTIONS.md +0 -0
  229. {dotscope-1.2.0 → dotscope-1.2.1}/LICENSE +0 -0
  230. {dotscope-1.2.0 → dotscope-1.2.1}/docs/architecture.md +0 -0
  231. {dotscope-1.2.0 → dotscope-1.2.1}/docs/cli-reference.md +0 -0
  232. {dotscope-1.2.0 → dotscope-1.2.1}/docs/how-it-works.md +0 -0
  233. {dotscope-1.2.0 → dotscope-1.2.1}/docs/mcp-setup.md +0 -0
  234. {dotscope-1.2.0 → dotscope-1.2.1}/docs/scope-file.md +0 -0
  235. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/.scope +0 -0
  236. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/absorber.py +0 -0
  237. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/assertions.py +0 -0
  238. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/ast_analyzer.py +0 -0
  239. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/backtest.py +0 -0
  240. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/bench.py +0 -0
  241. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/budget.py +0 -0
  242. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/cache.py +0 -0
  243. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/check/__init__.py +0 -0
  244. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/check/acknowledge.py +0 -0
  245. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/check/checker.py +0 -0
  246. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/check/checks/__init__.py +0 -0
  247. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/check/checks/antipattern.py +0 -0
  248. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/check/checks/boundary.py +0 -0
  249. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/check/checks/contracts.py +0 -0
  250. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/check/checks/direction.py +0 -0
  251. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/check/checks/intent.py +0 -0
  252. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/check/checks/stability.py +0 -0
  253. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/check/constraints.py +0 -0
  254. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/check/models.py +0 -0
  255. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/cli.py +0 -0
  256. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/composer.py +0 -0
  257. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/context.py +0 -0
  258. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/counterfactual.py +0 -0
  259. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/debug.py +0 -0
  260. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/discovery.py +0 -0
  261. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/eval/.scope +0 -0
  262. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/eval/__init__.py +0 -0
  263. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/eval/bootstrap.py +0 -0
  264. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/eval/compare.py +0 -0
  265. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/eval/corpus.py +0 -0
  266. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/eval/harness.py +0 -0
  267. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/eval/replay.py +0 -0
  268. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/formatter.py +0 -0
  269. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/generate/.scope +0 -0
  270. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/generate/__init__.py +0 -0
  271. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/generate/atlas.py +0 -0
  272. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/generate/contracts.py +0 -0
  273. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/generate/models.py +0 -0
  274. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/generate/network.py +0 -0
  275. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/graph.py +0 -0
  276. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/health.py +0 -0
  277. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/help.py +0 -0
  278. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/history.py +0 -0
  279. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/hooks.py +0 -0
  280. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/intent.py +0 -0
  281. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/lessons.py +0 -0
  282. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/matcher.py +0 -0
  283. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/mcp_server.py +0 -0
  284. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/merge/.scope +0 -0
  285. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/merge/__init__.py +0 -0
  286. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/merge/classifier.py +0 -0
  287. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/merge/composer.py +0 -0
  288. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/merge/differ.py +0 -0
  289. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/merge/driver.py +0 -0
  290. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/merge/imports.py +0 -0
  291. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/merge/models.py +0 -0
  292. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/merge/swarm.py +0 -0
  293. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/models/.scope +0 -0
  294. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/models/__init__.py +0 -0
  295. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/models/core.py +0 -0
  296. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/models/eval.py +0 -0
  297. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/models/history.py +0 -0
  298. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/models/intent.py +0 -0
  299. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/models/passes.py +0 -0
  300. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/models/state.py +0 -0
  301. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/models.py +0 -0
  302. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/near_miss.py +0 -0
  303. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/onboarding.py +0 -0
  304. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/parser.py +0 -0
  305. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/.scope +0 -0
  306. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/__init__.py +0 -0
  307. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/ast_analyzer.py +0 -0
  308. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/backtest.py +0 -0
  309. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/budget_allocator.py +0 -0
  310. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/convention_compliance.py +0 -0
  311. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/convention_discovery.py +0 -0
  312. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/convention_parser.py +0 -0
  313. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/hint_generator.py +0 -0
  314. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/history_miner.py +0 -0
  315. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/incremental.py +0 -0
  316. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/lang/__init__.py +0 -0
  317. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/lang/_base.py +0 -0
  318. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/lang/_treesitter.py +0 -0
  319. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/lang/go.py +0 -0
  320. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/lang/javascript.py +0 -0
  321. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/lazy.py +0 -0
  322. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/preflight.py +0 -0
  323. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/semantic_diff.py +0 -0
  324. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/sentinel/__init__.py +0 -0
  325. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/sentinel/acknowledge.py +0 -0
  326. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/sentinel/checker.py +0 -0
  327. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/sentinel/checks/__init__.py +0 -0
  328. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/sentinel/checks/antipattern.py +0 -0
  329. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/sentinel/checks/boundary.py +0 -0
  330. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/sentinel/checks/contracts.py +0 -0
  331. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/sentinel/checks/convention.py +0 -0
  332. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/sentinel/checks/direction.py +0 -0
  333. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/sentinel/checks/intent.py +0 -0
  334. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/sentinel/checks/network.py +0 -0
  335. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/sentinel/checks/spatial.py +0 -0
  336. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/sentinel/checks/stability.py +0 -0
  337. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/sentinel/checks/voice.py +0 -0
  338. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/sentinel/constraints.py +0 -0
  339. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/sentinel/line_filter.py +0 -0
  340. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/sentinel/models.py +0 -0
  341. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/spatial_autofix.py +0 -0
  342. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/virtual.py +0 -0
  343. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/voice.py +0 -0
  344. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/voice_defaults.py +0 -0
  345. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/passes/voice_discovery.py +0 -0
  346. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/paths.py +0 -0
  347. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/progress.py +0 -0
  348. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/refresh.py +0 -0
  349. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/regression.py +0 -0
  350. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/resolver.py +0 -0
  351. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/runtime_overlay.py +0 -0
  352. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/search/.scope +0 -0
  353. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/search/__init__.py +0 -0
  354. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/search/chunker.py +0 -0
  355. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/search/expander.py +0 -0
  356. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/search/flattener.py +0 -0
  357. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/search/models.py +0 -0
  358. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/search/observation.py +0 -0
  359. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/search/reranker.py +0 -0
  360. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/search/synthesizer.py +0 -0
  361. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/sessions.py +0 -0
  362. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/storage/.scope +0 -0
  363. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/storage/__init__.py +0 -0
  364. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/storage/cache.py +0 -0
  365. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/storage/claude_hooks.py +0 -0
  366. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/storage/git_hooks.py +0 -0
  367. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/storage/incremental_state.py +0 -0
  368. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/storage/mcp_config.py +0 -0
  369. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/storage/near_miss.py +0 -0
  370. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/storage/onboarding.py +0 -0
  371. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/storage/session_manager.py +0 -0
  372. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/storage/swarm_state.py +0 -0
  373. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/storage/timing.py +0 -0
  374. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/textio.py +0 -0
  375. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/timing.py +0 -0
  376. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/tokens.py +0 -0
  377. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/utility.py +0 -0
  378. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/virtual.py +0 -0
  379. {dotscope-1.2.0 → dotscope-1.2.1}/dotscope/visibility.py +0 -0
  380. {dotscope-1.2.0 → dotscope-1.2.1}/logo.png +0 -0
  381. {dotscope-1.2.0 → dotscope-1.2.1}/tests/.scope +0 -0
  382. {dotscope-1.2.0 → dotscope-1.2.1}/tests/__init__.py +0 -0
  383. {dotscope-1.2.0 → dotscope-1.2.1}/tests/conftest.py +0 -0
  384. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_absorber.py +0 -0
  385. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_ast_analyzer.py +0 -0
  386. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_backtest.py +0 -0
  387. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_budget.py +0 -0
  388. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_canonical_snippet.py +0 -0
  389. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_cli.py +0 -0
  390. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_composer.py +0 -0
  391. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_context.py +0 -0
  392. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_enforcement.py +0 -0
  393. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_eval_harness.py +0 -0
  394. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_experience.py +0 -0
  395. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_graph.py +0 -0
  396. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_health.py +0 -0
  397. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_history.py +0 -0
  398. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_ingest.py +0 -0
  399. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_lessons.py +0 -0
  400. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_line_filter.py +0 -0
  401. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_loop.py +0 -0
  402. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_matcher.py +0 -0
  403. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_near_miss.py +0 -0
  404. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_parser.py +0 -0
  405. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_refresh.py +0 -0
  406. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_resolver.py +0 -0
  407. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_rigor.py +0 -0
  408. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_routing.py +0 -0
  409. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_scanner.py +0 -0
  410. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_sessions.py +0 -0
  411. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_textio.py +0 -0
  412. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_treesitter.py +0 -0
  413. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_utility.py +0 -0
  414. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_virtual.py +0 -0
  415. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_visibility.py +0 -0
  416. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_voice_check.py +0 -0
  417. {dotscope-1.2.0 → dotscope-1.2.1}/tests/test_voice_discovery.py +0 -0
  418. {dotscope-1.2.0 → dotscope-1.2.1}/uv.lock +0 -0
@@ -0,0 +1,83 @@
1
+ Metadata-Version: 2.4
2
+ Name: dotscope
3
+ Version: 1.2.1
4
+ Summary: Agents see files. You see architecture. dotscope gives agents the architecture.
5
+ Author: Supremum
6
+ License-Expression: MIT
7
+ License-File: LICENSE
8
+ Keywords: agents,ai,coding,context,mcp,scope
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Topic :: Software Development :: Libraries
14
+ Requires-Python: >=3.10
15
+ Requires-Dist: tree-sitter-go>=0.23.0
16
+ Requires-Dist: tree-sitter-javascript>=0.23.0
17
+ Requires-Dist: tree-sitter-typescript>=0.23.0
18
+ Requires-Dist: tree-sitter>=0.23.0
19
+ Provides-Extra: all
20
+ Requires-Dist: mcp>=1.2.0; extra == 'all'
21
+ Requires-Dist: numpy; extra == 'all'
22
+ Requires-Dist: sentence-transformers; extra == 'all'
23
+ Requires-Dist: tiktoken; extra == 'all'
24
+ Provides-Extra: dev
25
+ Requires-Dist: pytest; extra == 'dev'
26
+ Requires-Dist: ruff; extra == 'dev'
27
+ Provides-Extra: embeddings
28
+ Requires-Dist: sentence-transformers; extra == 'embeddings'
29
+ Provides-Extra: mcp
30
+ Requires-Dist: mcp>=1.2.0; extra == 'mcp'
31
+ Provides-Extra: search
32
+ Requires-Dist: numpy; extra == 'search'
33
+ Requires-Dist: sentence-transformers; extra == 'search'
34
+ Provides-Extra: tokens
35
+ Requires-Dist: tiktoken; extra == 'tokens'
36
+ Description-Content-Type: text/markdown
37
+
38
+ <p align="center">
39
+ <img src="logo.png" alt="dotscope" width="400">
40
+ </p>
41
+
42
+ Your agent writes code that compiles, passes tests, and breaks production.
43
+
44
+ It changed a backend endpoint without touching the frontend that calls it.
45
+ It put a file in `src/helpers/` instead of next to the module that uses it.
46
+ It ignored the convention every other file follows. Two agents working at
47
+ the same time silently overwrote each other.
48
+
49
+ The agent sees files. You see architecture. dotscope closes that gap.
50
+
51
+ ```
52
+ $ dotscope ingest
53
+
54
+ Analyzing dependency graph...
55
+ Mining git history...
56
+ Discovering conventions...
57
+
58
+ Discoveries:
59
+ - version.py and environment.prod.ts always change together
60
+ - workflow-edit-dialog.component.ts and models.py are tightly coupled
61
+
62
+ Validation (49 commits backtested):
63
+ - Overall recall: 78%
64
+ - Token reduction: 67% (1.3M → 437K avg)
65
+
66
+ Output: 3 .scope files written.
67
+ ```
68
+
69
+ One MCP tool call. The agent gets the relevant code, its dependency
70
+ neighborhood, implicit contracts from git history, convention rules,
71
+ swarm lock status, and action hints. One call, not five.
72
+
73
+ dotscope learns from every commit. Files agents consistently need get
74
+ ranked higher. Conventions that hold get enforced harder. Rules that
75
+ get overridden get quieter. Recall starts at 78% and climbs past 91%.
76
+
77
+ ```
78
+ pip install dotscope && dotscope init
79
+ ```
80
+
81
+ Zero dependencies. Python 3.9+ stdlib only. MIT.
82
+
83
+ [How It Works](docs/how-it-works.md) · [Scope Files](docs/scope-file.md) · [Agent Instructions](AGENT_INSTRUCTIONS.md) · [MIT](LICENSE)
@@ -0,0 +1,46 @@
1
+ <p align="center">
2
+ <img src="logo.png" alt="dotscope" width="400">
3
+ </p>
4
+
5
+ Your agent writes code that compiles, passes tests, and breaks production.
6
+
7
+ It changed a backend endpoint without touching the frontend that calls it.
8
+ It put a file in `src/helpers/` instead of next to the module that uses it.
9
+ It ignored the convention every other file follows. Two agents working at
10
+ the same time silently overwrote each other.
11
+
12
+ The agent sees files. You see architecture. dotscope closes that gap.
13
+
14
+ ```
15
+ $ dotscope ingest
16
+
17
+ Analyzing dependency graph...
18
+ Mining git history...
19
+ Discovering conventions...
20
+
21
+ Discoveries:
22
+ - version.py and environment.prod.ts always change together
23
+ - workflow-edit-dialog.component.ts and models.py are tightly coupled
24
+
25
+ Validation (49 commits backtested):
26
+ - Overall recall: 78%
27
+ - Token reduction: 67% (1.3M → 437K avg)
28
+
29
+ Output: 3 .scope files written.
30
+ ```
31
+
32
+ One MCP tool call. The agent gets the relevant code, its dependency
33
+ neighborhood, implicit contracts from git history, convention rules,
34
+ swarm lock status, and action hints. One call, not five.
35
+
36
+ dotscope learns from every commit. Files agents consistently need get
37
+ ranked higher. Conventions that hold get enforced harder. Rules that
38
+ get overridden get quieter. Recall starts at 78% and climbs past 91%.
39
+
40
+ ```
41
+ pip install dotscope && dotscope init
42
+ ```
43
+
44
+ Zero dependencies. Python 3.9+ stdlib only. MIT.
45
+
46
+ [How It Works](docs/how-it-works.md) · [Scope Files](docs/scope-file.md) · [Agent Instructions](AGENT_INSTRUCTIONS.md) · [MIT](LICENSE)
@@ -1,3 +1,3 @@
1
1
  """dotscope — Directory-scoped context boundaries for AI coding agents."""
2
2
 
3
- __version__ = "1.2.0"
3
+ __version__ = "1.2.1"
@@ -2,20 +2,44 @@
2
2
 
3
3
  # Directories to always skip when walking a codebase
4
4
  SKIP_DIRS = frozenset({
5
+ # Version control
5
6
  ".git",
7
+ # Package managers
6
8
  "node_modules",
9
+ "vendor",
10
+ # Python
7
11
  "__pycache__",
8
12
  "venv",
9
13
  ".venv",
10
14
  "env",
11
15
  ".env",
12
- "dist",
13
- "build",
14
16
  ".tox",
15
17
  ".mypy_cache",
16
18
  ".ruff_cache",
17
19
  ".eggs",
18
20
  ".pytest_cache",
21
+ # Build output
22
+ "dist",
23
+ "build",
24
+ "out",
25
+ "target",
26
+ "bin",
27
+ "obj",
28
+ # JS/TS frameworks
29
+ ".next",
30
+ ".nuxt",
31
+ ".output",
32
+ ".parcel-cache",
33
+ # Caches
34
+ ".cache",
35
+ ".gradle",
36
+ ".terraform",
37
+ # Test/coverage output
38
+ "coverage",
39
+ "test-results",
40
+ # dotscope / Claude
41
+ ".dotscope",
42
+ ".claude",
19
43
  })
20
44
 
21
45
  # Source file extensions
@@ -118,8 +118,8 @@ def _load_config(root: str) -> GenerateConfig:
118
118
  return GenerateConfig()
119
119
 
120
120
  try:
121
- from ..parser import _parse_yaml_simple
122
- data = _parse_yaml_simple(config_path.read_text(encoding="utf-8"))
121
+ from ..parser import _parse_yaml
122
+ data = _parse_yaml(config_path.read_text(encoding="utf-8"))
123
123
  gen = data.get("generate", {})
124
124
  return GenerateConfig(
125
125
  output_dir=gen.get("output_dir", "docs/dotscope"),
@@ -0,0 +1,59 @@
1
+ """.dotscopeignore support — gitignore-style exclusion patterns.
2
+
3
+ Loaded once at scan start, passed through the pipeline. No per-file IO.
4
+ """
5
+
6
+ import fnmatch
7
+ import os
8
+ from pathlib import Path
9
+ from typing import List
10
+
11
+
12
+ def load_ignore_patterns(repo_root: str) -> List[str]:
13
+ """Load .dotscopeignore patterns. Returns empty list if no file."""
14
+ ignore_path = os.path.join(repo_root, ".dotscopeignore")
15
+ if not os.path.exists(ignore_path):
16
+ return []
17
+
18
+ patterns = []
19
+ try:
20
+ with open(ignore_path, "r", encoding="utf-8") as f:
21
+ for line in f:
22
+ line = line.strip()
23
+ if not line or line.startswith("#"):
24
+ continue
25
+ patterns.append(line)
26
+ except (IOError, OSError):
27
+ return []
28
+ return patterns
29
+
30
+
31
+ def should_skip(
32
+ path: str,
33
+ skip_dirs: frozenset,
34
+ ignore_patterns: List[str],
35
+ ) -> bool:
36
+ """Check if a path should be skipped.
37
+
38
+ Order: hardcoded skip_dirs first (O(1) lookup),
39
+ then .dotscopeignore patterns (glob matching).
40
+ """
41
+ parts = Path(path).parts
42
+ for part in parts:
43
+ if part in skip_dirs:
44
+ return True
45
+
46
+ for pattern in ignore_patterns:
47
+ if fnmatch.fnmatch(path, pattern):
48
+ return True
49
+ # Directory patterns: "renderer/target/" matches any file under it
50
+ if pattern.endswith("/"):
51
+ dir_prefix = pattern.rstrip("/")
52
+ if path.startswith(dir_prefix + "/") or path.startswith(dir_prefix + os.sep):
53
+ return True
54
+ # Also match against any path component
55
+ for part in parts:
56
+ if fnmatch.fnmatch(part, dir_prefix):
57
+ return True
58
+
59
+ return False
@@ -29,6 +29,26 @@ from .paths import (
29
29
  from .tokens import estimate_scope_tokens
30
30
 
31
31
 
32
+ def _safe_print(text, **kwargs):
33
+ """Print with ASCII fallback for Windows cp1252 terminals."""
34
+ try:
35
+ print(text, **kwargs)
36
+ except UnicodeEncodeError:
37
+ print(text.encode("ascii", errors="replace").decode("ascii"), **kwargs)
38
+
39
+
40
+ def _log_ingest_error(root: str, message: str) -> None:
41
+ """Append error to .dotscope/error.log for debugging."""
42
+ try:
43
+ log_dir = os.path.join(root, ".dotscope")
44
+ os.makedirs(log_dir, exist_ok=True)
45
+ import time
46
+ with open(os.path.join(log_dir, "error.log"), "a", encoding="utf-8") as f:
47
+ f.write(f"[{time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime())}] {message}\n")
48
+ except Exception:
49
+ pass # Logging failure should never block ingest
50
+
51
+
32
52
  def ingest(
33
53
  root: str,
34
54
  mine_history: bool = True,
@@ -168,8 +188,8 @@ def ingest(
168
188
  artifacts_path = os.path.join(root, ".dotscope_artifacts.yaml")
169
189
  if os.path.isfile(artifacts_path):
170
190
  try:
171
- from .parser import _parse_yaml_simple
172
- artifacts_data = _parse_yaml_simple(
191
+ from .parser import _parse_yaml
192
+ artifacts_data = _parse_yaml(
173
193
  open(artifacts_path, "r", encoding="utf-8").read()
174
194
  )
175
195
  for artifact in artifacts_data.get("artifacts", []):
@@ -191,13 +211,41 @@ def ingest(
191
211
  except Exception:
192
212
  pass
193
213
 
214
+ # Cap chunk count to prevent OOM on large repos
215
+ max_chunks = getattr(args, "max_chunks", 50_000) if args else 50_000
216
+ if len(all_chunks) > max_chunks:
217
+ # Prefer source files over tests/configs
218
+ def _chunk_priority(c):
219
+ p = c.file_path.lower()
220
+ if "/test" in p or p.startswith("test"):
221
+ return 2
222
+ if any(p.endswith(e) for e in (".json", ".yaml", ".yml", ".toml")):
223
+ return 1
224
+ return 0
225
+ all_chunks.sort(key=lambda c: (_chunk_priority(c), c.file_path))
226
+ _safe_print(
227
+ f"dotscope: {len(all_chunks)} chunks exceeds limit,"
228
+ f" keeping top {max_chunks}",
229
+ file=sys.stderr,
230
+ )
231
+ all_chunks = all_chunks[:max_chunks]
232
+
194
233
  if all_chunks:
195
234
  index = build_vector_index(root, all_chunks)
196
235
  progress.finish(f"{index.chunk_count} chunks, {index.model_name}")
197
236
  else:
198
237
  progress.finish("0 chunks")
199
238
  except Exception as e:
200
- progress.finish(f"skipped ({e})")
239
+ import traceback
240
+ _safe_print(
241
+ f"dotscope: search index failed: {e}\n"
242
+ f" Scopes still work. Search will be unavailable.\n"
243
+ f" Try: dotscope ingest . --max-chunks 25000",
244
+ file=sys.stderr,
245
+ )
246
+ # Log full traceback for debugging
247
+ _log_ingest_error(root, traceback.format_exc())
248
+ progress.finish("failed")
201
249
 
202
250
  # Step 4: Synthesize scope files
203
251
  progress.start("generating scopes")
@@ -14,6 +14,7 @@ from ..ast_analyzer import (
14
14
  resolve_python_import,
15
15
  )
16
16
  from ..constants import LANG_MAP, SKIP_DIRS
17
+ from ..ignore import load_ignore_patterns, should_skip
17
18
  from ..models.core import (
18
19
  DependencyGraph,
19
20
  FileNode,
@@ -201,15 +202,25 @@ def transitive_dependents(graph: DependencyGraph, file: str) -> Set[str]:
201
202
  def _collect_source_files(root: str) -> List[Tuple[str, str]]:
202
203
  """Walk the tree and collect (relative_path, language)."""
203
204
  lang_map = {k: v.lower() for k, v in LANG_MAP.items()}
205
+ ignore_patterns = load_ignore_patterns(root)
204
206
  results = []
205
207
 
206
208
  for dirpath, dirnames, filenames in os.walk(root):
207
- dirnames[:] = [d for d in dirnames if d not in SKIP_DIRS]
209
+ dirnames[:] = [
210
+ d for d in dirnames
211
+ if d not in SKIP_DIRS
212
+ and not should_skip(
213
+ os.path.relpath(os.path.join(dirpath, d), root),
214
+ SKIP_DIRS,
215
+ ignore_patterns,
216
+ )
217
+ ]
208
218
  for fn in filenames:
209
219
  ext = os.path.splitext(fn)[1].lower()
210
220
  if ext in lang_map:
211
221
  rel = normalize_relative_path(os.path.relpath(os.path.join(dirpath, fn), root))
212
- results.append((rel, lang_map[ext]))
222
+ if not should_skip(rel, frozenset(), ignore_patterns):
223
+ results.append((rel, lang_map[ext]))
213
224
 
214
225
  return sorted(results)
215
226
 
@@ -12,6 +12,7 @@ from typing import List, Optional, Set, Tuple
12
12
 
13
13
  from .constants import LANG_MAP, SKIP_DIRS
14
14
  from .context import parse_context
15
+ from .ignore import load_ignore_patterns, should_skip
15
16
  from .models import ScopeConfig
16
17
  from .tokens import estimate_file_tokens
17
18
 
@@ -100,11 +101,27 @@ def _scan_files(path: str) -> Tuple[List[str], Counter, int]:
100
101
  lang_counts: Counter = Counter()
101
102
  total_tokens = 0
102
103
 
104
+ # Load .dotscopeignore patterns from the repo root (or nearest parent)
105
+ ignore_patterns = load_ignore_patterns(path)
106
+
103
107
  for dirpath, dirnames, filenames in os.walk(path):
104
- dirnames[:] = [d for d in dirnames if d not in SKIP_DIRS]
108
+ dirnames[:] = [
109
+ d for d in dirnames
110
+ if d not in SKIP_DIRS
111
+ and not should_skip(
112
+ os.path.relpath(os.path.join(dirpath, d), path),
113
+ SKIP_DIRS,
114
+ ignore_patterns,
115
+ )
116
+ ]
105
117
 
106
118
  for filename in filenames:
107
119
  full = os.path.join(dirpath, filename)
120
+ rel = os.path.relpath(full, path)
121
+
122
+ if should_skip(rel, frozenset(), ignore_patterns):
123
+ continue
124
+
108
125
  files.append(full)
109
126
 
110
127
  ext = os.path.splitext(filename)[1].lower()
@@ -283,12 +283,30 @@ def _dense_search(query: str, embeddings, limit: int = 50) -> List[Tuple[int, fl
283
283
  return []
284
284
 
285
285
 
286
- def _embed_texts(texts: List[str]):
287
- """Embed texts using sentence-transformers. Returns numpy array or None."""
286
+ def _embed_texts(texts: List[str], batch_size: int = 512):
287
+ """Embed texts in batches using sentence-transformers. Returns numpy array or None."""
288
288
  try:
289
289
  from sentence_transformers import SentenceTransformer
290
+ import numpy as np
291
+
290
292
  model = SentenceTransformer("all-MiniLM-L6-v2")
291
- return model.encode(texts, show_progress_bar=False, convert_to_numpy=True)
293
+
294
+ if len(texts) <= batch_size:
295
+ return model.encode(texts, show_progress_bar=False, convert_to_numpy=True)
296
+
297
+ # Batch to avoid OOM on large repos
298
+ all_embeddings = []
299
+ for i in range(0, len(texts), batch_size):
300
+ batch = texts[i:i + batch_size]
301
+ try:
302
+ embeddings = model.encode(batch, show_progress_bar=False, convert_to_numpy=True)
303
+ all_embeddings.append(embeddings)
304
+ except Exception:
305
+ continue # Skip failed batch, keep going
306
+
307
+ if not all_embeddings:
308
+ return None
309
+ return np.vstack(all_embeddings)
292
310
  except ImportError:
293
311
  return None
294
312
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "dotscope"
3
- version = "1.2.0"
3
+ version = "1.2.1"
4
4
  description = "Agents see files. You see architecture. dotscope gives agents the architecture."
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -0,0 +1,64 @@
1
+ """Tests for .dotscopeignore pattern matching."""
2
+
3
+ import os
4
+ import tempfile
5
+
6
+ from dotscope.ignore import load_ignore_patterns, should_skip
7
+ from dotscope.constants import SKIP_DIRS
8
+
9
+
10
+ class TestLoadIgnorePatterns:
11
+ def test_no_file(self, tmp_path):
12
+ assert load_ignore_patterns(str(tmp_path)) == []
13
+
14
+ def test_empty_file(self, tmp_path):
15
+ (tmp_path / ".dotscopeignore").write_text("")
16
+ assert load_ignore_patterns(str(tmp_path)) == []
17
+
18
+ def test_comments_skipped(self, tmp_path):
19
+ (tmp_path / ".dotscopeignore").write_text("# comment\n\n# another\n")
20
+ assert load_ignore_patterns(str(tmp_path)) == []
21
+
22
+ def test_patterns_loaded(self, tmp_path):
23
+ (tmp_path / ".dotscopeignore").write_text(
24
+ "renderer/target/\n*.fbx\n# comment\nassets/raw/\n"
25
+ )
26
+ patterns = load_ignore_patterns(str(tmp_path))
27
+ assert patterns == ["renderer/target/", "*.fbx", "assets/raw/"]
28
+
29
+
30
+ class TestShouldSkip:
31
+ def test_skip_dirs_match(self):
32
+ assert should_skip("node_modules/foo.js", SKIP_DIRS, [])
33
+ assert should_skip("src/node_modules/bar.js", SKIP_DIRS, [])
34
+
35
+ def test_skip_dirs_no_match(self):
36
+ assert not should_skip("src/handler.py", SKIP_DIRS, [])
37
+
38
+ def test_glob_pattern(self):
39
+ assert should_skip("model.fbx", frozenset(), ["*.fbx"])
40
+ assert should_skip("assets/scene.fbx", frozenset(), ["*.fbx"])
41
+ assert not should_skip("handler.py", frozenset(), ["*.fbx"])
42
+
43
+ def test_directory_pattern(self):
44
+ patterns = ["renderer/target/"]
45
+ assert should_skip("renderer/target/debug/main.rs", frozenset(), patterns)
46
+ assert not should_skip("renderer/src/main.rs", frozenset(), patterns)
47
+
48
+ def test_combined(self):
49
+ patterns = ["*.wav", "build_output/"]
50
+ assert should_skip("node_modules/pkg.js", SKIP_DIRS, patterns)
51
+ assert should_skip("audio/effect.wav", SKIP_DIRS, patterns)
52
+ assert should_skip("build_output/release/app", SKIP_DIRS, patterns)
53
+ assert not should_skip("src/main.py", SKIP_DIRS, patterns)
54
+
55
+ def test_new_skip_dirs(self):
56
+ """Verify the expanded SKIP_DIRS covers common build dirs."""
57
+ assert should_skip("target/debug/main", SKIP_DIRS, [])
58
+ assert should_skip("src/target/release/bin", SKIP_DIRS, [])
59
+ assert should_skip(".next/cache/foo", SKIP_DIRS, [])
60
+ assert should_skip(".dotscope/sessions/abc.json", SKIP_DIRS, [])
61
+ assert should_skip(".claude/settings.json", SKIP_DIRS, [])
62
+ assert should_skip("out/compiled.js", SKIP_DIRS, [])
63
+ assert should_skip("obj/Debug/net6.0/app.dll", SKIP_DIRS, [])
64
+ assert should_skip("coverage/lcov.info", SKIP_DIRS, [])
dotscope-1.2.0/PKG-INFO DELETED
@@ -1,127 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: dotscope
3
- Version: 1.2.0
4
- Summary: Agents see files. You see architecture. dotscope gives agents the architecture.
5
- Author: Supremum
6
- License-Expression: MIT
7
- License-File: LICENSE
8
- Keywords: agents,ai,coding,context,mcp,scope
9
- Classifier: Development Status :: 3 - Alpha
10
- Classifier: Intended Audience :: Developers
11
- Classifier: License :: OSI Approved :: MIT License
12
- Classifier: Programming Language :: Python :: 3
13
- Classifier: Topic :: Software Development :: Libraries
14
- Requires-Python: >=3.10
15
- Requires-Dist: tree-sitter-go>=0.23.0
16
- Requires-Dist: tree-sitter-javascript>=0.23.0
17
- Requires-Dist: tree-sitter-typescript>=0.23.0
18
- Requires-Dist: tree-sitter>=0.23.0
19
- Provides-Extra: all
20
- Requires-Dist: mcp>=1.2.0; extra == 'all'
21
- Requires-Dist: numpy; extra == 'all'
22
- Requires-Dist: sentence-transformers; extra == 'all'
23
- Requires-Dist: tiktoken; extra == 'all'
24
- Provides-Extra: dev
25
- Requires-Dist: pytest; extra == 'dev'
26
- Requires-Dist: ruff; extra == 'dev'
27
- Provides-Extra: embeddings
28
- Requires-Dist: sentence-transformers; extra == 'embeddings'
29
- Provides-Extra: mcp
30
- Requires-Dist: mcp>=1.2.0; extra == 'mcp'
31
- Provides-Extra: search
32
- Requires-Dist: numpy; extra == 'search'
33
- Requires-Dist: sentence-transformers; extra == 'search'
34
- Provides-Extra: tokens
35
- Requires-Dist: tiktoken; extra == 'tokens'
36
- Description-Content-Type: text/markdown
37
-
38
- <p align="center">
39
- <img src="logo.png" alt="dotscope" width="400">
40
- </p>
41
-
42
- You give an agent a task. It searches your codebase, finds the files,
43
- writes the code, runs the tests, and ships. Sounds fine until you
44
- realize it changed a backend endpoint without touching the frontend
45
- that calls it. It put a utility function in `src/helpers/` instead of
46
- next to the module that uses it. It ignored the naming convention every
47
- other file follows. And when two agents worked at the same time, they
48
- silently overwrote each other's changes.
49
-
50
- The code compiled. The tests passed. Production broke.
51
-
52
- This happens because agents don't have what you have — the full
53
- picture. They see files. You see architecture.
54
-
55
- **dotscope is the operating system for agent-driven codebases.**
56
-
57
- One command scans your project and learns the architecture: which files
58
- depend on which, what patterns your code follows, how your backend
59
- talks to your frontend, and what breaks when something changes. From
60
- that point on, every agent gets the full picture before it writes a
61
- line.
62
-
63
- It does five things:
64
-
65
- 1. **One search, everything you need.** An agent describes what it
66
- wants to do. dotscope returns the relevant files, the functions
67
- they call, the contracts they must honor, the conventions they must
68
- follow, and which files are locked by other agents. One call. Not
69
- five.
70
-
71
- 2. **Enforces contracts across languages.** Your Python backend and
72
- TypeScript frontend share an invisible API contract. dotscope
73
- extracts routes from FastAPI, Flask, and DRF. It extracts fetch
74
- calls from React and Angular. It links them automatically. Change
75
- a Django ViewSet without updating the Angular component? Blocked.
76
-
77
- 3. **Routes files to the right place.** Before an agent creates a
78
- file, it asks dotscope where it should go. dotscope reads the
79
- dependency graph and routes the file there. No more `src/utils/`
80
- graveyards.
81
-
82
- 4. **Coordinates multiple agents.** When Agent A starts working on
83
- billing, dotscope locks the blast radius. Agent B works on auth
84
- without collision. If they touch the same function, the AST merge
85
- driver resolves it semantically — not with conflict markers.
86
-
87
- 5. **Gets smarter with every commit.** Which search results did agents
88
- actually use? Which did they ignore? dotscope tracks this and
89
- adjusts. Conventions that hold up get enforced harder. Rules that
90
- get overridden get quieter.
91
-
92
- Here's what it looks like on a real codebase:
93
-
94
- ```
95
- $ dotscope ingest
96
-
97
- Analyzing dependency graph...
98
- Mining git history...
99
- Discovering conventions...
100
-
101
- Discoveries:
102
- - version.py and environment.prod.ts always change together
103
- - workflow-edit-dialog.component.ts and models.py are tightly coupled
104
-
105
- Validation (49 commits backtested):
106
- - Overall recall: 78%
107
- - Token reduction: 67% (1.3M → 437K avg)
108
-
109
- Output: 3 .scope files written.
110
-
111
- $ dotscope check --backtest
112
-
113
- 13 issues flagged across 7 commits:
114
- - models.py changes need the Angular component updated
115
- - consumer.py changes need matching parser test updates
116
- - views.py changes typically need test_api_search.py updated
117
-
118
- 3 commits were clean.
119
- ```
120
-
121
- One command. Point it at anything.
122
-
123
- ```
124
- pip install dotscope && dotscope init
125
- ```
126
-
127
- [How It Works](docs/how-it-works.md) · [Scope Files](docs/scope-file.md) · [Agent Instructions](AGENT_INSTRUCTIONS.md) · [MIT](LICENSE)