carto-md 2.0.8 → 2.1.0
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.
- package/CONTRIBUTING.md +19 -15
- package/README.md +203 -286
- package/docs/anci/v0.1-DRAFT.md +420 -0
- package/docs/api/README.md +99 -0
- package/docs/api/did_we_discuss_this.md +34 -0
- package/docs/api/dismiss_suggestion.md +34 -0
- package/docs/api/explain_change_in_natural_language.md +33 -0
- package/docs/api/find_consumers_of_api.md +34 -0
- package/docs/api/get_action_patterns.md +32 -0
- package/docs/api/get_active_drift.md +32 -0
- package/docs/api/get_active_suggestions.md +25 -0
- package/docs/api/get_ai_cost_attribution.md +32 -0
- package/docs/api/get_arch_events.md +42 -0
- package/docs/api/get_architectural_drift.md +37 -0
- package/docs/api/get_architecture.md +25 -0
- package/docs/api/get_blast_radius.md +34 -0
- package/docs/api/get_canonical_pattern.md +39 -0
- package/docs/api/get_change_plan.md +34 -0
- package/docs/api/get_change_velocity.md +32 -0
- package/docs/api/get_churn_vs_blast_radius.md +32 -0
- package/docs/api/get_complexity_trend.md +39 -0
- package/docs/api/get_context.md +34 -0
- package/docs/api/get_conventions.md +32 -0
- package/docs/api/get_cross_domain.md +25 -0
- package/docs/api/get_cross_language_call_graph.md +25 -0
- package/docs/api/get_cross_repo_blast_radius.md +34 -0
- package/docs/api/get_cross_team_coupling.md +25 -0
- package/docs/api/get_data_flow.md +33 -0
- package/docs/api/get_dead_code_with_confidence.md +32 -0
- package/docs/api/get_decision_log.md +32 -0
- package/docs/api/get_dependency_surface.md +25 -0
- package/docs/api/get_domain.md +34 -0
- package/docs/api/get_domain_evolution.md +39 -0
- package/docs/api/get_domain_health.md +32 -0
- package/docs/api/get_domains_list.md +25 -0
- package/docs/api/get_drift_digest.md +32 -0
- package/docs/api/get_env_vars.md +32 -0
- package/docs/api/get_evolution_delta.md +36 -0
- package/docs/api/get_file_ownership.md +33 -0
- package/docs/api/get_file_summary.md +34 -0
- package/docs/api/get_high_impact_files.md +32 -0
- package/docs/api/get_hot_in_prod_no_tests.md +34 -0
- package/docs/api/get_hotspot_files.md +37 -0
- package/docs/api/get_iac_resources.md +25 -0
- package/docs/api/get_interface_contract.md +33 -0
- package/docs/api/get_intervention_history.md +32 -0
- package/docs/api/get_invariants.md +37 -0
- package/docs/api/get_llm_enrichment.md +33 -0
- package/docs/api/get_microservice_cut_points.md +32 -0
- package/docs/api/get_microservices_migration_cut_points.md +25 -0
- package/docs/api/get_minimal_context_for_intent.md +39 -0
- package/docs/api/get_models.md +32 -0
- package/docs/api/get_neighbors.md +39 -0
- package/docs/api/get_org_architecture.md +25 -0
- package/docs/api/get_org_domain_mapping.md +25 -0
- package/docs/api/get_pending_decisions.md +32 -0
- package/docs/api/get_predictive_risk.md +32 -0
- package/docs/api/get_progressive_disclosure_tree.md +25 -0
- package/docs/api/get_recent_decisions.md +37 -0
- package/docs/api/get_risk_weighted_blast_radius.md +32 -0
- package/docs/api/get_routes.md +25 -0
- package/docs/api/get_safety_checklist.md +33 -0
- package/docs/api/get_semantic_diff.md +34 -0
- package/docs/api/get_service_boundary_violations.md +25 -0
- package/docs/api/get_service_dependency_graph.md +25 -0
- package/docs/api/get_session_context.md +32 -0
- package/docs/api/get_similar_patterns.md +39 -0
- package/docs/api/get_stale_docs.md +25 -0
- package/docs/api/get_structure.md +25 -0
- package/docs/api/get_temporal_context.md +34 -0
- package/docs/api/get_test_coverage_map.md +25 -0
- package/docs/api/get_token_budget_report.md +36 -0
- package/docs/api/get_upgrade_risk.md +25 -0
- package/docs/api/get_working_memory.md +25 -0
- package/docs/api/ingest_otlp_traces.md +34 -0
- package/docs/api/scaffold_for_intent.md +34 -0
- package/docs/api/search_routes.md +34 -0
- package/docs/api/simulate_change_impact.md +37 -0
- package/docs/api/validate_change.md +39 -0
- package/docs/api/validate_diff.md +39 -0
- package/docs/concepts/anci.md +87 -0
- package/docs/concepts/blast-radius.md +66 -0
- package/docs/concepts/domains.md +91 -0
- package/docs/concepts/import-graph.md +102 -0
- package/docs/concepts/mcp-integration.md +148 -0
- package/docs/guides/adding-feature-safely.md +101 -0
- package/docs/guides/ci-integration.md +175 -0
- package/docs/guides/monorepo-setup.md +121 -0
- package/docs/guides/onboarding-new-engineer.md +121 -0
- package/docs/guides/pre-merge-review.md +139 -0
- package/docs/migration/v1-to-v2.md +110 -0
- package/docs/quickstart.md +95 -0
- package/docs/scale.md +129 -0
- package/docs/troubleshooting.md +180 -0
- package/package.json +12 -5
- package/scripts/gen-api-docs.js +170 -0
- package/scripts/postinstall.js +391 -24
- package/src/acp/agent.js +83 -11
- package/src/acp/config.js +64 -0
- package/src/acp/persistence.js +146 -0
- package/src/acp/providers/anthropic.js +179 -27
- package/src/acp/providers/index.js +15 -2
- package/src/acp/providers/openai.js +164 -38
- package/src/acp/providers/sse.js +82 -0
- package/src/acp/safety.js +128 -0
- package/src/acp/session.js +73 -0
- package/src/adjacent/call-graph.js +170 -0
- package/src/adjacent/iac.js +167 -0
- package/src/adjacent/llm-enrich.js +35 -0
- package/src/adjacent/runtime.js +216 -0
- package/src/adjacent/semantic-diff.js +143 -0
- package/src/agents/leiden.js +4 -4
- package/src/agents/scan-structure.js +2 -2
- package/src/ai/context-builder.js +215 -0
- package/src/ai/retrieval/lexical.js +122 -0
- package/src/ai/retrieval/rrf.js +121 -0
- package/src/ai/retrieval/semantic.js +35 -0
- package/src/ai/retrieval/structural.js +82 -0
- package/src/ai/tools.js +423 -0
- package/src/anci/consumer.js +305 -0
- package/src/anci/deserialize.js +160 -0
- package/src/anci/emit.js +85 -0
- package/src/anci/serialize.js +264 -0
- package/src/anci/yaml.js +401 -0
- package/src/bitmap/index.js +1 -1
- package/src/bitmap/tools.js +2 -2
- package/src/brain/conventions/index.js +185 -0
- package/src/brain/index.js +31 -0
- package/src/brain/invariants/index.js +252 -0
- package/src/brain/procedural/index.js +181 -0
- package/src/brain/suggestions/index.js +153 -0
- package/src/brain/working/index.js +170 -0
- package/src/cli/anci.js +237 -0
- package/src/cli/check.js +47 -1
- package/src/cli/diff.js +83 -0
- package/src/cli/doctor.js +270 -0
- package/src/cli/explain.js +61 -0
- package/src/cli/index.js +115 -0
- package/src/cli/init.js +144 -6
- package/src/cli/inspect.js +1 -1
- package/src/cli/org.js +172 -0
- package/src/cli/pr-impact.js +554 -0
- package/src/cli/serve.js +1 -1
- package/src/cli/status.js +211 -0
- package/src/cli/sync.js +2 -2
- package/src/cli/temporal.js +188 -0
- package/src/cli/validate.js +201 -0
- package/src/cli/watch.js +4 -4
- package/src/cli/why.js +101 -0
- package/src/extractors/frameworks.js +236 -0
- package/src/extractors/languages/dart.js +138 -0
- package/src/extractors/languages/go.js +11 -1
- package/src/extractors/languages/javascript.js +16 -6
- package/src/extractors/languages/kotlin.js +169 -0
- package/src/extractors/languages/php.js +195 -0
- package/src/extractors/languages/python.js +12 -1
- package/src/extractors/languages/swift.js +140 -0
- package/src/extractors/languages/typescript.js +15 -2
- package/src/extractors/plugin-api.js +102 -0
- package/src/mcp/change-plan.js +8 -8
- package/src/mcp/files-without-tests.js +285 -0
- package/src/mcp/middleware/index.js +451 -0
- package/src/mcp/server.js +2292 -0
- package/src/mcp/validate.js +1 -1
- package/src/org/detect.js +262 -0
- package/src/org/queries.js +144 -0
- package/src/org/store.js +173 -0
- package/src/org/sync.js +106 -0
- package/src/predictive/cut-points.js +83 -0
- package/src/predictive/drift-digest.js +88 -0
- package/src/predictive/ownership.js +145 -0
- package/src/predictive/risk-score.js +121 -0
- package/src/predictive/validate-change.js +55 -0
- package/src/store/store-adapter.js +3 -3
- package/src/store/{sync-v2.js → sync.js} +105 -16
- package/src/temporal/backfill.js +211 -0
- package/src/temporal/delta.js +85 -0
- package/src/temporal/events.js +180 -0
- package/src/temporal/queries.js +358 -0
- package/src/temporal/snapshot.js +151 -0
- package/src/temporal/store.js +400 -0
- package/src/mcp/server-v2.js +0 -986
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Guide: Pre-merge review
|
|
2
|
+
|
|
3
|
+
> Architecture review at PR time, automatically. The reviewer sees structural impact alongside the diff.
|
|
4
|
+
|
|
5
|
+
## What the GitHub Action does
|
|
6
|
+
|
|
7
|
+
On every pull request:
|
|
8
|
+
|
|
9
|
+
1. Checks out the PR head
|
|
10
|
+
2. Restores `.carto/` from `actions/cache` (or runs `carto init` cold)
|
|
11
|
+
3. Runs `carto pr-impact --base $BASE --head $HEAD --format markdown`
|
|
12
|
+
4. Posts the result as a sticky comment on the PR (one comment per PR, updated in place on every push)
|
|
13
|
+
|
|
14
|
+
The whole flow runs in 30–120 seconds on a warm cache, 1–3 minutes cold.
|
|
15
|
+
|
|
16
|
+
## Setup
|
|
17
|
+
|
|
18
|
+
In `.github/workflows/carto.yml`:
|
|
19
|
+
|
|
20
|
+
```yaml
|
|
21
|
+
name: Carto Impact Report
|
|
22
|
+
on:
|
|
23
|
+
pull_request:
|
|
24
|
+
branches: [main]
|
|
25
|
+
permissions:
|
|
26
|
+
contents: read
|
|
27
|
+
pull-requests: write
|
|
28
|
+
jobs:
|
|
29
|
+
carto:
|
|
30
|
+
runs-on: ubuntu-latest
|
|
31
|
+
steps:
|
|
32
|
+
- uses: actions/checkout@v4
|
|
33
|
+
with: { fetch-depth: 0 } # full history — pr-impact needs the base ref
|
|
34
|
+
- uses: theanshsonkar/carto@v2.0.9
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
That's the entire config. The action handles npm install, cache restore, sync, pr-impact, and the comment.
|
|
38
|
+
|
|
39
|
+
## What the comment looks like
|
|
40
|
+
|
|
41
|
+
```markdown
|
|
42
|
+
## 🗺️ Carto Impact Report
|
|
43
|
+
|
|
44
|
+
This PR touches **AUTH** and **DATABASE** domains.
|
|
45
|
+
|
|
46
|
+
| Metric | Value |
|
|
47
|
+
|--------|-------|
|
|
48
|
+
| Risk | 🔴 HIGH |
|
|
49
|
+
| Blast radius (union) | 47 files |
|
|
50
|
+
| Files changed | 6 |
|
|
51
|
+
| Cross-domain violations introduced | 2 |
|
|
52
|
+
| Files without tests in blast radius | 5 of 31 |
|
|
53
|
+
| High-impact file changed | src/auth/session.ts (8 direct dependents) |
|
|
54
|
+
|
|
55
|
+
<details>
|
|
56
|
+
<summary>Affected routes (4)</summary>
|
|
57
|
+
|
|
58
|
+
- POST /auth/login — risk: HIGH
|
|
59
|
+
- GET /auth/me — risk: HIGH
|
|
60
|
+
- POST /auth/register — risk: MEDIUM
|
|
61
|
+
- POST /api/users — risk: LOW
|
|
62
|
+
|
|
63
|
+
</details>
|
|
64
|
+
|
|
65
|
+
<details>
|
|
66
|
+
<summary>Cross-domain violations (2)</summary>
|
|
67
|
+
|
|
68
|
+
- auth/login.ts now imports from payments/billing.ts (AUTH→PAYMENTS)
|
|
69
|
+
- database/user-repo.ts now imports from auth/jwt.ts (DATABASE→AUTH)
|
|
70
|
+
|
|
71
|
+
</details>
|
|
72
|
+
|
|
73
|
+
<details>
|
|
74
|
+
<summary>Files without tests in blast radius (5)</summary>
|
|
75
|
+
|
|
76
|
+
- src/auth/middleware.ts
|
|
77
|
+
- src/auth/jwt-helpers.ts
|
|
78
|
+
- …
|
|
79
|
+
</details>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## What a reviewer does with this
|
|
83
|
+
|
|
84
|
+
Look at the four signals in order:
|
|
85
|
+
|
|
86
|
+
1. **Risk badge.** HIGH / MEDIUM / LOW / SAFE. If it's SAFE or LOW, you can mostly skip the structural review and focus on the code itself. If it's HIGH, look more carefully.
|
|
87
|
+
|
|
88
|
+
2. **Cross-domain violations.** Each one is a new dependency between domains. Sometimes correct (a refactor moving shared logic), sometimes a smell (auth pulling from payments). Reviewer applies judgment.
|
|
89
|
+
|
|
90
|
+
3. **Files without tests.** Files in the blast radius that don't have a sibling test file. Lower confidence in the change because there's no automated check. Suggest the author add tests, or document why not.
|
|
91
|
+
|
|
92
|
+
4. **High-impact file changed.** Anything modifying a >20-dependent file deserves an extra read-through. Subtle changes to a widely-used utility have outsized blast.
|
|
93
|
+
|
|
94
|
+
## Failing the build on risk
|
|
95
|
+
|
|
96
|
+
For repos that want a harder gate, set `fail-on` in the workflow:
|
|
97
|
+
|
|
98
|
+
```yaml
|
|
99
|
+
- uses: theanshsonkar/carto@v2.0.9
|
|
100
|
+
with:
|
|
101
|
+
fail-on: HIGH
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Now the build fails when the risk is HIGH. PRs need to lower the risk (split, add tests, refactor) before they can merge.
|
|
105
|
+
|
|
106
|
+
Use sparingly. HIGH-risk changes are sometimes correct and *necessary* — the right reviewer call is "look more carefully", not "block automatically".
|
|
107
|
+
|
|
108
|
+
## Inputs reference
|
|
109
|
+
|
|
110
|
+
| Input | Default | What it does |
|
|
111
|
+
|---------------|-------------|--------------|
|
|
112
|
+
| `carto-version` | `latest` | Pin in production for reproducibility. |
|
|
113
|
+
| `base` | auto | Git ref the PR branched from. Auto-detected from `origin/$GITHUB_BASE_REF`. |
|
|
114
|
+
| `head` | auto | Git ref of the PR head. Auto-detected from `$GITHUB_SHA`. |
|
|
115
|
+
| `fail-on` | _(empty)_ | Fail when risk ≥ this severity. `HIGH`, `MEDIUM`, or `LOW`. |
|
|
116
|
+
| `comment-mode`| `sticky` | `sticky` updates existing comment, `new` posts a new one every push, `none` skips the comment (renders to stdout). |
|
|
117
|
+
| `node-version`| `20` | Node version on the runner. |
|
|
118
|
+
|
|
119
|
+
## Outputs
|
|
120
|
+
|
|
121
|
+
| Output | Description |
|
|
122
|
+
|--------------|-------------|
|
|
123
|
+
| `risk` | `SAFE` / `LOW` / `MEDIUM` / `HIGH` — gate downstream steps on it. |
|
|
124
|
+
| `comment-url`| URL of the posted comment. |
|
|
125
|
+
|
|
126
|
+
## Running it locally (mirror the CI)
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
carto pr-impact --base origin/main --head HEAD
|
|
130
|
+
carto pr-impact --base origin/main --head HEAD --format json
|
|
131
|
+
carto pr-impact --base origin/main --head HEAD --fail-on HIGH
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Same engine, same output. Useful for testing changes before pushing.
|
|
135
|
+
|
|
136
|
+
## Related
|
|
137
|
+
|
|
138
|
+
- [`docs/guides/ci-integration.md`](./ci-integration.md) — broader CI patterns
|
|
139
|
+
- [`docs/concepts/blast-radius.md`](../concepts/blast-radius.md) — the math behind the metric
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Migration: V1 → V2
|
|
2
|
+
|
|
3
|
+
> Notes for anyone who installed `carto-md` pre-2.0.6.
|
|
4
|
+
|
|
5
|
+
## What V2 changed
|
|
6
|
+
|
|
7
|
+
V1 stored the index as JSON files at `.carto/cache/graph-cache.json` and `.carto/cache/hashes.json`. V2 stores it as SQLite at `.carto/carto.db` with a derived bitmap sidecar at `.carto/bitmap.bin`.
|
|
8
|
+
|
|
9
|
+
Why: SQLite handles 100K-file repos cleanly where the JSON approach started getting slow at ~10K files. The bitmap layer makes graph queries 100–10,000× faster than SQL at scale (see [`docs/scale.md`](../scale.md)).
|
|
10
|
+
|
|
11
|
+
V1 has been fully deleted from the tree as of carto-md@2.0.6.
|
|
12
|
+
|
|
13
|
+
## What you need to do
|
|
14
|
+
|
|
15
|
+
In most cases — nothing. `carto init` (or any `carto` command that touches the index) detects the old V1 cache files and migrates them transparently on first run.
|
|
16
|
+
|
|
17
|
+
Specifically, the migration:
|
|
18
|
+
|
|
19
|
+
1. Reads `.carto/cache/graph-cache.json` if present (V1 metadata)
|
|
20
|
+
2. Notices it's incompatible with the V2 schema
|
|
21
|
+
3. Runs a fresh `carto sync` to repopulate `.carto/carto.db` from source
|
|
22
|
+
4. Leaves the V1 files in place (they're harmless dead bytes)
|
|
23
|
+
|
|
24
|
+
The Spec 7 test suite explicitly covers this case: *"carto init migrates leftover V1 graph-cache.json cleanly (no errors)"*.
|
|
25
|
+
|
|
26
|
+
## Manual cleanup (optional)
|
|
27
|
+
|
|
28
|
+
After the first V2 sync succeeds, the V1 files are no longer read. Reclaim a bit of disk:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
rm -f .carto/cache/graph-cache.json
|
|
32
|
+
rm -f .carto/cache/hashes.json
|
|
33
|
+
rmdir .carto/cache # if empty
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Or just `carto remove && carto init` for a clean slate.
|
|
37
|
+
|
|
38
|
+
## MCP wiring changes
|
|
39
|
+
|
|
40
|
+
V1 exposed 12 MCP tools. V2 ships ~75, organized into 8 categories (core graph, episodic memory, temporal, brain, predictive, AI-native retrieval, adjacent, org-wide).
|
|
41
|
+
|
|
42
|
+
The highest-impact additions from V1:
|
|
43
|
+
|
|
44
|
+
- `get_architecture()` — the "use this first" tool
|
|
45
|
+
- `get_file_summary(file)` — surfaces what `carto why` shows
|
|
46
|
+
- `get_change_plan(intent)` — real graph traversal (V1 was keyword grep — Spec 2 rewrite)
|
|
47
|
+
- `get_similar_patterns(file)` — Jaccard-similarity over import sets
|
|
48
|
+
- `validate_diff(diff)` — sub-15ms pre-write governance, writes every call into the episodic log
|
|
49
|
+
- `did_we_discuss_this(topic)` — six-week recall over the decision log
|
|
50
|
+
- `get_predictive_risk(file?)` — P(file causes the next incident) score
|
|
51
|
+
- `get_minimal_context_for_intent(intent, budget)` — token-budgeted hybrid retrieval (structural + lexical + semantic with RRF fusion)
|
|
52
|
+
- `simulate_change_impact(files)` — bitmap-backed multi-file blast radius
|
|
53
|
+
|
|
54
|
+
Plus the temporal trio (`get_architectural_drift`, `get_domain_evolution`, `get_hotspot_files`), the brain stack (`get_invariants`, `get_conventions`, `get_action_patterns`, `scaffold_for_intent`), and the org/cross-repo set (`get_org_architecture`, `get_service_dependency_graph`, `find_consumers_of_api`).
|
|
55
|
+
|
|
56
|
+
Full reference: [`docs/api/`](../api/).
|
|
57
|
+
|
|
58
|
+
If your AI tool was configured against V1 and you're seeing tool-not-found errors, restart the tool to pick up the V2 server's new `tools/list` response. The wire protocol is the same.
|
|
59
|
+
|
|
60
|
+
## ACP agent
|
|
61
|
+
|
|
62
|
+
V1's ACP agent (in Zed / JetBrains / VS Code via `carto agent`) used its own in-memory index. V2's ACP agent shares the SQLite index with the MCP server (Spec 5). Re-running `carto init` in your project ensures both ACP and MCP see the same data.
|
|
63
|
+
|
|
64
|
+
## `.cartoignore` defaults
|
|
65
|
+
|
|
66
|
+
V2 expanded the default exclusion list from 12 patterns to 39 (Spec 8: SSH keys, AWS/GCP creds, `.netrc`, kubeconfig, etc.). If your project had a custom `.cartoignore`, it's preserved — Carto only writes a default when none exists. To pick up the new defaults, delete your `.cartoignore` and run `carto init` to regenerate.
|
|
67
|
+
|
|
68
|
+
## Git hooks
|
|
69
|
+
|
|
70
|
+
V1 didn't install git hooks. V2 (Spec 9) installs four:
|
|
71
|
+
|
|
72
|
+
- `pre-commit`
|
|
73
|
+
- `post-checkout`
|
|
74
|
+
- `post-merge`
|
|
75
|
+
- `post-rewrite`
|
|
76
|
+
|
|
77
|
+
Each runs `carto sync >/dev/null 2>&1 || true` — never blocks git, never errors loudly. If you already have hooks for other purposes, Carto appends to them non-destructively. Run `carto doctor` to confirm the hooks installed.
|
|
78
|
+
|
|
79
|
+
## Behavior changes worth flagging
|
|
80
|
+
|
|
81
|
+
| Behavior | V1 | V2 |
|
|
82
|
+
|----------|----|----|
|
|
83
|
+
| File-discovery cap | hard cap at ~50K files | uncapped |
|
|
84
|
+
| Index format | JSON | SQLite + bitmap |
|
|
85
|
+
| Re-parse on edit | only via `carto watch` | lazy at MCP query time + git hooks |
|
|
86
|
+
| `get_change_plan` | keyword grep | real graph traversal |
|
|
87
|
+
| Cross-domain detection | path-based | graph-clustered |
|
|
88
|
+
| ACP / MCP share index | no | yes |
|
|
89
|
+
| Read-only MCP DB | no | yes |
|
|
90
|
+
| Default `.cartoignore` | 12 patterns | 39 patterns |
|
|
91
|
+
|
|
92
|
+
If you depended on a V1-specific behavior that's no longer accurate, file an issue — we may have broken something we shouldn't have.
|
|
93
|
+
|
|
94
|
+
## Pinned-version recommendation
|
|
95
|
+
|
|
96
|
+
If you're upgrading in CI, pin a known-good Carto version:
|
|
97
|
+
|
|
98
|
+
```yaml
|
|
99
|
+
# .github/workflows/carto.yml
|
|
100
|
+
- uses: theanshsonkar/carto@v2.0.9
|
|
101
|
+
with:
|
|
102
|
+
carto-version: '2.0.9' # pin instead of `latest`
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
This way the action's output (and the PR-comment shape) stays stable across CI runs even when newer Carto versions ship.
|
|
106
|
+
|
|
107
|
+
## Related
|
|
108
|
+
|
|
109
|
+
- [`docs/troubleshooting.md`](../troubleshooting.md) — what to do when migration goes sideways
|
|
110
|
+
- [Spec 6](../../Progress/working.md) in `Progress/working.md` — the deletion that removed V1
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Quickstart — 10 minutes from install to first MCP query
|
|
2
|
+
|
|
3
|
+
Get carto wired into your AI tool and answering questions about your codebase in under ten minutes.
|
|
4
|
+
|
|
5
|
+
## 1. Install (30 seconds)
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g carto-md
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Carto ships prebuilt native binaries for macOS arm64/x64, Linux x64 (glibc + musl), and Windows x64. If you're on a platform without prebuilds you'll fall back to compiling from source — see [troubleshooting.md](./troubleshooting.md#native-build-fails) if that breaks.
|
|
12
|
+
|
|
13
|
+
Verify the install:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
carto --version
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## 2. Index your project (1 minute)
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
cd ~/your-project
|
|
23
|
+
carto init
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
You'll see something like:
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
[CARTO] Detecting project...
|
|
30
|
+
[CARTO] Detected: nextjs (typescript)
|
|
31
|
+
[CARTO] Found 847 JS/TS files (847 total)
|
|
32
|
+
[CARTO] Discovered 847 source files
|
|
33
|
+
[CARTO] Computing reverse dependencies...
|
|
34
|
+
[CARTO] Indexed 847 files in 1.8s
|
|
35
|
+
[CARTO] MCP auto-wired into: Cursor, Claude Code, Kiro
|
|
36
|
+
[CARTO] AGENTS.md generated.
|
|
37
|
+
|
|
38
|
+
┌─ Carto · indexed ─────────────────────────────────────────
|
|
39
|
+
│ 847 files · 5 domains · 23 routes · 1,204 import edges
|
|
40
|
+
│
|
|
41
|
+
│ Top domains:
|
|
42
|
+
│ CORE (677 files)
|
|
43
|
+
│ AUTH (42 files)
|
|
44
|
+
│ PAYMENTS (38 files)
|
|
45
|
+
│ DATABASE (67 files)
|
|
46
|
+
│
|
|
47
|
+
│ 💡 Highest-risk file: src/lib/db.ts
|
|
48
|
+
│ (34 files depend on it — try `carto why src/lib/db.ts`)
|
|
49
|
+
└───────────────────────────────────────────────────────────
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
What just happened:
|
|
53
|
+
|
|
54
|
+
- Carto walked the project, parsed every source file with tree-sitter
|
|
55
|
+
- Built an import graph, clustered files into domains (Leiden+CPM), extracted routes + models
|
|
56
|
+
- Wrote `.carto/` containing the SQLite index, the bitmap sidecar, the per-domain context files
|
|
57
|
+
- Wrote `AGENTS.md` at the project root
|
|
58
|
+
- Installed 4 git hooks so the index re-syncs on commit/checkout/merge/rebase
|
|
59
|
+
- Detected your installed AI tools and wrote MCP config files for each
|
|
60
|
+
|
|
61
|
+
## 3. Restart your AI tool
|
|
62
|
+
|
|
63
|
+
The MCP wiring lands when the AI tool starts fresh. Kill it and reopen, then verify carto loaded — most tools log MCP server connections.
|
|
64
|
+
|
|
65
|
+
## 4. Ask your first question
|
|
66
|
+
|
|
67
|
+
Open any prompt your AI tool exposes and try one of:
|
|
68
|
+
|
|
69
|
+
> *"What's the blast radius of `src/lib/db.ts`?"*
|
|
70
|
+
|
|
71
|
+
> *"Show me the architecture overview."*
|
|
72
|
+
|
|
73
|
+
> *"What files would I need to change to add rate limiting to /api/users?"*
|
|
74
|
+
|
|
75
|
+
The AI calls Carto's MCP tools (`get_blast_radius`, `get_architecture`, `get_change_plan`) and answers with structural facts instead of grepping.
|
|
76
|
+
|
|
77
|
+
## 5. Try the CLI too
|
|
78
|
+
|
|
79
|
+
While you're here:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
carto status # one-screen health view
|
|
83
|
+
carto why src/lib/db.ts # 3-line summary of a file
|
|
84
|
+
carto explain "add rate limiting" # natural-language → plan
|
|
85
|
+
carto check # cross-domain violations
|
|
86
|
+
carto doctor # diagnose any setup issues
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## What's next
|
|
90
|
+
|
|
91
|
+
- [`docs/concepts/blast-radius.md`](./concepts/blast-radius.md) — what "blast radius" means and how it's computed
|
|
92
|
+
- [`docs/concepts/domains.md`](./concepts/domains.md) — how the Leiden clusterer infers AUTH/PAYMENTS/etc. without config
|
|
93
|
+
- [`docs/concepts/mcp-integration.md`](./concepts/mcp-integration.md) — every MCP tool with an example call
|
|
94
|
+
- [`docs/guides/adding-feature-safely.md`](./guides/adding-feature-safely.md) — the workflow this whole thing enables
|
|
95
|
+
- [`docs/guides/ci-integration.md`](./guides/ci-integration.md) — drop the GitHub Action onto every PR
|
package/docs/scale.md
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Carto at scale
|
|
2
|
+
|
|
3
|
+
> Empirical scale data for the bitmap engine — synthetic stress sweep + every real-world repo in the Carto corpus. Reproducer commands at the bottom.
|
|
4
|
+
|
|
5
|
+
The bitmap-backed graph engine is designed to handle 100K-1M files cleanly. This page is the empirical receipt. It captures both the **dense-synth stress sweep** (deterministic worst-case fan-out distribution) and the **real-world corpus** (4 of the 7 larger repos, the largest open-source codebases under MIT/permissive licenses we routinely test against).
|
|
6
|
+
|
|
7
|
+
## What's measured
|
|
8
|
+
|
|
9
|
+
For each run we capture:
|
|
10
|
+
|
|
11
|
+
- **Init time** — full `runSync` from a wiped `.carto/` directory.
|
|
12
|
+
- **Sync time** — second `runSync` immediately after, no files changed (mtime+hash skip path).
|
|
13
|
+
- **DB size** — `.carto/carto.db` bytes on disk.
|
|
14
|
+
- **bitmap.bin size** — the sidecar bytes on disk.
|
|
15
|
+
- **Sidecar (RAM)** — sum of all bitmap word-array byte lengths held in memory.
|
|
16
|
+
- **Peak RSS** — process resident memory after init and during query workloads.
|
|
17
|
+
- **MCP query p50 / p99** — 1000 calls each (50-call warmup) for the 5 production bitmap tools (`blastRadius`, `crossDomain`, `highImpactFiles`, `similarPatterns`) plus `simulate_change_impact`. Random query inputs are seeded so identical `--seed` produces identical workloads.
|
|
18
|
+
|
|
19
|
+
The query stage opens SQLite **read-only** — invariant honored. The bitmap-as-derived-disposable invariant is also honored: the runner only reads from `bitmap.bin`, never writes.
|
|
20
|
+
|
|
21
|
+
All numbers below were captured on the maintainer dev box: Apple silicon, Node 20.20, macOS, NVMe SSD. Recapture via the commands at the bottom.
|
|
22
|
+
|
|
23
|
+
## Synthetic stress sweep (dense fan-out)
|
|
24
|
+
|
|
25
|
+
Source: `bench/scale-test/`. Generates a deterministic-for-seed TypeScript repo with a worst-case-shaped import graph: 5 domain-like top-level dirs (`auth`/`payments`/`database`/`events`/`core`), Pareto(α=2) fan-out clipped to [1,8], 75% same-domain / 25% cross-domain, hotspot-biased targets so the first ~10% of file ids accumulate most in-edges. Imports always reference an earlier file id (acyclic).
|
|
26
|
+
|
|
27
|
+
Edge density ≈ 1.5 per file. **This is denser than every real-world repo in the corpus** — real codebases have many leaf files with zero imports, so the synth deliberately exercises the worst case for the bitmap layer.
|
|
28
|
+
|
|
29
|
+
| Files | Edges | Init | Sync | DB | bitmap.bin | Sidecar (RAM) | Peak RSS |
|
|
30
|
+
|------:|------:|-----:|-----:|---:|-----------:|--------------:|---------:|
|
|
31
|
+
| 1,000 | 1,392 | 533ms | 70ms | 756 KB | 222 KB | 186 KB | 149 MB |
|
|
32
|
+
| 10,000 | 14,876 | 3.28s | 627ms | 6.5 MB | 17.0 MB | 18.1 MB | 350 MB |
|
|
33
|
+
| 50,000 | 76,145 | 1.1m | 5.14s | 36.9 MB | 414.9 MB | 488.4 MB | 1.35 GB |
|
|
34
|
+
|
|
35
|
+
| Files | blastRadius p50/p99 | crossDomain p50/p99 | highImpactFiles p50/p99 | similarPatterns p50/p99 | simulate_change_impact p50/p99 |
|
|
36
|
+
|------:|---------------------|---------------------|------------------------|------------------------|--------------------------------|
|
|
37
|
+
| 1,000 | 1.6µs / 24.4µs | 19.5µs / 25.0µs | 709ns / 4.3µs | 276µs / 484µs | 7.0µs / 78.8µs |
|
|
38
|
+
| 10,000 | 6.6µs / 67.7µs | 705µs / 914µs | 750ns / 1.4µs | 17.0ms / 19.3ms | 11.6µs / 113µs |
|
|
39
|
+
| 50,000 | 22.4µs / 472µs | 28.1ms / 28.9ms | 750ns / 1.3µs | 462ms / 798ms | 49.9µs / 455µs |
|
|
40
|
+
|
|
41
|
+
### What 50K reveals
|
|
42
|
+
|
|
43
|
+
Three distinct failure modes show up at the dense-synth 50K row, **all of them addressable by a Roaring-bitmap upgrade on the roadmap**:
|
|
44
|
+
|
|
45
|
+
1. **Storage scales linearly with N** — every file gets its own forward + reverse bitmap of size ~`N/8` bytes. At N=50K bitmap.bin is 415 MB; at N=100K linear extrapolation puts it at ~1.7 GB. The current pure-Node `Uint32Array` bitset (`src/bitmap/bitset.js`) trades storage efficiency for raw query speed and zero native deps. Roaring would cut this 5-50× depending on density.
|
|
46
|
+
2. **`crossDomain` p50 hits 28 ms** — linear sweep over the `crossForward` Map. Fixable with a precomputed cross-domain edge bitmap that's OR-aggregated once at build time, not iterated per query.
|
|
47
|
+
3. **`similarPatterns` p50 hits 462 ms** — Jaccard over import sets at scale costs O(candidates × set-intersection). The MCP layer calls this with `top_k=5` so user-facing latency is well under the raw bench number, but the absolute cost is real.
|
|
48
|
+
|
|
49
|
+
Three things stay healthy at 50K: `blastRadius` p50 22µs, `highImpactFiles` p50 750ns (popcount index is O(1) array slice), `simulate_change_impact` p50 50µs.
|
|
50
|
+
|
|
51
|
+
### Pending (not yet captured on this box)
|
|
52
|
+
|
|
53
|
+
| Files | Notes |
|
|
54
|
+
|------:|-------|
|
|
55
|
+
| 100,000 | Stress-test for the dense-bitset implementation. ~3-5 min walltime expected. Worth running before any Roaring work to lock in the regression baseline. |
|
|
56
|
+
| 500,000 | Practical ceiling for the dense-bitset; expect bitmap.bin > 4 GB, possibly hitting OOM on 16 GB-RAM dev boxes. |
|
|
57
|
+
| 1,000,000 | Roaring-bitmap upgrade target. Expect dense-bitset OOM. |
|
|
58
|
+
|
|
59
|
+
Reproducible via `npm run bench:scale -- --size 100000 --keep --out /tmp/carto-100k`.
|
|
60
|
+
|
|
61
|
+
## Real-world corpus
|
|
62
|
+
|
|
63
|
+
These are the 4 largest repos in `~/carto-test-repos`, all already indexed by `~/carto-test-repos/run-bench.sh` (the bench harness baseline). The query latency below was measured against those existing indexes via `--queries-only` so this measurement does not perturb the indexes used by `node test/accuracy-corpus.js`.
|
|
64
|
+
|
|
65
|
+
| Repo | Indexed files | Edges | DB | bitmap.bin | Sidecar (RAM) |
|
|
66
|
+
|------|--------------:|------:|---:|-----------:|--------------:|
|
|
67
|
+
| [cal.com](https://github.com/calcom/cal.com) | 4,351 | 3,478 | 3.1 MB | 1.9 MB | 2.0 MB |
|
|
68
|
+
| [nextjs](https://github.com/vercel/next.js) | 6,193 | 7,930 | 15.0 MB | 4.4 MB | 4.3 MB |
|
|
69
|
+
| [supabase](https://github.com/supabase/supabase) | 6,330 | 5,189 | 4.8 MB | 4.4 MB | 4.4 MB |
|
|
70
|
+
| [vscode](https://github.com/microsoft/vscode) | 7,567 | 13,335 | 14.3 MB | 4.1 MB | 4.5 MB |
|
|
71
|
+
|
|
72
|
+
| Repo | blastRadius p50/p99 | crossDomain p50/p99 | highImpactFiles p50/p99 | similarPatterns p50/p99 | simulate_change_impact p50/p99 |
|
|
73
|
+
|------|---------------------|---------------------|------------------------|------------------------|--------------------------------|
|
|
74
|
+
| cal.com | 4.3µs / 51µs | 148µs / 279µs | 667ns / 1.0µs | 1.0µs / 1.99ms | 10.3µs / 71.0µs |
|
|
75
|
+
| nextjs | 5.0µs / 155µs | 196µs / 284µs | 750ns / 1.3µs | 1.2µs / 3.01ms | 28.9µs / 211µs |
|
|
76
|
+
| supabase | 5.5µs / 47.9µs | 201µs / 260µs | 708ns / 1.0µs | 1.5µs / 3.19ms | 10.8µs / 65.9µs |
|
|
77
|
+
| vscode | 2.7µs / 428µs | 1.23ms / 1.47ms | 750ns / 1.7µs | 834ns / 4.03ms | 19.3µs / 637µs |
|
|
78
|
+
|
|
79
|
+
### Real-world vs dense-synth
|
|
80
|
+
|
|
81
|
+
The 7,567-file vscode row vs the 10,000-file synth row tells the most important story:
|
|
82
|
+
|
|
83
|
+
- vscode `similarPatterns` p50 is **834ns**; synth-10K is **17ms**. Real codebases have far sparser per-file import sets — most files import 0-3 things, a handful import many. Synth is a deliberate worst case (Pareto fan-out always ≥1, often 4-8). Real Jaccard-over-import-sets fits in cache; synth doesn't.
|
|
84
|
+
- vscode `crossDomain` p50 is **1.23ms**; synth-10K is **704µs**. Cross-domain edges scale with edge density; synth is denser. Both are sub-2ms at any sensible scale.
|
|
85
|
+
- vscode `bitmap.bin` is **4.1 MB** at 7,567 files; synth-10K is **17 MB** at 10,000 files. ~4× density difference, reflected directly in storage.
|
|
86
|
+
|
|
87
|
+
The takeaway: **dense-synth identifies the failure modes; real-world data sets the actual user expectations.** Both are needed.
|
|
88
|
+
|
|
89
|
+
## Linux kernel and Chromium
|
|
90
|
+
|
|
91
|
+
Block 1.B in PEAK §10 explicitly calls out the Linux kernel and Chromium as scale targets. Neither is in `~/carto-test-repos` today (multi-GB clones, gated on the maintainer's disk budget). The `bench/scale-test/real-world.js` driver lands here so capturing those rows is one command once a clone exists:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
git clone --depth=1 https://github.com/torvalds/linux ~/clones/linux
|
|
95
|
+
node bench/scale-test/real-world.js --repo ~/clones/linux --name linux-kernel
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
# Chromium follows the official `fetch` flow; expect a 30+ GB clone.
|
|
100
|
+
node bench/scale-test/real-world.js --repo ~/clones/chromium/src --name chromium
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
These rows are intentionally not yet captured. The 50K dense-synth + 7,567-file vscode + 6,330-file supabase rows above already establish the scaling profile of the current implementation; whether kernel/Chromium clear or fail is *known* in the bitmap-storage sense (linear in N, hits the GB scale at 100K+ files in the worst case). Capturing them on the maintainer box is a confirm-the-known activity, not a discover-the-unknown one.
|
|
104
|
+
|
|
105
|
+
## Reproducing this page
|
|
106
|
+
|
|
107
|
+
Every number above is mechanically reproducible. The exact commands:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
# Synth sweep (deterministic, dense-fan-out worst case)
|
|
111
|
+
npm run bench:scale -- --size 1000
|
|
112
|
+
npm run bench:scale -- --size 10000
|
|
113
|
+
npm run bench:scale -- --size 50000
|
|
114
|
+
|
|
115
|
+
# Real-world corpus (uses existing indexes; doesn't re-index)
|
|
116
|
+
node bench/scale-test/real-world.js --repo ~/carto-test-repos/tier-b/vscode --name vscode --queries-only
|
|
117
|
+
node bench/scale-test/real-world.js --repo ~/carto-test-repos/tier-b/supabase --name supabase --queries-only
|
|
118
|
+
node bench/scale-test/real-world.js --repo ~/carto-test-repos/tier-b/nextjs --name nextjs --queries-only
|
|
119
|
+
node bench/scale-test/real-world.js --repo ~/carto-test-repos/tier-b/cal.com --name cal.com --queries-only
|
|
120
|
+
|
|
121
|
+
# Larger (maintainer-machine work)
|
|
122
|
+
npm run bench:scale -- --size 100000 --keep --out /tmp/carto-100k
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Each run writes `bench/scale-test/results/<tag>-<ISO-timestamp>.json` and refreshes `bench/scale-test/REPORT.md`. The aggregator keeps the latest run per (kind, label) so re-running a row replaces the old number.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
_See `bench/scale-test/README.md` for full harness documentation._
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# Troubleshooting
|
|
2
|
+
|
|
3
|
+
> Real failure modes, with fixes.
|
|
4
|
+
|
|
5
|
+
## Install / native modules
|
|
6
|
+
|
|
7
|
+
### `node-gyp rebuild` fails on install
|
|
8
|
+
|
|
9
|
+
Symptom: `npm install -g carto-md` exits with C++ errors mentioning `tree-sitter` or `better-sqlite3`.
|
|
10
|
+
|
|
11
|
+
Why: no prebuilt binary for your platform → falling back to compile-from-source → no C++ toolchain present.
|
|
12
|
+
|
|
13
|
+
Fix: install build tools, then retry.
|
|
14
|
+
|
|
15
|
+
| OS | Command |
|
|
16
|
+
|---|---|
|
|
17
|
+
| macOS | `xcode-select --install` |
|
|
18
|
+
| Ubuntu / Debian | `sudo apt-get install build-essential python3` |
|
|
19
|
+
| RHEL / Fedora | `sudo dnf groupinstall "Development Tools"` |
|
|
20
|
+
| Windows | `npm install --global windows-build-tools` (run from elevated PowerShell) |
|
|
21
|
+
| Alpine | `apk add --no-cache python3 make g++` |
|
|
22
|
+
|
|
23
|
+
If you're on a supported platform (macOS arm64/x64, Linux x64 glibc + musl, Windows x64), you *shouldn't* be hitting this. Run `carto doctor` — the output will tell you which native module is the problem.
|
|
24
|
+
|
|
25
|
+
### Node version refused at install time
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
[CARTO] Node v16.x.x is too old. carto-md requires Node ≥ v18.
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Upgrade Node. https://nodejs.org/ — even-numbered LTS releases (18, 20, 22) are best.
|
|
32
|
+
|
|
33
|
+
### Missing optional grammars
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
⚠ Tree-sitter grammars (2 of 8 missing: tree-sitter-rust, tree-sitter-java)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The optional language grammars failed to prebuild on your platform. Files in those languages still get indexed — Carto falls back to regex extraction (less accurate but functional).
|
|
40
|
+
|
|
41
|
+
To force a grammar to install:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npm install -g tree-sitter-rust
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
If that fails too, the platform doesn't have a prebuild and won't compile. That's fine — regex fallback works.
|
|
48
|
+
|
|
49
|
+
## Index / sync
|
|
50
|
+
|
|
51
|
+
### `carto sync` says "0 files re-parsed" but I changed files
|
|
52
|
+
|
|
53
|
+
Cache hit. Carto stats each file's mtime+size and skips ones that haven't changed. If you genuinely changed a file but mtime didn't move (rare — usually copying a same-content file), force a re-parse:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
touch src/the/file.ts
|
|
57
|
+
carto sync
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
For a full rebuild from scratch:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
carto remove
|
|
64
|
+
carto init
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### `carto check` claims unstable clustering
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
[CARTO] Warning: 8.2% of files changed domain since last sync — clustering unstable.
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The Leiden+CPM clusterer can be sensitive when the codebase is borderline between two stable partitions. If this happens repeatedly:
|
|
74
|
+
|
|
75
|
+
1. Pin the important files with `anchor` in `carto.config.json`. See [`docs/concepts/domains.md`](./concepts/domains.md).
|
|
76
|
+
2. If a domain is genuinely splitting (a refactor in progress), this is informational — accept the drift.
|
|
77
|
+
3. If you don't care about exact domain names but want stability, set keyword hints in `carto.config.json` so the names are forced.
|
|
78
|
+
|
|
79
|
+
### Index is huge
|
|
80
|
+
|
|
81
|
+
A 100K-file repo produces a 160 MB `carto.db` and 20 MB `bitmap.bin`. Larger than expected? Most likely you're indexing `node_modules/`, a `vendor/` dir, or a generated `dist/`. Run:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
carto inspect | head -20
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
That shows the file count. If it's way bigger than your source tree, edit `.cartoignore` to exclude the offender:
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
node_modules/
|
|
91
|
+
vendor/
|
|
92
|
+
**/__generated__/
|
|
93
|
+
build/
|
|
94
|
+
dist/
|
|
95
|
+
out/
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## MCP / AI tool integration
|
|
99
|
+
|
|
100
|
+
### AI tool doesn't see Carto's tools
|
|
101
|
+
|
|
102
|
+
1. Restart the AI tool (it loads MCP config at startup).
|
|
103
|
+
2. Run `carto doctor` — it surfaces whether config files exist for the tools you have installed.
|
|
104
|
+
3. If `doctor` says "MCP configuration: no MCP config files found", re-run `carto init` (it auto-wires).
|
|
105
|
+
4. If `init` doesn't detect your tool, see the README's manual config snippets in the [Manual MCP wiring](../README.md) section (collapsed `<details>` block right after the install snippet).
|
|
106
|
+
|
|
107
|
+
### MCP server crashes
|
|
108
|
+
|
|
109
|
+
Pre-2.0.7 the MCP server could crash on tool errors and the AI tool would see `-32000 Failed to reconnect`. Fixed in 2.0.7. If you're seeing it on a newer version, set `CARTO_DEBUG=1` before launching the AI tool to capture stderr.
|
|
110
|
+
|
|
111
|
+
### "Lazy re-parse" doesn't fire on stale files
|
|
112
|
+
|
|
113
|
+
The MCP server stats the file on every file-aware query and re-parses if mtime is newer than the DB row. If a query returns stale data:
|
|
114
|
+
|
|
115
|
+
1. Check the file's mtime: `stat src/the/file.ts`
|
|
116
|
+
2. Compare against the DB row: `carto inspect | grep "last full sync"`
|
|
117
|
+
3. If mtime is older, sync was after edit and the data isn't stale.
|
|
118
|
+
4. If mtime is newer but the data is stale, file a bug — that's the regression test target.
|
|
119
|
+
|
|
120
|
+
## Validation API / PR Action
|
|
121
|
+
|
|
122
|
+
### `carto pr-impact` says "No carto index"
|
|
123
|
+
|
|
124
|
+
The action's cache restored an empty `.carto/`. Either:
|
|
125
|
+
|
|
126
|
+
- Cache key isn't invalidating. Check `hashFiles` glob in the workflow.
|
|
127
|
+
- First run on this branch — let it run `carto init` cold once.
|
|
128
|
+
- Index was removed; run `carto init` manually inside the workflow before pr-impact.
|
|
129
|
+
|
|
130
|
+
### Sticky comment isn't sticky
|
|
131
|
+
|
|
132
|
+
The action looks for the `<!-- carto-impact-report -->` marker in existing PR comments and updates the first match. If multiple comments have the marker (somehow), the action updates the first. If you see duplicate comments, check that the workflow isn't running twice (e.g. matrix builds, multiple triggers).
|
|
133
|
+
|
|
134
|
+
### `--fail-on HIGH` trips too often
|
|
135
|
+
|
|
136
|
+
Lower the threshold to `MEDIUM` for a softer gate, or use `--fail-on` only on `main`-bound PRs and not feature-branch PRs. Or accept that HIGH-risk PRs deserve careful review and let the gate work as intended.
|
|
137
|
+
|
|
138
|
+
## SWE-bench harness
|
|
139
|
+
|
|
140
|
+
### `bench/swe-bench/run.sh --task-set verified` says "dataset not found"
|
|
141
|
+
|
|
142
|
+
Download the SWE-bench-Verified dataset from Hugging Face:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
pip install huggingface_hub
|
|
146
|
+
huggingface-cli download princeton-nlp/SWE-bench_Verified \
|
|
147
|
+
--repo-type dataset --local-dir ~/swe-bench-verified
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Or set `CARTO_SWE_VERIFIED_PATH=/path/to/test.jsonl`.
|
|
151
|
+
|
|
152
|
+
### AnthropicAgent throws on `--arm carto`
|
|
153
|
+
|
|
154
|
+
You ran `--task-set verified` without `ANTHROPIC_API_KEY`. Set the key, or stick to `--task-set sample` which uses the deterministic StubAgent.
|
|
155
|
+
|
|
156
|
+
### Cost runaway during a real-API run
|
|
157
|
+
|
|
158
|
+
Set an Anthropic spend limit on your account dashboard *before* a long run. The harness emits per-task token counts to the JSONL output — tail it during the run to spot anomalies early:
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
tail -f bench/swe-bench/results/<run-id>.jsonl | jq .tokensInput
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## General
|
|
165
|
+
|
|
166
|
+
### `carto doctor` is the right starting point
|
|
167
|
+
|
|
168
|
+
For any "something is broken" report, run `carto doctor` first. It checks Node, native modules, the index, git hooks, MCP config, .cartoignore. The output points at the broken component with a `Fix:` line.
|
|
169
|
+
|
|
170
|
+
### Found a real bug
|
|
171
|
+
|
|
172
|
+
Open an issue with:
|
|
173
|
+
|
|
174
|
+
- `node --version`
|
|
175
|
+
- `carto --version`
|
|
176
|
+
- Output of `carto doctor`
|
|
177
|
+
- Output of `carto inspect | head -30`
|
|
178
|
+
- Steps to reproduce
|
|
179
|
+
|
|
180
|
+
The maintainer triage is fast on real bugs with reproducible info. The triage is slow on vague "carto doesn't work" reports.
|