code-session-memory 0.8.1 → 0.10.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 +59 -17
- package/dist/mcp/index.d.ts +1 -1
- package/dist/mcp/index.js +15 -13
- package/dist/mcp/index.js.map +1 -1
- package/dist/src/cli-query.d.ts +1 -0
- package/dist/src/cli-query.d.ts.map +1 -1
- package/dist/src/cli-query.js +8 -3
- package/dist/src/cli-query.js.map +1 -1
- package/dist/src/cli-sessions.d.ts.map +1 -1
- package/dist/src/cli-sessions.js +8 -0
- package/dist/src/cli-sessions.js.map +1 -1
- package/dist/src/cli.d.ts +1 -1
- package/dist/src/cli.js +608 -44
- package/dist/src/cli.js.map +1 -1
- package/dist/src/codex-session-to-messages.d.ts +22 -0
- package/dist/src/codex-session-to-messages.d.ts.map +1 -0
- package/dist/src/codex-session-to-messages.js +212 -0
- package/dist/src/codex-session-to-messages.js.map +1 -0
- package/dist/src/indexer-cli-codex.d.ts +12 -0
- package/dist/src/indexer-cli-codex.d.ts.map +1 -0
- package/dist/src/indexer-cli-codex.js +126 -0
- package/dist/src/indexer-cli-codex.js.map +1 -0
- package/dist/src/indexer-cli-vscode.d.ts +14 -0
- package/dist/src/indexer-cli-vscode.d.ts.map +1 -0
- package/dist/src/indexer-cli-vscode.js +88 -0
- package/dist/src/indexer-cli-vscode.js.map +1 -0
- package/dist/src/indexer.d.ts +1 -1
- package/dist/src/indexer.js +1 -1
- package/dist/src/types.d.ts +1 -1
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/vscode-transcript-to-messages.d.ts +41 -0
- package/dist/src/vscode-transcript-to-messages.d.ts.map +1 -0
- package/dist/src/vscode-transcript-to-messages.js +167 -0
- package/dist/src/vscode-transcript-to-messages.js.map +1 -0
- package/package.json +6 -3
- package/skill/memory.md +10 -4
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Entry point for VS Code (Copilot agent) session indexing.
|
|
5
|
+
*
|
|
6
|
+
* Called by the VS Code Stop hook. Receives JSON on stdin:
|
|
7
|
+
* { timestamp, cwd, sessionId, hookEventName, transcript_path, stop_hook_active }
|
|
8
|
+
*
|
|
9
|
+
* Reads the transcript file, converts to FullMessage[], and indexes
|
|
10
|
+
* new messages into the shared sqlite-vec DB.
|
|
11
|
+
*
|
|
12
|
+
* Runs as a Node.js subprocess (not Bun) so native addons load correctly.
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const database_1 = require("./database");
|
|
16
|
+
const indexer_1 = require("./indexer");
|
|
17
|
+
const vscode_transcript_to_messages_1 = require("./vscode-transcript-to-messages");
|
|
18
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
19
|
+
/**
|
|
20
|
+
* Returns true if the last meaningful message in the list is a tool result
|
|
21
|
+
* (user message with tool-invocation:result parts only). This indicates the
|
|
22
|
+
* JSONL was read before VS Code finished writing the final assistant
|
|
23
|
+
* response — we should retry.
|
|
24
|
+
*/
|
|
25
|
+
function endsWithToolResult(messages) {
|
|
26
|
+
if (messages.length === 0)
|
|
27
|
+
return false;
|
|
28
|
+
const last = messages[messages.length - 1];
|
|
29
|
+
if (last.info.role !== "user")
|
|
30
|
+
return false;
|
|
31
|
+
return last.parts.every((p) => p.type === "tool-invocation" && p.state === "result");
|
|
32
|
+
}
|
|
33
|
+
async function main() {
|
|
34
|
+
// Read JSON payload from stdin
|
|
35
|
+
const chunks = [];
|
|
36
|
+
for await (const chunk of process.stdin) {
|
|
37
|
+
chunks.push(chunk);
|
|
38
|
+
}
|
|
39
|
+
let payload;
|
|
40
|
+
try {
|
|
41
|
+
payload = JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
44
|
+
process.stderr.write(`[code-session-memory] Failed to parse stdin: ${err}\n`);
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
const { sessionId, transcript_path: transcriptPath, cwd } = payload;
|
|
48
|
+
if (!sessionId || !transcriptPath) {
|
|
49
|
+
process.stderr.write("[code-session-memory] Missing sessionId or transcript_path in stdin\n");
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
const dbPath = (0, database_1.resolveDbPath)();
|
|
53
|
+
const db = (0, database_1.openDatabase)({ dbPath });
|
|
54
|
+
try {
|
|
55
|
+
// Parse the transcript — retry if the JSONL ends on a tool result,
|
|
56
|
+
// which may mean the transcript is not fully written yet.
|
|
57
|
+
let messages = (0, vscode_transcript_to_messages_1.parseVscodeTranscript)(transcriptPath);
|
|
58
|
+
if (messages.length === 0)
|
|
59
|
+
return;
|
|
60
|
+
const MAX_RETRIES = 5;
|
|
61
|
+
const RETRY_DELAY_MS = 500;
|
|
62
|
+
for (let attempt = 0; attempt < MAX_RETRIES && endsWithToolResult(messages); attempt++) {
|
|
63
|
+
await sleep(RETRY_DELAY_MS);
|
|
64
|
+
messages = (0, vscode_transcript_to_messages_1.parseVscodeTranscript)(transcriptPath);
|
|
65
|
+
}
|
|
66
|
+
// Build a session title from the first user message
|
|
67
|
+
const existingMeta = (0, database_1.getSessionMeta)(db, sessionId);
|
|
68
|
+
const title = existingMeta?.session_title || (0, vscode_transcript_to_messages_1.deriveVscodeSessionTitle)(messages);
|
|
69
|
+
const session = {
|
|
70
|
+
id: sessionId,
|
|
71
|
+
title,
|
|
72
|
+
directory: cwd ?? "",
|
|
73
|
+
};
|
|
74
|
+
await (0, indexer_1.indexNewMessages)(db, session, messages, "vscode");
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
78
|
+
process.stderr.write(`[code-session-memory] Indexing error: ${msg}\n`);
|
|
79
|
+
}
|
|
80
|
+
finally {
|
|
81
|
+
db.close();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
main().catch((err) => {
|
|
85
|
+
process.stderr.write(`[code-session-memory] Fatal: ${err}\n`);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
});
|
|
88
|
+
//# sourceMappingURL=indexer-cli-vscode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indexer-cli-vscode.js","sourceRoot":"","sources":["../../src/indexer-cli-vscode.ts"],"names":[],"mappings":"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"}
|
package/dist/src/indexer.d.ts
CHANGED
|
@@ -19,7 +19,7 @@ export interface IndexerOptions {
|
|
|
19
19
|
* @param db Already-open database connection (caller manages lifecycle)
|
|
20
20
|
* @param session Session metadata (id, title, directory)
|
|
21
21
|
* @param messages All messages in the session
|
|
22
|
-
* @param source Which tool produced the session ("opencode" | "claude-code")
|
|
22
|
+
* @param source Which tool produced the session ("opencode" | "claude-code" | "cursor" | "vscode" | "codex")
|
|
23
23
|
* @param options Optional overrides for API key / model
|
|
24
24
|
*/
|
|
25
25
|
export declare function indexNewMessages(db: Database, session: SessionInfo, messages: FullMessage[], source?: SessionSource, options?: Pick<IndexerOptions, "openAiApiKey" | "embeddingModel">): Promise<{
|
package/dist/src/indexer.js
CHANGED
|
@@ -21,7 +21,7 @@ const session_to_md_1 = require("./session-to-md");
|
|
|
21
21
|
* @param db Already-open database connection (caller manages lifecycle)
|
|
22
22
|
* @param session Session metadata (id, title, directory)
|
|
23
23
|
* @param messages All messages in the session
|
|
24
|
-
* @param source Which tool produced the session ("opencode" | "claude-code")
|
|
24
|
+
* @param source Which tool produced the session ("opencode" | "claude-code" | "cursor" | "vscode" | "codex")
|
|
25
25
|
* @param options Optional overrides for API key / model
|
|
26
26
|
*/
|
|
27
27
|
async function indexNewMessages(db, session, messages, source = "opencode", options = {}) {
|
package/dist/src/types.d.ts
CHANGED
|
@@ -23,7 +23,7 @@ export interface DocumentChunk {
|
|
|
23
23
|
/**
|
|
24
24
|
* Which tool produced a session.
|
|
25
25
|
*/
|
|
26
|
-
export type SessionSource = "opencode" | "claude-code" | "cursor";
|
|
26
|
+
export type SessionSource = "opencode" | "claude-code" | "cursor" | "vscode" | "codex";
|
|
27
27
|
/**
|
|
28
28
|
* A row in the sessions_meta table — tracks per-session indexing progress.
|
|
29
29
|
*/
|
package/dist/src/types.d.ts.map
CHANGED
|
@@ -1 +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;QACrB,gHAAgH;QAChH,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,kFAAkF;QAClF,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,aAAa,GAAG,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses a VS Code (Copilot agent) JSONL transcript into the FullMessage[]
|
|
3
|
+
* format used by the indexer.
|
|
4
|
+
*
|
|
5
|
+
* VS Code writes transcripts to:
|
|
6
|
+
* <workspaceStorage>/<hash>/GitHub.copilot-chat/transcripts/<sessionId>.jsonl
|
|
7
|
+
*
|
|
8
|
+
* The transcript is an ordered event stream. Each line is a JSON object with:
|
|
9
|
+
* - `type`: event type string
|
|
10
|
+
* - `data`: event-specific payload
|
|
11
|
+
* - `id`: unique event UUID
|
|
12
|
+
* - `timestamp`: ISO 8601 timestamp
|
|
13
|
+
* - `parentId`: UUID of the parent event (forms a tree)
|
|
14
|
+
*
|
|
15
|
+
* Known event types:
|
|
16
|
+
* - `session.start` — session metadata (first line)
|
|
17
|
+
* - `user.message` — user turn: { content: string, attachments: [] }
|
|
18
|
+
* - `assistant.turn_start` — marks the start of an assistant turn
|
|
19
|
+
* - `assistant.message` — assistant text: { messageId, content, toolRequests, reasoningText? }
|
|
20
|
+
* - `tool.execution_start` — tool call: { toolCallId, toolName, arguments }
|
|
21
|
+
* - `tool.execution_complete` — tool result: { toolCallId, result, success }
|
|
22
|
+
* - `assistant.turn_end` — marks the end of an assistant turn
|
|
23
|
+
*/
|
|
24
|
+
import type { FullMessage } from "./types";
|
|
25
|
+
/**
|
|
26
|
+
* Parses a VS Code JSONL transcript file into FullMessage[].
|
|
27
|
+
*
|
|
28
|
+
* Produces one FullMessage per logical turn:
|
|
29
|
+
* - user.message → role "user" with text part
|
|
30
|
+
* - assistant.message + associated tool calls → role "assistant" with
|
|
31
|
+
* text part and tool-invocation parts
|
|
32
|
+
* - tool.execution_complete → added as tool-invocation result to the
|
|
33
|
+
* preceding assistant message (if matched) or as a standalone tool message
|
|
34
|
+
*/
|
|
35
|
+
export declare function parseVscodeTranscript(transcriptPath: string): FullMessage[];
|
|
36
|
+
/**
|
|
37
|
+
* Derives a session title from the transcript messages.
|
|
38
|
+
* Uses the first meaningful user message text, truncated to 60 chars.
|
|
39
|
+
*/
|
|
40
|
+
export declare function deriveVscodeSessionTitle(messages: FullMessage[]): string;
|
|
41
|
+
//# sourceMappingURL=vscode-transcript-to-messages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vscode-transcript-to-messages.d.ts","sourceRoot":"","sources":["../../src/vscode-transcript-to-messages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAe,MAAM,SAAS,CAAC;AA0CxD;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,cAAc,EAAE,MAAM,GAAG,WAAW,EAAE,CAiG3E;AAgBD;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,MAAM,CAWxE"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Parses a VS Code (Copilot agent) JSONL transcript into the FullMessage[]
|
|
4
|
+
* format used by the indexer.
|
|
5
|
+
*
|
|
6
|
+
* VS Code writes transcripts to:
|
|
7
|
+
* <workspaceStorage>/<hash>/GitHub.copilot-chat/transcripts/<sessionId>.jsonl
|
|
8
|
+
*
|
|
9
|
+
* The transcript is an ordered event stream. Each line is a JSON object with:
|
|
10
|
+
* - `type`: event type string
|
|
11
|
+
* - `data`: event-specific payload
|
|
12
|
+
* - `id`: unique event UUID
|
|
13
|
+
* - `timestamp`: ISO 8601 timestamp
|
|
14
|
+
* - `parentId`: UUID of the parent event (forms a tree)
|
|
15
|
+
*
|
|
16
|
+
* Known event types:
|
|
17
|
+
* - `session.start` — session metadata (first line)
|
|
18
|
+
* - `user.message` — user turn: { content: string, attachments: [] }
|
|
19
|
+
* - `assistant.turn_start` — marks the start of an assistant turn
|
|
20
|
+
* - `assistant.message` — assistant text: { messageId, content, toolRequests, reasoningText? }
|
|
21
|
+
* - `tool.execution_start` — tool call: { toolCallId, toolName, arguments }
|
|
22
|
+
* - `tool.execution_complete` — tool result: { toolCallId, result, success }
|
|
23
|
+
* - `assistant.turn_end` — marks the end of an assistant turn
|
|
24
|
+
*/
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.parseVscodeTranscript = parseVscodeTranscript;
|
|
30
|
+
exports.deriveVscodeSessionTitle = deriveVscodeSessionTitle;
|
|
31
|
+
const fs_1 = __importDefault(require("fs"));
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
// Parser
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
/**
|
|
36
|
+
* Parses a VS Code JSONL transcript file into FullMessage[].
|
|
37
|
+
*
|
|
38
|
+
* Produces one FullMessage per logical turn:
|
|
39
|
+
* - user.message → role "user" with text part
|
|
40
|
+
* - assistant.message + associated tool calls → role "assistant" with
|
|
41
|
+
* text part and tool-invocation parts
|
|
42
|
+
* - tool.execution_complete → added as tool-invocation result to the
|
|
43
|
+
* preceding assistant message (if matched) or as a standalone tool message
|
|
44
|
+
*/
|
|
45
|
+
function parseVscodeTranscript(transcriptPath) {
|
|
46
|
+
const raw = fs_1.default.readFileSync(transcriptPath, "utf8");
|
|
47
|
+
const lines = raw.split("\n").filter((l) => l.trim());
|
|
48
|
+
const events = [];
|
|
49
|
+
for (const line of lines) {
|
|
50
|
+
try {
|
|
51
|
+
events.push(JSON.parse(line));
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Index tool results by toolCallId for pairing with tool calls
|
|
58
|
+
const toolResults = new Map();
|
|
59
|
+
for (const ev of events) {
|
|
60
|
+
if (ev.type === "tool.execution_complete") {
|
|
61
|
+
const d = ev.data;
|
|
62
|
+
if (d.toolCallId) {
|
|
63
|
+
toolResults.set(d.toolCallId, d);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const messages = [];
|
|
68
|
+
for (const ev of events) {
|
|
69
|
+
switch (ev.type) {
|
|
70
|
+
case "user.message": {
|
|
71
|
+
const d = ev.data;
|
|
72
|
+
const text = d.content?.trim();
|
|
73
|
+
if (!text)
|
|
74
|
+
break;
|
|
75
|
+
messages.push({
|
|
76
|
+
info: {
|
|
77
|
+
id: ev.id,
|
|
78
|
+
role: "user",
|
|
79
|
+
time: { created: new Date(ev.timestamp).getTime() },
|
|
80
|
+
},
|
|
81
|
+
parts: [{ type: "text", text }],
|
|
82
|
+
});
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
case "assistant.message": {
|
|
86
|
+
const d = ev.data;
|
|
87
|
+
const parts = [];
|
|
88
|
+
if (d.content?.trim()) {
|
|
89
|
+
parts.push({ type: "text", text: d.content.trim() });
|
|
90
|
+
}
|
|
91
|
+
// Attach tool calls as tool-invocation parts
|
|
92
|
+
if (Array.isArray(d.toolRequests)) {
|
|
93
|
+
for (const req of d.toolRequests) {
|
|
94
|
+
const result = toolResults.get(req.toolCallId);
|
|
95
|
+
parts.push({
|
|
96
|
+
type: "tool-invocation",
|
|
97
|
+
toolName: req.toolName ?? "unknown",
|
|
98
|
+
toolCallId: req.toolCallId,
|
|
99
|
+
state: result ? "result" : "call",
|
|
100
|
+
args: req.arguments,
|
|
101
|
+
...(result ? { result: formatToolResult(result.result) } : {}),
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (parts.length === 0)
|
|
106
|
+
break;
|
|
107
|
+
messages.push({
|
|
108
|
+
info: {
|
|
109
|
+
id: ev.id,
|
|
110
|
+
role: "assistant",
|
|
111
|
+
time: { created: new Date(ev.timestamp).getTime() },
|
|
112
|
+
},
|
|
113
|
+
parts,
|
|
114
|
+
});
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
// tool.execution_start without a corresponding assistant.message
|
|
118
|
+
// (unlikely in practice, but handle gracefully)
|
|
119
|
+
case "tool.execution_start": {
|
|
120
|
+
const d = ev.data;
|
|
121
|
+
// Only emit standalone tool-call messages if there's no assistant.message
|
|
122
|
+
// that claims this toolCallId via toolRequests — we handle the common
|
|
123
|
+
// case in the assistant.message branch above.
|
|
124
|
+
// Standalone entries are skipped here to avoid duplication.
|
|
125
|
+
void d;
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
default:
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return messages;
|
|
133
|
+
}
|
|
134
|
+
function formatToolResult(result) {
|
|
135
|
+
if (result === undefined || result === null)
|
|
136
|
+
return "(no output)";
|
|
137
|
+
if (typeof result === "string")
|
|
138
|
+
return result;
|
|
139
|
+
try {
|
|
140
|
+
return JSON.stringify(result);
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
return String(result);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// ---------------------------------------------------------------------------
|
|
147
|
+
// Session title
|
|
148
|
+
// ---------------------------------------------------------------------------
|
|
149
|
+
/**
|
|
150
|
+
* Derives a session title from the transcript messages.
|
|
151
|
+
* Uses the first meaningful user message text, truncated to 60 chars.
|
|
152
|
+
*/
|
|
153
|
+
function deriveVscodeSessionTitle(messages) {
|
|
154
|
+
for (const msg of messages) {
|
|
155
|
+
if (msg.info.role !== "user")
|
|
156
|
+
continue;
|
|
157
|
+
for (const part of msg.parts) {
|
|
158
|
+
if (part.type === "text" && part.text) {
|
|
159
|
+
const title = part.text.replace(/\s+/g, " ").trim().slice(0, 60);
|
|
160
|
+
if (title)
|
|
161
|
+
return title;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return "VS Code Session";
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=vscode-transcript-to-messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vscode-transcript-to-messages.js","sourceRoot":"","sources":["../../src/vscode-transcript-to-messages.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "code-session-memory",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Automatically index OpenCode, Claude Code, and
|
|
3
|
+
"version": "0.10.0",
|
|
4
|
+
"description": "Automatically index OpenCode, Claude Code, Cursor, VS Code, and Codex sessions into a shared sqlite-vec vector database for semantic search across your AI coding history",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "dist/src/indexer.js",
|
|
7
7
|
"types": "dist/src/indexer.d.ts",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"skill/"
|
|
15
15
|
],
|
|
16
16
|
"scripts": {
|
|
17
|
-
"build": "tsc && chmod 755 dist/src/cli.js dist/mcp/index.js",
|
|
17
|
+
"build": "tsc && chmod 755 dist/src/cli.js dist/mcp/index.js dist/src/indexer-cli-vscode.js dist/src/indexer-cli-codex.js",
|
|
18
18
|
"build:watch": "tsc --watch",
|
|
19
19
|
"start:mcp": "node dist/mcp/index.js",
|
|
20
20
|
"test": "vitest run",
|
|
@@ -27,6 +27,8 @@
|
|
|
27
27
|
"opencode",
|
|
28
28
|
"claude-code",
|
|
29
29
|
"cursor",
|
|
30
|
+
"vscode",
|
|
31
|
+
"codex",
|
|
30
32
|
"mcp",
|
|
31
33
|
"sqlite-vec",
|
|
32
34
|
"vector",
|
|
@@ -46,6 +48,7 @@
|
|
|
46
48
|
"@opencode-ai/sdk": "^1.2.8",
|
|
47
49
|
"better-sqlite3": "^11.9.1",
|
|
48
50
|
"openai": "^4.20.1",
|
|
51
|
+
"smol-toml": "^1.6.0",
|
|
49
52
|
"sqlite-vec": "0.1.7-alpha.2",
|
|
50
53
|
"zod": "^3.24.2"
|
|
51
54
|
},
|
package/skill/memory.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Search past OpenCode
|
|
2
|
+
description: Search past OpenCode, Claude Code, Cursor, VS Code, and Codex sessions stored in the shared vector memory database
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
# code-session-memory
|
|
6
6
|
|
|
7
|
-
You have access to an MCP server called `code-session-memory` that automatically indexes all your past coding sessions — from
|
|
7
|
+
You have access to an MCP server called `code-session-memory` that automatically indexes all your past coding sessions — from **OpenCode**, **Claude Code**, **Cursor**, **VS Code**, and **Codex** — 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 all tools.
|
|
8
8
|
|
|
9
9
|
## Available tools
|
|
10
10
|
|
|
@@ -15,7 +15,7 @@ Semantically search across all indexed sessions to find past conversations, deci
|
|
|
15
15
|
**Parameters:**
|
|
16
16
|
- `queryText` *(required)*: A natural language description of what you are looking for.
|
|
17
17
|
- `project` *(optional)*: Filter results to a specific project directory path (e.g. `"/Users/me/myproject"`).
|
|
18
|
-
- `source` *(optional)*: Filter by tool — `"opencode"`, `"claude-code"`, or `"
|
|
18
|
+
- `source` *(optional)*: Filter by tool — `"opencode"`, `"claude-code"`, `"cursor"`, `"vscode"`, or `"codex"`. Omit to search across all.
|
|
19
19
|
- `limit` *(optional, default 5)*: Number of results to return (1–20).
|
|
20
20
|
- `fromDate` *(optional)*: Return only chunks indexed on or after this date. ISO 8601, e.g. `"2026-02-01"` or `"2026-02-20T15:00:00Z"`.
|
|
21
21
|
- `toDate` *(optional)*: Return only chunks indexed on or before this date. ISO 8601, e.g. `"2026-02-20"`. Date-only values are treated as end-of-day UTC.
|
|
@@ -51,6 +51,12 @@ query_sessions("dark mode toggle", project="/Users/me/myapp", source="opencode")
|
|
|
51
51
|
# Search only Claude Code sessions
|
|
52
52
|
query_sessions("sqlite migration", source="claude-code")
|
|
53
53
|
|
|
54
|
+
# Search only VS Code sessions
|
|
55
|
+
query_sessions("refactoring utils", source="vscode")
|
|
56
|
+
|
|
57
|
+
# Search only Codex sessions
|
|
58
|
+
query_sessions("openapi mock server", source="codex")
|
|
59
|
+
|
|
54
60
|
# Search sessions from a specific date range
|
|
55
61
|
query_sessions("authentication middleware", fromDate="2026-02-01", toDate="2026-02-20")
|
|
56
62
|
|
|
@@ -60,7 +66,7 @@ get_session_chunks("session://ses_abc123#msg_def456")
|
|
|
60
66
|
|
|
61
67
|
## Notes
|
|
62
68
|
|
|
63
|
-
- Sessions from OpenCode, Claude Code, and
|
|
69
|
+
- Sessions from OpenCode, Claude Code, Cursor, VS Code, and Codex are indexed into the **same** database.
|
|
64
70
|
- Indexing is automatic — no manual action needed.
|
|
65
71
|
- The database lives at `~/.local/share/code-session-memory/sessions.db`.
|
|
66
72
|
- Embeddings use OpenAI `text-embedding-3-large` (3072 dimensions).
|