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.
Files changed (36) hide show
  1. package/README.md +59 -17
  2. package/dist/mcp/index.d.ts +1 -1
  3. package/dist/mcp/index.js +15 -13
  4. package/dist/mcp/index.js.map +1 -1
  5. package/dist/src/cli-query.d.ts +1 -0
  6. package/dist/src/cli-query.d.ts.map +1 -1
  7. package/dist/src/cli-query.js +8 -3
  8. package/dist/src/cli-query.js.map +1 -1
  9. package/dist/src/cli-sessions.d.ts.map +1 -1
  10. package/dist/src/cli-sessions.js +8 -0
  11. package/dist/src/cli-sessions.js.map +1 -1
  12. package/dist/src/cli.d.ts +1 -1
  13. package/dist/src/cli.js +608 -44
  14. package/dist/src/cli.js.map +1 -1
  15. package/dist/src/codex-session-to-messages.d.ts +22 -0
  16. package/dist/src/codex-session-to-messages.d.ts.map +1 -0
  17. package/dist/src/codex-session-to-messages.js +212 -0
  18. package/dist/src/codex-session-to-messages.js.map +1 -0
  19. package/dist/src/indexer-cli-codex.d.ts +12 -0
  20. package/dist/src/indexer-cli-codex.d.ts.map +1 -0
  21. package/dist/src/indexer-cli-codex.js +126 -0
  22. package/dist/src/indexer-cli-codex.js.map +1 -0
  23. package/dist/src/indexer-cli-vscode.d.ts +14 -0
  24. package/dist/src/indexer-cli-vscode.d.ts.map +1 -0
  25. package/dist/src/indexer-cli-vscode.js +88 -0
  26. package/dist/src/indexer-cli-vscode.js.map +1 -0
  27. package/dist/src/indexer.d.ts +1 -1
  28. package/dist/src/indexer.js +1 -1
  29. package/dist/src/types.d.ts +1 -1
  30. package/dist/src/types.d.ts.map +1 -1
  31. package/dist/src/vscode-transcript-to-messages.d.ts +41 -0
  32. package/dist/src/vscode-transcript-to-messages.d.ts.map +1 -0
  33. package/dist/src/vscode-transcript-to-messages.js +167 -0
  34. package/dist/src/vscode-transcript-to-messages.js.map +1 -0
  35. package/package.json +6 -3
  36. 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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"}
@@ -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<{
@@ -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 = {}) {
@@ -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
  */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
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,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEvF;;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,GAAG,MAAM,CAAC;IACpC,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,GAAG,SAAS,CAAC;IAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;IACrD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;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,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B"}
@@ -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.8.1",
4
- "description": "Automatically index OpenCode, Claude Code, and Cursor sessions into a shared sqlite-vec vector database for semantic search across your AI coding history",
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 and Claude Code sessions stored in the shared vector memory database
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 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.
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 `"cursor"`. Omit to search across all.
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 Cursor are indexed into the **same** database.
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).