agentcache 0.3.0 → 0.3.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
@@ -27,33 +27,43 @@ No `init`. No `setup`. No config. No second command. The install itself:
27
27
  2. Detects installed IDEs (Claude Code, Cursor, Roo Code, Windsurf, Continue, Codex)
28
28
  3. Registers itself as an MCP server in each
29
29
  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
30
31
 
31
32
  ## How It Works
32
33
 
33
34
  ```
34
- ┌─────────────────────────────────────────────────────────────────┐
35
- Your Machine
36
-
37
- │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
38
- │ │ Claude │ │ Cursor │ │ Roo │ │ Codex │ ...
39
- │ │ Code │ │ │ │ Code │ │ │
40
- │ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘
41
- │ │ │ │ │
42
- │ └──────────────┴──────────────┴──────────────┘
43
- │ │
44
- │ MCP Protocol (stdio)
45
- │ │
46
- │ ┌────────────┴────────────┐
47
- │ │ AgentCache MCP Server │
48
- │ │ (agentcache serve) │
49
- └────────────┬────────────┘
50
-
51
- ┌─────────┴─────────┐
52
- ~/.agentcache/
53
- agentcache.db
54
- (SQLite + WAL)
55
- └───────────────────┘
56
- └─────────────────────────────────────────────────────────────────┘
35
+ ┌──────────────────────────────────────────────────────────────────────┐
36
+ Your Machine
37
+
38
+ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
39
+ │ │ Claude │ │ Cursor │ │ Roo │ │ Codex │ ...
40
+ │ │ Code │ │ │ │ Code │ │ │
41
+ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘
42
+ │ │ │ │ │
43
+ │ └──────────────┴──────────────┴──────────────┘
44
+ │ │
45
+ │ MCP Protocol (stdio)
46
+ │ │
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
+ │ └───────────────────┘ │
66
+ └──────────────────────────────────────────────────────────────────────┘
57
67
  ```
58
68
 
59
69
  ### The Cycle
@@ -92,9 +102,33 @@ AgentCache exposes 8 tools via the Model Context Protocol (prefixed as `mcp--age
92
102
 
93
103
  ```bash
94
104
  agentcache status # Show knowledge stats for current project
105
+ agentcache compile-all # Batch-compile all unprocessed transcripts
95
106
  agentcache setup # Re-register with IDEs (only if postinstall failed)
96
107
  ```
97
108
 
109
+ ### `compile-all` — Standalone Batch Compilation
110
+
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
+ ```
116
+
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
122
+
123
+ No API keys needed if you have any coding CLI installed — it uses their stored authentication.
124
+
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
129
+
130
+ **Transcript sources:** Claude Code, Continue, Codex, Roo Code, Goose
131
+
98
132
  Internal commands (called by hooks automatically, never by users):
99
133
  ```bash
100
134
  agentcache serve # MCP server (IDEs spawn this)
@@ -119,9 +153,10 @@ One database per developer (`~/.agentcache/agentcache.db`), not per project. Rul
119
153
 
120
154
  ### Resilient to Abrupt Exits
121
155
 
122
- Sessions can end without warning (crash, ctrl-c, network drop). AgentCache handles this through:
156
+ Sessions can end without warning (crash, ctrl-c, network drop, MCP pipe death). AgentCache handles this through:
123
157
  - **Incremental submission** — observations are saved as they happen, not batched at the end
124
- - **Transcript recovery** — for Claude Code and Continue, transcripts persist on disk and are compiled next session
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
125
160
  - **Pending queue in SQLite** — concurrent access is safe, nothing lost to race conditions
126
161
 
127
162
  ### Anti-Bloat
@@ -138,15 +173,18 @@ AgentCache prevents knowledge from growing unbounded:
138
173
  |-----|-----|-------------|--------------------|----|
139
174
  | Claude Code | Yes | Yes (automatic) | Full (JSONL) | Stop, SessionStart, PreToolUse |
140
175
  | Cursor | Yes | Yes (automatic) | Incremental only | — |
141
- | Roo Code | Yes | Yes (automatic) | Incremental only | — |
176
+ | Roo Code | Yes | Yes (automatic) | Full (JSON via compile-all) | — |
142
177
  | Windsurf | Yes | Yes (automatic) | Incremental only | — |
143
178
  | Continue | Yes | Yes (automatic) | Full (JSON) | — |
144
- | Codex | Yes | Yes (automatic) | Incremental only | — |
179
+ | Codex | Yes | Yes (automatic) | Full (JSONL via compile-all) | — |
180
+ | Goose | — | — | Full (SQLite via compile-all) | — |
145
181
 
146
182
  All IDEs are fully auto-approved at install time — no manual steps required.
147
183
 
148
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).
149
185
 
186
+ "via compile-all" means `agentcache compile-all` discovers and processes these transcripts in batch, independent of any active MCP session.
187
+
150
188
  ## Data Storage
151
189
 
152
190
  All data lives in `~/.agentcache/agentcache.db` (SQLite with WAL mode for concurrent access).
@@ -176,7 +214,9 @@ Extract → Normalize → Canonicalize → Cluster → Detect Contradictions →
176
214
  - authority: AUTO/USER
177
215
  ```
178
216
 
179
- The compiler is the LLM itself (the agent in your session). AgentCache provides extraction prompts and the agent processes them — no separate API keys or LLM calls needed.
217
+ **Two compilation paths:**
218
+ - **In-session** — the agent in your IDE processes extraction prompts via MCP tools (no separate LLM calls needed)
219
+ - **Batch (`compile-all`)** — runs independently using any available LLM CLI or API, processes the full backlog without depending on active sessions
180
220
 
181
221
  ## Project Identity
182
222
 
@@ -197,7 +237,7 @@ Projects are identified by a hash of their full filesystem path, not just the fo
197
237
  | Windsurf | Supported |
198
238
  | Continue | Supported |
199
239
  | Codex | Supported |
200
- | Goose (Block) | Coming soon |
240
+ | Goose | Supported (transcript recovery via SQLite) |
201
241
  | Aider | Coming soon |
202
242
  | GitHub Copilot | Coming soon |
203
243
  | Zed AI | Coming soon |
@@ -428,6 +428,97 @@ function formatItems(items) {
428
428
  }).join("\n") + "\n";
429
429
  }
430
430
 
431
+ // src/knowledge/passes/7b-skill-projector.ts
432
+ import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "fs";
433
+ import { join } from "path";
434
+ import { homedir } from "os";
435
+ var MAX_SKILL_TOKENS = 5e3;
436
+ var AVG_CHARS_PER_TOKEN = 4;
437
+ var MAX_SKILL_CHARS = MAX_SKILL_TOKENS * AVG_CHARS_PER_TOKEN;
438
+ function projectToSkills(items, projectRoot) {
439
+ const active = items.filter((i) => i.status === "active");
440
+ const globalItems = active.filter((i) => i.scope === "global");
441
+ const projectItems = active.filter((i) => i.scope === "project");
442
+ writeGlobalSkill(globalItems);
443
+ writeProjectSkill(projectItems, projectRoot);
444
+ }
445
+ function writeGlobalSkill(items) {
446
+ const skillDir = join(homedir(), ".agentcache", "skills", "developer-knowledge");
447
+ mkdirSync2(skillDir, { recursive: true });
448
+ const rules = items.filter((i) => i.type === "rule").sort(byConfidence);
449
+ const lessons = items.filter((i) => i.type === "lesson").sort(byConfidence);
450
+ const body = buildSkillBody(rules, lessons, [], []);
451
+ const content = buildSkillFile(
452
+ "developer-knowledge",
453
+ "Engineering rules and lessons learned across all projects \u2014 compiled automatically from coding sessions by AgentCache",
454
+ body
455
+ );
456
+ writeFileSync2(join(skillDir, "SKILL.md"), truncateToLimit(content), "utf-8");
457
+ }
458
+ function writeProjectSkill(items, projectRoot) {
459
+ if (!projectRoot || projectRoot === process.cwd()) return;
460
+ if (items.length === 0) return;
461
+ const skillDir = join(projectRoot, ".agentcache", "skills", "project-knowledge");
462
+ mkdirSync2(skillDir, { recursive: true });
463
+ const rules = items.filter((i) => i.type === "rule").sort(byConfidence);
464
+ const lessons = items.filter((i) => i.type === "lesson").sort(byConfidence);
465
+ const decisions = items.filter((i) => i.type === "decision").sort(byConfidence);
466
+ const context = items.filter((i) => i.type === "context").sort((a, b) => b.lastSeenAt - a.lastSeenAt);
467
+ const body = buildSkillBody(rules, lessons, decisions, context);
468
+ const content = buildSkillFile(
469
+ "project-knowledge",
470
+ "Project-specific decisions, rules, context, and lessons \u2014 compiled automatically from coding sessions by AgentCache",
471
+ body
472
+ );
473
+ writeFileSync2(join(skillDir, "SKILL.md"), truncateToLimit(content), "utf-8");
474
+ }
475
+ function buildSkillFile(name, description, body) {
476
+ return `---
477
+ name: ${name}
478
+ description: "${description}"
479
+ ---
480
+
481
+ ${body}`;
482
+ }
483
+ function buildSkillBody(rules, lessons, decisions, context) {
484
+ let out = "";
485
+ if (rules.length > 0) {
486
+ out += "## Rules\n\nFollow these without exception:\n\n";
487
+ out += rules.map((r) => `- ${r.content}${enforceTag(r)}`).join("\n") + "\n\n";
488
+ }
489
+ if (lessons.length > 0) {
490
+ out += "## Lessons\n\nPitfalls learned from past sessions:\n\n";
491
+ out += lessons.map((l) => `- ${l.content}`).join("\n") + "\n\n";
492
+ }
493
+ if (decisions.length > 0) {
494
+ out += "## Decisions\n\nArchitectural choices in effect \u2014 do not contradict:\n\n";
495
+ out += decisions.map((d) => `- ${d.content}`).join("\n") + "\n\n";
496
+ }
497
+ if (context.length > 0) {
498
+ out += "## Current Context\n\nActive project state (may be temporal):\n\n";
499
+ out += context.map((c) => `- ${c.content}`).join("\n") + "\n\n";
500
+ }
501
+ return out.trimEnd() + "\n";
502
+ }
503
+ function enforceTag(item) {
504
+ return item.enforce ? " [ENFORCED]" : "";
505
+ }
506
+ function byConfidence(a, b) {
507
+ const order = { high: 3, medium: 2, low: 1 };
508
+ return (order[b.confidence] || 0) - (order[a.confidence] || 0);
509
+ }
510
+ function truncateToLimit(content) {
511
+ if (content.length <= MAX_SKILL_CHARS) return content;
512
+ const lines = content.split("\n");
513
+ let result = "";
514
+ for (const line of lines) {
515
+ if ((result + line + "\n").length > MAX_SKILL_CHARS - 50) break;
516
+ result += line + "\n";
517
+ }
518
+ result += "\n<!-- Truncated to stay within 5000 token skill budget -->\n";
519
+ return result;
520
+ }
521
+
431
522
  // src/knowledge/compiler.ts
432
523
  var COMPILER_VERSION = "0.1.0";
433
524
  function startCompile(events, sessionId, project, projectRoot, repo, transcriptPath) {
@@ -472,7 +563,9 @@ function processExtraction(repo, responseText, sessionId, project, projectRoot)
472
563
  repo.saveObservations(normalized);
473
564
  if (canonicalized.needsClustering.length === 0) {
474
565
  saveCompileRun(repo, sessionId, project, normalized.length, canonicalized.autoReinforced.length, 0, 0, 0, 0, 0, Date.now());
475
- projectToMarkdown(repo.getKnowledgeItems(project, { status: "active" }), getDataDir(), COMPILER_VERSION);
566
+ const activeItems = repo.getKnowledgeItems(project, { status: "active" });
567
+ projectToMarkdown(activeItems, getDataDir(), COMPILER_VERSION);
568
+ projectToSkills(activeItems, projectRoot);
476
569
  return {
477
570
  status: "complete",
478
571
  diagnostics: formatDiagnostics(normalized.length, canonicalized.autoReinforced.length, 0, 0, 0, 0, 0, project, sessionId)
@@ -539,7 +632,9 @@ function processClustering(repo, responseText, sessionId, project, projectRoot)
539
632
  }
540
633
  const totalObs = sessionObs.length;
541
634
  saveCompileRun(repo, sessionId, project, totalObs, 0, compiled.created.length, compiled.reinforced.length, compiled.superseded.length, compiled.deprecated.length, compiled.ignored, startedAt);
542
- projectToMarkdown(repo.getKnowledgeItems(project, { status: "active" }), getDataDir(), COMPILER_VERSION);
635
+ const activeItems = repo.getKnowledgeItems(project, { status: "active" });
636
+ projectToMarkdown(activeItems, getDataDir(), COMPILER_VERSION);
637
+ projectToSkills(activeItems, projectRoot);
543
638
  return {
544
639
  status: "complete",
545
640
  diagnostics: formatDiagnostics(totalObs, 0, compiled.created.length, compiled.reinforced.length, compiled.superseded.length, compiled.deprecated.length, compiled.ignored, project, sessionId)
package/dist/cli.js CHANGED
@@ -3,7 +3,7 @@
3
3
  // src/cli.ts
4
4
  import { Command } from "commander";
5
5
  var program = new Command();
6
- program.name("agentcache").description("Engineering Knowledge Compiler \u2014 universal, zero-config").version("0.3.0");
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
8
  const { runSetup } = await import("./setup-5APZETPV.js");
9
9
  await runSetup();
@@ -46,7 +46,7 @@ program.command("enforce").description("PreToolUse hook: policy enforcement").ac
46
46
  }
47
47
  });
48
48
  program.command("compile-all").description("Batch-compile all unprocessed transcripts using an available LLM CLI").action(async () => {
49
- const { runCompileAll } = await import("./compile-all-RWCAU7MO.js");
49
+ const { runCompileAll } = await import("./compile-all-DOQ5XU5K.js");
50
50
  await runCompileAll();
51
51
  });
52
52
  program.command("status").description("Show AgentCache knowledge stats").action(async () => {
@@ -2,7 +2,7 @@ import {
2
2
  processClustering,
3
3
  processExtraction,
4
4
  startCompile
5
- } from "./chunk-IER56P6A.js";
5
+ } from "./chunk-R4SJESNM.js";
6
6
  import {
7
7
  acquireLock,
8
8
  releaseLock
package/dist/mcp.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  processClustering,
7
7
  processExtraction,
8
8
  startCompile
9
- } from "./chunk-IER56P6A.js";
9
+ } from "./chunk-R4SJESNM.js";
10
10
  import {
11
11
  spawnCompileAll
12
12
  } from "./chunk-RXBTPJVW.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentcache",
3
- "version": "0.3.0",
3
+ "version": "0.3.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",