agentcache 0.4.0 → 0.4.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 CHANGED
@@ -1,18 +1,19 @@
1
1
  # AgentCache
2
2
 
3
- **Knowledge cache for AI coding agents** — learns how you work, remembers across sessions, works everywhere.
3
+ Your AI coding agents forget everything between sessions. AgentCache fixes that it learns what you know, remembers it across sessions, and injects it into every future agent automatically, across every IDE.
4
4
 
5
- AgentCache observes your coding sessions and compiles reusable knowledge (rules, lessons, architectural decisions, context) into a local database. Every future sessionregardless of IDE or LLM gets the benefit of everything you've learned before.
5
+ > "Don't mock the database in integration testswe got burned when mocked tests passed but prod migration failed"
6
6
 
7
- ## Why
7
+ That lesson, learned once, becomes a permanent rule. Every future session with every IDE gets it. You never say it again.
8
8
 
9
- Every AI coding session starts from zero. The agent doesn't know your team's conventions, past mistakes, or architectural decisions. You repeat yourself. Bugs recur. Context is lost.
9
+ ## What it does
10
10
 
11
- AgentCache fixes this. It's a persistent knowledge layer that:
12
- - **Learns** rules, lessons, and decisions from your sessions
11
+ AgentCache observes your coding sessions and compiles reusable knowledge — rules, lessons, architectural decisions, project context — into a local database. Every future session gets that knowledge injected at the start, regardless of IDE or LLM.
12
+
13
+ - **Learns** from what your agents discover during sessions
13
14
  - **Injects** relevant knowledge at the start of every new session
14
15
  - **Works everywhere** — any IDE, any LLM, simultaneously
15
- - **Stays local** — SQLite database on your machine, nothing leaves your disk
16
+ - **Stays local** — SQLite on your machine, nothing leaves your disk
16
17
 
17
18
  ## Install
18
19
 
@@ -20,294 +21,223 @@ AgentCache fixes this. It's a persistent knowledge layer that:
20
21
  npm install -g agentcache
21
22
  ```
22
23
 
23
- Done. Start a new session in any IDE. AgentCache is already running.
24
+ Done. Start a session in any IDE AgentCache is already running.
25
+
26
+ No init. No setup. No config. The install:
24
27
 
25
- No `init`. No `setup`. No config. No second command. The install itself:
26
- 1. Creates `~/.agentcache/agentcache.db` (your knowledge store)
28
+ 1. Creates `~/.agentcache/agentcache.db`
27
29
  2. Detects installed IDEs (Claude Code, Cursor, Roo Code, Windsurf, Continue, Codex)
28
30
  3. Registers itself as an MCP server in each
29
31
  4. Sets up Claude Code hooks for automatic transcript recovery
30
- 5. Spawns `compile-all` in background compiles your entire transcript history from all IDEs immediately
32
+ 5. Spawns `compile-all` in background to process your existing transcript history
31
33
 
32
- ## How It Works
34
+ ## Team knowledge — without a sync server
35
+
36
+ Compiled project knowledge is written to `<repo>/.agentcache/skills/project-knowledge/SKILL.md`. Commit it. Every teammate gets your team's accumulated decisions and context on clone, automatically picked up by any Agent Skills-compatible tool.
37
+
38
+ ```markdown
39
+ ## Decisions
40
+ - Using Drizzle ORM over Prisma for raw SQL escape hatches
41
+ - PostgreSQL for all persistent state, Redis for ephemeral cache only
42
+
43
+ ## Current Context
44
+ - Migrating from REST to GraphQL, both coexist until Q3
45
+ ```
46
+
47
+ No sync server. No accounts. Just git.
48
+
49
+ ## How it works
33
50
 
34
51
  ```
35
52
  ┌────────────────────────────────────────────────────────────────────────┐
36
53
  │ Your Machine │
37
54
  │ │
38
- │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
39
- │ │ Claude │ │ Cursor │ │ Roo │ │ Codex │ ...
40
- │ │ Code │ │ │ │ Code │ │ │
41
- │ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘
42
- │ │ │ │ │ │
43
- └─────────────┴─────────────┴─────────────┘
44
-
45
- MCP Protocol (stdio)
55
+ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
56
+ │ │ Claude │ │ Cursor │ │ Roo │ │ Codex │ ...
57
+ │ │ Code │ │ │ │ Code │ │ │
58
+ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘
59
+ └─────────────┴─────────────┴─────────────┘
60
+ MCP Protocol (stdio) │
61
+ ┌────────────┴────────────┐
62
+ │ AgentCache MCP Server
63
+ │ └────────────┬────────────┘ │
46
64
  │ │ │
47
- ┌────────────┴────────────┐ ┌────────────────────┐
48
- AgentCache MCP Server │ │ agentcache
49
- (agentcache serve) │ compile-all
50
- │ │ (standalone CLI)
51
- │ spawns compile-all ────┼────▶│
52
- │ │ when pending > 20 │ │ Uses: claude, │ │
53
- │ └────────────┬────────────┘ │ codex, gemini, │ │
54
- │ │ │ ollama, API keys │ │
55
- │ │ └─────────┬──────────┘ │
56
- │ │ │ │
57
- │ ┌─────────┴────────────────────────────┘ │
58
- │ │ │
59
- │ ▼ │
60
- │ ┌────────────────────┐ │
61
- │ │ ~/.agentcache/ │ │
62
- │ │ agentcache.db │ │
63
- │ │ compile-all.lock │ │
64
- │ │ (SQLite + WAL) │ │
65
- │ └────────────────────┘ │
65
+ ┌─────────┴──────────┐
66
+ ~/.agentcache/
67
+ agentcache.db
68
+ │ (SQLite + WAL)
69
+ └────────────────────┘
66
70
  └────────────────────────────────────────────────────────────────────────┘
67
71
  ```
68
72
 
69
- ### The Cycle
73
+ ### The cycle
70
74
 
71
- 1. **Session starts** — agent calls `inject_context` → gets compiled rules, lessons, decisions
75
+ 1. **Session starts** — agent calls `inject_context` → receives compiled rules, lessons, decisions
72
76
  2. **During session** — agent calls `compile_submit` incrementally as it learns things
73
- 3. **Session ends** — knowledge is already saved. If agent didn't submit (abrupt exit), transcript recovery handles it next session.
77
+ 3. **Session ends** — observations are already saved. If the session terminates unexpectedly, transcript recovery handles it next time.
74
78
 
75
- ### Knowledge Types
79
+ ### Knowledge types
76
80
 
77
81
  | Type | Scope | Example |
78
82
  |------|-------|---------|
79
- | **Rule** | Global | "Always use snake_case for database columns" |
80
- | **Lesson** | Global | "Don't mock the database in integration tests — we got burned when mocked tests passed but prod migration failed" |
81
- | **Decision** | Project | "Using Drizzle ORM over Prisma because we need raw SQL escape hatches" |
82
- | **Context** | Project | "Currently migrating from REST to GraphQL, both coexist" |
83
+ | Rule | Global | "Always use snake_case for database columns" |
84
+ | Lesson | Global | "Don't mock the database in integration tests — mocked tests passed but prod migration failed" |
85
+ | Decision | Project | "Using Drizzle ORM over Prisma because we need raw SQL escape hatches" |
86
+ | Context | Project | "Currently migrating from REST to GraphQL, both coexist" |
83
87
 
84
- Rules and lessons are **global** — they apply to all your projects. Decisions and context are **project-specific**.
88
+ Rules and lessons are global — they apply to all your projects. Decisions and context are project-scoped.
85
89
 
86
- ## MCP Tools
90
+ ## Security model
87
91
 
88
- AgentCache exposes 8 tools via the Model Context Protocol (prefixed as `mcp--agentcache--<tool>` in IDEs):
92
+ AgentCache creates a persistent feedback loop: agents write observations → observations compile into knowledge → knowledge injects into future sessions. This is the product's core value **and** its main attack surface. Both are the same thing.
89
93
 
90
- | Tool | Purpose |
91
- |------|---------|
92
- | `inject_context` | Load compiled knowledge at session start |
93
- | `compile_submit` | Submit observations incrementally during session |
94
- | `compile_cluster` | Resolve clustering when observations overlap existing knowledge |
95
- | `compile_extract` | Process queued transcripts from previous sessions |
96
- | `enforce` | Check tool calls against enforced policy rules |
97
- | `save_observation` | Save a permanent observation (USER authority, never auto-deprecated) |
98
- | `get_knowledge` | Query the knowledge database |
99
- | `deprecate_knowledge` | Mark knowledge as deprecated when it's no longer valid |
94
+ ### What the security model guarantees
100
95
 
101
- ## CLI Commands
96
+ - **Quarantine by default** — AUTO observations (agent-submitted) are never injected until confirmed across 2+ independent sessions. A single prompt-injected `compile_submit` call cannot poison your knowledge base — it lands in quarantine and requires independent reinforcement before it's ever served.
97
+ - **Enforced rules are human-only** — The enforce mechanism (which blocks agent tool calls) can only be set via CLI (`agentcache add-rule --enforce`). No MCP tool can create policy an agent is subject to.
98
+ - **Scope gate** — Agent-submitted observations are always project-scoped. Promotion to global scope requires explicit human action (USER authority). An agent cannot write a global rule.
99
+ - **Quarantine ≠ absent** — Quarantined items are captured and visible in `agentcache review`. They just don't inject. The review command is how you clear or promote them.
102
100
 
103
- ```bash
104
- agentcache status # Show knowledge stats for current project
105
- agentcache compile-all # Batch-compile all unprocessed transcripts
106
- agentcache setup # Re-register with IDEs (only if postinstall failed)
107
- ```
101
+ ### What the security model does not guarantee
108
102
 
109
- ### `compile-all` Standalone Batch Compilation
103
+ - `compile-all` processes raw transcripts that may contain injected content. Extraction prompt hardening raises the bar, but a sufficiently crafted transcript can still produce a quarantined (non-injecting) entry. Review your pending queue periodically.
104
+ - `locked` mode disables `compile_submit` entirely and requires human-triggered batch compilation. It reduces the attack surface significantly but `compile-all` against a poisoned transcript is still a vector.
110
105
 
111
- Processes all pending transcripts across every IDE without depending on MCP pipes or active sessions. Runs independently in a terminal.
112
-
113
- ```bash
114
- agentcache compile-all
115
- ```
106
+ ### Security modes
116
107
 
117
- **LLM backend detection** (first available wins):
118
- 1. CLI tools with stored auth: `claude`, `codex`, `gemini`, `copilot`, `aider`, `goose`
119
- 2. Ollama running locally (`localhost:11434`)
120
- 3. `ANTHROPIC_API_KEY` environment variable
121
- 4. `OPENAI_API_KEY` environment variable
108
+ Configure in `~/.agentcache/config.json`:
122
109
 
123
- No API keys needed if you have any coding CLI installed — it uses their stored authentication.
110
+ ```json
111
+ { "security": "auto" }
112
+ ```
124
113
 
125
- **Automatic triggers:**
126
- - Runs as a background process after `npm install -g agentcache` (clears initial backlog)
127
- - Spawned by the MCP server when pending transcripts exceed 20 (ongoing janitor)
128
- - Lockfile (`~/.agentcache/compile-all.lock`) prevents concurrent runs
114
+ | Mode | Behavior | For |
115
+ |------|----------|-----|
116
+ | `auto` (default) | Quarantine AUTO items inject after 2+ session confirmations | Solo devs, indie shops |
117
+ | `review` | All new items land in quarantine. Nothing injects until `agentcache review` approves it | BFSI, healthcare, regulated environments |
118
+ | `locked` | `compile_submit` disabled. Compile-all only, human-triggered batch review | Maximum control |
129
119
 
130
- **Transcript sources:** Claude Code, Continue, Codex, Roo Code, Goose
120
+ ## CLI commands
131
121
 
132
- Internal commands (called by hooks automatically, never by users):
133
122
  ```bash
134
- agentcache serve # MCP server (IDEs spawn this)
135
- agentcache compile-session # Stop hook
136
- agentcache discover # SessionStart hook
137
- agentcache enforce # PreToolUse hook
123
+ agentcache status # Knowledge stats for current project
124
+ agentcache doctor # Diagnose installation problems
125
+ agentcache review # List quarantined items, approve or reject
126
+ agentcache promote <id> # Promote a single item past quarantine
127
+ agentcache add-rule "never commit secrets" --enforce # Create enforced policy (human only)
128
+ agentcache add-rule "use tabs" --global # Global rule across all projects
129
+ agentcache compile-all # Batch-compile all unprocessed transcripts
130
+ agentcache setup # Re-register with IDEs (only if postinstall failed)
138
131
  ```
139
132
 
140
- ## Design Principles
141
-
142
- ### Zero Config
143
-
144
- `npm install -g agentcache` is the only step. It detects your IDEs, registers itself, and starts working. No dotfiles in your project. No init commands. No config to maintain.
133
+ ## compile-all — batch compilation
145
134
 
146
- ### Universal
135
+ Processes all pending transcripts without depending on active MCP sessions.
147
136
 
148
- AgentCache uses MCP (Model Context Protocol) as its only interface. Any IDE that supports MCP works. Any LLM — Claude, GPT, Gemini, Qwen, Llama — can use the tools. No IDE-specific code paths. No LLM-specific logic.
137
+ **LLM backend (first available wins):**
149
138
 
150
- ### Developer-Scoped
151
-
152
- One database per developer (`~/.agentcache/agentcache.db`), not per project. Rules and lessons learned in one project benefit all your projects. Project-specific decisions stay scoped to their project.
153
-
154
- ### Resilient to Abrupt Exits
155
-
156
- Sessions can end without warning (crash, ctrl-c, network drop, MCP pipe death). AgentCache handles this through:
157
- - **Incremental submission** — observations are saved as they happen, not batched at the end
158
- - **Transcript recovery** — transcripts persist on disk across 5 IDEs (Claude Code, Continue, Codex, Roo Code, Goose) and are compiled by `compile-all`
159
- - **Pipe-independent compilation** — `compile-all` runs as a standalone process, not through MCP stdio pipes that can break during long operations
160
- - **Pending queue in SQLite** — concurrent access is safe, nothing lost to race conditions
161
-
162
- ### Anti-Bloat
163
-
164
- AgentCache prevents knowledge from growing unbounded:
165
- - **Confidence promotion** — observations need repeated confirmation before becoming high-confidence
166
- - **Decay** — auto-compiled items not seen in 30 days get archived
167
- - **Budget caps** — max 20 rules, 10 lessons, 10 decisions, 5 context items injected per session
168
- - **Priority ranking** — USER authority first, then by confidence and recency
169
-
170
- ## Supported IDEs
171
-
172
- | IDE | MCP | Auto-Approve | Transcript Recovery | Hooks |
173
- |-----|-----|-------------|--------------------|----|
174
- | Claude Code | Yes | Yes (automatic) | Full (JSONL) | Stop, SessionStart, PreToolUse |
175
- | Cursor | Yes | Yes (automatic) | Incremental only | — |
176
- | Roo Code | Yes | Yes (automatic) | Full (JSON via compile-all) | — |
177
- | Windsurf | Yes | Yes (automatic) | Incremental only | — |
178
- | Continue | Yes | Yes (automatic) | Full (JSON) | — |
179
- | Codex | Yes | Yes (automatic) | Full (JSONL via compile-all) | — |
180
- | Goose | — | — | Full (SQLite via compile-all) | — |
139
+ 1. CLI tools with stored auth: `claude`, `codex`, `gemini`, `copilot`, `aider`, `goose`
140
+ 2. Ollama at `localhost:11434`
141
+ 3. `ANTHROPIC_API_KEY` or `OPENAI_API_KEY`
181
142
 
182
- All IDEs are fully auto-approved at install time — no manual steps required.
143
+ **Triggers automatically:**
183
144
 
184
- "Incremental only" means if the agent submits observations during the session, they're saved. If the session terminates before any submission, those observations are lost (no transcript access).
145
+ - After `npm install -g agentcache` (clears initial backlog)
146
+ - When pending transcripts exceed 20 (background janitor)
147
+ - Lockfile prevents concurrent runs
185
148
 
186
- "via compile-all" means `agentcache compile-all` discovers and processes these transcripts in batch, independent of any active MCP session.
149
+ ## MCP tools
187
150
 
188
- ## Skill Output (Agent Skills Spec)
151
+ | Tool | Purpose |
152
+ |------|---------|
153
+ | `inject_context` | Load compiled knowledge at session start |
154
+ | `compile_submit` | Submit observations incrementally during session |
155
+ | `compile_cluster` | Resolve clustering when observations overlap existing knowledge |
156
+ | `compile_extract` | Process queued transcripts from previous sessions |
157
+ | `enforce` | Check tool calls against enforced policy rules |
158
+ | `save_observation` | Save a permanent observation (USER authority, never auto-deprecated) |
159
+ | `get_knowledge` | Query the knowledge database |
160
+ | `deprecate_knowledge` | Mark knowledge as deprecated |
189
161
 
190
- Compiled knowledge is automatically projected to SKILL.md files — the [Agent Skills open standard](https://agentskills.io) supported by 38+ tools (Claude Code, Cursor, Codex, Gemini CLI, Copilot, Roo Code, and more).
162
+ ## How knowledge compiles
191
163
 
192
164
  ```
193
- ~/.agentcache/skills/developer-knowledge/SKILL.md # Global: rules + lessons
194
- <repo>/.agentcache/skills/project-knowledge/SKILL.md # Project: decisions + context
165
+ Observations (raw)
166
+
167
+
168
+ Extract → Normalize → Canonicalize → Cluster → Detect Contradictions → Compile
169
+
170
+ ┌───────────────────────────────────────────┘
171
+
172
+ PENDING store
173
+
174
+ ┌─────────┴──────────┐
175
+ │ │
176
+ AUTO items USER items
177
+ (quarantine gate) (inject immediately)
178
+ 2+ sessions before
179
+ injection
195
180
  ```
196
181
 
197
- **Global skill** (`~/.agentcache/skills/`) — your developer identity. Rules and lessons learned across all projects. Auto-discovered by any Agent Skills-compatible tool without MCP.
198
-
199
- **Project skill** (`<repo>/.agentcache/skills/`) — project-specific decisions, context, and rules. Git-trackable. Team members get it on clone. **This is team knowledge sharing without a sync server — just git.**
200
-
201
- Skills auto-refresh on every compilation. Each file stays under 5,000 tokens (Agent Skills budget limit). High-confidence items appear first.
182
+ **Two compilation paths:**
202
183
 
203
- Example output:
204
- ```markdown
205
- ---
206
- name: project-knowledge
207
- description: "Project-specific decisions, rules, context, and lessons — compiled automatically from coding sessions by AgentCache"
208
- ---
184
+ - **In-session** — agent processes extraction via MCP tools in your IDE
185
+ - **Batch** — `compile-all` runs independently, processes full backlog
209
186
 
210
- ## Rules
187
+ **Two output formats:**
211
188
 
212
- Follow these without exception:
189
+ - **MCP injection** — structured context via `inject_context`
190
+ - **SKILL.md** — Agent Skills spec files auto-discovered by 38+ tools without MCP
213
191
 
214
- - Always use path aliases in imports
215
- - Never commit .env files [ENFORCED]
192
+ ## Design principles
216
193
 
217
- ## Decisions
194
+ **Zero config** — `npm install -g agentcache` is the only step. No dotfiles, no init, no config to maintain.
218
195
 
219
- Architectural choices in effect do not contradict:
196
+ **Universal** MCP is the only interface. Any IDE, any LLM. No IDE-specific code paths.
220
197
 
221
- - Using Drizzle ORM over Prisma for raw SQL escape hatches
222
- - PostgreSQL for all persistent state, Redis for ephemeral cache only
198
+ **Developer-scoped** One database per developer, not per project. Global knowledge (rules, lessons) benefits all your projects. Project knowledge stays scoped.
223
199
 
224
- ## Current Context
200
+ **Resilient to abrupt exits** — Incremental submission + transcript recovery + pipe-independent compilation means knowledge survives crashes, ctrl-c, and MCP disconnects.
225
201
 
226
- Active project state (may be temporal):
202
+ **Anti-bloat** Confidence promotion, 30-day decay on unused items, budget caps (20 rules / 10 lessons / 10 decisions / 5 context per session), priority ranking.
227
203
 
228
- - Migrating from REST to GraphQL, both coexist until Q3
229
- ```
204
+ ## Supported IDEs
230
205
 
231
- ## Data Storage
206
+ | IDE | MCP | Auto-Approve | Transcript Recovery | Hooks |
207
+ |-----|-----|-------------|-------------------|-------|
208
+ | Claude Code | Yes | Yes | Full (JSONL) | Stop, SessionStart, PreToolUse |
209
+ | Cursor | Yes | Yes | Incremental only | — |
210
+ | Roo Code | Yes | Yes | Full (JSON via compile-all) | — |
211
+ | Windsurf | Yes | Yes | Incremental only | — |
212
+ | Continue | Yes | Yes | Full (JSON) | — |
213
+ | Codex | Yes | Yes | Full (JSONL via compile-all) | — |
214
+ | Goose | — | — | Full (SQLite via compile-all) | — |
215
+ | Aider | Coming soon | | | |
216
+ | GitHub Copilot | Coming soon | | | |
217
+ | Zed AI | Coming soon | | | |
232
218
 
233
- All data lives in `~/.agentcache/` (SQLite with WAL mode for concurrent access).
219
+ ## Data storage
234
220
 
235
221
  ```
236
222
  ~/.agentcache/
237
223
  ├── agentcache.db # Knowledge, observations, sessions, pending queue
224
+ ├── config.json # Security mode and settings
238
225
  ├── compile-all.lock # Prevents concurrent compilation
239
226
  └── skills/developer-knowledge/SKILL.md # Global skill (auto-generated)
240
227
  ```
241
228
 
242
229
  No data leaves your machine. No network calls. No telemetry. No accounts.
243
230
 
244
- ## How Knowledge Compiles
245
-
246
- ```
247
- Observations (raw)
248
-
249
-
250
- Extract → Normalize → Canonicalize → Cluster → Detect Contradictions → Compile
251
- │ │
252
- │ "Always use ESLint" │
253
- │ "Always use ESLint" ──→ deduplicated, confidence promoted │
254
- │ "Use Prettier not ESLint" ──→ contradiction detected │
255
- │ ▼
256
- Knowledge Items (compiled)
257
- - status: active/deprecated/superseded
258
- - confidence: low/medium/high
259
- - authority: AUTO/USER
260
- ```
261
-
262
- **Two compilation paths:**
263
- - **In-session** — the agent in your IDE processes extraction prompts via MCP tools (no separate LLM calls needed)
264
- - **Batch (`compile-all`)** — runs independently using any available LLM CLI or API, processes the full backlog without depending on active sessions
265
-
266
- **Two output formats:**
267
- - **MCP injection** — structured context served to agents at session start via `inject_context`
268
- - **SKILL.md files** — Agent Skills spec-compliant files auto-discovered by 38+ tools without MCP
269
-
270
- ## Project Identity
231
+ ### Project identity
271
232
 
272
- Projects are identified by a hash of their full filesystem path, not just the folder name. This means:
273
- - `/work/api` and `/personal/api` are different projects
274
- - Renaming a folder creates a new project identity
275
- - Knowledge doesn't leak between same-named projects
233
+ Projects are identified by a hash of their full filesystem path. `/work/api` and `/personal/api` are different projects. Knowledge never leaks between same-named projects in different locations.
276
234
 
277
235
  ## Roadmap
278
236
 
279
- ### More IDEs & Coding Agents
280
-
281
- | Platform | Status |
282
- |----------|--------|
283
- | Claude Code | Supported |
284
- | Cursor | Supported |
285
- | Roo Code | Supported |
286
- | Windsurf | Supported |
287
- | Continue | Supported |
288
- | Codex | Supported |
289
- | Goose | Supported (transcript recovery via SQLite) |
290
- | Aider | Coming soon |
291
- | GitHub Copilot | Coming soon |
292
- | Zed AI | Coming soon |
293
-
294
- Any tool that supports MCP can use AgentCache today via `agentcache serve`. Native integrations for the above are planned to ensure zero-config setup.
295
-
296
- ### Native Plugins
297
-
298
- Marketplace listings and deeper UI integrations for all supported IDEs — surfacing knowledge inline, showing compilation status, and providing one-click management of rules and decisions.
299
-
300
- ### Team Knowledge Sharing
301
-
302
- Share compiled knowledge across your team. Rules and lessons that work for one developer benefit everyone.
303
-
304
- ### Cloud Sync
305
-
306
- Sync your knowledge database across machines. Same developer, different computers, same knowledge.
307
-
308
- ### Analytics Dashboard
309
-
310
- Visibility into what AgentCache is learning — compilation stats, knowledge growth, most-referenced rules, and session coverage.
237
+ - **Native plugins** Marketplace listings and deeper UI integrations for all supported IDEs
238
+ - **Team knowledge sharing** — Share compiled knowledge across your team
239
+ - **Cloud sync** Same developer, different machines, same knowledge
240
+ - **Analytics dashboard** — Compilation stats, knowledge growth, most-referenced rules
311
241
 
312
242
  ## Contributing
313
243
 
@@ -277,16 +277,17 @@ var SqliteKnowledgeRepository = class {
277
277
  if (!row) return null;
278
278
  return this.mapKnowledgeItem(row);
279
279
  }
280
- getKnowledgeForContext(project) {
280
+ getKnowledgeForContext(project, opts) {
281
281
  const decayThreshold = Date.now() - 30 * 24 * 60 * 60 * 1e3;
282
282
  this.db.prepare(
283
283
  `UPDATE knowledge_items SET status = 'archived', updated_at = ?
284
284
  WHERE status = 'active' AND authority = 'AUTO' AND last_seen_at < ?`
285
285
  ).run(Date.now(), decayThreshold);
286
+ const authorityFilter = opts?.userOnly ? `AND authority = 'USER'` : `AND (authority = 'USER' OR observation_count >= 2)`;
286
287
  const rows = this.db.prepare(
287
288
  `SELECT * FROM knowledge_items WHERE status = 'active'
288
289
  AND (scope = 'global' OR project = ?)
289
- AND (authority = 'USER' OR observation_count >= 2)
290
+ ${authorityFilter}
290
291
  ORDER BY
291
292
  CASE authority WHEN 'USER' THEN 0 ELSE 1 END,
292
293
  CASE confidence WHEN 'high' THEN 3 WHEN 'medium' THEN 2 ELSE 1 END DESC,
@@ -382,6 +383,11 @@ var SqliteKnowledgeRepository = class {
382
383
  const row = this.db.prepare("SELECT COUNT(*) as count FROM pending_transcripts").get();
383
384
  return row.count;
384
385
  }
386
+ grandfatherExistingItems() {
387
+ this.db.prepare(
388
+ `UPDATE knowledge_items SET observation_count = 2 WHERE authority = 'AUTO' AND observation_count < 2 AND status = 'active'`
389
+ ).run();
390
+ }
385
391
  getQuarantinedItems(project) {
386
392
  const sql = project ? `SELECT * FROM knowledge_items WHERE status = 'active' AND authority = 'AUTO' AND observation_count < 2 AND (scope = 'global' OR project = ?) ORDER BY created_at DESC` : `SELECT * FROM knowledge_items WHERE status = 'active' AND authority = 'AUTO' AND observation_count < 2 ORDER BY created_at DESC`;
387
393
  const rows = project ? this.db.prepare(sql).all(project) : this.db.prepare(sql).all();
package/dist/cli.js CHANGED
@@ -5,7 +5,7 @@ import { Command } from "commander";
5
5
  var program = new Command();
6
6
  program.name("agentcache").description("Engineering Knowledge Compiler \u2014 universal, zero-config").version("0.3.1");
7
7
  program.command("setup").description("Detect IDEs and register AgentCache (runs automatically on install)").action(async () => {
8
- const { runSetup } = await import("./setup-HE7ZHOEI.js");
8
+ const { runSetup } = await import("./setup-45BVUDXN.js");
9
9
  await runSetup();
10
10
  });
11
11
  program.command("serve").description("Start AgentCache MCP server (spawned by IDEs automatically)").action(async () => {
@@ -14,7 +14,7 @@ program.command("serve").description("Start AgentCache MCP server (spawned by ID
14
14
  });
15
15
  program.command("compile-session").description("Stop hook: queue transcript for compilation").action(async () => {
16
16
  try {
17
- const { handleStop } = await import("./stop-YDXXQJCE.js");
17
+ const { handleStop } = await import("./stop-TPCRE7RE.js");
18
18
  let payload;
19
19
  try {
20
20
  let data = "";
@@ -34,7 +34,7 @@ program.command("compile-session").description("Stop hook: queue transcript for
34
34
  });
35
35
  program.command("discover").description("SessionStart hook: discover uncompiled transcripts").action(async () => {
36
36
  try {
37
- const { handleSessionStart } = await import("./session-start-2OKCIAGB.js");
37
+ const { handleSessionStart } = await import("./session-start-EIHYCS3J.js");
38
38
  await handleSessionStart();
39
39
  } catch (err) {
40
40
  process.stderr.write(`agentcache discover: ${err.message}
@@ -47,7 +47,7 @@ program.command("enforce").description("PreToolUse hook: policy enforcement").ac
47
47
  data += chunk;
48
48
  }
49
49
  try {
50
- const { handlePreToolUse } = await import("./pre-tool-use-D3GM3GEQ.js");
50
+ const { handlePreToolUse } = await import("./pre-tool-use-7F7NTHCS.js");
51
51
  const input = JSON.parse(data);
52
52
  const result = handlePreToolUse(input);
53
53
  process.stdout.write(JSON.stringify(result));
@@ -63,7 +63,7 @@ program.command("review").description("Review quarantined observations \u2014 ap
63
63
  console.log("AgentCache not initialized. Run: agentcache setup");
64
64
  return;
65
65
  }
66
- const { SqliteKnowledgeRepository } = await import("./sqlite-MHG4WEHL.js");
66
+ const { SqliteKnowledgeRepository } = await import("./sqlite-NM2BVHUY.js");
67
67
  const repo = new SqliteKnowledgeRepository(getDbPath());
68
68
  const project = getProjectId(findProjectRoot());
69
69
  const items = repo.getQuarantinedItems(project);
@@ -108,7 +108,7 @@ program.command("promote <id>").description("Promote a specific quarantined item
108
108
  console.log("AgentCache not initialized. Run: agentcache setup");
109
109
  return;
110
110
  }
111
- const { SqliteKnowledgeRepository } = await import("./sqlite-MHG4WEHL.js");
111
+ const { SqliteKnowledgeRepository } = await import("./sqlite-NM2BVHUY.js");
112
112
  const repo = new SqliteKnowledgeRepository(getDbPath());
113
113
  const item = repo.getKnowledgeItem(id);
114
114
  if (!item) {
@@ -127,7 +127,7 @@ program.command("add-rule <content>").description("Add an enforced policy rule (
127
127
  console.log("AgentCache not initialized. Run: agentcache setup");
128
128
  return;
129
129
  }
130
- const { SqliteKnowledgeRepository } = await import("./sqlite-MHG4WEHL.js");
130
+ const { SqliteKnowledgeRepository } = await import("./sqlite-NM2BVHUY.js");
131
131
  const { computeCanonicalHash } = await import("./3-canonicalizer-HIN2F7SZ.js");
132
132
  const repo = new SqliteKnowledgeRepository(getDbPath());
133
133
  const project = getProjectId(findProjectRoot());
@@ -185,7 +185,7 @@ program.command("doctor").description("Diagnose AgentCache installation and repo
185
185
  const dbPath = getDbPath();
186
186
  if (existsSync(dbPath)) {
187
187
  try {
188
- const { SqliteKnowledgeRepository } = await import("./sqlite-MHG4WEHL.js");
188
+ const { SqliteKnowledgeRepository } = await import("./sqlite-NM2BVHUY.js");
189
189
  const repo = new SqliteKnowledgeRepository(dbPath);
190
190
  repo.close();
191
191
  pass(`Database accessible: ${dbPath}`);
@@ -267,7 +267,7 @@ ${ok} passed, ${warn} warnings, ${fail} errors`);
267
267
  if (fail > 0) process.exit(1);
268
268
  });
269
269
  program.command("compile-all").description("Batch-compile all unprocessed transcripts using an available LLM CLI").action(async () => {
270
- const { runCompileAll } = await import("./compile-all-GFWXWRPX.js");
270
+ const { runCompileAll } = await import("./compile-all-7ESDEBFG.js");
271
271
  await runCompileAll();
272
272
  });
273
273
  program.command("status").description("Show AgentCache knowledge stats").action(async () => {
@@ -276,7 +276,7 @@ program.command("status").description("Show AgentCache knowledge stats").action(
276
276
  console.log("AgentCache not initialized. Run: agentcache setup");
277
277
  return;
278
278
  }
279
- const { SqliteKnowledgeRepository } = await import("./sqlite-MHG4WEHL.js");
279
+ const { SqliteKnowledgeRepository } = await import("./sqlite-NM2BVHUY.js");
280
280
  const repo = new SqliteKnowledgeRepository(getDbPath());
281
281
  const projectRoot = findProjectRoot();
282
282
  const project = getProjectId(projectRoot);
@@ -24,7 +24,7 @@ import {
24
24
  } from "./chunk-T4COG3XD.js";
25
25
  import {
26
26
  SqliteKnowledgeRepository
27
- } from "./chunk-ESDTP63R.js";
27
+ } from "./chunk-PSASDZQE.js";
28
28
  import {
29
29
  __esm,
30
30
  __export,
package/dist/mcp.js CHANGED
@@ -24,7 +24,7 @@ import {
24
24
  } from "./chunk-T4COG3XD.js";
25
25
  import {
26
26
  SqliteKnowledgeRepository
27
- } from "./chunk-ESDTP63R.js";
27
+ } from "./chunk-PSASDZQE.js";
28
28
  import "./chunk-KFQGP6VL.js";
29
29
 
30
30
  // src/mcp.ts
@@ -92,9 +92,34 @@ function checkForUpdates() {
92
92
  }
93
93
 
94
94
  // src/mcp.ts
95
- import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
95
+ import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
96
+
97
+ // src/utils/config.ts
98
+ import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
99
+ import { join as join2 } from "path";
100
+ var DEFAULT_CONFIG = {
101
+ security: "auto"
102
+ };
103
+ function getConfigPath() {
104
+ return join2(getDataDir(), "config.json");
105
+ }
106
+ function getConfig() {
107
+ const path = getConfigPath();
108
+ if (!existsSync2(path)) return { ...DEFAULT_CONFIG };
109
+ try {
110
+ const raw = JSON.parse(readFileSync2(path, "utf-8"));
111
+ return { ...DEFAULT_CONFIG, ...raw };
112
+ } catch {
113
+ return { ...DEFAULT_CONFIG };
114
+ }
115
+ }
116
+ function saveConfig(config) {
117
+ writeFileSync2(getConfigPath(), JSON.stringify(config, null, 2), "utf-8");
118
+ }
119
+
120
+ // src/mcp.ts
96
121
  import { randomUUID } from "crypto";
97
- var PKG_VERSION = JSON.parse(readFileSync2(new URL("../package.json", import.meta.url), "utf-8")).version;
122
+ var PKG_VERSION = JSON.parse(readFileSync3(new URL("../package.json", import.meta.url), "utf-8")).version;
98
123
  function defaultScope(type) {
99
124
  return type === "rule" || type === "lesson" ? "global" : "project";
100
125
  }
@@ -117,6 +142,17 @@ function getResolvedProjectRoot() {
117
142
  function getResolvedProjectId() {
118
143
  return getProjectId(getResolvedProjectRoot());
119
144
  }
145
+ function migrateToV04() {
146
+ const config = getConfig();
147
+ if (config.migrated_v04) return;
148
+ try {
149
+ const repo = new SqliteKnowledgeRepository(getDbPath());
150
+ repo.grandfatherExistingItems();
151
+ repo.close();
152
+ saveConfig({ ...config, migrated_v04: true });
153
+ } catch {
154
+ }
155
+ }
120
156
  async function startMcpServer() {
121
157
  const server = new Server(
122
158
  { name: "agentcache", version: PKG_VERSION },
@@ -128,6 +164,7 @@ async function startMcpServer() {
128
164
  server.oninitialized = async () => {
129
165
  await resolveRoots(server);
130
166
  checkForUpdates();
167
+ migrateToV04();
131
168
  };
132
169
  server.setNotificationHandler(RootsListChangedNotificationSchema, async () => {
133
170
  await resolveRoots(server);
@@ -273,7 +310,8 @@ async function startMcpServer() {
273
310
  case "inject_context": {
274
311
  const args = request.params.arguments || {};
275
312
  const project = args.project || detectedProject;
276
- const items = repo.getKnowledgeForContext(project);
313
+ const securityMode = getConfig().security;
314
+ const items = repo.getKnowledgeForContext(project, { userOnly: securityMode === "review" });
277
315
  const rules = items.filter((i) => i.type === "rule").slice(0, 20);
278
316
  const lessons = items.filter((i) => i.type === "lesson").slice(0, 10);
279
317
  const decisions = items.filter((i) => i.type === "decision").slice(0, 10);
@@ -322,6 +360,10 @@ ${quarantined.length} observation(s) pending review \u2014 run \`agentcache revi
322
360
  return { content: [{ type: "text", text: output.trim() }] };
323
361
  }
324
362
  case "compile_submit": {
363
+ const securityMode = getConfig().security;
364
+ if (securityMode === "locked") {
365
+ return { content: [{ type: "text", text: JSON.stringify({ error: "compile_submit disabled \u2014 security mode is 'locked'. Use compile-all for batch processing." }) }], isError: true };
366
+ }
325
367
  const args = request.params.arguments;
326
368
  const project = args.project || detectedProject;
327
369
  const sessionId = `sess_${randomUUID().slice(0, 8)}`;
@@ -348,7 +390,7 @@ ${quarantined.length} observation(s) pending review \u2014 run \`agentcache revi
348
390
  if (!entry) {
349
391
  return { content: [{ type: "text", text: JSON.stringify({ message: "No pending sessions to compile." }) }] };
350
392
  }
351
- if (!existsSync2(entry.transcriptPath)) {
393
+ if (!existsSync3(entry.transcriptPath)) {
352
394
  return { content: [{ type: "text", text: JSON.stringify({ message: `Transcript not found: ${entry.transcriptPath}, skipped.` }) }] };
353
395
  }
354
396
  const events = parseTranscript(entry.transcriptPath);
@@ -13,7 +13,7 @@ import {
13
13
  } from "./chunk-T4COG3XD.js";
14
14
  import {
15
15
  SqliteKnowledgeRepository
16
- } from "./chunk-ESDTP63R.js";
16
+ } from "./chunk-PSASDZQE.js";
17
17
  import "./chunk-KFQGP6VL.js";
18
18
 
19
19
  // src/postinstall.ts
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-T4COG3XD.js";
10
10
  import {
11
11
  SqliteKnowledgeRepository
12
- } from "./chunk-ESDTP63R.js";
12
+ } from "./chunk-PSASDZQE.js";
13
13
  import "./chunk-KFQGP6VL.js";
14
14
 
15
15
  // src/hooks/pre-tool-use.ts
@@ -11,7 +11,7 @@ import {
11
11
  } from "./chunk-T4COG3XD.js";
12
12
  import {
13
13
  SqliteKnowledgeRepository
14
- } from "./chunk-ESDTP63R.js";
14
+ } from "./chunk-PSASDZQE.js";
15
15
  import "./chunk-KFQGP6VL.js";
16
16
 
17
17
  // src/hooks/session-start.ts
@@ -10,7 +10,7 @@ import {
10
10
  } from "./chunk-T4COG3XD.js";
11
11
  import {
12
12
  SqliteKnowledgeRepository
13
- } from "./chunk-ESDTP63R.js";
13
+ } from "./chunk-PSASDZQE.js";
14
14
  import "./chunk-KFQGP6VL.js";
15
15
 
16
16
  // src/setup.ts
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  SqliteKnowledgeRepository
3
- } from "./chunk-ESDTP63R.js";
3
+ } from "./chunk-PSASDZQE.js";
4
4
  import "./chunk-KFQGP6VL.js";
5
5
  export {
6
6
  SqliteKnowledgeRepository
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-T4COG3XD.js";
7
7
  import {
8
8
  SqliteKnowledgeRepository
9
- } from "./chunk-ESDTP63R.js";
9
+ } from "./chunk-PSASDZQE.js";
10
10
  import "./chunk-KFQGP6VL.js";
11
11
 
12
12
  // src/hooks/stop.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentcache",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "Knowledge cache for AI agents — learns how you work, remembers across sessions, works everywhere",
5
5
  "type": "module",
6
6
  "license": "MIT",