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.
- dotscope-1.3.0/.claude/settings.local.json +7 -0
- {dotscope-1.2.1 → dotscope-1.3.0}/.github/workflows/python-publish.yml +1 -1
- dotscope-1.3.0/.mcp.json +8 -0
- dotscope-1.3.0/.virtual/isolated-hubs.scope +14 -0
- dotscope-1.3.0/CLAUDE.md +10 -0
- {dotscope-1.2.1 → dotscope-1.3.0}/PKG-INFO +3 -3
- {dotscope-1.2.1 → dotscope-1.3.0}/docs/mcp-setup.md +80 -2
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/__init__.py +1 -1
- dotscope-1.3.0/dotscope/cli/__init__.py +320 -0
- dotscope-1.3.0/dotscope/cli/core.py +214 -0
- dotscope-1.3.0/dotscope/cli/hooks.py +491 -0
- dotscope-1.3.0/dotscope/cli/ingest.py +243 -0
- dotscope-1.3.0/dotscope/cli/observability.py +342 -0
- {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/composer.py +3 -1
- {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/discovery.py +0 -21
- dotscope-1.3.0/dotscope/explain.py +189 -0
- {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/formatter.py +13 -1
- {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/health.py +76 -12
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/help.py +2 -0
- {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/ingest.py +3 -1
- dotscope-1.3.0/dotscope/mcp/__init__.py +139 -0
- dotscope-1.3.0/dotscope/mcp/core.py +459 -0
- dotscope-1.3.0/dotscope/mcp/hooks.py +8 -0
- dotscope-1.3.0/dotscope/mcp/ingest.py +99 -0
- dotscope-1.3.0/dotscope/mcp/observability.py +188 -0
- {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/models/core.py +4 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/models/intent.py +2 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/models/state.py +1 -0
- {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/passes/convention_discovery.py +40 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/sentinel/checks/antipattern.py +2 -0
- {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/passes/sentinel/checks/boundary.py +2 -0
- {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/passes/sentinel/checks/contracts.py +4 -0
- {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/passes/sentinel/checks/convention.py +2 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/sentinel/checks/direction.py +2 -0
- {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/passes/sentinel/checks/intent.py +8 -0
- {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/passes/sentinel/checks/network.py +2 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/sentinel/checks/spatial.py +2 -0
- {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/passes/sentinel/checks/stability.py +2 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/sentinel/checks/voice.py +4 -0
- {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/passes/virtual.py +1 -1
- dotscope-1.3.0/dotscope/paths/repo.py +24 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/refresh.py +135 -4
- {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/resolver.py +2 -2
- {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/runtime_overlay.py +1 -1
- {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/search/synthesizer.py +17 -7
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/storage/claude_hooks.py +47 -0
- dotscope-1.3.0/dotscope/storage/mcp_config.py +216 -0
- {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/tokens.py +1 -1
- dotscope-1.3.0/epic.yaml +75 -0
- dotscope-1.3.0/intent.yaml +42 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/pyproject.toml +3 -3
- dotscope-1.3.0/run_epic.py +108 -0
- {dotscope-1.2.1 → dotscope-1.3.0}/tests/test_health.py +1 -1
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_ingest.py +1 -1
- dotscope-1.3.0/tests/test_mcp_config.py +153 -0
- dotscope-1.3.0/tests/test_mcp_server.py +67 -0
- {dotscope-1.2.1 → dotscope-1.3.0}/tests/test_parser.py +1 -1
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_virtual.py +1 -1
- dotscope-1.3.0/virtual/_treesitter_lifecycle/.scope +23 -0
- dotscope-1.3.0/virtual/absorber_lifecycle/.scope +33 -0
- dotscope-1.3.0/virtual/acknowledge_lifecycle/.scope +52 -0
- dotscope-1.3.0/virtual/ast_analyzer_lifecycle/.scope +30 -0
- dotscope-1.3.0/virtual/budget_lifecycle/.scope +25 -0
- dotscope-1.3.0/virtual/constants_lifecycle/.scope +32 -0
- dotscope-1.3.0/virtual/constraints_lifecycle/.scope +64 -0
- dotscope-1.3.0/virtual/context_lifecycle/.scope +79 -0
- dotscope-1.3.0/virtual/core_lifecycle/.scope +55 -0
- dotscope-1.3.0/virtual/counterfactual_lifecycle/.scope +27 -0
- dotscope-1.3.0/virtual/go_lifecycle/.scope +23 -0
- dotscope-1.3.0/virtual/harness_lifecycle/.scope +25 -0
- dotscope-1.3.0/virtual/history_lifecycle/.scope +51 -0
- dotscope-1.3.0/virtual/ignore_lifecycle/.scope +21 -0
- dotscope-1.3.0/virtual/incremental_lifecycle/.scope +43 -0
- dotscope-1.3.0/virtual/incremental_state_lifecycle/.scope +47 -0
- dotscope-1.3.0/virtual/intent_lifecycle/.scope +106 -0
- dotscope-1.3.0/virtual/line_filter_lifecycle/.scope +22 -0
- dotscope-1.3.0/virtual/matcher_lifecycle/.scope +53 -0
- dotscope-1.3.0/virtual/merge_lifecycle/.scope +40 -0
- dotscope-1.3.0/virtual/models_lifecycle/.scope +64 -0
- dotscope-1.3.0/virtual/parser_lifecycle/.scope +103 -0
- dotscope-1.3.0/virtual/refresh_lifecycle/.scope +73 -0
- dotscope-1.3.0/virtual/resolver_lifecycle/.scope +44 -0
- dotscope-1.3.0/virtual/runtime_overlay_lifecycle/.scope +41 -0
- dotscope-1.3.0/virtual/sessions_lifecycle/.scope +30 -0
- dotscope-1.3.0/virtual/state_lifecycle/.scope +50 -0
- dotscope-1.3.0/virtual/textio_lifecycle/.scope +53 -0
- dotscope-1.3.0/virtual/utility_lifecycle/.scope +80 -0
- dotscope-1.2.1/.claude/settings.local.json +0 -35
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/.claude/hooks/pre-commit-check.sh +0 -41
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/.claude/settings.json +0 -15
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/.claude/settings.local.json +0 -52
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/.git +0 -1
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/README.md +0 -90
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/docs/mcp-setup.md +0 -255
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/cli.py +0 -1561
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/composer.py +0 -229
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/constants.py +0 -45
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/discovery.py +0 -138
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/formatter.py +0 -157
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/generate/engine.py +0 -189
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/health.py +0 -272
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/ingest.py +0 -972
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/mcp_server.py +0 -1457
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/models/core.py +0 -328
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/models.py +0 -9
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/passes/convention_discovery.py +0 -345
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/passes/graph_builder.py +0 -437
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/passes/sentinel/checks/boundary.py +0 -46
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/passes/sentinel/checks/contracts.py +0 -148
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/passes/sentinel/checks/convention.py +0 -54
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/passes/sentinel/checks/intent.py +0 -207
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/passes/sentinel/checks/network.py +0 -91
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/passes/sentinel/checks/stability.py +0 -66
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/passes/virtual.py +0 -247
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/resolver.py +0 -198
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/runtime_overlay.py +0 -403
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/scanner.py +0 -246
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/search/retriever.py +0 -368
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/search/synthesizer.py +0 -292
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/storage/mcp_config.py +0 -98
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/tokens.py +0 -53
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/tests/test_health.py +0 -142
- dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/tests/test_parser.py +0 -180
- dotscope-1.2.1/.gitignore +0 -10
- dotscope-1.2.1/.mcp.json +0 -9
- dotscope-1.2.1/.scopes +0 -28
- dotscope-1.2.1/AGENT_INSTRUCTIONS.md +0 -129
- dotscope-1.2.1/LICENSE +0 -21
- dotscope-1.2.1/docs/architecture.md +0 -72
- dotscope-1.2.1/docs/cli-reference.md +0 -67
- dotscope-1.2.1/docs/how-it-works.md +0 -146
- dotscope-1.2.1/docs/scope-file.md +0 -285
- dotscope-1.2.1/dotscope/.scope +0 -82
- dotscope-1.2.1/dotscope/__init__.py +0 -3
- dotscope-1.2.1/dotscope/absorber.py +0 -390
- dotscope-1.2.1/dotscope/assertions.py +0 -127
- dotscope-1.2.1/dotscope/ast_analyzer.py +0 -2
- dotscope-1.2.1/dotscope/backtest.py +0 -2
- dotscope-1.2.1/dotscope/bench.py +0 -141
- dotscope-1.2.1/dotscope/budget.py +0 -3
- dotscope-1.2.1/dotscope/cache.py +0 -2
- dotscope-1.2.1/dotscope/check/__init__.py +0 -1
- dotscope-1.2.1/dotscope/check/acknowledge.py +0 -2
- dotscope-1.2.1/dotscope/check/checker.py +0 -3
- dotscope-1.2.1/dotscope/check/checks/__init__.py +0 -1
- dotscope-1.2.1/dotscope/check/checks/antipattern.py +0 -2
- dotscope-1.2.1/dotscope/check/checks/boundary.py +0 -2
- dotscope-1.2.1/dotscope/check/checks/contracts.py +0 -3
- dotscope-1.2.1/dotscope/check/checks/direction.py +0 -2
- dotscope-1.2.1/dotscope/check/checks/intent.py +0 -2
- dotscope-1.2.1/dotscope/check/checks/stability.py +0 -2
- dotscope-1.2.1/dotscope/check/constraints.py +0 -2
- dotscope-1.2.1/dotscope/check/models.py +0 -15
- dotscope-1.2.1/dotscope/cli.py +0 -1561
- dotscope-1.2.1/dotscope/context.py +0 -60
- dotscope-1.2.1/dotscope/counterfactual.py +0 -180
- dotscope-1.2.1/dotscope/debug.py +0 -220
- dotscope-1.2.1/dotscope/eval/.scope +0 -27
- dotscope-1.2.1/dotscope/eval/__init__.py +0 -18
- dotscope-1.2.1/dotscope/eval/bootstrap.py +0 -231
- dotscope-1.2.1/dotscope/eval/compare.py +0 -147
- dotscope-1.2.1/dotscope/eval/corpus.py +0 -214
- dotscope-1.2.1/dotscope/eval/harness.py +0 -310
- dotscope-1.2.1/dotscope/eval/replay.py +0 -356
- dotscope-1.2.1/dotscope/generate/.scope +0 -24
- dotscope-1.2.1/dotscope/generate/__init__.py +0 -1
- dotscope-1.2.1/dotscope/generate/atlas.py +0 -341
- dotscope-1.2.1/dotscope/generate/contracts.py +0 -296
- dotscope-1.2.1/dotscope/generate/models.py +0 -27
- dotscope-1.2.1/dotscope/generate/network.py +0 -284
- dotscope-1.2.1/dotscope/graph.py +0 -3
- dotscope-1.2.1/dotscope/help.py +0 -218
- dotscope-1.2.1/dotscope/history.py +0 -6
- dotscope-1.2.1/dotscope/hooks.py +0 -2
- dotscope-1.2.1/dotscope/intent.py +0 -614
- dotscope-1.2.1/dotscope/lessons.py +0 -223
- dotscope-1.2.1/dotscope/matcher.py +0 -104
- dotscope-1.2.1/dotscope/mcp_server.py +0 -1457
- dotscope-1.2.1/dotscope/merge/.scope +0 -34
- dotscope-1.2.1/dotscope/merge/__init__.py +0 -1
- dotscope-1.2.1/dotscope/merge/classifier.py +0 -83
- dotscope-1.2.1/dotscope/merge/composer.py +0 -210
- dotscope-1.2.1/dotscope/merge/differ.py +0 -178
- dotscope-1.2.1/dotscope/merge/driver.py +0 -147
- dotscope-1.2.1/dotscope/merge/imports.py +0 -114
- dotscope-1.2.1/dotscope/merge/models.py +0 -62
- dotscope-1.2.1/dotscope/merge/swarm.py +0 -336
- dotscope-1.2.1/dotscope/models/.scope +0 -45
- dotscope-1.2.1/dotscope/models/__init__.py +0 -8
- dotscope-1.2.1/dotscope/models/eval.py +0 -96
- dotscope-1.2.1/dotscope/models/history.py +0 -73
- dotscope-1.2.1/dotscope/models/intent.py +0 -214
- dotscope-1.2.1/dotscope/models/passes.py +0 -58
- dotscope-1.2.1/dotscope/models/state.py +0 -251
- dotscope-1.2.1/dotscope/models.py +0 -9
- dotscope-1.2.1/dotscope/near_miss.py +0 -3
- dotscope-1.2.1/dotscope/onboarding.py +0 -2
- dotscope-1.2.1/dotscope/parser.py +0 -395
- dotscope-1.2.1/dotscope/passes/.scope +0 -105
- dotscope-1.2.1/dotscope/passes/__init__.py +0 -1
- dotscope-1.2.1/dotscope/passes/ast_analyzer.py +0 -757
- dotscope-1.2.1/dotscope/passes/backtest.py +0 -198
- dotscope-1.2.1/dotscope/passes/budget_allocator.py +0 -343
- dotscope-1.2.1/dotscope/passes/convention_compliance.py +0 -40
- dotscope-1.2.1/dotscope/passes/convention_parser.py +0 -235
- dotscope-1.2.1/dotscope/passes/hint_generator.py +0 -128
- dotscope-1.2.1/dotscope/passes/history_miner.py +0 -336
- dotscope-1.2.1/dotscope/passes/incremental.py +0 -221
- dotscope-1.2.1/dotscope/passes/lang/__init__.py +0 -38
- dotscope-1.2.1/dotscope/passes/lang/_base.py +0 -20
- dotscope-1.2.1/dotscope/passes/lang/_treesitter.py +0 -93
- dotscope-1.2.1/dotscope/passes/lang/go.py +0 -334
- dotscope-1.2.1/dotscope/passes/lang/javascript.py +0 -431
- dotscope-1.2.1/dotscope/passes/lazy.py +0 -177
- dotscope-1.2.1/dotscope/passes/preflight.py +0 -117
- dotscope-1.2.1/dotscope/passes/semantic_diff.py +0 -160
- dotscope-1.2.1/dotscope/passes/sentinel/__init__.py +0 -1
- dotscope-1.2.1/dotscope/passes/sentinel/acknowledge.py +0 -222
- dotscope-1.2.1/dotscope/passes/sentinel/checker.py +0 -428
- dotscope-1.2.1/dotscope/passes/sentinel/checks/__init__.py +0 -1
- dotscope-1.2.1/dotscope/passes/sentinel/checks/antipattern.py +0 -84
- dotscope-1.2.1/dotscope/passes/sentinel/checks/direction.py +0 -71
- dotscope-1.2.1/dotscope/passes/sentinel/checks/spatial.py +0 -115
- dotscope-1.2.1/dotscope/passes/sentinel/checks/voice.py +0 -108
- dotscope-1.2.1/dotscope/passes/sentinel/constraints.py +0 -472
- dotscope-1.2.1/dotscope/passes/sentinel/line_filter.py +0 -88
- dotscope-1.2.1/dotscope/passes/sentinel/models.py +0 -15
- dotscope-1.2.1/dotscope/passes/spatial_autofix.py +0 -206
- dotscope-1.2.1/dotscope/passes/voice.py +0 -161
- dotscope-1.2.1/dotscope/passes/voice_defaults.py +0 -68
- dotscope-1.2.1/dotscope/passes/voice_discovery.py +0 -245
- dotscope-1.2.1/dotscope/paths.py +0 -83
- dotscope-1.2.1/dotscope/progress.py +0 -44
- dotscope-1.2.1/dotscope/refresh.py +0 -543
- dotscope-1.2.1/dotscope/regression.py +0 -147
- dotscope-1.2.1/dotscope/search/.scope +0 -29
- dotscope-1.2.1/dotscope/search/__init__.py +0 -1
- dotscope-1.2.1/dotscope/search/chunker.py +0 -343
- dotscope-1.2.1/dotscope/search/expander.py +0 -129
- dotscope-1.2.1/dotscope/search/flattener.py +0 -187
- dotscope-1.2.1/dotscope/search/models.py +0 -70
- dotscope-1.2.1/dotscope/search/observation.py +0 -279
- dotscope-1.2.1/dotscope/search/reranker.py +0 -85
- dotscope-1.2.1/dotscope/sessions.py +0 -2
- dotscope-1.2.1/dotscope/storage/.scope +0 -64
- dotscope-1.2.1/dotscope/storage/__init__.py +0 -1
- dotscope-1.2.1/dotscope/storage/cache.py +0 -177
- dotscope-1.2.1/dotscope/storage/claude_hooks.py +0 -119
- dotscope-1.2.1/dotscope/storage/git_hooks.py +0 -500
- dotscope-1.2.1/dotscope/storage/incremental_state.py +0 -124
- dotscope-1.2.1/dotscope/storage/mcp_config.py +0 -98
- dotscope-1.2.1/dotscope/storage/near_miss.py +0 -183
- dotscope-1.2.1/dotscope/storage/onboarding.py +0 -150
- dotscope-1.2.1/dotscope/storage/session_manager.py +0 -195
- dotscope-1.2.1/dotscope/storage/swarm_state.py +0 -144
- dotscope-1.2.1/dotscope/storage/timing.py +0 -84
- dotscope-1.2.1/dotscope/textio.py +0 -122
- dotscope-1.2.1/dotscope/timing.py +0 -2
- dotscope-1.2.1/dotscope/utility.py +0 -123
- dotscope-1.2.1/dotscope/virtual.py +0 -3
- dotscope-1.2.1/dotscope/visibility.py +0 -687
- dotscope-1.2.1/logo.png +0 -0
- dotscope-1.2.1/pyproject.toml +0 -45
- dotscope-1.2.1/tests/.scope +0 -29
- dotscope-1.2.1/tests/__init__.py +0 -0
- dotscope-1.2.1/tests/conftest.py +0 -152
- dotscope-1.2.1/tests/test_absorber.py +0 -91
- dotscope-1.2.1/tests/test_ast_analyzer.py +0 -168
- dotscope-1.2.1/tests/test_backtest.py +0 -114
- dotscope-1.2.1/tests/test_budget.py +0 -124
- dotscope-1.2.1/tests/test_canonical_snippet.py +0 -70
- dotscope-1.2.1/tests/test_cli.py +0 -122
- dotscope-1.2.1/tests/test_composer.py +0 -125
- dotscope-1.2.1/tests/test_context.py +0 -52
- dotscope-1.2.1/tests/test_enforcement.py +0 -423
- dotscope-1.2.1/tests/test_eval_harness.py +0 -376
- dotscope-1.2.1/tests/test_experience.py +0 -237
- dotscope-1.2.1/tests/test_graph.py +0 -78
- dotscope-1.2.1/tests/test_history.py +0 -71
- dotscope-1.2.1/tests/test_ingest.py +0 -319
- dotscope-1.2.1/tests/test_lessons.py +0 -91
- dotscope-1.2.1/tests/test_line_filter.py +0 -67
- dotscope-1.2.1/tests/test_loop.py +0 -384
- dotscope-1.2.1/tests/test_matcher.py +0 -47
- dotscope-1.2.1/tests/test_near_miss.py +0 -161
- dotscope-1.2.1/tests/test_refresh.py +0 -251
- dotscope-1.2.1/tests/test_resolver.py +0 -100
- dotscope-1.2.1/tests/test_rigor.py +0 -223
- dotscope-1.2.1/tests/test_routing.py +0 -207
- dotscope-1.2.1/tests/test_scanner.py +0 -54
- dotscope-1.2.1/tests/test_sessions.py +0 -122
- dotscope-1.2.1/tests/test_textio.py +0 -85
- dotscope-1.2.1/tests/test_treesitter.py +0 -359
- dotscope-1.2.1/tests/test_utility.py +0 -48
- dotscope-1.2.1/tests/test_virtual.py +0 -95
- dotscope-1.2.1/tests/test_visibility.py +0 -417
- dotscope-1.2.1/tests/test_voice_check.py +0 -123
- dotscope-1.2.1/tests/test_voice_discovery.py +0 -143
- dotscope-1.2.1/uv.lock +0 -2375
- {dotscope-1.2.1 → dotscope-1.3.0}/.claude/hooks/pre-commit-check.sh +0 -0
- {dotscope-1.2.1 → dotscope-1.3.0}/.claude/settings.json +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/.gitignore +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/.scopes +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/AGENT_INSTRUCTIONS.md +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/LICENSE +0 -0
- {dotscope-1.2.1 → dotscope-1.3.0}/README.md +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/docs/architecture.md +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/docs/cli-reference.md +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/docs/how-it-works.md +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/docs/scope-file.md +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/.scope +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/absorber.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/assertions.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/ast_analyzer.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/backtest.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/bench.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/budget.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/cache.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/check/__init__.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/check/acknowledge.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/check/checker.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/check/checks/__init__.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/check/checks/antipattern.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/check/checks/boundary.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/check/checks/contracts.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/check/checks/direction.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/check/checks/intent.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/check/checks/stability.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/check/constraints.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/check/models.py +0 -0
- {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/constants.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/context.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/counterfactual.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/debug.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/eval/.scope +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/eval/__init__.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/eval/bootstrap.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/eval/compare.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/eval/corpus.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/eval/harness.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/eval/replay.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/generate/.scope +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/generate/__init__.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/generate/atlas.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/generate/contracts.py +0 -0
- {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/generate/engine.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/generate/models.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/generate/network.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/graph.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/history.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/hooks.py +0 -0
- {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/ignore.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/intent.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/lessons.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/matcher.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/merge/.scope +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/merge/__init__.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/merge/classifier.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/merge/composer.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/merge/differ.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/merge/driver.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/merge/imports.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/merge/models.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/merge/swarm.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/models/.scope +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/models/__init__.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/models/eval.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/models/history.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/models/passes.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/near_miss.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/onboarding.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/parser.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/.scope +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/__init__.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/ast_analyzer.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/backtest.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/budget_allocator.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/convention_compliance.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/convention_parser.py +0 -0
- {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/passes/graph_builder.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/hint_generator.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/history_miner.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/incremental.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/lang/__init__.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/lang/_base.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/lang/_treesitter.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/lang/go.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/lang/javascript.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/lazy.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/preflight.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/semantic_diff.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/sentinel/__init__.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/sentinel/acknowledge.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/sentinel/checker.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/sentinel/checks/__init__.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/sentinel/constraints.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/sentinel/line_filter.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/sentinel/models.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/spatial_autofix.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/voice.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/voice_defaults.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/passes/voice_discovery.py +0 -0
- /dotscope-1.2.1/.claude/worktrees/hopeful-chatelet/dotscope/paths.py → /dotscope-1.3.0/dotscope/paths/__init__.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/progress.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/regression.py +0 -0
- {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/scanner.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/search/.scope +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/search/__init__.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/search/chunker.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/search/expander.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/search/flattener.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/search/models.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/search/observation.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/search/reranker.py +0 -0
- {dotscope-1.2.1 → dotscope-1.3.0}/dotscope/search/retriever.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/sessions.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/storage/.scope +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/storage/__init__.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/storage/cache.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/storage/git_hooks.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/storage/incremental_state.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/storage/near_miss.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/storage/onboarding.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/storage/session_manager.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/storage/swarm_state.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/storage/timing.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/textio.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/timing.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/utility.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/virtual.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/dotscope/visibility.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/logo.png +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/.scope +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/__init__.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/conftest.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_absorber.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_ast_analyzer.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_backtest.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_budget.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_canonical_snippet.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_cli.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_composer.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_context.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_enforcement.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_eval_harness.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_experience.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_graph.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_history.py +0 -0
- {dotscope-1.2.1 → dotscope-1.3.0}/tests/test_ignore.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_lessons.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_line_filter.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_loop.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_matcher.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_near_miss.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_refresh.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_resolver.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_rigor.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_routing.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_scanner.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_sessions.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_textio.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_treesitter.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_utility.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_visibility.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_voice_check.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/tests/test_voice_discovery.py +0 -0
- {dotscope-1.2.1/.claude/worktrees/hopeful-chatelet → dotscope-1.3.0}/uv.lock +0 -0
|
@@ -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:
|
|
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
|
#
|
dotscope-1.3.0/.mcp.json
ADDED
|
@@ -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
|
dotscope-1.3.0/CLAUDE.md
ADDED
|
@@ -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.
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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.
|
|
@@ -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()
|