agentcache 0.3.1 → 0.3.2

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
@@ -32,38 +32,38 @@ No `init`. No `setup`. No config. No second command. The install itself:
32
32
  ## How It Works
33
33
 
34
34
  ```
35
- ┌──────────────────────────────────────────────────────────────────────┐
36
- │ Your Machine
37
-
38
- │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
39
- │ │ Claude │ │ Cursor │ │ Roo │ │ Codex │ ...
40
- │ │ Code │ │ │ │ Code │ │ │
41
- │ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘
42
- │ │
43
- └──────────────┴──────────────┴──────────────┘
35
+ ┌────────────────────────────────────────────────────────────────────────┐
36
+ │ Your Machine
37
+
38
+ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
39
+ │ │ Claude │ │ Cursor │ │ Roo │ │ Codex │ ...
40
+ │ │ Code │ │ │ │ Code │ │ │
41
+ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘
42
+ │ │
43
+ └─────────────┴─────────────┴─────────────┘
44
44
  │ │ │
45
45
  │ MCP Protocol (stdio) │
46
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, │ │
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
54
  │ │ │ ollama, API keys │ │
55
55
  │ │ └─────────┬──────────┘ │
56
56
  │ │ │ │
57
57
  │ ┌─────────┴────────────────────────────┘ │
58
- │ │
59
- │ ▼
60
- ┌───────────────────┐
61
- │ │ ~/.agentcache/ │
62
- │ │ agentcache.db │
63
- │ │ compile-all.lock │
64
- │ │ (SQLite + WAL) │
65
- └───────────────────┘
66
- └──────────────────────────────────────────────────────────────────────┘
58
+ │ │
59
+ │ ▼
60
+ ┌────────────────────┐
61
+ │ │ ~/.agentcache/ │
62
+ │ │ agentcache.db │
63
+ │ │ compile-all.lock │
64
+ │ │ (SQLite + WAL) │
65
+ └────────────────────┘
66
+ └────────────────────────────────────────────────────────────────────────┘
67
67
  ```
68
68
 
69
69
  ### The Cycle
@@ -185,13 +185,58 @@ All IDEs are fully auto-approved at install time — no manual steps required.
185
185
 
186
186
  "via compile-all" means `agentcache compile-all` discovers and processes these transcripts in batch, independent of any active MCP session.
187
187
 
188
+ ## Skill Output (Agent Skills Spec)
189
+
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).
191
+
192
+ ```
193
+ ~/.agentcache/skills/developer-knowledge/SKILL.md # Global: rules + lessons
194
+ <repo>/.agentcache/skills/project-knowledge/SKILL.md # Project: decisions + context
195
+ ```
196
+
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.
202
+
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
+ ---
209
+
210
+ ## Rules
211
+
212
+ Follow these without exception:
213
+
214
+ - Always use path aliases in imports
215
+ - Never commit .env files [ENFORCED]
216
+
217
+ ## Decisions
218
+
219
+ Architectural choices in effect — do not contradict:
220
+
221
+ - Using Drizzle ORM over Prisma for raw SQL escape hatches
222
+ - PostgreSQL for all persistent state, Redis for ephemeral cache only
223
+
224
+ ## Current Context
225
+
226
+ Active project state (may be temporal):
227
+
228
+ - Migrating from REST to GraphQL, both coexist until Q3
229
+ ```
230
+
188
231
  ## Data Storage
189
232
 
190
- All data lives in `~/.agentcache/agentcache.db` (SQLite with WAL mode for concurrent access).
233
+ All data lives in `~/.agentcache/` (SQLite with WAL mode for concurrent access).
191
234
 
192
235
  ```
193
236
  ~/.agentcache/
194
- └── agentcache.db # All knowledge, observations, sessions, pending queue
237
+ ├── agentcache.db # Knowledge, observations, sessions, pending queue
238
+ ├── compile-all.lock # Prevents concurrent compilation
239
+ └── skills/developer-knowledge/SKILL.md # Global skill (auto-generated)
195
240
  ```
196
241
 
197
242
  No data leaves your machine. No network calls. No telemetry. No accounts.
@@ -218,6 +263,10 @@ Extract → Normalize → Canonicalize → Cluster → Detect Contradictions →
218
263
  - **In-session** — the agent in your IDE processes extraction prompts via MCP tools (no separate LLM calls needed)
219
264
  - **Batch (`compile-all`)** — runs independently using any available LLM CLI or API, processes the full backlog without depending on active sessions
220
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
+
221
270
  ## Project Identity
222
271
 
223
272
  Projects are identified by a hash of their full filesystem path, not just the folder name. This means:
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  getDataDir,
3
3
  getGitContext
4
- } from "./chunk-WHP4Z32Z.js";
4
+ } from "./chunk-S4GSIEKL.js";
5
5
 
6
6
  // src/knowledge/passes/3-canonicalizer.ts
7
7
  import { createHash } from "crypto";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  getClaudeTranscriptsDir,
3
3
  getContinueSessionsDir
4
- } from "./chunk-WHP4Z32Z.js";
4
+ } from "./chunk-S4GSIEKL.js";
5
5
  import {
6
6
  __export
7
7
  } from "./chunk-KFQGP6VL.js";
@@ -8,12 +8,14 @@ import { createHash } from "crypto";
8
8
  import { execSync } from "child_process";
9
9
  function run(cmd, cwd) {
10
10
  try {
11
- return execSync(cmd, { cwd, encoding: "utf-8", timeout: 5e3 }).trim();
11
+ return execSync(cmd, { cwd, encoding: "utf-8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] }).trim();
12
12
  } catch {
13
13
  return "";
14
14
  }
15
15
  }
16
16
  function getGitContext(projectRoot) {
17
+ const empty = { branch: "", commit: "", recentCommits: [], modifiedFiles: [] };
18
+ if (!run("git rev-parse --git-dir", projectRoot)) return empty;
17
19
  const branch = run("git rev-parse --abbrev-ref HEAD", projectRoot);
18
20
  const commit = run("git rev-parse --short HEAD", projectRoot);
19
21
  const recentCommits = run("git log --oneline -10", projectRoot).split("\n").filter(Boolean);
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getDataDir
3
- } from "./chunk-WHP4Z32Z.js";
3
+ } from "./chunk-S4GSIEKL.js";
4
4
 
5
5
  // src/utils/background-compile.ts
6
6
  import { spawn } from "child_process";
@@ -128,6 +128,9 @@ var SqliteKnowledgeRepository = class {
128
128
  if (!row) return null;
129
129
  return this.mapSession(row);
130
130
  }
131
+ updateSessionTranscriptPath(sessionId, transcriptPath) {
132
+ this.db.prepare("UPDATE sessions SET transcript_path = ? WHERE id = ?").run(transcriptPath, sessionId);
133
+ }
131
134
  getCompiledTranscriptPaths(project) {
132
135
  const rows = this.db.prepare("SELECT transcript_path FROM sessions WHERE project = ? AND transcript_path != ''").all(project);
133
136
  return rows.map((r) => r.transcript_path);
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-5APZETPV.js");
8
+ const { runSetup } = await import("./setup-TVNRAAK3.js");
9
9
  await runSetup();
10
10
  });
11
11
  program.command("serve").description("Start AgentCache MCP server (spawned by IDEs automatically)").action(async () => {
@@ -13,7 +13,7 @@ program.command("serve").description("Start AgentCache MCP server (spawned by ID
13
13
  await startMcpServer();
14
14
  });
15
15
  program.command("compile-session").description("Stop hook: queue transcript for compilation").action(async () => {
16
- const { handleStop } = await import("./stop-6SROS34Q.js");
16
+ const { handleStop } = await import("./stop-HFZZ2LFA.js");
17
17
  let payload;
18
18
  try {
19
19
  let data = "";
@@ -28,11 +28,11 @@ program.command("compile-session").description("Stop hook: queue transcript for
28
28
  await handleStop(payload);
29
29
  });
30
30
  program.command("discover").description("SessionStart hook: discover uncompiled transcripts").action(async () => {
31
- const { handleSessionStart } = await import("./session-start-YSRUGD5N.js");
31
+ const { handleSessionStart } = await import("./session-start-SUR6FXRD.js");
32
32
  await handleSessionStart();
33
33
  });
34
34
  program.command("enforce").description("PreToolUse hook: policy enforcement").action(async () => {
35
- const { handlePreToolUse } = await import("./pre-tool-use-OWWS54XG.js");
35
+ const { handlePreToolUse } = await import("./pre-tool-use-UBJFRHCW.js");
36
36
  let data = "";
37
37
  for await (const chunk of process.stdin) {
38
38
  data += chunk;
@@ -46,16 +46,16 @@ 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-DOQ5XU5K.js");
49
+ const { runCompileAll } = await import("./compile-all-XQBGUI3F.js");
50
50
  await runCompileAll();
51
51
  });
52
52
  program.command("status").description("Show AgentCache knowledge stats").action(async () => {
53
- const { getDbPath, isInitialized, findProjectRoot, getProjectId, getProjectDisplayName } = await import("./paths-LOLEIMI5.js");
53
+ const { getDbPath, isInitialized, findProjectRoot, getProjectId, getProjectDisplayName } = await import("./paths-ULP2T4HZ.js");
54
54
  if (!isInitialized()) {
55
55
  console.log("AgentCache not initialized. Run: agentcache setup");
56
56
  return;
57
57
  }
58
- const { SqliteKnowledgeRepository } = await import("./sqlite-AUND6HGQ.js");
58
+ const { SqliteKnowledgeRepository } = await import("./sqlite-MP6SRBBQ.js");
59
59
  const repo = new SqliteKnowledgeRepository(getDbPath());
60
60
  const projectRoot = findProjectRoot();
61
61
  const project = getProjectId(projectRoot);
@@ -2,11 +2,11 @@ import {
2
2
  processClustering,
3
3
  processExtraction,
4
4
  startCompile
5
- } from "./chunk-R4SJESNM.js";
5
+ } from "./chunk-OXHITHDC.js";
6
6
  import {
7
7
  acquireLock,
8
8
  releaseLock
9
- } from "./chunk-RXBTPJVW.js";
9
+ } from "./chunk-VFE4SDMO.js";
10
10
  import {
11
11
  findAllClaudeTranscripts,
12
12
  findAllCodexTranscripts,
@@ -14,15 +14,15 @@ import {
14
14
  findAllRooCodeTranscripts,
15
15
  getGooseDbPath,
16
16
  parseTranscript
17
- } from "./chunk-TE6DBLJ5.js";
17
+ } from "./chunk-QVQJPJGX.js";
18
18
  import {
19
19
  getDbPath,
20
20
  getProjectId,
21
21
  isInitialized
22
- } from "./chunk-WHP4Z32Z.js";
22
+ } from "./chunk-S4GSIEKL.js";
23
23
  import {
24
24
  SqliteKnowledgeRepository
25
- } from "./chunk-MMSMDJ4O.js";
25
+ } from "./chunk-ZVDODLZ7.js";
26
26
  import {
27
27
  __esm,
28
28
  __export,
@@ -317,16 +317,18 @@ function processOneTranscript(repo, path, project, projectRoot, backend) {
317
317
  const events = parseTranscript(path);
318
318
  if (events.length < 3) return { created: 0, reinforced: 0, skipped: true };
319
319
  const sessionId = `sess_${randomUUID().slice(0, 8)}`;
320
- const state = startCompile(events, sessionId, project, projectRoot, repo, path);
320
+ const state = startCompile(events, sessionId, project, projectRoot, repo);
321
321
  const extractionResponse = backend.invoke(state.prompt);
322
322
  if (!extractionResponse) return { created: 0, reinforced: 0, skipped: true };
323
323
  const extractResult = processExtraction(repo, extractionResponse, sessionId, project, projectRoot);
324
324
  if (extractResult.status === "complete") {
325
+ repo.updateSessionTranscriptPath(sessionId, path);
325
326
  return { created: 0, reinforced: 0, skipped: false };
326
327
  }
327
328
  const clusterResponse = backend.invoke(extractResult.clusteringPrompt);
328
329
  if (!clusterResponse) return { created: 0, reinforced: 0, skipped: true };
329
330
  const clusterResult = processClustering(repo, clusterResponse, sessionId, project, projectRoot);
331
+ repo.updateSessionTranscriptPath(sessionId, path);
330
332
  const diag = clusterResult.diagnostics;
331
333
  const createdMatch = diag.match(/(\d+) new knowledge/);
332
334
  const reinforcedMatch = diag.match(/(\d+) reinforced/);
package/dist/mcp.js CHANGED
@@ -6,22 +6,22 @@ import {
6
6
  processClustering,
7
7
  processExtraction,
8
8
  startCompile
9
- } from "./chunk-R4SJESNM.js";
9
+ } from "./chunk-OXHITHDC.js";
10
10
  import {
11
11
  spawnCompileAll
12
- } from "./chunk-RXBTPJVW.js";
12
+ } from "./chunk-VFE4SDMO.js";
13
13
  import {
14
14
  parseTranscript
15
- } from "./chunk-TE6DBLJ5.js";
15
+ } from "./chunk-QVQJPJGX.js";
16
16
  import {
17
17
  findProjectRoot,
18
18
  getDbPath,
19
19
  getProjectId,
20
20
  isInitialized
21
- } from "./chunk-WHP4Z32Z.js";
21
+ } from "./chunk-S4GSIEKL.js";
22
22
  import {
23
23
  SqliteKnowledgeRepository
24
- } from "./chunk-MMSMDJ4O.js";
24
+ } from "./chunk-ZVDODLZ7.js";
25
25
  import "./chunk-KFQGP6VL.js";
26
26
 
27
27
  // src/mcp.ts
@@ -8,7 +8,7 @@ import {
8
8
  getProjectId,
9
9
  isInitialized,
10
10
  migrateFromLegacy
11
- } from "./chunk-WHP4Z32Z.js";
11
+ } from "./chunk-S4GSIEKL.js";
12
12
  import "./chunk-KFQGP6VL.js";
13
13
  export {
14
14
  findProjectRoot,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  spawnCompileAll
3
- } from "./chunk-RXBTPJVW.js";
3
+ } from "./chunk-VFE4SDMO.js";
4
4
  import {
5
5
  detectInstalledIdes,
6
6
  registerClaudeHooks,
@@ -10,10 +10,10 @@ import {
10
10
  getDataDir,
11
11
  getDbPath,
12
12
  migrateFromLegacy
13
- } from "./chunk-WHP4Z32Z.js";
13
+ } from "./chunk-S4GSIEKL.js";
14
14
  import {
15
15
  SqliteKnowledgeRepository
16
- } from "./chunk-MMSMDJ4O.js";
16
+ } from "./chunk-ZVDODLZ7.js";
17
17
  import "./chunk-KFQGP6VL.js";
18
18
 
19
19
  // src/postinstall.ts
@@ -6,10 +6,10 @@ import {
6
6
  getDbPath,
7
7
  getProjectId,
8
8
  isInitialized
9
- } from "./chunk-WHP4Z32Z.js";
9
+ } from "./chunk-S4GSIEKL.js";
10
10
  import {
11
11
  SqliteKnowledgeRepository
12
- } from "./chunk-MMSMDJ4O.js";
12
+ } from "./chunk-ZVDODLZ7.js";
13
13
  import "./chunk-KFQGP6VL.js";
14
14
 
15
15
  // src/hooks/pre-tool-use.ts
@@ -3,15 +3,15 @@ import {
3
3
  findAllCodexTranscripts,
4
4
  findAllContinueTranscripts,
5
5
  findAllRooCodeTranscripts
6
- } from "./chunk-TE6DBLJ5.js";
6
+ } from "./chunk-QVQJPJGX.js";
7
7
  import {
8
8
  getDbPath,
9
9
  getProjectId,
10
10
  isInitialized
11
- } from "./chunk-WHP4Z32Z.js";
11
+ } from "./chunk-S4GSIEKL.js";
12
12
  import {
13
13
  SqliteKnowledgeRepository
14
- } from "./chunk-MMSMDJ4O.js";
14
+ } from "./chunk-ZVDODLZ7.js";
15
15
  import "./chunk-KFQGP6VL.js";
16
16
 
17
17
  // src/hooks/session-start.ts
@@ -7,10 +7,10 @@ import {
7
7
  getDataDir,
8
8
  getDbPath,
9
9
  migrateFromLegacy
10
- } from "./chunk-WHP4Z32Z.js";
10
+ } from "./chunk-S4GSIEKL.js";
11
11
  import {
12
12
  SqliteKnowledgeRepository
13
- } from "./chunk-MMSMDJ4O.js";
13
+ } from "./chunk-ZVDODLZ7.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-MMSMDJ4O.js";
3
+ } from "./chunk-ZVDODLZ7.js";
4
4
  import "./chunk-KFQGP6VL.js";
5
5
  export {
6
6
  SqliteKnowledgeRepository
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  findLatestTranscript
3
- } from "./chunk-TE6DBLJ5.js";
3
+ } from "./chunk-QVQJPJGX.js";
4
4
  import {
5
5
  findProjectRoot,
6
6
  getDbPath,
7
7
  getProjectId,
8
8
  isInitialized
9
- } from "./chunk-WHP4Z32Z.js";
9
+ } from "./chunk-S4GSIEKL.js";
10
10
  import {
11
11
  SqliteKnowledgeRepository
12
- } from "./chunk-MMSMDJ4O.js";
12
+ } from "./chunk-ZVDODLZ7.js";
13
13
  import "./chunk-KFQGP6VL.js";
14
14
 
15
15
  // src/hooks/stop.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentcache",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
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",