carto-md 2.0.0 → 2.0.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/README.md +58 -0
- package/acp-strategy.md +480 -0
- package/package.json +6 -2
- package/src/acp/agent.js +221 -0
- package/src/acp/prompt.js +69 -0
- package/src/acp/providers/anthropic.js +125 -0
- package/src/acp/providers/index.js +83 -0
- package/src/acp/providers/openai.js +137 -0
- package/src/acp/session.js +71 -0
- package/src/acp/tools.js +150 -0
- package/src/cli/agent.js +13 -0
- package/src/cli/index.js +3 -0
package/README.md
CHANGED
|
@@ -162,12 +162,70 @@ Custom domains via `carto.config.json`:
|
|
|
162
162
|
| `carto sync` | Full re-index (skips unchanged files via mtime+size cache) |
|
|
163
163
|
| `carto watch` | Incremental live re-index on every file save (<50ms) |
|
|
164
164
|
| `carto serve` | Start MCP server for Kiro / Cursor / Claude |
|
|
165
|
+
| `carto agent` | Start ACP agent mode (for Zed / JetBrains / VS Code) |
|
|
165
166
|
| `carto impact <file>` | Blast radius: risk level, affected files, routes at risk |
|
|
166
167
|
| `carto check` | Cross-domain violations, high-risk uncommitted changes, domain health |
|
|
167
168
|
| `carto remove` | Remove AGENTS.md and .carto/ from project |
|
|
168
169
|
|
|
169
170
|
---
|
|
170
171
|
|
|
172
|
+
## ACP Agent (Zed / JetBrains / VS Code)
|
|
173
|
+
|
|
174
|
+
Carto works as a full **ACP agent** — not just a passive tool server, but an active coding agent with architectural awareness.
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
User: "Add rate limiting to /api/users"
|
|
178
|
+
↓
|
|
179
|
+
Carto auto-queries its own SQLite:
|
|
180
|
+
- Blast radius of relevant files
|
|
181
|
+
- Domain context (AUTH)
|
|
182
|
+
- Similar patterns in codebase
|
|
183
|
+
↓
|
|
184
|
+
Builds rich prompt with structural context
|
|
185
|
+
↓
|
|
186
|
+
Sends to LLM (your API key) → streams answer + diffs back to editor
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Setup in Zed
|
|
190
|
+
|
|
191
|
+
Add to `~/.config/zed/settings.json`:
|
|
192
|
+
|
|
193
|
+
```json
|
|
194
|
+
{
|
|
195
|
+
"agent_servers": {
|
|
196
|
+
"Carto": {
|
|
197
|
+
"command": "carto",
|
|
198
|
+
"args": ["agent"]
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### BYOK (Bring Your Own Key)
|
|
205
|
+
|
|
206
|
+
Carto supports any LLM provider — configure in your editor:
|
|
207
|
+
|
|
208
|
+
| Provider | Models |
|
|
209
|
+
|----------|--------|
|
|
210
|
+
| Anthropic | Claude Sonnet 4, Haiku |
|
|
211
|
+
| OpenAI | GPT-4o, GPT-4o-mini, o1, o3 |
|
|
212
|
+
| Google Gemini | Gemini 2.5 Pro, 2.5 Flash |
|
|
213
|
+
| Ollama | Any local model (free) |
|
|
214
|
+
| OpenRouter | Any model via single API |
|
|
215
|
+
| Groq | Ultra-fast inference |
|
|
216
|
+
| Together AI | Open-source models |
|
|
217
|
+
| Azure OpenAI | Enterprise deployments |
|
|
218
|
+
|
|
219
|
+
### What makes it different
|
|
220
|
+
|
|
221
|
+
Other agents are smart but blind. Carto sees the architecture:
|
|
222
|
+
- Auto-indexes your project on first session (1-10s depending on size)
|
|
223
|
+
- Injects structural context into every LLM call (blast radius, domains, routes)
|
|
224
|
+
- 12 internal tools the LLM can call during reasoning
|
|
225
|
+
- Zero cost to you beyond your own API key
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
171
229
|
## V1 → V2 migration
|
|
172
230
|
|
|
173
231
|
Run `carto sync` — it auto-migrates your existing `graph-cache.json` and `map.json` into SQLite and renames them to `.bak`. No manual steps.
|
package/acp-strategy.md
ADDED
|
@@ -0,0 +1,480 @@
|
|
|
1
|
+
# Carto ACP Agent — Strategy & Implementation Plan
|
|
2
|
+
|
|
3
|
+
> Build the brain, not the editor. Ship to every IDE in weeks.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## What is ACP?
|
|
8
|
+
|
|
9
|
+
**Agent Client Protocol (ACP)** is an open standard created by Zed Industries that lets any AI coding agent work inside any compatible editor — without custom integrations.
|
|
10
|
+
|
|
11
|
+
- **LSP** = one standard so any editor supports any programming language
|
|
12
|
+
- **ACP** = one standard so any editor supports any AI coding agent
|
|
13
|
+
|
|
14
|
+
**Transport:** JSON-RPC 2.0 over stdin/stdout (local) or HTTP/WebSocket (remote)
|
|
15
|
+
**Editors:** Zed, JetBrains (IntelliJ, WebStorm, etc.), VS Code (in progress)
|
|
16
|
+
**SDK:** `@agentclientprotocol/sdk` (TypeScript/JS, Python, Rust, Kotlin, Java)
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## The Core Idea
|
|
21
|
+
|
|
22
|
+
Instead of building a standalone editor, build Carto as an **ACP agent** that plugs into existing editors. Carto already has the structural intelligence — ACP gives it hands.
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
┌─────────────────────────────────────────┐
|
|
26
|
+
│ Zed / JetBrains / VS Code │
|
|
27
|
+
│ ┌───────────────────────────────────┐ │
|
|
28
|
+
│ │ Agent Panel → "Carto" thread │ │
|
|
29
|
+
│ │ │ │
|
|
30
|
+
│ │ User: "Add rate limiting to │ │
|
|
31
|
+
│ │ /api/users" │ │
|
|
32
|
+
│ │ │ │
|
|
33
|
+
│ │ Carto: I see AUTH domain has │ │
|
|
34
|
+
│ │ 12 files, 3 routes. Highest │ │
|
|
35
|
+
│ │ impact: auth/session.ts │ │
|
|
36
|
+
│ │ (8 dependents). Here's my plan: │ │
|
|
37
|
+
│ │ [shows file diffs inline] │ │
|
|
38
|
+
│ └───────────────────────────────────┘ │
|
|
39
|
+
└─────────────────────────────────────────┘
|
|
40
|
+
↕ ACP (stdin/stdout)
|
|
41
|
+
┌─────────────────────────────────────────┐
|
|
42
|
+
│ carto agent (Node.js process) │
|
|
43
|
+
│ ├── Carto structural intelligence │
|
|
44
|
+
│ ├── LLM calls (user's own API key) │
|
|
45
|
+
│ └── File edits streamed back │
|
|
46
|
+
└─────────────────────────────────────────┘
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## How Data Flows (MCP vs ACP)
|
|
52
|
+
|
|
53
|
+
### Current: MCP (passive tool server)
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
External AI (Claude/Cursor) decides to call a tool
|
|
57
|
+
↓
|
|
58
|
+
get_blast_radius("auth.service.ts")
|
|
59
|
+
↓
|
|
60
|
+
Carto returns a SUMMARY → "3 files affected, risk HIGH"
|
|
61
|
+
↓
|
|
62
|
+
AI uses summary to answer (may miss context, can't read files through Carto)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Problem:** LLM gets summaries, not full context. It has to guess which tools to call. It can't read actual file contents through Carto.
|
|
66
|
+
|
|
67
|
+
### New: ACP (active intelligent agent)
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
User asks: "Add rate limiting to /api/users"
|
|
71
|
+
↓
|
|
72
|
+
Carto agent receives message
|
|
73
|
+
↓
|
|
74
|
+
Carto INTERNALLY queries its own SQLite:
|
|
75
|
+
- Blast radius of relevant files
|
|
76
|
+
- Domain context (AUTH)
|
|
77
|
+
- Similar patterns in codebase
|
|
78
|
+
- Import graph neighbors
|
|
79
|
+
↓
|
|
80
|
+
Carto reads ACTUAL file contents via ACP fileSystem
|
|
81
|
+
↓
|
|
82
|
+
Carto builds a RICH prompt with all context + file contents
|
|
83
|
+
↓
|
|
84
|
+
Sends to LLM (user's API key) → gets response
|
|
85
|
+
↓
|
|
86
|
+
Streams answer + file diffs back to editor
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**Key difference:** Carto controls the LLM call. It proactively provides the right context instead of waiting for the LLM to ask.
|
|
90
|
+
|
|
91
|
+
### What the LLM receives (built by Carto):
|
|
92
|
+
|
|
93
|
+
| Data | How it gets to the LLM |
|
|
94
|
+
|------|----------------------|
|
|
95
|
+
| Structural facts (blast radius, domains, routes) | Carto queries SQLite internally → injects into system prompt |
|
|
96
|
+
| Relevant file contents (actual code) | Carto reads via ACP fileSystem → includes in prompt |
|
|
97
|
+
| Domain context (`.carto/context/AUTH.md` etc.) | Carto reads internally → includes relevant domain |
|
|
98
|
+
| Import graph | Carto summarizes relevant portion → injects |
|
|
99
|
+
| Similar patterns | Carto finds matching files → includes as examples |
|
|
100
|
+
|
|
101
|
+
Carto acts as a **smart filter** — only sends what's relevant. No token waste.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Auto-Index on First Session
|
|
106
|
+
|
|
107
|
+
When a user opens a Carto agent thread in any project:
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
User opens Carto agent thread in Zed
|
|
111
|
+
↓
|
|
112
|
+
Carto checks: does .carto/carto.db exist?
|
|
113
|
+
↓
|
|
114
|
+
NO → automatically runs full indexing
|
|
115
|
+
↓
|
|
116
|
+
• Discovers all source files
|
|
117
|
+
• tree-sitter parse → imports + symbols (0.05–0.2ms/file)
|
|
118
|
+
• Babel deep parse → routes + models (API files only)
|
|
119
|
+
• Leiden+CPM graph clustering → domain detection
|
|
120
|
+
• Computes reverse deps → blast radius
|
|
121
|
+
• Writes .carto/carto.db + context/*.md
|
|
122
|
+
↓
|
|
123
|
+
Takes 1-10 seconds depending on repo size:
|
|
124
|
+
• Prisma (3,303 files): 1.6s
|
|
125
|
+
• Supabase (6,818 files): 4.9s
|
|
126
|
+
• VS Code (10,565 files): 9.7s
|
|
127
|
+
↓
|
|
128
|
+
Agent responds: "Indexed! Found X files, Y routes, Z domains. How can I help?"
|
|
129
|
+
↓
|
|
130
|
+
YES → opens SQLite instantly (<10ms), ready to go
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**On subsequent sessions:** No re-indexing. SQLite opens in <10ms.
|
|
134
|
+
|
|
135
|
+
**On file changes:** If `carto watch` is running, DB stays live. If not, agent can do a quick mtime check on session start (178ms–1.2s for unchanged repos).
|
|
136
|
+
|
|
137
|
+
### What gets created on disk:
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
project/
|
|
141
|
+
├── .carto/
|
|
142
|
+
│ ├── carto.db ← SQLite (import graph, routes, models, domains, blast radius)
|
|
143
|
+
│ ├── config.json ← project settings
|
|
144
|
+
│ └── context/
|
|
145
|
+
│ ├── AUTH.md ← domain context (auto-generated)
|
|
146
|
+
│ ├── CORE.md
|
|
147
|
+
│ ├── DATABASE.md
|
|
148
|
+
│ └── PAYMENTS.md
|
|
149
|
+
├── AGENTS.md ← still generated (useful for other MCP tools)
|
|
150
|
+
└── src/...
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Same as today. ACP doesn't change what Carto creates — just who reads it.
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Supported LLM Providers (BYOK)
|
|
158
|
+
|
|
159
|
+
Carto currently has **zero LLM integration** — it's purely structural intelligence. The ACP agent adds LLM calls. We support any provider the user brings:
|
|
160
|
+
|
|
161
|
+
### Tier 1 — Full support (streaming, tool use, all models)
|
|
162
|
+
|
|
163
|
+
| Provider | Protocol | Models |
|
|
164
|
+
|----------|----------|--------|
|
|
165
|
+
| **OpenAI** | `openai` | GPT-4o, GPT-4o-mini, o1, o3 |
|
|
166
|
+
| **Anthropic** | `anthropic` | Claude Sonnet 4, Claude Haiku |
|
|
167
|
+
| **Google Gemini** | `openai` (compatible) | Gemini 2.5 Pro, 2.5 Flash |
|
|
168
|
+
|
|
169
|
+
### Tier 2 — Works via OpenAI-compatible API
|
|
170
|
+
|
|
171
|
+
| Provider | Protocol | Notes |
|
|
172
|
+
|----------|----------|-------|
|
|
173
|
+
| **Azure OpenAI** | `azure` | Enterprise deployments |
|
|
174
|
+
| **AWS Bedrock** | `bedrock` | Claude/Titan via AWS |
|
|
175
|
+
| **Ollama** | `openai` | Local models (Llama, Mistral, Qwen, DeepSeek) |
|
|
176
|
+
| **OpenRouter** | `openai` | Any model via single API |
|
|
177
|
+
| **Together AI** | `openai` | Open-source models hosted |
|
|
178
|
+
| **Groq** | `openai` | Ultra-fast inference |
|
|
179
|
+
| **LM Studio** | `openai` | Local GUI + API |
|
|
180
|
+
| **vLLM** | `openai` | Self-hosted inference |
|
|
181
|
+
|
|
182
|
+
### How BYOK works in ACP:
|
|
183
|
+
|
|
184
|
+
```
|
|
185
|
+
1. User installs Carto agent in Zed/JetBrains
|
|
186
|
+
2. Editor calls providers/list → Carto returns supported providers
|
|
187
|
+
3. User configures their key in editor settings:
|
|
188
|
+
- API key (stored securely by editor)
|
|
189
|
+
- Base URL (for self-hosted/proxy)
|
|
190
|
+
- Model name
|
|
191
|
+
4. Editor calls providers/set → Carto stores config
|
|
192
|
+
5. All LLM calls use user's key — zero cost to us
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Provider config stored in:
|
|
196
|
+
|
|
197
|
+
```json
|
|
198
|
+
// .carto/agent-config.json (gitignored)
|
|
199
|
+
{
|
|
200
|
+
"provider": {
|
|
201
|
+
"apiType": "anthropic",
|
|
202
|
+
"baseUrl": "https://api.anthropic.com",
|
|
203
|
+
"model": "claude-sonnet-4-20250514"
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
API keys are NEVER stored by Carto — they're passed via ACP `providers/set` headers at runtime and held in memory only.
|
|
209
|
+
|
|
210
|
+
### Cost to user:
|
|
211
|
+
|
|
212
|
+
| Usage Level | Tokens/day | Claude Sonnet | Gemini Flash (free) | Ollama (local) |
|
|
213
|
+
|-------------|-----------|---------------|--------------------|----|
|
|
214
|
+
| Light (5 tasks) | ~50K | ~$0.15 | $0.00 | $0.00 |
|
|
215
|
+
| Medium (15 tasks) | ~150K | ~$0.50 | $0.00 | $0.00 |
|
|
216
|
+
| Heavy (30+ tasks) | ~400K | ~$1.20 | $0.00 (rate limits) | $0.00 |
|
|
217
|
+
| Power user | ~1M | ~$3.00 | Needs paid tier | $0.00 |
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## What ACP Gives You For Free
|
|
222
|
+
|
|
223
|
+
Everything the editor handles natively — zero code from us:
|
|
224
|
+
|
|
225
|
+
| Feature | ACP / Editor Handles It |
|
|
226
|
+
|---------|------------------------|
|
|
227
|
+
| Chat panel UI | ✅ Zed/JetBrains Agent Panel |
|
|
228
|
+
| Multiple chats / threads | ✅ Built-in threads sidebar |
|
|
229
|
+
| Conversation persistence & resume | ✅ Editor manages sessions |
|
|
230
|
+
| Stop / Interrupt button | ✅ Native editor stop |
|
|
231
|
+
| Inline diffs with Accept / Reject | ✅ ACP native diff content type |
|
|
232
|
+
| "Open in Editor" for large diffs | ✅ Native editor behavior |
|
|
233
|
+
| Tool call visibility (collapsed) | ✅ Editor renders agent plan |
|
|
234
|
+
| File read / write / create / delete | ✅ ACP `fileSystem` capability |
|
|
235
|
+
| Terminal / command execution | ✅ ACP `terminals` capability |
|
|
236
|
+
| Streaming token responses | ✅ ACP streams natively |
|
|
237
|
+
| BYOK (Bring Your Own Key) | ✅ ACP `providers/set` |
|
|
238
|
+
| Session list / resume old chats | ✅ ACP `session/list`, `session/resume` |
|
|
239
|
+
| Redirect mid-task | ✅ Editor supports new message while agent runs |
|
|
240
|
+
| Keyboard shortcuts | ✅ Editor-native |
|
|
241
|
+
|
|
242
|
+
**~75-80% of the chat.md spec is free from ACP.**
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## What We Build (The Actual Product)
|
|
247
|
+
|
|
248
|
+
### 1. Auto-Context Injection
|
|
249
|
+
|
|
250
|
+
Every user message gets enriched with structural context before hitting the LLM:
|
|
251
|
+
|
|
252
|
+
```javascript
|
|
253
|
+
// What we inject into the system prompt (user doesn't see this)
|
|
254
|
+
const context = carto.getContextForFile(session.currentFile);
|
|
255
|
+
|
|
256
|
+
// Becomes:
|
|
257
|
+
`Current file: src/auth/auth.service.ts
|
|
258
|
+
Domain: AUTH
|
|
259
|
+
Blast radius: 3 routes, 2 services affected
|
|
260
|
+
- Directly affected: auth.routes.ts, auth.controller.ts, auth.middleware.ts
|
|
261
|
+
- Routes impacted: POST /auth/login, GET /auth/me, POST /auth/register
|
|
262
|
+
Import graph: session.service.ts, user.repository.ts
|
|
263
|
+
Imported by: auth.routes.ts, auth.middleware.ts`
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### 2. Carto Intelligence as Internal Tools
|
|
267
|
+
|
|
268
|
+
The LLM can call these during reasoning (Carto handles them internally):
|
|
269
|
+
|
|
270
|
+
```
|
|
271
|
+
get_blast_radius(file) → full impact analysis
|
|
272
|
+
get_structure() → project architecture
|
|
273
|
+
get_domain(name) → domain routes, models, files
|
|
274
|
+
get_routes() → all API endpoints
|
|
275
|
+
get_change_plan(intent) → files to touch, similar patterns
|
|
276
|
+
get_context(file) → everything about a file
|
|
277
|
+
get_similar_patterns(file) → conventions to follow
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### 3. The Agent Loop
|
|
281
|
+
|
|
282
|
+
```javascript
|
|
283
|
+
async function handlePrompt(userMessage, session) {
|
|
284
|
+
// 1. Auto-index if needed
|
|
285
|
+
if (!dbExists(session.workingDir)) {
|
|
286
|
+
await indexProject(session.workingDir);
|
|
287
|
+
stream("Indexed! Found X files, Y routes, Z domains.\n\n");
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// 2. Get structural context for current file
|
|
291
|
+
const context = carto.getContextForFile(session.currentFile);
|
|
292
|
+
|
|
293
|
+
// 3. Build messages with rich context
|
|
294
|
+
const messages = [
|
|
295
|
+
{ role: "system", content: buildSystemPrompt(context) },
|
|
296
|
+
...session.history,
|
|
297
|
+
{ role: "user", content: userMessage }
|
|
298
|
+
];
|
|
299
|
+
|
|
300
|
+
// 4. Agent loop
|
|
301
|
+
let iterations = 0;
|
|
302
|
+
while (iterations++ < 25) {
|
|
303
|
+
const response = await callLLM(messages, {
|
|
304
|
+
provider: session.provider,
|
|
305
|
+
tools: [...CARTO_TOOLS, ...FILE_TOOLS],
|
|
306
|
+
stream: true
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
for (const block of response) {
|
|
310
|
+
if (block.type === "text") stream(block.text);
|
|
311
|
+
if (block.type === "tool_use") {
|
|
312
|
+
const result = await executeTool(block, session);
|
|
313
|
+
messages.push(toolResult(block.id, result));
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
if (noMoreToolCalls(response)) break;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### 4. System Prompt
|
|
323
|
+
|
|
324
|
+
```
|
|
325
|
+
You are Carto, an AI coding agent with deep architectural awareness.
|
|
326
|
+
|
|
327
|
+
You understand this project's structure before writing a single line:
|
|
328
|
+
- Every file's blast radius (what breaks if this changes)
|
|
329
|
+
- All API routes and which files define them
|
|
330
|
+
- Domain clusters (AUTH, PAYMENTS, DATABASE, etc.)
|
|
331
|
+
- The full import graph and cross-domain dependencies
|
|
332
|
+
|
|
333
|
+
RULES:
|
|
334
|
+
1. Always check blast radius before making changes to high-impact files
|
|
335
|
+
2. Reference real file names and routes — never hallucinate paths
|
|
336
|
+
3. Make minimal, focused changes — read first, then write
|
|
337
|
+
4. Warn the user if a change crosses domain boundaries
|
|
338
|
+
5. After changes, confirm what was changed and what it affects
|
|
339
|
+
6. Use existing patterns (check get_similar_patterns before writing new code)
|
|
340
|
+
7. If unsure, read the relevant files — don't guess
|
|
341
|
+
|
|
342
|
+
CONTEXT (auto-provided every message):
|
|
343
|
+
Current file: {filePath}
|
|
344
|
+
Domain: {domain}
|
|
345
|
+
Blast radius: {blastRadius}
|
|
346
|
+
Imports: {imports}
|
|
347
|
+
Imported by: {importedBy}
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
---
|
|
351
|
+
|
|
352
|
+
## What You Lose vs Standalone Editor
|
|
353
|
+
|
|
354
|
+
| Spec Feature | Reality with ACP |
|
|
355
|
+
|---|---|
|
|
356
|
+
| Custom UI layout (exact mockup) | ❌ Editor's standard agent panel |
|
|
357
|
+
| `📖 🎯 ⚡` icons per tool type | ❌ Editor decides tool call rendering |
|
|
358
|
+
| Auto-context badge visible to user | ❌ Context is invisible (sent to LLM only) |
|
|
359
|
+
| Custom storage format | ❌ Editor manages persistence |
|
|
360
|
+
| Custom keyboard shortcuts | ❌ Editor controls shortcuts |
|
|
361
|
+
|
|
362
|
+
**All cosmetic.** The intelligence differentiators are fully preserved.
|
|
363
|
+
|
|
364
|
+
---
|
|
365
|
+
|
|
366
|
+
## ACP vs Building Standalone
|
|
367
|
+
|
|
368
|
+
| | Standalone Editor | ACP Agent |
|
|
369
|
+
|---|---|---|
|
|
370
|
+
| Time to ship V1 | 6-12 months | 4-6 weeks |
|
|
371
|
+
| UI control | Full | Limited (editor's panel) |
|
|
372
|
+
| Editor reach | Only ours | Zed + JetBrains + VS Code |
|
|
373
|
+
| Core intelligence | ✅ | ✅ (same) |
|
|
374
|
+
| Blast radius / domain awareness | ✅ | ✅ (same) |
|
|
375
|
+
| BYOK | Build it | Free from ACP |
|
|
376
|
+
| Diff viewer | Build it | Free from ACP |
|
|
377
|
+
| Terminal integration | Build it | Free from ACP |
|
|
378
|
+
| Session persistence | Build it | Free from ACP |
|
|
379
|
+
| LLM provider switching | Build it | Free from ACP |
|
|
380
|
+
|
|
381
|
+
---
|
|
382
|
+
|
|
383
|
+
## Implementation Plan
|
|
384
|
+
|
|
385
|
+
### Phase 1 — Core Agent (Week 1-2)
|
|
386
|
+
|
|
387
|
+
- [ ] Add `carto agent` CLI command (starts ACP mode via stdin/stdout)
|
|
388
|
+
- [ ] Implement `AgentSideConnection` with capabilities: `fileSystem`, `terminals`
|
|
389
|
+
- [ ] Auto-index on first session (detect missing `.carto/carto.db` → run sync)
|
|
390
|
+
- [ ] Wire Carto tools as internal agent tools
|
|
391
|
+
- [ ] Build agent loop (context injection → LLM call → tool routing → stream back)
|
|
392
|
+
- [ ] Write system prompt with auto-context
|
|
393
|
+
|
|
394
|
+
### Phase 2 — LLM Providers / BYOK (Week 2-3)
|
|
395
|
+
|
|
396
|
+
- [ ] Implement `providers/list` — advertise supported providers
|
|
397
|
+
- [ ] Implement `providers/set` — accept API key + base URL + model
|
|
398
|
+
- [ ] OpenAI provider (GPT-4o, GPT-4o-mini)
|
|
399
|
+
- [ ] Anthropic provider (Claude Sonnet, Haiku)
|
|
400
|
+
- [ ] Gemini provider (via OpenAI-compatible endpoint)
|
|
401
|
+
- [ ] Generic OpenAI-compatible provider (Ollama, OpenRouter, Together, Groq, LM Studio, vLLM)
|
|
402
|
+
- [ ] Azure OpenAI provider
|
|
403
|
+
- [ ] Store model config in `.carto/agent-config.json` (gitignored, no secrets)
|
|
404
|
+
|
|
405
|
+
### Phase 3 — Polish (Week 3-4)
|
|
406
|
+
|
|
407
|
+
- [ ] 25-iteration safety cap with pause + user prompt
|
|
408
|
+
- [ ] Context overflow handling (auto-summarize old messages)
|
|
409
|
+
- [ ] Blast radius check before AND after file writes
|
|
410
|
+
- [ ] Cross-domain change warnings
|
|
411
|
+
- [ ] Register in ACP Registry (discoverable from Zed/JetBrains)
|
|
412
|
+
|
|
413
|
+
### Phase 4 — Advanced (Week 5+)
|
|
414
|
+
|
|
415
|
+
- [ ] Parallel agent support (multiple Carto threads on different tasks)
|
|
416
|
+
- [ ] Slash commands (`/blast`, `/domain`, `/routes`)
|
|
417
|
+
- [ ] Agent plan display (show what Carto intends to do before doing it)
|
|
418
|
+
- [ ] If traction warrants: standalone editor with full UI control
|
|
419
|
+
|
|
420
|
+
---
|
|
421
|
+
|
|
422
|
+
## Technical Setup
|
|
423
|
+
|
|
424
|
+
```bash
|
|
425
|
+
# Install ACP SDK
|
|
426
|
+
npm install @agentclientprotocol/sdk
|
|
427
|
+
|
|
428
|
+
# CLI commands
|
|
429
|
+
carto serve # existing — MCP mode (passive tools, keep as-is)
|
|
430
|
+
carto agent # new — ACP mode (active agent, stdin/stdout)
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
### File structure (new code):
|
|
434
|
+
|
|
435
|
+
```
|
|
436
|
+
src/
|
|
437
|
+
├── acp/
|
|
438
|
+
│ ├── agent.js ← ACP AgentSideConnection setup
|
|
439
|
+
│ ├── session.js ← Session management + auto-index
|
|
440
|
+
│ ├── prompt.js ← System prompt builder + context injection
|
|
441
|
+
│ ├── tools.js ← Carto tools exposed to LLM
|
|
442
|
+
│ └── providers/
|
|
443
|
+
│ ├── index.js ← Provider registry + BYOK logic
|
|
444
|
+
│ ├── openai.js ← OpenAI/compatible provider
|
|
445
|
+
│ ├── anthropic.js ← Anthropic provider
|
|
446
|
+
│ └── types.js ← Shared types
|
|
447
|
+
├── cli/
|
|
448
|
+
│ ├── index.js ← add "agent" command
|
|
449
|
+
│ └── agent.js ← new: starts ACP mode
|
|
450
|
+
├── mcp/ ← existing MCP server (unchanged)
|
|
451
|
+
└── ... ← existing Carto intelligence (unchanged)
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
---
|
|
455
|
+
|
|
456
|
+
## References
|
|
457
|
+
|
|
458
|
+
- **ACP TypeScript SDK:** `@agentclientprotocol/sdk` ([npm](https://www.npmjs.com/package/@agentclientprotocol/sdk))
|
|
459
|
+
- **ACP Spec:** https://agentclientprotocol.com
|
|
460
|
+
- **Reference impl:** [Gemini CLI ACP](https://github.com/google-gemini/gemini-cli/blob/main/packages/cli/src/zed-integration/zedIntegration.ts)
|
|
461
|
+
- **ACP Registry:** https://zed.dev/blog/acp-registry
|
|
462
|
+
- **Configurable LLM Providers RFD:** https://agentclientprotocol.com/rfds/custom-llm-endpoint
|
|
463
|
+
|
|
464
|
+
---
|
|
465
|
+
|
|
466
|
+
## Why This Makes Sense
|
|
467
|
+
|
|
468
|
+
Carto already has the hard part — understanding codebases at scale:
|
|
469
|
+
- 10,565 files indexed in <10 seconds
|
|
470
|
+
- Blast radius computed in <5ms
|
|
471
|
+
- Domain detection via graph clustering
|
|
472
|
+
- Route/model extraction across 8 languages
|
|
473
|
+
|
|
474
|
+
What it's missing: the ability to **act** on that knowledge. ACP gives it hands (file edits, terminal) and a voice (LLM reasoning). The combination — structural intelligence + LLM + editor integration — is what makes this better than every other AI coding agent.
|
|
475
|
+
|
|
476
|
+
Other agents are smart but blind. Carto sees the architecture. ACP lets it act on what it sees.
|
|
477
|
+
|
|
478
|
+
---
|
|
479
|
+
|
|
480
|
+
*Decision: Go ACP. Auto-index on first session. Support all major LLM providers via BYOK. Ship to Zed + JetBrains in 4-6 weeks.*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "carto-md",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "Structural intelligence layer for AI coding tools. Indexes your codebase into SQLite — routes, models, import graph, blast radius, domains — and exposes 16 MCP tools for Kiro, Cursor, and Claude.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"carto": "src/cli/index.js"
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"test:benchmark": "node test/benchmark.js"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
+
"@agentclientprotocol/sdk": "^0.22.1",
|
|
15
16
|
"@babel/parser": "^7.29.3",
|
|
16
17
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
17
18
|
"better-sqlite3": "11.7.0",
|
|
@@ -39,6 +40,8 @@
|
|
|
39
40
|
"agents",
|
|
40
41
|
"AGENTS.md",
|
|
41
42
|
"AI",
|
|
43
|
+
"acp",
|
|
44
|
+
"agent-client-protocol",
|
|
42
45
|
"context",
|
|
43
46
|
"codebase",
|
|
44
47
|
"developer-tools",
|
|
@@ -51,6 +54,7 @@
|
|
|
51
54
|
"blast-radius",
|
|
52
55
|
"import-graph",
|
|
53
56
|
"kiro",
|
|
54
|
-
"claude"
|
|
57
|
+
"claude",
|
|
58
|
+
"zed"
|
|
55
59
|
]
|
|
56
60
|
}
|