code-session-memory 0.3.0
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 +290 -0
- package/dist/mcp/index.d.ts +15 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +140 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/server.d.ts +60 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +192 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/src/chunker.d.ts +18 -0
- package/dist/src/chunker.d.ts.map +1 -0
- package/dist/src/chunker.js +149 -0
- package/dist/src/chunker.js.map +1 -0
- package/dist/src/cli.d.ts +11 -0
- package/dist/src/cli.d.ts.map +1 -0
- package/dist/src/cli.js +514 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/database.d.ts +50 -0
- package/dist/src/database.d.ts.map +1 -0
- package/dist/src/database.js +238 -0
- package/dist/src/database.js.map +1 -0
- package/dist/src/embedder.d.ts +19 -0
- package/dist/src/embedder.d.ts.map +1 -0
- package/dist/src/embedder.js +80 -0
- package/dist/src/embedder.js.map +1 -0
- package/dist/src/indexer-cli-claude.d.ts +14 -0
- package/dist/src/indexer-cli-claude.d.ts.map +1 -0
- package/dist/src/indexer-cli-claude.js +67 -0
- package/dist/src/indexer-cli-claude.js.map +1 -0
- package/dist/src/indexer-cli.d.ts +16 -0
- package/dist/src/indexer-cli.d.ts.map +1 -0
- package/dist/src/indexer-cli.js +53 -0
- package/dist/src/indexer-cli.js.map +1 -0
- package/dist/src/indexer.d.ts +44 -0
- package/dist/src/indexer.d.ts.map +1 -0
- package/dist/src/indexer.js +129 -0
- package/dist/src/indexer.js.map +1 -0
- package/dist/src/session-to-md.d.ts +15 -0
- package/dist/src/session-to-md.d.ts.map +1 -0
- package/dist/src/session-to-md.js +148 -0
- package/dist/src/session-to-md.js.map +1 -0
- package/dist/src/transcript-to-messages.d.ts +32 -0
- package/dist/src/transcript-to-messages.d.ts.map +1 -0
- package/dist/src/transcript-to-messages.js +230 -0
- package/dist/src/transcript-to-messages.js.map +1 -0
- package/dist/src/types.d.ts +91 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +3 -0
- package/dist/src/types.js.map +1 -0
- package/package.json +59 -0
- package/plugin/memory.ts +42 -0
- package/skill/memory.md +61 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A single chunk of content ready to be embedded and stored.
|
|
3
|
+
*/
|
|
4
|
+
export interface DocumentChunk {
|
|
5
|
+
content: string;
|
|
6
|
+
metadata: {
|
|
7
|
+
session_id: string;
|
|
8
|
+
session_title: string;
|
|
9
|
+
project: string;
|
|
10
|
+
heading_hierarchy: string[];
|
|
11
|
+
section: string;
|
|
12
|
+
chunk_id: string;
|
|
13
|
+
url: string;
|
|
14
|
+
hash: string;
|
|
15
|
+
chunk_index: number;
|
|
16
|
+
total_chunks: number;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Which tool produced a session.
|
|
21
|
+
*/
|
|
22
|
+
export type SessionSource = "opencode" | "claude-code";
|
|
23
|
+
/**
|
|
24
|
+
* A row in the sessions_meta table — tracks per-session indexing progress.
|
|
25
|
+
*/
|
|
26
|
+
export interface SessionMeta {
|
|
27
|
+
session_id: string;
|
|
28
|
+
session_title: string;
|
|
29
|
+
project: string;
|
|
30
|
+
source: SessionSource;
|
|
31
|
+
last_indexed_message_id: string | null;
|
|
32
|
+
updated_at: number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Minimal session info shape (subset of OpenCode SDK Session type).
|
|
36
|
+
*/
|
|
37
|
+
export interface SessionInfo {
|
|
38
|
+
id: string;
|
|
39
|
+
title?: string;
|
|
40
|
+
directory?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Minimal message shape used by the indexer (subset of OpenCode SDK types).
|
|
44
|
+
*/
|
|
45
|
+
export interface MessageInfo {
|
|
46
|
+
id: string;
|
|
47
|
+
role: "user" | "assistant";
|
|
48
|
+
time?: {
|
|
49
|
+
created?: number;
|
|
50
|
+
completed?: number;
|
|
51
|
+
};
|
|
52
|
+
agent?: string;
|
|
53
|
+
modelID?: string;
|
|
54
|
+
}
|
|
55
|
+
export interface MessagePart {
|
|
56
|
+
type: string;
|
|
57
|
+
text?: string;
|
|
58
|
+
toolName?: string;
|
|
59
|
+
toolCallId?: string;
|
|
60
|
+
state?: string;
|
|
61
|
+
args?: unknown;
|
|
62
|
+
result?: unknown;
|
|
63
|
+
filename?: string;
|
|
64
|
+
mediaType?: string;
|
|
65
|
+
}
|
|
66
|
+
export interface FullMessage {
|
|
67
|
+
info: MessageInfo;
|
|
68
|
+
parts: MessagePart[];
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Result row returned by the MCP server query tools.
|
|
72
|
+
*/
|
|
73
|
+
export interface QueryResult {
|
|
74
|
+
chunk_id: string;
|
|
75
|
+
distance?: number;
|
|
76
|
+
content: string;
|
|
77
|
+
url?: string;
|
|
78
|
+
section?: string;
|
|
79
|
+
heading_hierarchy?: string;
|
|
80
|
+
chunk_index?: number;
|
|
81
|
+
total_chunks?: number;
|
|
82
|
+
source?: SessionSource;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Config for the database layer.
|
|
86
|
+
*/
|
|
87
|
+
export interface DatabaseConfig {
|
|
88
|
+
dbPath: string;
|
|
89
|
+
embeddingDimension?: number;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE;QACR,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,EAAE,MAAM,CAAC;QACtB,OAAO,EAAE,MAAM,CAAC;QAChB,iBAAiB,EAAE,MAAM,EAAE,CAAC;QAC5B,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,aAAa,CAAC;AAEvD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,aAAa,CAAC;IACtB,uBAAuB,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "code-session-memory",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Automatically index OpenCode and Claude Code sessions into a shared sqlite-vec vector database for semantic search across your AI coding history",
|
|
5
|
+
"type": "commonjs",
|
|
6
|
+
"main": "dist/src/indexer.js",
|
|
7
|
+
"types": "dist/src/indexer.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"code-session-memory": "dist/src/cli.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist/",
|
|
13
|
+
"plugin/",
|
|
14
|
+
"skill/"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsc && chmod 755 dist/src/cli.js dist/mcp/index.js",
|
|
18
|
+
"build:watch": "tsc --watch",
|
|
19
|
+
"start:mcp": "node dist/mcp/index.js",
|
|
20
|
+
"test": "vitest run",
|
|
21
|
+
"test:watch": "vitest",
|
|
22
|
+
"test:coverage": "vitest run --coverage",
|
|
23
|
+
"prepublishOnly": "npm run build"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"opencode",
|
|
27
|
+
"claude-code",
|
|
28
|
+
"mcp",
|
|
29
|
+
"sqlite-vec",
|
|
30
|
+
"vector",
|
|
31
|
+
"memory",
|
|
32
|
+
"ai",
|
|
33
|
+
"sessions"
|
|
34
|
+
],
|
|
35
|
+
"author": "Denis Jannot <djannot@gmail.com>",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"access": "public"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
42
|
+
"@opencode-ai/plugin": "^1.2.8",
|
|
43
|
+
"@opencode-ai/sdk": "^1.2.8",
|
|
44
|
+
"better-sqlite3": "^11.9.1",
|
|
45
|
+
"openai": "^4.20.1",
|
|
46
|
+
"sqlite-vec": "0.1.7-alpha.2",
|
|
47
|
+
"zod": "^3.24.2"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@types/better-sqlite3": "^7.6.12",
|
|
51
|
+
"@types/node": "^20.10.0",
|
|
52
|
+
"@vitest/coverage-v8": "^2.0.0",
|
|
53
|
+
"typescript": "^5.3.2",
|
|
54
|
+
"vitest": "^2.0.0"
|
|
55
|
+
},
|
|
56
|
+
"engines": {
|
|
57
|
+
"node": ">=18.0.0"
|
|
58
|
+
}
|
|
59
|
+
}
|
package/plugin/memory.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* opencode-memory plugin
|
|
3
|
+
*
|
|
4
|
+
* Listens for session.idle events and incrementally indexes new messages
|
|
5
|
+
* into the sqlite-vec database by spawning a Node.js subprocess (so that
|
|
6
|
+
* native modules like better-sqlite3 / sqlite-vec load correctly).
|
|
7
|
+
*
|
|
8
|
+
* Install this file at:
|
|
9
|
+
* ~/.config/opencode/plugins/opencode-memory.ts
|
|
10
|
+
*
|
|
11
|
+
* Or run:
|
|
12
|
+
* npx opencode-memory install
|
|
13
|
+
*
|
|
14
|
+
* Required environment variable:
|
|
15
|
+
* OPENAI_API_KEY — used for generating embeddings
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import type { Plugin } from "@opencode-ai/plugin";
|
|
19
|
+
|
|
20
|
+
// The path below is replaced with an absolute path at install time.
|
|
21
|
+
const INDEXER_CLI = "OPENCODE_MEMORY_INDEXER_PATH";
|
|
22
|
+
|
|
23
|
+
const MemoryPlugin: Plugin = async ({ $, serverUrl }) => {
|
|
24
|
+
return {
|
|
25
|
+
event: async ({ event }) => {
|
|
26
|
+
if (event.type !== "session.idle") return;
|
|
27
|
+
|
|
28
|
+
const sessionId = event.properties.sessionID;
|
|
29
|
+
if (!sessionId) return;
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
await $`node ${INDEXER_CLI} ${sessionId} ${serverUrl.toString()}`.quiet();
|
|
33
|
+
} catch (err: unknown) {
|
|
34
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
35
|
+
console.error(`[opencode-memory] Failed to index session ${sessionId}: ${msg}`);
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export default MemoryPlugin;
|
|
42
|
+
export { MemoryPlugin };
|
package/skill/memory.md
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Search past OpenCode and Claude Code sessions stored in the shared vector memory database
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# code-session-memory
|
|
6
|
+
|
|
7
|
+
You have access to an MCP server called `code-session-memory` that automatically indexes all your past coding sessions — from both **OpenCode** and **Claude Code** — into a single shared local vector database. Every time a session completes a turn, the new messages are embedded and stored, giving you a searchable memory of your entire AI coding history across both tools.
|
|
8
|
+
|
|
9
|
+
## Available tools
|
|
10
|
+
|
|
11
|
+
### `query_sessions`
|
|
12
|
+
|
|
13
|
+
Semantically search across all indexed sessions to find past conversations, decisions, code snippets, or context.
|
|
14
|
+
|
|
15
|
+
**Parameters:**
|
|
16
|
+
- `queryText` *(required)*: A natural language description of what you are looking for.
|
|
17
|
+
- `project` *(optional)*: Filter results to a specific project directory path (e.g. `"/Users/me/myproject"`).
|
|
18
|
+
- `source` *(optional)*: Filter by tool — `"opencode"` or `"claude-code"`. Omit to search across both.
|
|
19
|
+
- `limit` *(optional, default 5)*: Number of results to return (1–20).
|
|
20
|
+
|
|
21
|
+
### `get_session_chunks`
|
|
22
|
+
|
|
23
|
+
Retrieve the full ordered content of a specific session message by URL.
|
|
24
|
+
|
|
25
|
+
**Parameters:**
|
|
26
|
+
- `sessionUrl` *(required)*: The `session://ses_xxx#msg_yyy` URL from a `query_sessions` result.
|
|
27
|
+
- `startIndex` *(optional)*: First chunk index to retrieve (0-based).
|
|
28
|
+
- `endIndex` *(optional)*: Last chunk index to retrieve (0-based, inclusive).
|
|
29
|
+
|
|
30
|
+
## When to use these tools
|
|
31
|
+
|
|
32
|
+
Use `query_sessions` proactively when:
|
|
33
|
+
- The user asks about past work: *"How did we implement the auth flow last week?"*
|
|
34
|
+
- You need context about a recurring problem: *"Have we seen this error before?"*
|
|
35
|
+
- The user references a previous decision: *"What did we decide about the database schema?"*
|
|
36
|
+
- You want to avoid repeating past mistakes or reinventing solutions
|
|
37
|
+
|
|
38
|
+
Use `get_session_chunks` to read the full context around a match from `query_sessions`.
|
|
39
|
+
|
|
40
|
+
## Example usage
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
# Find past work on a topic across all tools
|
|
44
|
+
query_sessions("authentication middleware implementation")
|
|
45
|
+
|
|
46
|
+
# Search only OpenCode sessions for a specific project
|
|
47
|
+
query_sessions("dark mode toggle", project="/Users/me/myapp", source="opencode")
|
|
48
|
+
|
|
49
|
+
# Search only Claude Code sessions
|
|
50
|
+
query_sessions("sqlite migration", source="claude-code")
|
|
51
|
+
|
|
52
|
+
# Get more context from a specific result
|
|
53
|
+
get_session_chunks("session://ses_abc123#msg_def456")
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Notes
|
|
57
|
+
|
|
58
|
+
- Sessions from both OpenCode and Claude Code are indexed into the **same** database.
|
|
59
|
+
- Indexing is automatic — no manual action needed.
|
|
60
|
+
- The database lives at `~/.local/share/code-session-memory/sessions.db`.
|
|
61
|
+
- Embeddings use OpenAI `text-embedding-3-large` (3072 dimensions).
|