Skip to content

feat(install): add --project flag for per-project CMM installation#63

Open
halindrome wants to merge 10 commits intoDeusData:mainfrom
halindrome:feat/project-install
Open

feat(install): add --project flag for per-project CMM installation#63
halindrome wants to merge 10 commits intoDeusData:mainfrom
halindrome:feat/project-install

Conversation

@halindrome
Copy link

Summary

  • Add --project [path] flag to install command for project-local .mcp.json registration
  • Add claudeConfigDir() helper that respects CLAUDE_CONFIG_DIR env var (non-default Claude Code config paths)
  • Add uninstall --project [path] to cleanly remove project-local registration
  • Add ConfigMetricsPath config key so per-project installs accumulate token savings independently
  • Add CODEBASE_MEMORY_DB_DIR env var override for per-project database location

Dependency

⚠️ This PR depends on PR #61 (feat/token-savings-estimation). It builds on initMetricsTracker(), ConfigMetricsEnabled, and the metrics infrastructure introduced there. Merge #61 first, then this PR will rebase cleanly.

Behavior

  • codebase-memory-mcp install --project — writes .mcp.json in CWD, installs global skills, skips editor registrations
  • codebase-memory-mcp install --project /path/to/repo — same, with explicit path
  • codebase-memory-mcp install --project --dry-run — previews without writing
  • codebase-memory-mcp uninstall --project [path] — removes entry from project .mcp.json, preserves other servers
  • Global install (no --project) is fully unchanged

Test plan

  • TestCLI_InstallProject — .mcp.json written, skills global, no editor registrations
  • TestCLI_InstallProjectDryRun — no file created in dry-run
  • TestCLI_UninstallProject — .mcp.json removed (single-entry)
  • TestCLI_UninstallProjectPreservesOtherServers — selective removal
  • TestCLI_InstallCLAUDE_CONFIG_DIR — skills under custom dir
  • TestCacheDir_EnvOverride — CODEBASE_MEMORY_DB_DIR override
  • TestCacheDir_Default — default cache path
  • TestInitMetricsTracker/custom_metrics_path — ConfigMetricsPath override
  • All existing 10 CLI tests still pass
  • Full go test ./... passes (14 packages)
  • go vet clean

QA rounds

2 QA rounds completed per CONTRIBUTING.md process:

🤖 Generated with Claude Code

shanemccarron-maker and others added 10 commits March 15, 2026 12:05
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extract metrics block into searchResultWithMeta to reduce cognitive
complexity. Add TestGetCodeSnippet_MetaField to snippet_test.go.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Adds TestSearchGraph_MetaField in internal/tools/search_test.go
- Verifies _meta field is present in search_graph response when metricsTracker is attached
- Asserts tokens_saved >= 0, baseline_tokens >= 0 (may be 0 for test fixtures), response_tokens > 0

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix DeusData#1: EstimateTokens comment says "bytes" not "characters" (accurate)
- Fix DeusData#3: Unexport Tracker fields (InstallID, TotalTokensSaved, TotalCostAvoided)
  to prevent unsynchronized access; use Snapshot() instead
- Fix DeusData#6: Add priceForConfig test covering all 4 pricing branches
- Fix DeusData#7: Add initMetricsTracker test (default enabled + disabled via config)
- Fix DeusData#8: Rename CompressionRatio → ReductionRatio (ratio < 1 = reduction,
  > 1 = expansion — semantically clearer)
- Fix DeusData#10: Add GetFloat64 unit test for config store
- Design choice comment: document which tools are instrumented and why others
  are intentionally excluded from _meta

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ject metrics path

- Add claudeConfigDir() helper (respects CLAUDE_CONFIG_DIR env var, defaults to ~/.claude)
- Update installSkills/removeClaudeSkills to use claudeConfigDir() instead of hardcoded ~/.claude
- Add --project flag to runInstall: writes project-local .mcp.json, skips global editor registrations
- Add writeProjectMCPJSON() to upsert mcpServers entry in project root .mcp.json
- Add store.ConfigMetricsPath constant ("metrics_path") to internal/store/config.go
- Update initMetricsTracker to read ConfigMetricsPath from config; falls back to global savings.json
- Add CODEBASE_MEMORY_DB_DIR env override to cacheDir() in internal/store/store.go
- Fix testEnvWithHome in cli_test.go to strip CLAUDE_CONFIG_DIR so tests are hermetic

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…overage

- Fix DeusData#4: Add `uninstall --project [path]` to remove project-local .mcp.json
  entry. Removes file entirely when no other servers remain; preserves other
  entries when present.
- Fix DeusData#5: Add test coverage for all new code paths:
  - TestCLI_InstallProject: verifies .mcp.json written, skills global, no
    editor registrations
  - TestCLI_InstallProjectDryRun: verifies no file created
  - TestCLI_UninstallProject: verifies .mcp.json removed
  - TestCLI_UninstallProjectPreservesOtherServers: verifies selective removal
  - TestCLI_InstallCLAUDE_CONFIG_DIR: verifies skills under custom dir
  - TestCacheDir_EnvOverride: verifies CODEBASE_MEMORY_DB_DIR override
  - TestCacheDir_Default: verifies default path
  - TestInitMetricsTracker custom_metrics_path: verifies ConfigMetricsPath

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants