carto-md 2.1.0 → 2.1.1
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/CHANGELOG.md +135 -0
- package/CONTRIBUTING.md +11 -8
- package/README.md +165 -213
- package/docs/anci/v0.1-DRAFT.md +132 -2
- package/docs/api/README.md +27 -2
- package/docs/api/did_we_discuss_this.md +2 -0
- package/docs/api/dismiss_gap.md +39 -0
- package/docs/api/find_consumers_of_api.md +2 -0
- package/docs/api/get_action_patterns.md +2 -0
- package/docs/api/get_arch_events.md +2 -0
- package/docs/api/get_architectural_drift.md +2 -0
- package/docs/api/get_blast_radius.md +2 -0
- package/docs/api/get_canonical_pattern.md +2 -0
- package/docs/api/get_change_velocity.md +2 -0
- package/docs/api/get_churn_vs_blast_radius.md +2 -0
- package/docs/api/get_complexity_trend.md +2 -0
- package/docs/api/get_conventions.md +2 -0
- package/docs/api/get_cross_repo_blast_radius.md +2 -0
- package/docs/api/get_data_flow.md +2 -0
- package/docs/api/get_decision_log.md +2 -0
- package/docs/api/get_domain_evolution.md +2 -0
- package/docs/api/get_domain_health.md +2 -0
- package/docs/api/get_file_receipts.md +34 -0
- package/docs/api/get_gaps.md +52 -0
- package/docs/api/get_hotspot_files.md +2 -0
- package/docs/api/get_intent.md +25 -0
- package/docs/api/get_intervention_history.md +2 -0
- package/docs/api/get_invariants.md +2 -0
- package/docs/api/get_microservices_migration_cut_points.md +2 -0
- package/docs/api/get_neighbors.md +2 -0
- package/docs/api/get_org_architecture.md +2 -0
- package/docs/api/get_org_domain_mapping.md +2 -0
- package/docs/api/get_pending_decisions.md +2 -0
- package/docs/api/get_recent_decisions.md +2 -0
- package/docs/api/get_service_boundary_violations.md +2 -0
- package/docs/api/get_service_dependency_graph.md +2 -0
- package/docs/api/get_session_context.md +2 -0
- package/docs/api/get_temporal_context.md +2 -0
- package/docs/api/history.md +78 -0
- package/docs/api/impact.md +56 -0
- package/docs/api/memory.md +70 -0
- package/docs/api/org.md +51 -0
- package/docs/api/patterns.md +63 -0
- package/docs/api/set_intent.md +45 -0
- package/docs/api/simulate_change_impact.md +2 -0
- package/docs/concepts/domains.md +75 -50
- package/docs/concepts/mcp-integration.md +4 -2
- package/docs/guides/pre-merge-review.md +2 -2
- package/docs/migration/v1-to-v2.md +2 -2
- package/docs/screenshots/carto-supabase-blast-radius.png +0 -0
- package/package.json +2 -1
- package/scripts/gen-api-docs.js +51 -19
- package/src/agents/domains.js +72 -24
- package/src/ai/tools.js +4 -2
- package/src/anci/consumer.js +83 -3
- package/src/anci/emit.js +18 -1
- package/src/anci/git-meta.js +171 -0
- package/src/anci/pack.js +288 -0
- package/src/anci/serialize.js +77 -6
- package/src/anci/staleness.js +161 -0
- package/src/brain/conventions/index.js +134 -20
- package/src/brain/invariants/index.js +76 -22
- package/src/cli/anci.js +27 -1
- package/src/cli/doctor.js +69 -0
- package/src/cli/export.js +128 -0
- package/src/cli/index.js +19 -1
- package/src/cli/init.js +84 -1
- package/src/cli/load.js +125 -0
- package/src/extractors/imports.js +35 -10
- package/src/extractors/languages/javascript.js +8 -4
- package/src/extractors/languages/prisma.js +1 -1
- package/src/extractors/languages/typescript.js +13 -49
- package/src/extractors/schemas.js +60 -0
- package/src/extractors/tree-sitter-parser.js +39 -0
- package/src/mcp/change-plan.js +131 -12
- package/src/mcp/impact.js +119 -0
- package/src/mcp/server.js +708 -82
- package/src/rules/concepts/auth-middleware.md +111 -0
- package/src/rules/concepts/money-as-float.md +80 -0
- package/src/rules/engine.js +178 -0
- package/src/rules/intent.js +178 -0
- package/src/rules/registry.js +24 -0
- package/src/rules/rules/auth-missing-on-mutating-route.js +255 -0
- package/src/rules/rules/money-as-float.js +166 -0
- package/src/store/config-loader.js +77 -3
- package/src/store/sqlite-store.js +248 -7
- package/src/store/sync.js +69 -39
package/README.md
CHANGED
|
@@ -1,13 +1,52 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Carto
|
|
2
|
+
|
|
3
|
+
**The portable AI container for your codebase. Package a repo once - every AI tool understands it in seconds, and knows what breaks before it changes anything.**
|
|
4
|
+
|
|
5
|
+
[Docs](docs/) · [Quickstart](docs/quickstart.md) · [Tools](#tools-your-ai-can-call) · [ANCI Spec](docs/anci/v0.1-DRAFT.md) · [Benchmarks](docs/scale.md) · [Changelog](CHANGELOG.md)
|
|
2
6
|
|
|
3
7
|
[](https://github.com/theanshsonkar/carto/actions/workflows/test.yml)
|
|
4
8
|
[](https://www.npmjs.com/package/carto-md)
|
|
5
9
|
[](LICENSE)
|
|
6
10
|
[](https://www.npmjs.com/package/carto-md)
|
|
7
11
|
|
|
8
|
-
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
> **Docker made apps portable. Carto makes codebases portable for AI.**
|
|
15
|
+
|
|
16
|
+
Every AI tool re-reads your entire codebase from scratch, every single session. Cursor builds its own index. Copilot builds its own. Claude Code builds its own. Same parsing, every tool, every time - and none of them remember what they learned yesterday.
|
|
17
|
+
|
|
18
|
+
Carto fixes that. It packages a repository into a **portable AI container** that captures its architecture, dependencies, engineering history, and safety context - so any AI coding assistant understands the project in seconds instead of rediscovering it from scratch. And because the container knows how everything connects, it can tell you **what breaks before you change it.**
|
|
19
|
+
|
|
20
|
+
One SQLite file on your disk. No network. No telemetry. No cloud.
|
|
9
21
|
|
|
10
|
-
>
|
|
22
|
+
> **Passive context vs. active guardrail.** Most tools hand the AI context and hope for the best. Carto grades every proposed diff *before* it lands - blast radius, risk, cross-domain violations - and can block a HIGH-risk edit before it ever reaches disk. Context that pushes back.
|
|
23
|
+
|
|
24
|
+

|
|
25
|
+
|
|
26
|
+
| | |
|
|
27
|
+
|---|---|
|
|
28
|
+
| 🗺️ **Architecture** | Import graph, routes, models, and auto-detected domains - the whole shape of the repo, mapped once. |
|
|
29
|
+
| 💥 **Blast Radius** | "Touch this file and 22 things break." Transitive impact of any change, in microseconds. |
|
|
30
|
+
| 🧠 **Memory** | Every decision and validated diff is remembered across sessions. Ask *"did we agree on snake_case here?"* six weeks later and get the actual verdict. |
|
|
31
|
+
| ⏳ **History** | Snapshots every commit. Tracks drift, churn, and architectural events. The container gets smarter the longer the repo lives. |
|
|
32
|
+
| 🎯 **Predictive Risk** | Every file scored 0–1: *P(this causes the next incident)*. High-risk files surface before the PR is opened. |
|
|
33
|
+
| 📦 **Portable (ANCI)** | The **structural core** is an open format - `.carto/anci.{yaml,bin}`, stamped with its source commit + a content digest so it's versioned and verifiable. Any AI tool can read it without re-indexing. |
|
|
34
|
+
| 🔐 **Verifiable** | Every container is stamped with its source commit, grammar versions, and a sha256 content digest. Same repo → same digest. Integrity is checked on load. |
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Use Carto
|
|
39
|
+
|
|
40
|
+
| | |
|
|
41
|
+
|---|---|
|
|
42
|
+
| ### 🧑💻 I use AI coding tools | ### 🔧 I'm building AI dev tools |
|
|
43
|
+
| Install once and Carto auto-wires into every AI tool on your machine. Your assistant instantly knows your architecture, remembers past decisions, and gets blocked from risky edits. **[→ Quick start](#quick-start)** | Consume the portable container directly via the ANCI format, or query it live through a compact MCP surface (a core-10 plus parameterized families). Stop building your own index. **[→ Build on Carto](#build-on-carto)** |
|
|
44
|
+
|
|
45
|
+
**Works with:** Cursor · Claude Code · Codex · Kiro · Claude Desktop · Windsurf · VS Code Copilot · Zed · JetBrains
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Quick start
|
|
11
50
|
|
|
12
51
|
```bash
|
|
13
52
|
npm install -g carto-md
|
|
@@ -15,71 +54,46 @@ cd your-project
|
|
|
15
54
|
carto init
|
|
16
55
|
```
|
|
17
56
|
|
|
18
|
-
That's it.
|
|
57
|
+
That's it. `carto init` reads your repo, builds the container, and wires itself into every AI tool it finds. Restart the tool. Your AI now knows your codebase - and keeps a memory of every decision it makes inside it.
|
|
19
58
|
|
|
20
|
-
|
|
59
|
+
### Wiring it into your AI tool
|
|
21
60
|
|
|
22
|
-
|
|
61
|
+
`carto init` auto-detects the AI tools on your machine and writes each one's MCP config for you. If you'd rather wire it by hand, the MCP server config is just:
|
|
23
62
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
carto
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
every diff it proposes runs validate_diff first —
|
|
34
|
-
risky ones blocked before they hit your screen.
|
|
35
|
-
carto also pushes nudges back: "coupling jumped in
|
|
36
|
-
AUTH", "two sessions are editing this file."
|
|
37
|
-
|
|
38
|
-
brain invariants and conventions are mined from your
|
|
39
|
-
import graph. action patterns ("when a route is
|
|
40
|
-
added, auth/middleware is touched 89% of the time")
|
|
41
|
-
are mined from your git history. nobody writes
|
|
42
|
-
these rules.
|
|
43
|
-
|
|
44
|
-
timeline every commit takes a snapshot. drift, churn, and
|
|
45
|
-
architectural events accumulate. your AI can read
|
|
46
|
-
the whole story at any time: "AUTH grew 18 files
|
|
47
|
-
and lost stability when payments/billing.ts moved
|
|
48
|
-
out." carto gets smarter the longer the repo lives.
|
|
49
|
-
|
|
50
|
-
predicts every file is scored: P(causes the next bug).
|
|
51
|
-
the score blends blast radius × churn × past
|
|
52
|
-
interventions × test coverage. high-risk files
|
|
53
|
-
surface on every PR, before the PR is opened.
|
|
54
|
-
|
|
55
|
-
always one SQLite file on your disk. no network, no
|
|
56
|
-
telemetry, no cloud.
|
|
57
|
-
─────────────────────────────────────────────────────────────────────
|
|
63
|
+
```json
|
|
64
|
+
{
|
|
65
|
+
"mcpServers": {
|
|
66
|
+
"carto": {
|
|
67
|
+
"command": "carto",
|
|
68
|
+
"args": ["serve"]
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
58
72
|
```
|
|
59
73
|
|
|
60
|
-
|
|
74
|
+
Point any MCP client at that and restart it - the tool spawns `carto serve` on demand, and every chat starts with your architecture, blast radius, and past decisions already loaded. Exact config file per tool is below.
|
|
61
75
|
|
|
62
76
|
<details>
|
|
63
|
-
<summary>Manual MCP wiring (if
|
|
77
|
+
<summary>Manual MCP wiring for every other tool (if it wasn't auto-detected)</summary>
|
|
64
78
|
|
|
65
|
-
### Cursor
|
|
79
|
+
### Cursor - `~/.cursor/mcp.json`
|
|
66
80
|
```json
|
|
67
81
|
{ "mcpServers": { "carto": { "command": "carto", "args": ["serve"], "cwd": "/your/project" } } }
|
|
68
82
|
```
|
|
69
83
|
|
|
70
|
-
### Claude Code
|
|
84
|
+
### Claude Code - `<project>/.mcp.json`
|
|
71
85
|
```bash
|
|
72
86
|
claude mcp add carto -- carto serve
|
|
73
87
|
```
|
|
74
88
|
|
|
75
|
-
### Codex
|
|
89
|
+
### Codex - `~/.codex/config.toml`
|
|
76
90
|
```toml
|
|
77
91
|
[mcp_servers.carto]
|
|
78
92
|
command = "carto"
|
|
79
93
|
args = ["serve"]
|
|
80
94
|
```
|
|
81
95
|
|
|
82
|
-
### Kiro
|
|
96
|
+
### Kiro - `~/.kiro/settings/mcp.json`
|
|
83
97
|
```json
|
|
84
98
|
{ "mcpServers": { "carto": { "command": "carto", "args": ["serve"], "cwd": "/your/project" } } }
|
|
85
99
|
```
|
|
@@ -93,177 +107,163 @@ args = ["serve"]
|
|
|
93
107
|
{ "mcpServers": { "carto": { "command": "carto", "args": ["serve"], "cwd": "/your/project" } } }
|
|
94
108
|
```
|
|
95
109
|
|
|
96
|
-
### VS Code Copilot
|
|
110
|
+
### VS Code Copilot - `.vscode/mcp.json`
|
|
97
111
|
```json
|
|
98
112
|
{ "servers": { "carto": { "type": "stdio", "command": "carto", "args": ["serve"] } } }
|
|
99
113
|
```
|
|
100
114
|
|
|
101
|
-
### Windsurf
|
|
115
|
+
### Windsurf - `~/.codeium/windsurf/mcp_config.json`
|
|
102
116
|
```json
|
|
103
117
|
{ "mcpServers": { "carto": { "command": "carto", "args": ["serve"], "cwd": "/your/project" } } }
|
|
104
118
|
```
|
|
105
119
|
|
|
106
120
|
</details>
|
|
107
121
|
|
|
108
|
-
|
|
122
|
+
### How it works
|
|
109
123
|
|
|
110
|
-
|
|
124
|
+
1. **`carto init` builds the container.** It parses your repo (imports, routes, models, domains, blast radius), writes it to `.carto/`, and auto-wires every AI tool on your machine.
|
|
125
|
+
2. **Your AI loads it instead of re-reading everything.** Every chat starts with the architecture already known - the right 6–12 files, not the usual 40+.
|
|
126
|
+
3. **Every proposed diff is checked first.** Risky changes are graded *before* they hit your screen - and `carto mcp-middleware` can block a HIGH-risk edit before it ever reaches disk. Carto also nudges: *"coupling jumped in AUTH," "two sessions are editing this file."*
|
|
127
|
+
4. **The container remembers - and knows when it's stale.** Decisions, validations, and drift accumulate in one SQLite file, so the next session picks up where the last left off. And if the repo moves ahead of the index, queries warn *"graph is N commits stale"* instead of silently serving old numbers.
|
|
111
128
|
|
|
112
|
-
|
|
129
|
+
---
|
|
113
130
|
|
|
114
|
-
|
|
131
|
+
## An index is not a container
|
|
115
132
|
|
|
116
|
-
|
|
117
|
-
- **Temporal** — snapshots, churn, deltas. *"AUTH grew 18 files this quarter and lost stability when `payments/billing.ts` moved out."*
|
|
118
|
-
- **Semantic** — invariants and conventions mined from the import graph itself, not declared by humans.
|
|
119
|
-
- **Procedural** — patterns mined from git history. *"When a route gets added, the auth middleware is touched 89% of the time."*
|
|
120
|
-
- **Working** — one call that returns what's open, what's drifting, what warnings are unresolved. Read at the start of every session.
|
|
133
|
+
Most tools build an **index** - a snapshot of what's in the repo *right now*. Stateless. Thrown away at the end of the session. Rebuilt from scratch by the next tool.
|
|
121
134
|
|
|
122
|
-
|
|
135
|
+
A **container** is different: portable, versioned, and verifiable. Carto's engine keeps **five kinds of memory** a plain index can't - all queryable **live** over MCP:
|
|
123
136
|
|
|
124
|
-
|
|
137
|
+
- **Structural** - imports, routes, models, domains, blast radius.
|
|
138
|
+
- **Episodic** - every diff validated, every decision made. Queryable weeks later.
|
|
139
|
+
- **Temporal** - snapshots, churn, deltas. *"AUTH grew 18 files and lost stability when `billing.ts` moved out."*
|
|
140
|
+
- **Semantic** - invariants and conventions mined from the import graph, not declared by humans.
|
|
141
|
+
- **Procedural** - patterns mined from git history. *"When a route is added, auth middleware is touched 89% of the time."*
|
|
125
142
|
|
|
126
|
-
|
|
143
|
+
All five run live in the engine - one SQLite file (`.carto/carto.db`), queried over MCP. The **portable container file** - the open [ANCI](docs/anci/v0.1-DRAFT.md) export any tool can read *without* Carto's runtime - today carries the **structural core** (import graph, domains, routes, models, blast radius), stamped with its source commit + a content digest so it's versioned and verifiable. Making the other four memories portable *in the file* is on the roadmap.
|
|
127
144
|
|
|
128
|
-
|
|
145
|
+
Your AI tool sees files. Carto's container sees architecture, history, *and* consequences.
|
|
129
146
|
|
|
130
|
-
|
|
147
|
+
---
|
|
131
148
|
|
|
132
|
-
|
|
133
|
-
Risk: 🔴 HIGH
|
|
134
|
-
Files changed: 1
|
|
135
|
-
Union blast radius: 83 transitive dependents
|
|
149
|
+
## Is this Docker?
|
|
136
150
|
|
|
137
|
-
|
|
138
|
-
HIGH · high_blast · packages/pg-meta/src/pg-format/index.ts
|
|
139
|
-
83 transitive dependents (threshold: 50)
|
|
140
|
-
```
|
|
151
|
+
No. Docker containerizes **compute** - the OS, libraries, and binaries a CPU needs to run your code anywhere. Carto containerizes **context** - the import graph, blast radius, and structural boundaries an LLM needs to reason about your code without re-reading it.
|
|
141
152
|
|
|
142
|
-
|
|
153
|
+
There's no daemon, no image pull, no virtual network. A Carto container is just a lightweight `.carto/` folder: a local SQLite database plus an open [ANCI](docs/anci/v0.1-DRAFT.md) map. It costs nothing while idle, answers a blast-radius query in microseconds on a 7,500-file repo, and never touches the cloud. Any AI agent - Claude Code, Cursor, or your CI pipeline - taps into it instantly instead of re-indexing from scratch.
|
|
143
154
|
|
|
144
|
-
|
|
155
|
+
---
|
|
145
156
|
|
|
146
|
-
|
|
157
|
+
## Build once, load anywhere
|
|
147
158
|
|
|
148
|
-
|
|
159
|
+
The whole point of a container is that it's *one file you can move.* Build it on one machine, load it on another - no re-index, no Carto runtime needed to read it.
|
|
149
160
|
|
|
150
|
-
|
|
161
|
+
```bash
|
|
162
|
+
# machine A - build and pack into a single file
|
|
163
|
+
carto init
|
|
164
|
+
carto export --out myrepo.anci # one file: yaml + bitmap + manifest
|
|
151
165
|
|
|
152
|
-
|
|
166
|
+
# machine B - load it, no re-parsing the repo
|
|
167
|
+
carto load myrepo.anci # unpacks + verifies the content digest
|
|
168
|
+
carto impact src/auth/session.ts # blast radius, instantly
|
|
169
|
+
```
|
|
153
170
|
|
|
154
|
-
|
|
171
|
+
Copy it, attach it to a release, or hand it to a teammate - the receiving machine gets the full structural container in seconds. The digest is verified on load, and loaded contents are treated as **untrusted data, never instructions.**
|
|
155
172
|
|
|
156
173
|
---
|
|
157
174
|
|
|
158
|
-
##
|
|
175
|
+
## Under the hood
|
|
159
176
|
|
|
160
|
-
|
|
177
|
+
```
|
|
178
|
+
your repo
|
|
179
|
+
↓
|
|
180
|
+
carto init ──────────── parse (tree-sitter, 17 languages)
|
|
181
|
+
↓
|
|
182
|
+
┌─────────────────────────────────────────────────────┐
|
|
183
|
+
│ the container ── .carto/ │
|
|
184
|
+
│ │
|
|
185
|
+
│ ├── carto.db SQLite: graph, routes, models, │
|
|
186
|
+
│ │ domains, decisions, history │
|
|
187
|
+
│ ├── bitmap.bin Roaring Bitmap reverse-dep │
|
|
188
|
+
│ │ graph - blast radius in µs │
|
|
189
|
+
│ └── anci.{yaml,bin} portable open format - `carto export` │
|
|
190
|
+
│ packs it into one verifiable .anci file │
|
|
191
|
+
└─────────────────────────────────────────────────────┘
|
|
192
|
+
↓
|
|
193
|
+
your AI tool ── loads it via MCP (core-10 + families) or ANCI directly
|
|
194
|
+
```
|
|
161
195
|
|
|
162
|
-
|
|
196
|
+
**Blast radius is not search.** Search finds files that *mention* something. Blast radius finds files that *break* when you change something - transitively, over the real import graph. On a 7,500-file repo, one query returns in ~3 microseconds thanks to the bitmap engine.
|
|
163
197
|
|
|
164
198
|
---
|
|
165
199
|
|
|
166
|
-
##
|
|
200
|
+
## Build on Carto
|
|
167
201
|
|
|
168
|
-
|
|
202
|
+
The container is an open format. Read it without running Carto's engine:
|
|
169
203
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
| [supabase/supabase](https://github.com/supabase/supabase) | 6,358 | 5.9s | 967ms | 4.8 MB |
|
|
174
|
-
| [vercel/next.js](https://github.com/vercel/next.js) | 6,193 | 6.9s | 978ms | 15.1 MB |
|
|
175
|
-
| [microsoft/vscode](https://github.com/microsoft/vscode) | 7,567 | 8.6s | 1.1s | 14.3 MB |
|
|
176
|
-
|
|
177
|
-
**Query latency** on vscode (7,567 files):
|
|
204
|
+
```js
|
|
205
|
+
const { loadAnci } = require('carto-md/src/anci/consumer');
|
|
206
|
+
const reader = loadAnci('./.carto');
|
|
178
207
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
208
|
+
reader.domains; // [{ name: 'AUTH', file_count: 42 }, ...]
|
|
209
|
+
reader.getHighImpactFiles(5); // top 5 by transitive dependents
|
|
210
|
+
reader.blastRadius('src/auth/session.ts'); // { count, hops, files: [...] }
|
|
211
|
+
```
|
|
183
212
|
|
|
184
|
-
|
|
213
|
+
Or query it live through the MCP server your AI tool already runs.
|
|
185
214
|
|
|
186
215
|
---
|
|
187
216
|
|
|
188
217
|
## Tools your AI can call
|
|
189
218
|
|
|
190
|
-
|
|
219
|
+
A small **core** is exposed by default (≈10 tools), with the rest collapsed into a handful of
|
|
220
|
+
**parameterized families** - so your AI tool spends its context on your codebase, not on a tool menu.
|
|
191
221
|
|
|
192
|
-
|
|
|
222
|
+
| Core tool | What it's for |
|
|
193
223
|
|---|---|
|
|
194
|
-
|
|
|
195
|
-
|
|
|
196
|
-
|
|
|
197
|
-
|
|
|
198
|
-
|
|
|
199
|
-
|
|
|
200
|
-
|
|
|
201
|
-
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
```bash
|
|
212
|
-
carto org init
|
|
213
|
-
carto org add ../service-a ../service-b ../service-c
|
|
214
|
-
carto org sync
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
Then ask: *"if I rename `User.email` in service-a, who notices?"* — one `get_cross_repo_blast_radius` call away.
|
|
224
|
+
| `get_architecture` · `get_context` | Orient in the repo; full context for one file |
|
|
225
|
+
| `impact` | Blast radius / multi-file simulate / neighbors / data flow - *what breaks if I touch this?* (`mode=`) |
|
|
226
|
+
| `validate_diff` | Grade a proposed diff (risk + violations) |
|
|
227
|
+
| `get_change_plan` | Natural-language intent → files to touch |
|
|
228
|
+
| `memory` | Episodic memory - search past decisions, logs, sessions, interventions (`kind=`) |
|
|
229
|
+
| `history` | Temporal history - drift, hotspots, evolution, churn, health (`view=`) |
|
|
230
|
+
| `patterns` | Mined invariants / conventions / canonical exemplar / co-change patterns (`kind=`) |
|
|
231
|
+
| `get_predictive_risk` · `get_minimal_context_for_intent` | Risk score per file; token-budgeted context picker |
|
|
232
|
+
|
|
233
|
+
Beyond the core, `org(view=…)` covers multi-repo, and advanced/experimental tools (`get_routes`,
|
|
234
|
+
`get_models`, `get_gaps`, `scaffold_for_intent`, …) are available by widening the surface with
|
|
235
|
+
`CARTO_MCP_TIER=advanced` (or `all`), or `carto.config.json` → `mcp.tier`. The ~30 former sibling
|
|
236
|
+
tools (`get_blast_radius`, `did_we_discuss_this`, …) still resolve as **deprecated shims** that
|
|
237
|
+
forward to the new families with byte-identical output.
|
|
238
|
+
|
|
239
|
+
Full reference at [`docs/api/`](docs/api/). You don't need to memorize any of these - your AI picks the right one mid-task.
|
|
218
240
|
|
|
219
241
|
---
|
|
220
242
|
|
|
221
|
-
##
|
|
243
|
+
## How fast
|
|
222
244
|
|
|
223
|
-
|
|
245
|
+
Fresh runs on real open-source repos (Apple M-series, 8 CPUs, 8 GB RAM):
|
|
224
246
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
247
|
+
| Repo | Files | First index | Re-index | Container size |
|
|
248
|
+
|---|--:|--:|--:|--:|
|
|
249
|
+
| [cal.com](https://github.com/calcom/cal.com) | 4,352 | 3.9s | 805ms | 3.1 MB |
|
|
250
|
+
| [supabase/supabase](https://github.com/supabase/supabase) | 6,358 | 5.9s | 967ms | 4.8 MB |
|
|
251
|
+
| [vercel/next.js](https://github.com/vercel/next.js) | 6,193 | 6.9s | 978ms | 15.1 MB |
|
|
252
|
+
| [microsoft/vscode](https://github.com/microsoft/vscode) | 7,567 | 8.6s | 1.1s | 14.3 MB |
|
|
228
253
|
|
|
229
|
-
|
|
254
|
+
Query latency on vscode (7,567 files): `validate_diff` p50 **84 µs** · `get_blast_radius` p50 **2.7 µs** · `get_high_impact_files` p50 **750 ns**. Full table in [`docs/scale.md`](docs/scale.md).
|
|
230
255
|
|
|
231
256
|
---
|
|
232
257
|
|
|
233
|
-
## Languages
|
|
258
|
+
## Languages
|
|
234
259
|
|
|
235
|
-
|
|
236
|
-
<summary>Import graph + symbols (any repo)</summary>
|
|
260
|
+
**Import graph + symbols:** JavaScript/TypeScript · Python · Go · Rust · Java/Kotlin · C/C++ · C# · Ruby · PHP · Swift · Dart · R · Prisma · HTML
|
|
237
261
|
|
|
238
|
-
|
|
239
|
-
|---|---|
|
|
240
|
-
| JavaScript / TypeScript | `.js` `.jsx` `.ts` `.tsx` `.mjs` `.cjs` |
|
|
241
|
-
| Python | `.py` |
|
|
242
|
-
| Go | `.go` |
|
|
243
|
-
| Rust | `.rs` |
|
|
244
|
-
| Java / Kotlin | `.java` `.kt` |
|
|
245
|
-
| C / C++ | `.cpp` `.cc` `.h` `.hpp` |
|
|
246
|
-
| C# | `.cs` |
|
|
247
|
-
| Ruby | `.rb` |
|
|
248
|
-
| PHP | `.php` |
|
|
249
|
-
| Swift | `.swift` |
|
|
250
|
-
| Dart | `.dart` |
|
|
251
|
-
| R | `.r` `.R` |
|
|
252
|
-
| Prisma schema | `.prisma` |
|
|
253
|
-
| HTML | `.html` (for `fetch()` discovery) |
|
|
254
|
-
|
|
255
|
-
TypeScript path aliases from `tsconfig.json` / `jsconfig.json` are resolved into the import graph. `@/components/Button` lands on the real file.
|
|
262
|
+
**Routes:** Express · Next.js · tRPC · React Router · FastAPI · Flask · Django · Gin · Echo · Chi · Actix · Axum · Rocket · Spring · JAX-RS · ASP.NET · Rails · Sinatra
|
|
256
263
|
|
|
257
|
-
|
|
264
|
+
**Models:** Prisma · Zod · Drizzle · Pydantic · SQLAlchemy · Django · Go structs · Rust structs · JPA · ActiveRecord · Eloquent
|
|
258
265
|
|
|
259
|
-
|
|
260
|
-
<summary>Route + model extraction</summary>
|
|
261
|
-
|
|
262
|
-
**Routes:** Express, Next.js (App + Pages), tRPC, React Router, FastAPI, Flask, Django, Gin, Echo, Chi, net/http, Actix-web, Axum, Rocket, Spring MVC, JAX-RS, ASP.NET Core, Rails, Sinatra.
|
|
263
|
-
|
|
264
|
-
**Models:** Prisma, Zod, Drizzle, TS interfaces, Pydantic, SQLAlchemy, Go structs, Rust structs, JPA, EF Core, ActiveRecord.
|
|
265
|
-
|
|
266
|
-
</details>
|
|
266
|
+
> _Planned (not yet extracted end-to-end):_ EF Core.
|
|
267
267
|
|
|
268
268
|
---
|
|
269
269
|
|
|
@@ -271,10 +271,11 @@ TypeScript path aliases from `tsconfig.json` / `jsconfig.json` are resolved into
|
|
|
271
271
|
|
|
272
272
|
| Command | What it does |
|
|
273
273
|
|---|---|
|
|
274
|
-
| `carto init` |
|
|
275
|
-
| `carto sync` | Re-
|
|
274
|
+
| `carto init` | Build the container, generate AGENTS.md, install git hooks, wire every AI tool found |
|
|
275
|
+
| `carto sync` | Re-build changed files (auto-runs on commit / checkout / merge / rebase) |
|
|
276
|
+
| `carto export` | Pack the container into one portable, verifiable `.anci` file |
|
|
277
|
+
| `carto load <file>` | Load an `.anci` container into a queryable `.carto/` - no re-index, digest verified |
|
|
276
278
|
| `carto serve` | Start the MCP server (your AI tool runs this) |
|
|
277
|
-
| `carto agent` | ACP agent mode for Zed / JetBrains |
|
|
278
279
|
| `carto impact <file>` | Blast radius of one file |
|
|
279
280
|
| `carto pr-impact` | Diff-shaped impact report between two refs |
|
|
280
281
|
| `carto check` | Domain health, cross-domain violations, drift |
|
|
@@ -282,72 +283,23 @@ TypeScript path aliases from `tsconfig.json` / `jsconfig.json` are resolved into
|
|
|
282
283
|
| `carto doctor` | 9-check setup diagnostic |
|
|
283
284
|
| `carto why <file>` | 3-line file summary |
|
|
284
285
|
| `carto explain <intent>` | Natural-language intent → architectural plan |
|
|
285
|
-
| `carto inspect` | Index paths, sizes, freshness (read-only) |
|
|
286
|
-
|
|
287
|
-
---
|
|
288
|
-
|
|
289
|
-
## ACP agent (Zed / JetBrains / VS Code)
|
|
290
|
-
|
|
291
|
-
Carto also runs as a full ACP agent — not just a passive MCP server. It pulls its own context, streams tokens, applies diffs.
|
|
292
|
-
|
|
293
|
-
```json
|
|
294
|
-
{ "agent_servers": { "Carto": { "command": "carto", "args": ["agent"] } } }
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
Bring your own key: Anthropic, OpenAI, Gemini, Groq, Ollama, OpenRouter, Together, Azure.
|
|
298
|
-
|
|
299
|
-
---
|
|
300
|
-
|
|
301
|
-
## GitHub Action
|
|
302
|
-
|
|
303
|
-
Drop Carto onto every PR. Sticky comment with blast radius, cross-domain violations, affected routes, risk badge.
|
|
304
|
-
|
|
305
|
-
```yaml
|
|
306
|
-
- uses: theanshsonkar/carto@v2.0.9
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
`fail-on: HIGH | MEDIUM | LOW` gates the workflow on Carto's verdict. Full config in [`docs/guides/ci-integration.md`](docs/guides/ci-integration.md).
|
|
310
|
-
|
|
311
|
-
---
|
|
312
|
-
|
|
313
|
-
## ANCI — the open format for codebases describing themselves to AI
|
|
314
|
-
|
|
315
|
-
Every AI tool today re-indexes from scratch on every session. Cursor builds its own. Cline builds its own. Continue builds its own. Same parsing, every tool, every time.
|
|
316
|
-
|
|
317
|
-
**ANCI** (Architecturally Normalized Code Index) fixes that. Two files at `.carto/anci.{yaml,bin}` that describe a codebase's architecture in a form any AI tool can read without doing its own indexing. OpenAPI did this for REST APIs. ANCI does it for codebases.
|
|
318
|
-
|
|
319
|
-
`carto sync` writes both files automatically. Spec at [`docs/anci/v0.1-DRAFT.md`](docs/anci/v0.1-DRAFT.md). Carto is the reference implementation; any tool can consume an ANCI pair:
|
|
320
|
-
|
|
321
|
-
```js
|
|
322
|
-
const { loadAnci } = require('carto-md/src/anci/consumer');
|
|
323
|
-
const reader = loadAnci('./.carto');
|
|
324
|
-
|
|
325
|
-
reader.domains; // [{ name: 'AUTH', file_count: 42 }, ...]
|
|
326
|
-
reader.getHighImpactFiles(5); // top 5 by transitive dependents
|
|
327
|
-
reader.blastRadius('src/auth/session.ts'); // { count, hops, files: [...] }
|
|
328
|
-
```
|
|
329
|
-
|
|
330
|
-
> Status: v0.1.0-DRAFT — wire format may change up to v1.0.
|
|
331
286
|
|
|
332
287
|
---
|
|
333
288
|
|
|
334
289
|
## What Carto never does
|
|
335
290
|
|
|
336
291
|
- **Sends your code anywhere.** Local only. SQLite on disk. No telemetry.
|
|
337
|
-
- **Writes secrets into
|
|
292
|
+
- **Writes secrets into the container.** `.cartoignore` blocks `.env` and credential files by default.
|
|
338
293
|
- **Touches your manual notes.** Only writes between `<!-- CARTO:AUTO -->` markers.
|
|
339
|
-
- **Forces you to install a C++ toolchain.** Prebuilt binaries for macOS arm64, Linux x64 (glibc + musl), Windows x64. Other platforms fall back to source build, then regex-only extraction.
|
|
340
294
|
- **Costs money.** MIT. Free forever.
|
|
341
295
|
|
|
342
296
|
---
|
|
343
297
|
|
|
344
298
|
## Origin
|
|
345
299
|
|
|
346
|
-
I was building [Emfirge](https://www.emfirge.cloud)
|
|
347
|
-
|
|
348
|
-
The AI inside Emfirge kept hallucinating about resources it had only half-seen. So I wrote a module called `cartography.py` that mapped every account into a structured graph the AI could query directly. The hallucinations stopped. The AI worked with facts.
|
|
300
|
+
I was building [Emfirge](https://www.emfirge.cloud) - a cloud security agent that maps AWS infrastructure into a graph and simulates the blast radius of every change. The AI inside it kept hallucinating about resources it had only half-seen, so I wrote a module that mapped every account into a structured graph the AI could query directly. The hallucinations stopped.
|
|
349
301
|
|
|
350
|
-
Carto is that idea, applied to source code
|
|
302
|
+
Carto is that idea, applied to source code: package a system into a container the AI can query - and it stops guessing, and stops forgetting.
|
|
351
303
|
|
|
352
304
|
---
|
|
353
305
|
|
|
@@ -357,4 +309,4 @@ MIT. Free forever.
|
|
|
357
309
|
|
|
358
310
|
---
|
|
359
311
|
|
|
360
|
-
*Your code changes. Carto knows. Every AI you use knows
|
|
312
|
+
*Your code changes. Carto knows. Every AI you use knows - and remembers.*
|