codevira 1.7.1__tar.gz → 2.0.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.
- {codevira-1.7.1 → codevira-2.0.0}/CHANGELOG.md +512 -0
- {codevira-1.7.1/codevira.egg-info → codevira-2.0.0}/PKG-INFO +206 -34
- {codevira-1.7.1 → codevira-2.0.0}/README.md +203 -31
- codevira-2.0.0/agents/qa/01-code-review.md +57 -0
- codevira-2.0.0/agents/qa/02-adversarial-fix-review.md +57 -0
- codevira-2.0.0/agents/qa/03-cross-module-impact.md +57 -0
- codevira-2.0.0/agents/qa/06-doc-drift.md +47 -0
- codevira-2.0.0/agents/qa/07-security-audit.md +73 -0
- codevira-2.0.0/agents/qa/12-llm-redteam.md +53 -0
- codevira-2.0.0/agents/qa/13-multi-ide-schema.md +62 -0
- codevira-2.0.0/agents/qa/22-competitor-benchmark.md +70 -0
- codevira-2.0.0/agents/qa/README.md +73 -0
- codevira-2.0.0/agents/qa/tier2-scripts.md +242 -0
- codevira-2.0.0/agents/qa/tier3-manual.md +167 -0
- {codevira-1.7.1 → codevira-2.0.0/codevira.egg-info}/PKG-INFO +206 -34
- codevira-2.0.0/codevira.egg-info/SOURCES.txt +229 -0
- codevira-2.0.0/docs/alpha-tester-invites.md +124 -0
- codevira-2.0.0/docs/demo/README.md +69 -0
- codevira-2.0.0/docs/heroes/00-engine.md +388 -0
- codevira-2.0.0/docs/heroes/01-decision-lock.md +271 -0
- codevira-2.0.0/docs/heroes/02-anti-regression.md +269 -0
- codevira-2.0.0/docs/heroes/03-scope-contract.md +272 -0
- codevira-2.0.0/docs/heroes/04-blast-radius.md +298 -0
- codevira-2.0.0/docs/heroes/05-cross-session.md +300 -0
- codevira-2.0.0/docs/heroes/06-token-budget.md +292 -0
- codevira-2.0.0/docs/heroes/07-live-style.md +272 -0
- codevira-2.0.0/docs/heroes/08-decision-replay.md +295 -0
- codevira-2.0.0/docs/heroes/09-intent-inference.md +257 -0
- codevira-2.0.0/docs/heroes/10-ai-promotion.md +331 -0
- codevira-2.0.0/docs/heroes/README.md +51 -0
- codevira-2.0.0/docs/heroes/pillar-1-setup.md +392 -0
- codevira-2.0.0/docs/hn-launch-day.md +224 -0
- codevira-2.0.0/docs/local-pypi-https.md +184 -0
- codevira-2.0.0/docs/qa-playbook.md +400 -0
- codevira-2.0.0/docs/v2-completion-plan.md +211 -0
- codevira-2.0.0/docs/v2-execution-log.md +2582 -0
- codevira-2.0.0/docs/v2-master-plan.md +251 -0
- codevira-2.0.0/docs/vs-other-memory-tools.md +110 -0
- codevira-2.0.0/indexer/__init__.py +7 -0
- codevira-2.0.0/indexer/_dedupe_migration.py +101 -0
- codevira-2.0.0/indexer/_fork_safety.py +69 -0
- codevira-2.0.0/indexer/_sqlite_util.py +84 -0
- codevira-2.0.0/indexer/fix_history.py +626 -0
- {codevira-1.7.1 → codevira-2.0.0}/indexer/global_db.py +54 -4
- {codevira-1.7.1 → codevira-2.0.0}/indexer/index_codebase.py +349 -58
- {codevira-1.7.1 → codevira-2.0.0}/indexer/outcome_tracker.py +89 -4
- {codevira-1.7.1 → codevira-2.0.0}/indexer/sqlite_graph.py +296 -22
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/__init__.py +1 -1
- codevira-2.0.0/mcp_server/_ghost_check.py +88 -0
- codevira-2.0.0/mcp_server/_project_inventory.py +276 -0
- codevira-2.0.0/mcp_server/_prompts.py +82 -0
- codevira-2.0.0/mcp_server/_repair_init.py +126 -0
- codevira-2.0.0/mcp_server/_safe_crash.py +58 -0
- codevira-2.0.0/mcp_server/agents_md.py +436 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/auto_init.py +69 -6
- codevira-2.0.0/mcp_server/cli.py +1923 -0
- codevira-2.0.0/mcp_server/cli_agents.py +220 -0
- codevira-2.0.0/mcp_server/cli_budget.py +213 -0
- codevira-2.0.0/mcp_server/cli_configure.py +855 -0
- codevira-2.0.0/mcp_server/cli_hooks_admin.py +184 -0
- codevira-2.0.0/mcp_server/cli_insights.py +337 -0
- codevira-2.0.0/mcp_server/cli_projects.py +139 -0
- codevira-2.0.0/mcp_server/cli_replay.py +136 -0
- codevira-2.0.0/mcp_server/data/__pycache__/__init__.cpython-313.pyc +0 -0
- codevira-2.0.0/mcp_server/data/hooks/post_tool_use.sh +37 -0
- codevira-2.0.0/mcp_server/data/hooks/pre_tool_use.sh +57 -0
- codevira-2.0.0/mcp_server/data/hooks/session_start.sh +41 -0
- codevira-2.0.0/mcp_server/data/hooks/stop.sh +40 -0
- codevira-2.0.0/mcp_server/data/hooks/user_prompt_submit.sh +42 -0
- codevira-2.0.0/mcp_server/data/templates/agents_md.tmpl +3 -0
- codevira-2.0.0/mcp_server/data/templates/canonical_block.md +81 -0
- codevira-2.0.0/mcp_server/data/templates/claude_md.tmpl +3 -0
- codevira-2.0.0/mcp_server/data/templates/copilot_instructions.tmpl +3 -0
- codevira-2.0.0/mcp_server/data/templates/cursor_rules.mdc.tmpl +8 -0
- codevira-2.0.0/mcp_server/data/templates/gemini_md.tmpl +3 -0
- codevira-2.0.0/mcp_server/data/templates/windsurfrules.tmpl +3 -0
- codevira-2.0.0/mcp_server/decision_replay.py +424 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/detect.py +76 -3
- codevira-2.0.0/mcp_server/doctor.py +771 -0
- codevira-2.0.0/mcp_server/engine/__init__.py +85 -0
- codevira-2.0.0/mcp_server/engine/demo_policy.py +62 -0
- codevira-2.0.0/mcp_server/engine/events.py +125 -0
- codevira-2.0.0/mcp_server/engine/intent_classifier.py +214 -0
- codevira-2.0.0/mcp_server/engine/policies/__init__.py +44 -0
- codevira-2.0.0/mcp_server/engine/policies/_signature_detect.py +314 -0
- codevira-2.0.0/mcp_server/engine/policies/ai_promotion.py +337 -0
- codevira-2.0.0/mcp_server/engine/policies/anti_regression.py +190 -0
- codevira-2.0.0/mcp_server/engine/policies/blast_radius.py +262 -0
- codevira-2.0.0/mcp_server/engine/policies/cross_session.py +363 -0
- codevira-2.0.0/mcp_server/engine/policies/decision_lock.py +255 -0
- codevira-2.0.0/mcp_server/engine/policies/intent_inference.py +421 -0
- codevira-2.0.0/mcp_server/engine/policies/live_style.py +445 -0
- codevira-2.0.0/mcp_server/engine/policies/scope_contract.py +362 -0
- codevira-2.0.0/mcp_server/engine/policies/token_budget.py +100 -0
- codevira-2.0.0/mcp_server/engine/policy.py +160 -0
- codevira-2.0.0/mcp_server/engine/promotion_score.py +208 -0
- codevira-2.0.0/mcp_server/engine/runner.py +263 -0
- codevira-2.0.0/mcp_server/engine/scope_contract.py +201 -0
- codevira-2.0.0/mcp_server/engine/signals.py +436 -0
- codevira-2.0.0/mcp_server/engine/token_meter.py +337 -0
- codevira-2.0.0/mcp_server/engine/wiring/__init__.py +16 -0
- codevira-2.0.0/mcp_server/engine/wiring/claude_code_hooks.py +368 -0
- codevira-2.0.0/mcp_server/engine/wiring/mcp_dispatch.py +186 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/http_server.py +26 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/ide_inject.py +223 -7
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/paths.py +98 -4
- codevira-2.0.0/mcp_server/roadmap_drift.py +249 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/server.py +307 -11
- codevira-2.0.0/mcp_server/setup_wizard.py +893 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/tools/graph.py +162 -6
- codevira-2.0.0/mcp_server/tools/learning.py +575 -0
- codevira-2.0.0/mcp_server/tools/playbook.py +205 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/tools/search.py +120 -5
- {codevira-1.7.1 → codevira-2.0.0}/pyproject.toml +3 -3
- codevira-2.0.0/tests/test__prompts.py +138 -0
- {codevira-1.7.1 → codevira-2.0.0}/tests/test_auto_init.py +75 -3
- codevira-2.0.0/tests/test_call_edge_fk_safety.py +162 -0
- {codevira-1.7.1 → codevira-2.0.0}/tests/test_chunker.py +18 -7
- {codevira-1.7.1 → codevira-2.0.0}/tests/test_cli.py +305 -0
- codevira-2.0.0/tests/test_cli_agents.py +375 -0
- codevira-2.0.0/tests/test_cli_configure.py +1075 -0
- codevira-2.0.0/tests/test_cli_insights.py +159 -0
- codevira-2.0.0/tests/test_cli_projects.py +224 -0
- codevira-2.0.0/tests/test_cli_replay.py +234 -0
- codevira-2.0.0/tests/test_cli_version.py +51 -0
- codevira-2.0.0/tests/test_dedupe_migration.py +249 -0
- {codevira-1.7.1 → codevira-2.0.0}/tests/test_detect.py +78 -11
- codevira-2.0.0/tests/test_doctor.py +424 -0
- codevira-2.0.0/tests/test_fk_safety_extended.py +178 -0
- codevira-2.0.0/tests/test_fork_safety.py +206 -0
- codevira-2.0.0/tests/test_ghost_check.py +116 -0
- codevira-2.0.0/tests/test_hook_resilience.py +283 -0
- {codevira-1.7.1 → codevira-2.0.0}/tests/test_http_server.py +11 -4
- {codevira-1.7.1 → codevira-2.0.0}/tests/test_ide_inject.py +232 -8
- {codevira-1.7.1 → codevira-2.0.0}/tests/test_index_codebase.py +454 -0
- {codevira-1.7.1 → codevira-2.0.0}/tests/test_outcome_tracker.py +51 -0
- {codevira-1.7.1 → codevira-2.0.0}/tests/test_paths.py +119 -0
- codevira-2.0.0/tests/test_record_decision.py +274 -0
- codevira-2.0.0/tests/test_repair_init.py +191 -0
- codevira-2.0.0/tests/test_retire_rule.py +271 -0
- codevira-2.0.0/tests/test_roadmap_drift.py +385 -0
- {codevira-1.7.1 → codevira-2.0.0}/tests/test_server.py +134 -9
- codevira-2.0.0/tests/test_setup_wizard.py +836 -0
- {codevira-1.7.1 → codevira-2.0.0}/tests/test_sqlite_graph.py +362 -0
- codevira-2.0.0/tests/test_sqlite_util.py +115 -0
- {codevira-1.7.1 → codevira-2.0.0}/tests/test_tools_learning.py +307 -3
- {codevira-1.7.1 → codevira-2.0.0}/tests/test_tools_playbook.py +23 -10
- {codevira-1.7.1 → codevira-2.0.0}/tests/test_tools_search.py +20 -6
- codevira-2.0.0/tests/test_watcher_circuit.py +124 -0
- codevira-1.7.1/codevira.egg-info/SOURCES.txt +0 -117
- codevira-1.7.1/indexer/__init__.py +0 -1
- codevira-1.7.1/mcp_server/cli.py +0 -964
- codevira-1.7.1/mcp_server/tools/learning.py +0 -244
- codevira-1.7.1/mcp_server/tools/playbook.py +0 -89
- {codevira-1.7.1 → codevira-2.0.0}/LICENSE +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/MANIFEST.in +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/agents/builder.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/agents/developer.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/agents/documenter.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/agents/orchestrator.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/agents/planner.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/agents/reviewer.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/agents/tester.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/codevira.egg-info/dependency_links.txt +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/codevira.egg-info/entry_points.txt +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/codevira.egg-info/requires.txt +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/codevira.egg-info/top_level.txt +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/config.example.yaml +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/docs/how-i-built-persistent-memory-for-ai-agents.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/docs/linkedin-article-ai-agent-memory.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/docs/linkedin-post-ai-agent-memory.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/docs/medium-your-ai-coding-agent-has-amnesia.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/docs/roadmap.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/graph/_schema.yaml +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/indexer/chunker.py +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/indexer/graph_generator.py +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/indexer/rule_learner.py +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/indexer/treesitter_parser.py +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/__main__.py +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/crash_logger.py +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/__init__.py +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/agents/builder.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/agents/developer.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/agents/documenter.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/agents/orchestrator.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/agents/planner.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/agents/reviewer.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/agents/tester.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/config.example.yaml +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/rules/coding-standards.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/rules/engineering-excellence.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/rules/git-cicd-governance.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/rules/git_commits.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/rules/incremental-updates.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/rules/master_rule.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/rules/multi-language.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/rules/persistence.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/rules/resilience-observability.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/rules/smoke-testing.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/rules/testing-standards.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/gitignore.py +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/global_sync.py +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/launchd.py +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/log_retention.py +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/migrate.py +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/prompts.py +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/tools/__init__.py +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/tools/changesets.py +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/tools/code_reader.py +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/mcp_server/tools/roadmap.py +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/rules/coding-standards.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/rules/engineering-excellence.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/rules/git-cicd-governance.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/rules/git_commits.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/rules/incremental-updates.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/rules/master_rule.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/rules/persistence.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/rules/resilience-observability.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/rules/smoke-testing.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/rules/testing-standards.md +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/setup.cfg +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/tests/test_crash_logger.py +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/tests/test_gitignore.py +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/tests/test_global_db.py +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/tests/test_global_sync.py +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/tests/test_graph_generator.py +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/tests/test_launchd.py +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/tests/test_log_retention.py +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/tests/test_migrate.py +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/tests/test_prompts.py +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/tests/test_rule_learner.py +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/tests/test_tools_changesets.py +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/tests/test_tools_code_reader.py +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/tests/test_tools_graph.py +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/tests/test_tools_roadmap.py +0 -0
- {codevira-1.7.1 → codevira-2.0.0}/tests/test_treesitter_parser.py +0 -0
|
@@ -11,6 +11,518 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|
|
11
11
|
|
|
12
12
|
## [Unreleased]
|
|
13
13
|
|
|
14
|
+
### Planned for v2.1
|
|
15
|
+
|
|
16
|
+
See [ROADMAP.md](ROADMAP.md#-v21--honest-known-limitations-from-the-rc5-audit-2026-05-13).
|
|
17
|
+
|
|
18
|
+
- **Multi-language `get_signature` / `get_code`** — wire tree-sitter (already
|
|
19
|
+
used for graph indexing) into these tools so non-Python projects stop
|
|
20
|
+
getting "Python-only by design".
|
|
21
|
+
- **`record_decisions_batch` API** — compress 50× ~800 B per-call overhead
|
|
22
|
+
into one round-trip.
|
|
23
|
+
- **CLI naming clarity** — pick a canonical hierarchy among `init` / `setup` /
|
|
24
|
+
`register` / `configure`; add a `codevira inspect` umbrella; deprecate one
|
|
25
|
+
of `--project-dir` (global) / `--project PATH` (per-subcommand) on a
|
|
26
|
+
v2.1 → v2.2 cycle.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## [2.0.0] — 2026-05-14 — First public 2.0 release
|
|
31
|
+
|
|
32
|
+
The 2.0 release moves codevira from "memory layer for one developer in one IDE" to
|
|
33
|
+
"active guardian for every AI coding tool you use, on every project, on your local
|
|
34
|
+
machine." Five internal iterations (rc1..rc5 in dev tags) plus a same-day public
|
|
35
|
+
release-candidate cycle (`2.0.0rc1`) of dogfood + audit + product-credibility
|
|
36
|
+
work consolidate into 2.0.0. **Full changelog: [RELEASE_NOTES.md](RELEASE_NOTES.md).**
|
|
37
|
+
|
|
38
|
+
### Added
|
|
39
|
+
|
|
40
|
+
- **All 10 hero policies** — active guardian engine intercepts every AI tool
|
|
41
|
+
call (Edit, Write, prompt submit, session start) and routes through
|
|
42
|
+
registered policies (Decision Lock, Anti-Regression, Scope Contract,
|
|
43
|
+
Blast-Radius Veto, Cross-Session Consistency, Token Budget, Live Style
|
|
44
|
+
Enforcement, Decision Replay, Proactive Intent Inference, AI Promotion
|
|
45
|
+
Score).
|
|
46
|
+
- **`codevira setup`** — one-prompt installer that detects every AI tool
|
|
47
|
+
on the machine (Claude Code, Cursor, Windsurf, Antigravity, OpenAI Codex,
|
|
48
|
+
GitHub Copilot, Continue.dev, Aider) and configures all of them at once.
|
|
49
|
+
- **`codevira projects`** — canonical inventory with `tracked / ghost /
|
|
50
|
+
orphan / stale` classification (`--json` for scripting; `--ghosts-only`
|
|
51
|
+
pairs with `clean --ghosts`).
|
|
52
|
+
- **`codevira hooks list / uninstall`** — admin commands for Claude Code
|
|
53
|
+
lifecycle hooks; surgical install + clean removal.
|
|
54
|
+
- **`codevira clean --ghosts`** — surgical removal of incomplete project
|
|
55
|
+
data dirs without touching tracked projects.
|
|
56
|
+
- **`codevira init --single-language`** — opt-out flag for the new
|
|
57
|
+
index-everything default.
|
|
58
|
+
- **`codevira engine` subcommand** — internal hook dispatcher; surfaces in
|
|
59
|
+
`--help` so the lifecycle hooks can call it.
|
|
60
|
+
- **4 new doctor checks** — `claude_mcp_visibility`, `codeindex_freshness`,
|
|
61
|
+
`semantic_search_health`, `ghost_projects` (total 14 per run).
|
|
62
|
+
- **Per-project config opt-out for cross-session injection** —
|
|
63
|
+
`.codevira/config.yaml: project: { cross_session_mode: off }` disables
|
|
64
|
+
the per-prompt context block without touching env vars.
|
|
65
|
+
|
|
66
|
+
### Changed
|
|
67
|
+
|
|
68
|
+
- **`codevira init` default** — indexes every common source/config/docs
|
|
69
|
+
extension (~75 total: `.py`, `.ts`, `.go`, `.yaml`, `.toml`, `.md`,
|
|
70
|
+
`.html`, `.sql`, `.proto`, …) instead of narrowing to one language.
|
|
71
|
+
- **`codevira agents` default** — renders nudge files for **detected** IDEs
|
|
72
|
+
only; `--ide=all` opt-in for the legacy "render for every supported IDE"
|
|
73
|
+
behavior.
|
|
74
|
+
- **`codevira doctor`** — now genuinely read-only; snapshots the projects
|
|
75
|
+
dir at entry and removes any new dirs at exit.
|
|
76
|
+
- **`search_codebase`** — graceful structural fallback (filename + symbol
|
|
77
|
+
substring) when the semantic index is unavailable, with the correct
|
|
78
|
+
`fix_command` instead of a misleading "reinstall codevira" hint.
|
|
79
|
+
- **`get_node` / `get_impact` / `query_graph`** — three-case error
|
|
80
|
+
differentiation: "no graph DB" / "graph empty" / "file not in populated
|
|
81
|
+
graph", each with its own `fix_command`.
|
|
82
|
+
- **`get_decision_confidence`** — exposes `decisions_in_db_total` and
|
|
83
|
+
`decisions_eligible_for_outcomes` plus a four-state interpretation so
|
|
84
|
+
users understand WHY their `total_decisions` may be zero. Outcome
|
|
85
|
+
tracker also classifies file-less decisions via mention-extraction.
|
|
86
|
+
- **Playbooks** — project-scoped first
|
|
87
|
+
(`<data_dir>/playbooks/` or `<project>/.codevira/playbooks/`); bundled
|
|
88
|
+
Python defaults are skipped with a clear warning when project language
|
|
89
|
+
≠ Python.
|
|
90
|
+
- **`register_project`** uses `ON CONFLICT … COALESCE(excluded.git_remote,
|
|
91
|
+
projects.git_remote)` — subsequent registrations can't silently clear
|
|
92
|
+
the `git_remote` column.
|
|
93
|
+
- **Auto-init self-heal** runs SYNCHRONOUSLY in the calling thread of every
|
|
94
|
+
CLI invocation — daemon thread death no longer leaves ghost data dirs.
|
|
95
|
+
- **Default install** includes ChromaDB + sentence-transformers (no
|
|
96
|
+
`[search]` extra needed for semantic search).
|
|
97
|
+
- **README "92% reduction" claim** qualified with honest scope, per-prompt
|
|
98
|
+
cost, and amortization curve.
|
|
99
|
+
- **`register` deprecation** now names the removal version (v2.1).
|
|
100
|
+
|
|
101
|
+
### Fixed
|
|
102
|
+
|
|
103
|
+
- macOS Apple Silicon **fork-safety segfault on first `codevira index`**
|
|
104
|
+
(auto-applied at indexer import).
|
|
105
|
+
- **Setup interactive prompt** silent-fail on unexpected input — replaced
|
|
106
|
+
with a shared `_prompts.confirm` helper that retries, flushes stdout,
|
|
107
|
+
and handles `KeyboardInterrupt` cleanly.
|
|
108
|
+
- Three **`status --global` UI typos** that always rendered 0/0/0
|
|
109
|
+
regardless of actual `global.db` state.
|
|
110
|
+
- Four **FK race conditions** in the watcher pipeline.
|
|
111
|
+
- **Python `None` leaked into argparse choices** for `agents --ide` and
|
|
112
|
+
`budget` positional.
|
|
113
|
+
- Several **silent argument clamps** in `replay --since`, `insights --since`,
|
|
114
|
+
and `insights --top` now print visible warnings.
|
|
115
|
+
|
|
116
|
+
### Tests
|
|
117
|
+
|
|
118
|
+
- 2395 / 2395 passing (deterministic).
|
|
119
|
+
- ~1091 net new tests since v1.8.0 (mostly from the v2.0 hero policies +
|
|
120
|
+
audit-driven regression coverage).
|
|
121
|
+
|
|
122
|
+
### Note on internal v1.8.1 + 2.0.0rc1
|
|
123
|
+
|
|
124
|
+
A v1.8.1 production hotfix existed in dev tags but was never published to
|
|
125
|
+
PyPI; its fixes are folded into 2.0.0. A `2.0.0rc1` was briefly published
|
|
126
|
+
on PyPI (2026-05-14) as a same-day public release candidate; the code is
|
|
127
|
+
identical to 2.0.0. Anyone who installed `codevira==2.0.0rc1` can
|
|
128
|
+
`pipx install --upgrade codevira` to move to 2.0.0 final.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## [Original v1.9 plan, deferred]
|
|
133
|
+
|
|
134
|
+
- **Interactive checkbox UI for `codevira configure`**. The current
|
|
135
|
+
prompt asks users to type comma-separated indices ("1,3,5") into a
|
|
136
|
+
numbered list — fine for 3–5 items, awkward for 15+. v1.9 will add
|
|
137
|
+
arrow-key navigation + space-to-toggle multi-select, matching the
|
|
138
|
+
UX of `npm create vite`, `gh repo create`, etc.
|
|
139
|
+
|
|
140
|
+
**Design (opt-in dependency):**
|
|
141
|
+
- Default install (`pip install codevira`) keeps the current numbered
|
|
142
|
+
prompt — zero new dependencies, zero new failure modes.
|
|
143
|
+
- `pip install codevira[ui]` pulls `questionary` (~3 MB). When
|
|
144
|
+
importable AND `sys.stdin.isatty()` AND `os.environ.get("TERM")
|
|
145
|
+
!= "dumb"`, `prompt_multi_select` switches to the checkbox UI.
|
|
146
|
+
- `--dirs` and `--extensions` flags continue to work for both paths
|
|
147
|
+
(CI / scripts / non-interactive use).
|
|
148
|
+
|
|
149
|
+
**Why deferred from v1.8.1:** v1.8.1 is a pure crash hotfix; mixing
|
|
150
|
+
in a UX feature would slow the release and complicate testing. The
|
|
151
|
+
numbered prompt has shipped since v1.8.0 and works fine — this is
|
|
152
|
+
polish, not a fix.
|
|
153
|
+
|
|
154
|
+
**Implementation notes for whoever picks this up:**
|
|
155
|
+
- Site: `mcp_server/cli_configure.py:prompt_multi_select` (line ~176)
|
|
156
|
+
- Add `[ui]` extra in `pyproject.toml` with `questionary>=2.0`
|
|
157
|
+
- TTY detection already exists (`NonInteractiveError` raised on
|
|
158
|
+
`not sys.stdin.isatty()`); extend it to also branch on
|
|
159
|
+
questionary availability
|
|
160
|
+
- Test surface: split into two test classes — one mocks `input()`
|
|
161
|
+
(current behavior), one mocks `questionary.checkbox()`. Skip the
|
|
162
|
+
questionary tests when not installed.
|
|
163
|
+
- Accessibility: keep the numbered prompt for screen-reader users;
|
|
164
|
+
document `CODEVIRA_DISABLE_TUI=1` env var as the override.
|
|
165
|
+
- No schema changes, no public-API changes.
|
|
166
|
+
|
|
167
|
+
### Other v1.9 candidates (no design yet)
|
|
168
|
+
|
|
169
|
+
- Watcher restart circuit breaker (deferred from v1.8.1 — see "Out of
|
|
170
|
+
scope" below).
|
|
171
|
+
- Refactor `_enable_wal_with_retry` into a shared `indexer/_sqlite_util.py`
|
|
172
|
+
(deferred from v1.8.1).
|
|
173
|
+
- Watcher hot-reload of `config.yaml` on disk changes.
|
|
174
|
+
- `crash_logger` size cap or rotation (currently grows unbounded).
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## [1.8.1] — 2026-05-02 — Production Hotfix from Real-World Crash Logs
|
|
179
|
+
|
|
180
|
+
Pure bug-fix release. No new features, no schema changes, no public-API
|
|
181
|
+
changes. Motivated by a real production failure on the maintainer's
|
|
182
|
+
machine: **43 crashes in 70 minutes** logged by `crash_logger` between
|
|
183
|
+
07:37 and 08:47 on 2026-04-24, all under
|
|
184
|
+
`WHERE: background watcher: incremental reindex`.
|
|
185
|
+
|
|
186
|
+
Breakdown:
|
|
187
|
+
- **41 × `InterruptedError` (EINTR, errno 4)** in
|
|
188
|
+
`_get_changed_files`'s rglob walk, all walking
|
|
189
|
+
`~/Library/Group Containers/...` (WhatsApp, Office, etc.) and
|
|
190
|
+
`~/Library/Containers/...` (TextEdit, mediaanalysisd, …).
|
|
191
|
+
- **2 × `OperationalError("database is locked")`** in
|
|
192
|
+
`SQLiteGraph.add_symbol` and `remove_symbols_for_file`.
|
|
193
|
+
|
|
194
|
+
Root cause: a rogue project data dir with
|
|
195
|
+
`metadata.json.original_path = "/Users/sachin"` (the user's `$HOME`).
|
|
196
|
+
`auto_detect_project` saw `Library`, `Downloads`, `Documents`, `go` as
|
|
197
|
+
"subdirs", and the watcher then walked huge unrelated trees. v1.8.0's
|
|
198
|
+
bootstrap (`cmd_configure`, `auto_init`) didn't refuse `$HOME`, and
|
|
199
|
+
neither did `cmd_init`.
|
|
200
|
+
|
|
201
|
+
### Fixed
|
|
202
|
+
|
|
203
|
+
- **Refuse `$HOME` and system top-levels as a project root** (the
|
|
204
|
+
critical fix — eliminates 41 of the 43 production crashes by
|
|
205
|
+
preventing the rogue project from forming). New helper
|
|
206
|
+
`mcp_server.paths.is_invalid_project_root()` rejects `$HOME`, `/`,
|
|
207
|
+
`/Users`, `/home`, `/tmp`, `/private/tmp`, `/var`, `/private/var`,
|
|
208
|
+
`/etc`, `/opt` (plus the macOS-resolved `/private/etc` and
|
|
209
|
+
`/System/Volumes/Data/home` forms). Wired into TEN distinct sites
|
|
210
|
+
covering every state-creating path the codebase exposes:
|
|
211
|
+
- **CLI entry points (6):** `cmd_configure`, `cmd_init`, `cmd_index`,
|
|
212
|
+
`cmd_register`, `cmd_serve` (refuses both regular serve AND
|
|
213
|
+
`--install-service`; `--uninstall-service` is exempt so users can
|
|
214
|
+
always remove old launchd plists), `auto_init._run_background_init`.
|
|
215
|
+
- **MCP server entry points (2):** `mcp_server.server.main()` (stdio
|
|
216
|
+
transport) and `mcp_server.http_server.run_http_server()` (HTTP
|
|
217
|
+
transport). Both are reachable directly via `python -m`, not just
|
|
218
|
+
through the CLI.
|
|
219
|
+
- **Direct module entry (1):** `indexer.index_codebase.__main__`
|
|
220
|
+
(`python -m indexer.index_codebase --full | --watch | (default)`)
|
|
221
|
+
— this is a separate CLI surface from the `codevira` binary;
|
|
222
|
+
pre-revalidation it bypassed `cli.cmd_index`'s guard entirely.
|
|
223
|
+
`--status` is exempt (read-only, bails on missing graph.db).
|
|
224
|
+
- **Defense-in-depth (1):** `indexer.index_codebase.start_background_watcher`
|
|
225
|
+
refuses to start the watcher even if a programmatic caller bypasses
|
|
226
|
+
every entry-point guard above. Returns `None`; both `cmd_watch` and
|
|
227
|
+
`server.main` handle `None` correctly.
|
|
228
|
+
|
|
229
|
+
The `server.main()` and `run_http_server` guards are the most critical
|
|
230
|
+
— without them, a user upgrading from v1.8.0 *without* first running
|
|
231
|
+
`clean --orphans` would still hit the original crash mode: their
|
|
232
|
+
leftover rogue `config.yaml` would drive `start_background_watcher`
|
|
233
|
+
into walking `~/Library/Group Containers/...`, which is exactly where
|
|
234
|
+
the 41 production `InterruptedError` crashes came from. The
|
|
235
|
+
`start_background_watcher` defense-in-depth guard is a belt-and-braces
|
|
236
|
+
fallback — even if all entry-point guards regressed, the watcher
|
|
237
|
+
itself cannot start with an invalid project root.
|
|
238
|
+
|
|
239
|
+
`cmd_index`, `cmd_register`, `cmd_serve --install-service` close
|
|
240
|
+
defense-in-depth holes that pre-revalidation could have leaked state
|
|
241
|
+
on disk: silent dead-weight `mkdir` of
|
|
242
|
+
`~/.codevira/projects/<HOME_slug>/{graph,codeindex}/`, IDE configs
|
|
243
|
+
pinned to broken paths, and persistent launchd plists pointing at
|
|
244
|
+
`$HOME`. Pre-release revalidation across three rounds walked every
|
|
245
|
+
CLI sub-command, the stdio/HTTP server entry, the launchd
|
|
246
|
+
`--install-service` path, the `start_background_watcher` direct call
|
|
247
|
+
path, and the production-replay scenario (synthetic v1.8.0 leftover
|
|
248
|
+
rogue + `codevira` from `$HOME`). All paths refuse cleanly with zero
|
|
249
|
+
new crashes; legitimate projects untouched.
|
|
250
|
+
|
|
251
|
+
`auto_init` sets `_progress["status"] = "error"` so the MCP server
|
|
252
|
+
stops looping on retries.
|
|
253
|
+
|
|
254
|
+
- **`SQLiteGraph` WAL with retry — port of the v1.8.0 GlobalDB fix**
|
|
255
|
+
(eliminates the 2 of 43 `database is locked` crashes). v1.8.0 fixed
|
|
256
|
+
the same race for `GlobalDB` after round 3 of binocular review;
|
|
257
|
+
`SQLiteGraph` was missed. `__init__` now opens with `timeout=30`,
|
|
258
|
+
enables WAL via the same retry loop pattern, and sets
|
|
259
|
+
`PRAGMA busy_timeout=30000` for subsequent writes.
|
|
260
|
+
|
|
261
|
+
- **`_get_changed_files` and `cmd_full_rebuild` rglob loops tolerate
|
|
262
|
+
`OSError`** (defense-in-depth — even on legitimate projects,
|
|
263
|
+
transient `EINTR`, `PermissionError`, or "directory changed during
|
|
264
|
+
iteration" should not kill the whole reindex). Per-watch-dir scope
|
|
265
|
+
matches `watchdog.Observer`'s thread-per-watch model: the
|
|
266
|
+
microsecond-spaced parallel-thread crashes (3 within 6μs at
|
|
267
|
+
08:15:29 and 08:26:04 in the production log) confirm this is the
|
|
268
|
+
right granularity. `InterruptedError` is a subclass of `OSError`, so
|
|
269
|
+
the broader catch covers EINTR plus other transient walk failures.
|
|
270
|
+
|
|
271
|
+
### Added
|
|
272
|
+
|
|
273
|
+
- **`codevira clean --orphans`** — recovery path for users already hit
|
|
274
|
+
by the `$HOME`-bootstrap bug on v1.8.0. Walks
|
|
275
|
+
`~/.codevira/projects/*/metadata.json`; for each entry whose
|
|
276
|
+
`original_path` is rejected by `is_invalid_project_root()` OR no
|
|
277
|
+
longer exists on disk, removes the data dir and deletes the matching
|
|
278
|
+
row from `~/.codevira/global.db`. Reuses the existing `--dry-run`
|
|
279
|
+
and `-y/--yes` flags. Without this, affected users would need to
|
|
280
|
+
`rm -rf` and run raw sqlite by hand.
|
|
281
|
+
|
|
282
|
+
- **Denylist macOS/Linux/cloud-sync user-data dirs in
|
|
283
|
+
`auto_detect_project`** (defense-in-depth). `_SKIP_DIRS` extended
|
|
284
|
+
with `Library`, `Downloads`, `Music`, `Movies`, `Pictures`,
|
|
285
|
+
`Desktop`, `Public`, `Applications`, `Videos`, `Templates`, plus
|
|
286
|
+
cloud-sync top-levels (`Dropbox`, `iCloud Drive`, `OneDrive`,
|
|
287
|
+
`Google Drive`, `Box`). Even if `is_invalid_project_root` somehow
|
|
288
|
+
misses (e.g. a user passes `--project-dir` to a `$HOME`-shaped
|
|
289
|
+
layout), these never show up in `watched_dirs`. A user who
|
|
290
|
+
legitimately has a project named e.g. `Library` can still pass
|
|
291
|
+
`codevira configure --dirs Library` to opt in.
|
|
292
|
+
|
|
293
|
+
### Out of scope (deferred to v1.9)
|
|
294
|
+
|
|
295
|
+
- **Watcher restart circuit breaker.** Crash log shows ~60s gaps
|
|
296
|
+
between EINTR crashes — no backoff. Adding a circuit breaker is real
|
|
297
|
+
design work; the rglob `OSError` tolerance closes the immediate
|
|
298
|
+
hole.
|
|
299
|
+
- **Refactoring `_enable_wal_with_retry` to a shared util.** 25 lines
|
|
300
|
+
of duplication for one patch cycle is the right call; touching
|
|
301
|
+
`GlobalDB`'s tested-in-v1.8.0 code is higher risk.
|
|
302
|
+
- **`crash_logger` size cap or rotation.** Log file is ~97KB now; will
|
|
303
|
+
grow unbounded over time. Out of scope for hotfix; flagged for v1.9.
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
## [1.8.0] — 2026-04-23 — Memory Sharpening + Config UX
|
|
308
|
+
|
|
309
|
+
Three internal improvements that make the memory we already capture **sharper**,
|
|
310
|
+
without making it heavier. Zero new MCP tools. Zero new tables. The public API
|
|
311
|
+
shape changes only one thing: `get_session_context()` gains a `focus_source`
|
|
312
|
+
field (~10 tokens, additive, backwards-compatible).
|
|
313
|
+
|
|
314
|
+
The problem this release solves:
|
|
315
|
+
- `get_session_context()` returned the 3 newest decisions by timestamp —
|
|
316
|
+
regardless of whether they had anything to do with the current task.
|
|
317
|
+
- `search_decisions()` ordered purely by recency — a `file_path` match
|
|
318
|
+
was no better than a match buried in an unrelated session summary.
|
|
319
|
+
- `log_session()` inserted every decision unconditionally — a day of
|
|
320
|
+
iterative agent work logged the same intent 5+ times.
|
|
321
|
+
|
|
322
|
+
### Fixed
|
|
323
|
+
|
|
324
|
+
- **MCP `serverInfo.version` reported the MCP library version, not codevira's**
|
|
325
|
+
(pre-existing bug, surfaced during v1.8 install verification on Python
|
|
326
|
+
3.13). `Server("codevira")` was constructed without a `version=` argument,
|
|
327
|
+
so the framework defaulted to its own pip-package version (e.g. `1.27.0`)
|
|
328
|
+
in the JSON-RPC `initialize` handshake response. Clients use this field
|
|
329
|
+
for telemetry and version gating, so the wrong value misled them.
|
|
330
|
+
One-line fix: `Server("codevira", version=__version__)`.
|
|
331
|
+
- **`get_session_context()` read the wrong dict key** (pre-existing bug).
|
|
332
|
+
`list_open_changesets()` returns `{"open_changesets": [...], ...}`, but
|
|
333
|
+
`get_session_context` looked for `"changesets"`. The `open_changesets`
|
|
334
|
+
field in the session-context response was **always empty** in production.
|
|
335
|
+
Tests didn't catch it because mocks used the same wrong key.
|
|
336
|
+
|
|
337
|
+
- **`GlobalDB` concurrent-open race condition** (pre-existing bug — latent
|
|
338
|
+
since v1.6's centralized storage introduced shared `~/.codevira/global.db`).
|
|
339
|
+
`PRAGMA journal_mode=WAL` requires an exclusive lock and — unlike normal
|
|
340
|
+
SQL — does NOT honour `sqlite3`'s `busy_timeout`. When multiple processes
|
|
341
|
+
or threads opened the same fresh database concurrently (e.g. several
|
|
342
|
+
projects' first-ever `codevira register` running in parallel, or the
|
|
343
|
+
`global_sync` background export racing the MCP server thread), one or
|
|
344
|
+
more would raise `OperationalError('database is locked')` and silently
|
|
345
|
+
fail to register. The test `test_concurrent_access_from_threads` was
|
|
346
|
+
flaky at 60% failure rate, hinting at the real issue. Fixed with WAL-
|
|
347
|
+
enable retry loop + short-circuit when WAL is already active. Stability
|
|
348
|
+
verified at 20/20 passes across 20 test runs.
|
|
349
|
+
|
|
350
|
+
### Changed
|
|
351
|
+
|
|
352
|
+
- **Focus-weighted `recent_decisions` in `get_session_context()`**. Instead
|
|
353
|
+
of chronological "newest 3", decisions are now ranked by what the agent
|
|
354
|
+
is currently focused on:
|
|
355
|
+
1. Open changeset with `files_pending` → focus = first file path of the
|
|
356
|
+
most-recently-created changeset.
|
|
357
|
+
2. Strong `current_phase.next_action` signal → focus = extracted keywords
|
|
358
|
+
(rejects short or stop-list-only actions like "continue work").
|
|
359
|
+
3. Otherwise → chronological fallback (unchanged behaviour).
|
|
360
|
+
If focus returns fewer than 3, the list pads with `get_recent_decisions()`.
|
|
361
|
+
New response field `focus_source` (`"open_changeset:<id>"`, `"next_action"`,
|
|
362
|
+
or `null`) lets the agent see *why* it got these decisions.
|
|
363
|
+
|
|
364
|
+
- **Smarter `search_decisions()` ranking**. SQL now adds `file_path` to both
|
|
365
|
+
the WHERE clause and a CASE-based ORDER BY:
|
|
366
|
+
`file_path match (0) > decision text (1) > context (2) > summary-only (3)`,
|
|
367
|
+
then newest first within each tier. Searching for `"src/auth.py"` now
|
|
368
|
+
surfaces file-path matches even when the decision text doesn't mention
|
|
369
|
+
the path.
|
|
370
|
+
|
|
371
|
+
- **Decision dedup on write**. `log_session()` now skips a new decision
|
|
372
|
+
if it has a `file_path` and its token-set overlaps ≥ 80% with any of
|
|
373
|
+
the 5 most recent decisions for that same file. The session row is
|
|
374
|
+
always created; only redundant *decisions* are dropped. Short
|
|
375
|
+
decisions (< 3 tokens) and decisions without `file_path` are always
|
|
376
|
+
inserted.
|
|
377
|
+
|
|
378
|
+
### Added
|
|
379
|
+
|
|
380
|
+
- `focus_source` field on `get_session_context()` response (≈10 tokens).
|
|
381
|
+
- `mcp_server.tools.learning._infer_focus()` — pure helper, module-private.
|
|
382
|
+
- `indexer.sqlite_graph._is_duplicate()` — pure token-overlap helper,
|
|
383
|
+
module-private, independently testable.
|
|
384
|
+
- **`codevira configure`** — new CLI subcommand. Scans your project
|
|
385
|
+
(gitignore-aware via existing `discover_source_files()`), shows discovered
|
|
386
|
+
directories and file extensions with counts, lets you pick via a numbered-
|
|
387
|
+
list prompt, writes the choices back to `.codevira/config.yaml`, and offers
|
|
388
|
+
to rebuild the index. Non-interactive:
|
|
389
|
+
`codevira configure --dirs src,lib --extensions .py,.ts --no-reindex`.
|
|
390
|
+
Solves the AgentStore-style "0 chunks indexed" case where
|
|
391
|
+
`auto_detect_project()` mis-guesses a monorepo layout.
|
|
392
|
+
When `config.yaml` is missing (normal state after `codevira register` but
|
|
393
|
+
before the first MCP tool call), `configure` auto-bootstraps it in full
|
|
394
|
+
parity with `auto_init`'s first-init path: writes `metadata.json` (rename-
|
|
395
|
+
resilient lookup via `git_remote`) and registers the project in
|
|
396
|
+
`~/.codevira/global.db` for cross-project intelligence. Missing these on
|
|
397
|
+
earlier drafts would have left the project invisible to rename-resilient
|
|
398
|
+
path lookup and absent from global memory until the first session log.
|
|
399
|
+
- **Zero-chunks safety hint at index time.** When `codevira index --full` or
|
|
400
|
+
`codevira index` (incremental, project-wide) matches no files against your
|
|
401
|
+
`watched_dirs` + `file_extensions`, the indexer now prints a one-line
|
|
402
|
+
remedy pointing at `codevira configure`. Output goes to **stderr** (not
|
|
403
|
+
stdout) so the hint never leaks into the MCP JSON-RPC wire when
|
|
404
|
+
`start_background_full_index` runs during auto_init inside the MCP server
|
|
405
|
+
process. Also logged at WARNING level so background invocations
|
|
406
|
+
(auto-init, launchd watcher) leave a trace regardless of terminal
|
|
407
|
+
capture. Does NOT fire for caller-scoped incremental runs (e.g. the
|
|
408
|
+
`refresh_index` MCP tool targeting a specific file) — zero matches there
|
|
409
|
+
is the caller's choice, not a misconfiguration.
|
|
410
|
+
- `codevira register` success banner now nudges toward `codevira configure`.
|
|
411
|
+
|
|
412
|
+
### Internal
|
|
413
|
+
|
|
414
|
+
- 87 new tests:
|
|
415
|
+
- 34 for v1.8 memory sharpening (focus inference priority rules, ranking
|
|
416
|
+
tier ordering, dedup threshold behaviour, session-row-always-created
|
|
417
|
+
invariant, NULL file_path fallback, session_id filtering + new ranking SQL)
|
|
418
|
+
- 43 for `codevira configure` (scan_project with centralized-mode
|
|
419
|
+
decoupling + skip_dirs honoring, multi-select prompt incl. non-TTY
|
|
420
|
+
fallback + Ctrl+C clean-abort, config writer preserve/dedupe/idempotency,
|
|
421
|
+
orchestrator edge cases incl. bootstrap on missing config, dry-run disk
|
|
422
|
+
safety, corrupt-YAML handling, empty-extensions safety, PermissionError
|
|
423
|
+
friendly wrapper, `--dirs`/`--extensions` normalization)
|
|
424
|
+
- 10 for the zero-chunks hint (unit tests of the helper proving it writes
|
|
425
|
+
to stderr not stdout + integration tests proving it fires ONLY for full
|
|
426
|
+
or project-wide-incremental scans, not caller-scoped or normal "no files
|
|
427
|
+
changed")
|
|
428
|
+
- Full test suite: **1,398 passing, 0 deterministic failures** (up from
|
|
429
|
+
1,306 at v1.7.1 → +92). The two "pre-existing watchdog failures" that
|
|
430
|
+
haunted earlier drafts of this CHANGELOG turned out to be an environment
|
|
431
|
+
issue in a single dev machine (system Python 3.9 without `watchdog`);
|
|
432
|
+
the pipx-installed v1.8.0 environment has all required deps. The one
|
|
433
|
+
pre-existing flaky test (`test_concurrent_access_from_threads`) is now
|
|
434
|
+
fixed by the `GlobalDB` WAL-enable retry loop described above.
|
|
435
|
+
|
|
436
|
+
### Verified environments
|
|
437
|
+
|
|
438
|
+
- **macOS (APFS)** + Python 3.9 system + Python 3.11 pipx: full regression
|
|
439
|
+
passes; all interactive + non-interactive flows manually verified on three
|
|
440
|
+
real projects (AgentStore, UDAP, ToolsConnector).
|
|
441
|
+
- **Cross-process + thread concurrency**: stress-tested (12 threads × 20
|
|
442
|
+
writes, 8 subprocesses × 25 writes, 100 concurrent-read/write cycles) —
|
|
443
|
+
0 errors, 0 data loss.
|
|
444
|
+
|
|
445
|
+
### Unverified environments / known gaps (candidates for v1.8.1 or v1.9)
|
|
446
|
+
|
|
447
|
+
- **Windows**: `os.replace` atomicity weakens when the destination is open
|
|
448
|
+
by another process. If a Windows user has Claude Code reading
|
|
449
|
+
`config.yaml` at the moment `codevira configure` writes it, the write
|
|
450
|
+
may fail with `PermissionError`. Pre-existing risk; v1.8 does not fix
|
|
451
|
+
and does not regress. Windows smoke-testing is a v1.9 scope item.
|
|
452
|
+
- **Network filesystems (NFS, SMB)**: atomic-replace guarantees are weaker
|
|
453
|
+
on network FS. Unlikely in solo-dev environments (codevira's target);
|
|
454
|
+
possible in enterprise setups.
|
|
455
|
+
- **Python 3.10, 3.12**: The APIs `codevira configure` uses are stable
|
|
456
|
+
across 3.10+. Syntax-verified against 3.10+. **Python 3.13.7
|
|
457
|
+
empirically verified** during v1.8 install validation (full pipx
|
|
458
|
+
install + MCP handshake working). 3.10 and 3.12 are syntax-verified
|
|
459
|
+
only. CI on all Python versions is a v1.8.x task.
|
|
460
|
+
- **Case-insensitive filesystem slugs**: On macOS APFS (default), paths
|
|
461
|
+
differing only in case (`~/Documents` vs `~/documents`) produce
|
|
462
|
+
different slugs for the same physical directory, creating split state.
|
|
463
|
+
Pre-existing since v1.5 — fixing requires a migration step for existing
|
|
464
|
+
users and is scoped to v1.9.
|
|
465
|
+
- **Interactive TTY automated coverage**: The interactive prompt flow is
|
|
466
|
+
tested via mocked stdin + `sys.stdin.isatty`. A real terminal session
|
|
467
|
+
was manually verified during development; automated TTY testing (via
|
|
468
|
+
pexpect or similar) is a v1.8.x nice-to-have.
|
|
469
|
+
- **MCP client post-upgrade reload**: `codevira register` writes config;
|
|
470
|
+
each MCP client (Claude Code, Cursor, Windsurf, Antigravity, Claude
|
|
471
|
+
Desktop) needs to reload to see changes. Verified for Claude Code.
|
|
472
|
+
Other clients may have edge cases that surface post-release.
|
|
473
|
+
|
|
474
|
+
### Known test flake (NOT v1.8; pre-existing)
|
|
475
|
+
|
|
476
|
+
- `test_chunk_error_continues_to_next_file` fails ~3/10 times in the full
|
|
477
|
+
suite on Python 3.9 (system) due to a chromadb+pydantic version
|
|
478
|
+
incompatibility raising `TypeError` during `import chromadb`, which
|
|
479
|
+
`_check_search_deps()` doesn't catch (it only catches `ImportError`).
|
|
480
|
+
**Not introduced by v1.8 and not touched by v1.8 code paths** — verified
|
|
481
|
+
by measuring the same 3/10 flake rate on clean v1.7.1. v1.8 deliberately
|
|
482
|
+
does not widen the exception catch because it would silently mask real
|
|
483
|
+
dep issues; a proper fix belongs in a targeted follow-up PR with its own
|
|
484
|
+
test coverage. Does not affect production users — the condition requires
|
|
485
|
+
a specific dev environment (Py 3.9 + mismatched chromadb/pydantic).
|
|
486
|
+
- Regression guards added by the binocular review pass:
|
|
487
|
+
- `test_centralized_mode_data_dir_and_project_root_decoupled` — catches
|
|
488
|
+
the production bug where `data_dir.parent` was used where
|
|
489
|
+
`get_project_root()` was required (centralized mode v1.6+).
|
|
490
|
+
- `test_bootstraps_config_when_missing` — catches the workflow where
|
|
491
|
+
`codevira register` was run but config.yaml hasn't been written yet
|
|
492
|
+
(auto_init hadn't fired because no MCP tool call had happened).
|
|
493
|
+
- `test_bootstrap_respects_dry_run` — catches bootstrap writing disk
|
|
494
|
+
during `--dry-run`.
|
|
495
|
+
- `test_fires_on_stderr_when_not_quiet` — catches zero-chunks hint
|
|
496
|
+
leaking to stdout, which would corrupt the MCP JSON-RPC wire in stdio
|
|
497
|
+
mode.
|
|
498
|
+
- `test_empty_extensions_non_interactive_errors_exit_2` — catches
|
|
499
|
+
`--extensions ""` being silently accepted, which would write an empty
|
|
500
|
+
`file_extensions: []` and re-create the zero-chunks bug.
|
|
501
|
+
- `test_ctrl_c_in_prompt_returns_exit_0` — catches KeyboardInterrupt
|
|
502
|
+
propagating a traceback to the user.
|
|
503
|
+
- `test_permission_error_on_write_exits_1` — catches PermissionError /
|
|
504
|
+
OSError propagating a traceback when config.yaml isn't writable.
|
|
505
|
+
- `test_honors_user_skip_dirs_from_config` — catches scan_project
|
|
506
|
+
ignoring the user's explicit skip_dirs in config.yaml.
|
|
507
|
+
|
|
508
|
+
### Known limitations
|
|
509
|
+
|
|
510
|
+
- A running file-watcher or live MCP server session won't pick up config
|
|
511
|
+
changes until it restarts (the watcher snapshots `watched_dirs` at boot).
|
|
512
|
+
Restart your AI tool after `codevira configure` to apply changes.
|
|
513
|
+
- `yaml.safe_dump` doesn't preserve comments in `config.yaml`. First-time
|
|
514
|
+
configs are auto-generated and have no comments; users who hand-edited
|
|
515
|
+
may see formatting normalized after `codevira configure` rewrites the file.
|
|
516
|
+
|
|
517
|
+
### Unchanged (intentionally)
|
|
518
|
+
|
|
519
|
+
- No new MCP tools. No new tables. No schema migration.
|
|
520
|
+
- `search_decisions()` method signature unchanged.
|
|
521
|
+
- `log_session()` method signature unchanged.
|
|
522
|
+
- `get_session_context()` keys are additive — no removals.
|
|
523
|
+
- `auto_init.py`, `detect.py`, `gitignore.py`, and `metadata.json` writer
|
|
524
|
+
untouched; `codevira configure` reuses all existing detection machinery.
|
|
525
|
+
|
|
14
526
|
---
|
|
15
527
|
|
|
16
528
|
## [1.7.1] — 2026-04-22 — Search Timeout Fix & Version Display
|