code-session-memory 0.4.4 → 0.6.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 +75 -58
  2. package/dist/mcp/index.js +23 -2
  3. package/dist/mcp/index.js.map +1 -1
  4. package/dist/mcp/server.d.ts +4 -2
  5. package/dist/mcp/server.d.ts.map +1 -1
  6. package/dist/mcp/server.js +11 -3
  7. package/dist/mcp/server.js.map +1 -1
  8. package/dist/src/cli-sessions.d.ts +6 -7
  9. package/dist/src/cli-sessions.d.ts.map +1 -1
  10. package/dist/src/cli-sessions.js +238 -178
  11. package/dist/src/cli-sessions.js.map +1 -1
  12. package/dist/src/cli.js +272 -12
  13. package/dist/src/cli.js.map +1 -1
  14. package/dist/src/cursor-to-messages.d.ts +64 -0
  15. package/dist/src/cursor-to-messages.d.ts.map +1 -0
  16. package/dist/src/cursor-to-messages.js +243 -0
  17. package/dist/src/cursor-to-messages.js.map +1 -0
  18. package/dist/src/cursor-transcript-to-messages.d.ts +22 -0
  19. package/dist/src/cursor-transcript-to-messages.d.ts.map +1 -0
  20. package/dist/src/cursor-transcript-to-messages.js +79 -0
  21. package/dist/src/cursor-transcript-to-messages.js.map +1 -0
  22. package/dist/src/database.d.ts +13 -2
  23. package/dist/src/database.d.ts.map +1 -1
  24. package/dist/src/database.js +42 -8
  25. package/dist/src/database.js.map +1 -1
  26. package/dist/src/indexer-cli-cursor.d.ts +25 -0
  27. package/dist/src/indexer-cli-cursor.d.ts.map +1 -0
  28. package/dist/src/indexer-cli-cursor.js +118 -0
  29. package/dist/src/indexer-cli-cursor.js.map +1 -0
  30. package/dist/src/indexer.d.ts.map +1 -1
  31. package/dist/src/indexer.js +46 -9
  32. package/dist/src/indexer.js.map +1 -1
  33. package/dist/src/types.d.ts +6 -1
  34. package/dist/src/types.d.ts.map +1 -1
  35. package/package.json +3 -2
  36. package/skill/memory.md +7 -2
@@ -0,0 +1,243 @@
1
+ "use strict";
2
+ /**
3
+ * Reads a Cursor conversation from the SQLite state.vscdb and converts it
4
+ * to the FullMessage[] format used by the indexer.
5
+ *
6
+ * Cursor stores conversations in:
7
+ * ~/Library/Application Support/Cursor/User/globalStorage/state.vscdb
8
+ *
9
+ * Key namespaces used:
10
+ * composerData:<composerId> — session metadata + ordered bubble headers
11
+ * bubbleId:<composerId>:<bubbleId> — individual message bubbles
12
+ *
13
+ * Bubble types:
14
+ * type 1 — user message (field: text)
15
+ * type 2 — AI message (field: text, or toolFormerData for tool calls)
16
+ *
17
+ * Tool call bubbles have toolFormerData:
18
+ * { name, rawArgs (JSON string), result (JSON string), status }
19
+ *
20
+ * Empty AI bubbles (no text, no toolFormerData) are placeholder/streaming
21
+ * artifacts — we skip them.
22
+ */
23
+ var __importDefault = (this && this.__importDefault) || function (mod) {
24
+ return (mod && mod.__esModule) ? mod : { "default": mod };
25
+ };
26
+ Object.defineProperty(exports, "__esModule", { value: true });
27
+ exports.resolveCursorDbPath = resolveCursorDbPath;
28
+ exports.openCursorDb = openCursorDb;
29
+ exports.getComposerData = getComposerData;
30
+ exports.listComposerIds = listComposerIds;
31
+ exports.cursorSessionToMessages = cursorSessionToMessages;
32
+ exports.deriveCursorSessionTitle = deriveCursorSessionTitle;
33
+ const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
34
+ const path_1 = __importDefault(require("path"));
35
+ const os_1 = __importDefault(require("os"));
36
+ // ---------------------------------------------------------------------------
37
+ // DB path resolution
38
+ // ---------------------------------------------------------------------------
39
+ function resolveCursorDbPath() {
40
+ switch (process.platform) {
41
+ case "darwin":
42
+ return path_1.default.join(os_1.default.homedir(), "Library", "Application Support", "Cursor", "User", "globalStorage", "state.vscdb");
43
+ case "linux":
44
+ return path_1.default.join(os_1.default.homedir(), ".config", "Cursor", "User", "globalStorage", "state.vscdb");
45
+ case "win32":
46
+ return path_1.default.join(process.env.APPDATA ?? os_1.default.homedir(), "Cursor", "User", "globalStorage", "state.vscdb");
47
+ default:
48
+ throw new Error(`Unsupported platform for Cursor: ${process.platform}`);
49
+ }
50
+ }
51
+ // ---------------------------------------------------------------------------
52
+ // Cursor DB reader
53
+ // ---------------------------------------------------------------------------
54
+ /**
55
+ * Opens the Cursor state.vscdb in read-only mode and returns a wrapper.
56
+ * The caller must call close() when done.
57
+ */
58
+ function openCursorDb(dbPath) {
59
+ const resolved = dbPath ?? resolveCursorDbPath();
60
+ // Open read-only — we never write to Cursor's DB
61
+ return new better_sqlite3_1.default(resolved, { readonly: true, fileMustExist: true });
62
+ }
63
+ /**
64
+ * Reads composer metadata for a given composerId.
65
+ */
66
+ function getComposerData(db, composerId) {
67
+ const row = db
68
+ .prepare("SELECT value FROM cursorDiskKV WHERE key = ?")
69
+ .get(`composerData:${composerId}`);
70
+ if (!row)
71
+ return null;
72
+ try {
73
+ return JSON.parse(row.value);
74
+ }
75
+ catch {
76
+ return null;
77
+ }
78
+ }
79
+ /**
80
+ * Reads a single bubble by composerId + bubbleId.
81
+ */
82
+ function getBubble(db, composerId, bubbleId) {
83
+ const row = db
84
+ .prepare("SELECT value FROM cursorDiskKV WHERE key = ?")
85
+ .get(`bubbleId:${composerId}:${bubbleId}`);
86
+ if (!row)
87
+ return null;
88
+ try {
89
+ return JSON.parse(row.value);
90
+ }
91
+ catch {
92
+ return null;
93
+ }
94
+ }
95
+ /**
96
+ * Lists all composerIds in the DB, ordered by most-recently-updated first.
97
+ * Used by the incremental indexer to find new/updated sessions.
98
+ */
99
+ function listComposerIds(db) {
100
+ const rows = db
101
+ .prepare("SELECT key, value FROM cursorDiskKV WHERE key LIKE 'composerData:%' ORDER BY rowid DESC")
102
+ .all();
103
+ return rows.map((r) => r.key.replace("composerData:", ""));
104
+ }
105
+ // ---------------------------------------------------------------------------
106
+ // Bubble → FullMessage conversion
107
+ // ---------------------------------------------------------------------------
108
+ function convertUserBubble(bubble) {
109
+ const text = (bubble.text ?? "").trim();
110
+ if (!text)
111
+ return null;
112
+ return {
113
+ info: {
114
+ id: bubble.bubbleId,
115
+ role: "user",
116
+ time: bubble.createdAt
117
+ ? { created: new Date(bubble.createdAt).getTime() }
118
+ : {},
119
+ },
120
+ parts: [{ type: "text", text }],
121
+ };
122
+ }
123
+ function convertAiBubble(bubble) {
124
+ // Skip thinking bubbles
125
+ if (bubble.isThought)
126
+ return null;
127
+ const parts = [];
128
+ const tf = bubble.toolFormerData;
129
+ if (tf?.name) {
130
+ // Tool call bubble
131
+ let args;
132
+ try {
133
+ args = tf.rawArgs ? JSON.parse(tf.rawArgs) : undefined;
134
+ }
135
+ catch {
136
+ args = tf.rawArgs;
137
+ }
138
+ let result;
139
+ try {
140
+ result = tf.result ? JSON.parse(tf.result) : undefined;
141
+ }
142
+ catch {
143
+ result = tf.result;
144
+ }
145
+ // Extract a readable result string
146
+ let resultText;
147
+ if (result !== undefined) {
148
+ if (typeof result === "string") {
149
+ resultText = result;
150
+ }
151
+ else if (result &&
152
+ typeof result === "object" &&
153
+ "contents" in result &&
154
+ typeof result.contents === "string") {
155
+ resultText = result.contents;
156
+ }
157
+ else {
158
+ resultText = JSON.stringify(result, null, 2);
159
+ }
160
+ }
161
+ const state = tf.status === "completed" ? "result" : "call";
162
+ parts.push({
163
+ type: "tool-invocation",
164
+ toolName: tf.name,
165
+ toolCallId: tf.toolCallId ?? bubble.bubbleId,
166
+ state,
167
+ args,
168
+ result: state === "result" ? (resultText ?? "(no output)") : undefined,
169
+ });
170
+ }
171
+ else {
172
+ // Text bubble
173
+ const text = (bubble.text ?? "").trim();
174
+ if (!text)
175
+ return null;
176
+ parts.push({ type: "text", text });
177
+ }
178
+ if (parts.length === 0)
179
+ return null;
180
+ return {
181
+ info: {
182
+ id: bubble.bubbleId,
183
+ role: "assistant",
184
+ time: bubble.createdAt
185
+ ? { created: new Date(bubble.createdAt).getTime() }
186
+ : {},
187
+ },
188
+ parts,
189
+ };
190
+ }
191
+ // ---------------------------------------------------------------------------
192
+ // Public API
193
+ // ---------------------------------------------------------------------------
194
+ /**
195
+ * Reads all messages for a Cursor conversation from the DB and converts them
196
+ * to FullMessage[]. Preserves the order defined by fullConversationHeadersOnly.
197
+ *
198
+ * @param db Open Cursor state.vscdb connection
199
+ * @param composerId The conversation ID (same as conversation_id in hook payload)
200
+ */
201
+ function cursorSessionToMessages(db, composerId) {
202
+ const composer = getComposerData(db, composerId);
203
+ if (!composer)
204
+ return [];
205
+ const headers = composer.fullConversationHeadersOnly ?? [];
206
+ const messages = [];
207
+ for (const header of headers) {
208
+ const bubble = getBubble(db, composerId, header.bubbleId);
209
+ if (!bubble)
210
+ continue;
211
+ let msg = null;
212
+ if (bubble.type === 1) {
213
+ msg = convertUserBubble(bubble);
214
+ }
215
+ else if (bubble.type === 2) {
216
+ msg = convertAiBubble(bubble);
217
+ }
218
+ if (msg)
219
+ messages.push(msg);
220
+ }
221
+ return messages;
222
+ }
223
+ /**
224
+ * Derives a session title from the first user message text.
225
+ */
226
+ function deriveCursorSessionTitle(composer, messages) {
227
+ // Use the composer name if it was set by Cursor
228
+ if (composer.name && composer.name.trim()) {
229
+ return composer.name.trim().slice(0, 80);
230
+ }
231
+ // Fall back to first user message text
232
+ for (const msg of messages) {
233
+ if (msg.info.role !== "user")
234
+ continue;
235
+ for (const part of msg.parts) {
236
+ if (part.type === "text" && part.text) {
237
+ return part.text.replace(/\s+/g, " ").trim().slice(0, 80);
238
+ }
239
+ }
240
+ }
241
+ return "Cursor Session";
242
+ }
243
+ //# sourceMappingURL=cursor-to-messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor-to-messages.js","sourceRoot":"","sources":["../../src/cursor-to-messages.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Parses a Cursor agent transcript JSONL file into FullMessage[].
3
+ *
4
+ * Cursor writes the transcript to disk BEFORE firing the stop hook, so this
5
+ * file is always complete and consistent — unlike state.vscdb which is written
6
+ * asynchronously and may lag behind the hook by several seconds.
7
+ *
8
+ * Transcript format (one JSON object per line):
9
+ * { "role": "user" | "assistant", "message": { "content": [{ "type": "text", "text": "..." }] } }
10
+ *
11
+ * Message IDs are derived as "<composerId>-<lineIndex>" since the JSONL has no
12
+ * bubble IDs. These are stable: line order never changes (only appended).
13
+ */
14
+ import type { FullMessage } from "./types";
15
+ /**
16
+ * Reads a Cursor transcript JSONL and returns FullMessage[].
17
+ *
18
+ * @param transcriptPath Absolute path to the .jsonl file
19
+ * @param composerId Used to derive stable per-message IDs
20
+ */
21
+ export declare function cursorTranscriptToMessages(transcriptPath: string, composerId: string): FullMessage[];
22
+ //# sourceMappingURL=cursor-transcript-to-messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor-transcript-to-messages.d.ts","sourceRoot":"","sources":["../../src/cursor-transcript-to-messages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAsB3C;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,GACjB,WAAW,EAAE,CAoDf"}
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ /**
3
+ * Parses a Cursor agent transcript JSONL file into FullMessage[].
4
+ *
5
+ * Cursor writes the transcript to disk BEFORE firing the stop hook, so this
6
+ * file is always complete and consistent — unlike state.vscdb which is written
7
+ * asynchronously and may lag behind the hook by several seconds.
8
+ *
9
+ * Transcript format (one JSON object per line):
10
+ * { "role": "user" | "assistant", "message": { "content": [{ "type": "text", "text": "..." }] } }
11
+ *
12
+ * Message IDs are derived as "<composerId>-<lineIndex>" since the JSONL has no
13
+ * bubble IDs. These are stable: line order never changes (only appended).
14
+ */
15
+ var __importDefault = (this && this.__importDefault) || function (mod) {
16
+ return (mod && mod.__esModule) ? mod : { "default": mod };
17
+ };
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.cursorTranscriptToMessages = cursorTranscriptToMessages;
20
+ const fs_1 = __importDefault(require("fs"));
21
+ // ---------------------------------------------------------------------------
22
+ // Parser
23
+ // ---------------------------------------------------------------------------
24
+ /**
25
+ * Reads a Cursor transcript JSONL and returns FullMessage[].
26
+ *
27
+ * @param transcriptPath Absolute path to the .jsonl file
28
+ * @param composerId Used to derive stable per-message IDs
29
+ */
30
+ function cursorTranscriptToMessages(transcriptPath, composerId) {
31
+ let raw;
32
+ try {
33
+ raw = fs_1.default.readFileSync(transcriptPath, "utf8");
34
+ }
35
+ catch {
36
+ return [];
37
+ }
38
+ const lines = raw.split("\n").filter((l) => l.trim());
39
+ const messages = [];
40
+ for (let i = 0; i < lines.length; i++) {
41
+ let entry;
42
+ try {
43
+ entry = JSON.parse(lines[i]);
44
+ }
45
+ catch {
46
+ continue;
47
+ }
48
+ const { role, message } = entry;
49
+ if (role !== "user" && role !== "assistant")
50
+ continue;
51
+ // Extract plain text from content
52
+ const content = message?.content;
53
+ let text = "";
54
+ if (typeof content === "string") {
55
+ text = content;
56
+ }
57
+ else if (Array.isArray(content)) {
58
+ text = content
59
+ .filter((p) => p.type === "text" && p.text)
60
+ .map((p) => p.text)
61
+ .join("\n");
62
+ }
63
+ // Strip Cursor's <user_query> wrapper tags
64
+ text = text
65
+ .replace(/^<user_query>\s*/i, "")
66
+ .replace(/\s*<\/user_query>$/i, "")
67
+ .trim();
68
+ if (!text)
69
+ continue;
70
+ // Stable ID: composerId + line index
71
+ const id = `${composerId}-${i}`;
72
+ messages.push({
73
+ info: { id, role },
74
+ parts: [{ type: "text", text }],
75
+ });
76
+ }
77
+ return messages;
78
+ }
79
+ //# sourceMappingURL=cursor-transcript-to-messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor-transcript-to-messages.js","sourceRoot":"","sources":["../../src/cursor-transcript-to-messages.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;;;;;AA+BH,gEAuDC;AApFD,4CAAoB;AAmBpB,8EAA8E;AAC9E,SAAS;AACT,8EAA8E;AAE9E;;;;;GAKG;AACH,SAAgB,0BAA0B,CACxC,cAAsB,EACtB,UAAkB;IAElB,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,YAAE,CAAC,YAAY,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAkB,EAAE,CAAC;IAEnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,IAAI,KAAsB,CAAC;QAC3B,IAAI,CAAC;YACH,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAoB,CAAC;QAClD,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QAED,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;QAChC,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,WAAW;YAAE,SAAS;QAEtD,kCAAkC;QAClC,MAAM,OAAO,GAAG,OAAO,EAAE,OAAO,CAAC;QACjC,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAChC,IAAI,GAAG,OAAO,CAAC;QACjB,CAAC;aAAM,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YAClC,IAAI,GAAG,OAAO;iBACX,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC;iBAC1C,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAK,CAAC;iBACnB,IAAI,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC;QAED,2CAA2C;QAC3C,IAAI,GAAG,IAAI;aACR,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC;aAChC,OAAO,CAAC,qBAAqB,EAAE,EAAE,CAAC;aAClC,IAAI,EAAE,CAAC;QAEV,IAAI,CAAC,IAAI;YAAE,SAAS;QAEpB,qCAAqC;QACrC,MAAM,EAAE,GAAG,GAAG,UAAU,IAAI,CAAC,EAAE,CAAC;QAEhC,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE;YAClB,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;SAChC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -40,7 +40,7 @@ export declare function upsertSessionMeta(db: Database, meta: SessionMeta): void
40
40
  * Chunks with duplicate chunk_ids are silently skipped (IGNORE conflict).
41
41
  */
42
42
  export declare function insertChunks(db: Database, chunks: DocumentChunk[], embeddings: number[][]): void;
43
- export declare function queryByEmbedding(db: Database, queryEmbedding: number[], topK?: number, projectFilter?: string, sourceFilter?: SessionSource): QueryResult[];
43
+ export declare function queryByEmbedding(db: Database, queryEmbedding: number[], topK?: number, projectFilter?: string, sourceFilter?: SessionSource, fromMs?: number, toMs?: number): QueryResult[];
44
44
  export declare function getChunksByUrl(db: Database, url: string, startIndex?: number, endIndex?: number): QueryResult[];
45
45
  /**
46
46
  * Lists all session URLs stored in the DB (for "get_session_chunks" calls that
@@ -70,7 +70,10 @@ export interface ChunkRow {
70
70
  url: string;
71
71
  }
72
72
  /**
73
- * Returns all chunks for a session ordered by chunk_index ASC.
73
+ * Returns all chunks for a session ordered by message_order ASC, chunk_index ASC.
74
+ * message_order is the 0-based position of the message within the session at
75
+ * index time — stable and source-agnostic (works for OpenCode, Claude Code,
76
+ * and Cursor whose message IDs are not guaranteed to sort chronologically).
74
77
  */
75
78
  export declare function getSessionChunksOrdered(db: Database, sessionId: string): ChunkRow[];
76
79
  /**
@@ -78,4 +81,12 @@ export declare function getSessionChunksOrdered(db: Database, sessionId: string)
78
81
  * Returns the number of chunks deleted.
79
82
  */
80
83
  export declare function deleteSession(db: Database, sessionId: string): number;
84
+ /**
85
+ * Deletes all sessions last updated before `olderThanMs` (unix milliseconds).
86
+ * Returns the number of sessions and chunks removed.
87
+ */
88
+ export declare function deleteSessionsOlderThan(db: Database, olderThanMs: number): {
89
+ sessions: number;
90
+ chunks: number;
91
+ };
81
92
  //# sourceMappingURL=database.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/database.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/database.ts"],"names":[],"mappings":"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"}
@@ -15,6 +15,7 @@ exports.listSessionUrls = listSessionUrls;
15
15
  exports.listSessions = listSessions;
16
16
  exports.getSessionChunksOrdered = getSessionChunksOrdered;
17
17
  exports.deleteSession = deleteSession;
18
+ exports.deleteSessionsOlderThan = deleteSessionsOlderThan;
18
19
  const path_1 = __importDefault(require("path"));
19
20
  const os_1 = __importDefault(require("os"));
20
21
  const fs_1 = __importDefault(require("fs"));
@@ -88,7 +89,9 @@ function initSchema(db, embeddingDimension = DEFAULT_EMBEDDING_DIMENSION) {
88
89
  url TEXT,
89
90
  hash TEXT,
90
91
  chunk_index INTEGER,
91
- total_chunks INTEGER
92
+ total_chunks INTEGER,
93
+ message_order INTEGER,
94
+ created_at INTEGER
92
95
  );
93
96
  `);
94
97
  // Metadata table for tracking incremental indexing progress
@@ -148,11 +151,11 @@ function insertChunks(db, chunks, embeddings) {
148
151
  INSERT INTO vec_items (
149
152
  embedding, session_id, session_title, project,
150
153
  heading_hierarchy, section, chunk_id, content, url, hash,
151
- chunk_index, total_chunks
154
+ chunk_index, total_chunks, message_order, created_at
152
155
  ) VALUES (
153
156
  ?, ?, ?, ?,
154
157
  ?, ?, ?, ?, ?, ?,
155
- ?, ?
158
+ ?, ?, ?, ?
156
159
  )
157
160
  `);
158
161
  // sqlite-vec does not enforce UNIQUE constraints via INSERT OR IGNORE on
@@ -165,7 +168,7 @@ function insertChunks(db, chunks, embeddings) {
165
168
  // Skip if chunk already exists (idempotent indexing)
166
169
  if (exists.get(m.chunk_id))
167
170
  continue;
168
- insert.run(new Float32Array(embedding), m.session_id, m.session_title, m.project, JSON.stringify(m.heading_hierarchy), m.section, m.chunk_id, chunk.content, m.url, m.hash, BigInt(m.chunk_index), BigInt(m.total_chunks));
171
+ insert.run(new Float32Array(embedding), m.session_id, m.session_title, m.project, JSON.stringify(m.heading_hierarchy), m.section, m.chunk_id, chunk.content, m.url, m.hash, BigInt(m.chunk_index), BigInt(m.total_chunks), BigInt(m.message_order ?? 0), BigInt(m.created_at ?? Date.now()));
169
172
  }
170
173
  });
171
174
  insertMany(chunks.map((chunk, i) => ({ chunk, embedding: embeddings[i] })));
@@ -173,7 +176,7 @@ function insertChunks(db, chunks, embeddings) {
173
176
  // ---------------------------------------------------------------------------
174
177
  // Query helpers (used by MCP server)
175
178
  // ---------------------------------------------------------------------------
176
- function queryByEmbedding(db, queryEmbedding, topK = 10, projectFilter, sourceFilter) {
179
+ function queryByEmbedding(db, queryEmbedding, topK = 10, projectFilter, sourceFilter, fromMs, toMs) {
177
180
  // sqlite-vec requires the LIMIT (k) constraint to be part of the KNN WHERE
178
181
  // clause. We use a CTE to perform the KNN first, then join sessions_meta for
179
182
  // the source column and apply optional post-filters.
@@ -182,7 +185,7 @@ function queryByEmbedding(db, queryEmbedding, topK = 10, projectFilter, sourceFi
182
185
  SELECT
183
186
  chunk_id, content, url, section, heading_hierarchy,
184
187
  chunk_index, total_chunks, session_id, session_title, project,
185
- distance
188
+ distance, created_at
186
189
  FROM vec_items
187
190
  WHERE embedding MATCH ?
188
191
  AND k = ?
@@ -201,6 +204,14 @@ function queryByEmbedding(db, queryEmbedding, topK = 10, projectFilter, sourceFi
201
204
  sql += " AND m.source = ?";
202
205
  params.push(sourceFilter);
203
206
  }
207
+ if (typeof fromMs === "number") {
208
+ sql += " AND knn.created_at >= ?";
209
+ params.push(BigInt(fromMs));
210
+ }
211
+ if (typeof toMs === "number") {
212
+ sql += " AND knn.created_at <= ?";
213
+ params.push(BigInt(toMs));
214
+ }
204
215
  sql += " ORDER BY distance";
205
216
  const rows = db.prepare(sql).all(...params);
206
217
  // Strip raw embedding bytes from results
@@ -273,14 +284,17 @@ function listSessions(db, filter = {}) {
273
284
  return db.prepare(sql).all(...params);
274
285
  }
275
286
  /**
276
- * Returns all chunks for a session ordered by chunk_index ASC.
287
+ * Returns all chunks for a session ordered by message_order ASC, chunk_index ASC.
288
+ * message_order is the 0-based position of the message within the session at
289
+ * index time — stable and source-agnostic (works for OpenCode, Claude Code,
290
+ * and Cursor whose message IDs are not guaranteed to sort chronologically).
277
291
  */
278
292
  function getSessionChunksOrdered(db, sessionId) {
279
293
  return db.prepare(`
280
294
  SELECT chunk_id, chunk_index, total_chunks, section, heading_hierarchy, content, url
281
295
  FROM vec_items
282
296
  WHERE session_id = ?
283
- ORDER BY chunk_index ASC
297
+ ORDER BY message_order ASC, chunk_index ASC
284
298
  `).all(sessionId);
285
299
  }
286
300
  /**
@@ -298,4 +312,24 @@ function deleteSession(db, sessionId) {
298
312
  })();
299
313
  return chunkCount;
300
314
  }
315
+ /**
316
+ * Deletes all sessions last updated before `olderThanMs` (unix milliseconds).
317
+ * Returns the number of sessions and chunks removed.
318
+ */
319
+ function deleteSessionsOlderThan(db, olderThanMs) {
320
+ const candidates = listSessions(db, { toDate: olderThanMs });
321
+ if (candidates.length === 0)
322
+ return { sessions: 0, chunks: 0 };
323
+ const deleteChunks = db.prepare("DELETE FROM vec_items WHERE session_id = ?");
324
+ const deleteMeta = db.prepare("DELETE FROM sessions_meta WHERE session_id = ?");
325
+ let totalChunks = 0;
326
+ db.transaction(() => {
327
+ for (const s of candidates) {
328
+ const result = deleteChunks.run(s.session_id);
329
+ totalChunks += result.changes;
330
+ deleteMeta.run(s.session_id);
331
+ }
332
+ })();
333
+ return { sessions: candidates.length, chunks: totalChunks };
334
+ }
301
335
  //# sourceMappingURL=database.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/database.ts"],"names":[],"mappings":";;;;;AAiBA,sCASC;AAwCD,oCAgBC;AAMD,gCAqCC;AAMD,wCAKC;AAED,8CAkBC;AAUD,oCAsDC;AAMD,4CA6CC;AAED,wCAwBC;AAMD,0CAKC;AAoBD,oCAgCC;AAeD,0DAOC;AAMD,sCAYC;AAhZD,gDAAwB;AACxB,4CAAoB;AACpB,4CAAoB;AAGpB,MAAM,2BAA2B,GAAG,IAAI,CAAC;AAEzC,8EAA8E;AAC9E,kBAAkB;AAClB,8EAA8E;AAE9E;;;;;GAKG;AACH,SAAgB,aAAa,CAAC,YAAqB;IACjD,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,YAAE,CAAC,OAAO,EAAE,CAAC,CAAC;IAClD,CAAC;IACD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC;IACpD,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,YAAE,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,cAAI,CAAC,IAAI,CAAC,YAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,qBAAqB,EAAE,aAAa,CAAC,CAAC;AAC1F,CAAC;AAoBD,qFAAqF;AACrF,IAAI,SAAS,GAA4C,IAAI,CAAC;AAC9D,IAAI,UAAU,GAA4C,IAAI,CAAC;AAE/D,SAAS,QAAQ;IACf,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,8DAA8D;QAC9D,SAAS,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACxC,CAAC;IACD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,8DAA8D;QAC9D,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,SAAU,EAAE,SAAS,EAAE,UAAW,EAAE,CAAC;AAC1D,CAAC;AAED;;;GAGG;AACH,SAAgB,YAAY,CAAC,MAAsB;IACjD,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,QAAQ,EAAE,CAAC;IAC3C,MAAM,EAAE,MAAM,EAAE,kBAAkB,GAAG,2BAA2B,EAAE,GAAG,MAAM,CAAC;IAE5E,8BAA8B;IAC9B,YAAE,CAAC,SAAS,CAAC,cAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAExD,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC;IAChC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEnB,qBAAqB;IACrB,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAChC,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;IAElC,UAAU,CAAC,EAAE,EAAE,kBAAkB,CAAC,CAAC;IACnC,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;GAGG;AACH,SAAgB,UAAU,CAAC,EAAY,EAAE,kBAAkB,GAAG,2BAA2B;IACvF,kCAAkC;IAClC,EAAE,CAAC,IAAI,CAAC;;gCAEsB,kBAAkB;;;;;;;;;;;;;GAa/C,CAAC,CAAC;IAEH,4DAA4D;IAC5D,EAAE,CAAC,IAAI,CAAC;;;;;;;;;GASP,CAAC,CAAC;IAEH,qDAAqD;IACrD,IAAI,CAAC;QACH,EAAE,CAAC,IAAI,CAAC,8EAA8E,CAAC,CAAC;IAC1F,CAAC;IAAC,MAAM,CAAC;QACP,iCAAiC;IACnC,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,oBAAoB;AACpB,8EAA8E;AAE9E,SAAgB,cAAc,CAAC,EAAY,EAAE,SAAiB;IAC5D,MAAM,GAAG,GAAG,EAAE;SACX,OAAO,CAAC,kDAAkD,CAAC;SAC3D,GAAG,CAAC,SAAS,CAA4B,CAAC;IAC7C,OAAO,GAAG,IAAI,IAAI,CAAC;AACrB,CAAC;AAED,SAAgB,iBAAiB,CAAC,EAAY,EAAE,IAAiB;IAC/D,EAAE,CAAC,OAAO,CAAC;;;;;;;;;GASV,CAAC,CAAC,GAAG,CACJ,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,aAAa,EAClB,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,uBAAuB,EAC5B,IAAI,CAAC,UAAU,CAChB,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E;;;GAGG;AACH,SAAgB,YAAY,CAC1B,EAAY,EACZ,MAAuB,EACvB,UAAsB;IAEtB,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU,CAAC,MAAM,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CACb,aAAa,MAAM,CAAC,MAAM,eAAe,UAAU,CAAC,MAAM,aAAa,CACxE,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAEhC,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC;;;;;;;;;;GAUzB,CAAC,CAAC;IAEH,yEAAyE;IACzE,mDAAmD;IACnD,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CACvB,oDAAoD,CACrD,CAAC;IAEF,MAAM,UAAU,GAAG,EAAE,CAAC,WAAW,CAAC,CAAC,GAAG,IAAe,EAAE,EAAE;QACvD,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAyD,CAAC;QAC7E,KAAK,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC;YACxC,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,KAAK,CAAC;YAC9B,qDAAqD;YACrD,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC;gBAAE,SAAS;YACrC,MAAM,CAAC,GAAG,CACR,IAAI,YAAY,CAAC,SAAS,CAAC,EAC3B,CAAC,CAAC,UAAU,EACZ,CAAC,CAAC,aAAa,EACf,CAAC,CAAC,OAAO,EACT,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,iBAAiB,CAAC,EACnC,CAAC,CAAC,OAAO,EACT,CAAC,CAAC,QAAQ,EACV,KAAK,CAAC,OAAO,EACb,CAAC,CAAC,GAAG,EACL,CAAC,CAAC,IAAI,EACN,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,EACrB,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CACvB,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED,8EAA8E;AAC9E,qCAAqC;AACrC,8EAA8E;AAE9E,SAAgB,gBAAgB,CAC9B,EAAY,EACZ,cAAwB,EACxB,IAAI,GAAG,EAAE,EACT,aAAsB,EACtB,YAA4B;IAE5B,2EAA2E;IAC3E,6EAA6E;IAC7E,qDAAqD;IACrD,IAAI,GAAG,GAAG;;;;;;;;;;;;;;GAcT,CAAC;IACF,MAAM,MAAM,GAAc,CAAC,IAAI,YAAY,CAAC,cAAc,CAAC,EAAE,IAAI,CAAC,CAAC;IAEnE,IAAI,aAAa,EAAE,CAAC;QAClB,GAAG,IAAI,sBAAsB,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC7B,CAAC;IAED,IAAI,YAAY,EAAE,CAAC;QACjB,GAAG,IAAI,mBAAmB,CAAC;QAC3B,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC5B,CAAC;IAED,GAAG,IAAI,oBAAoB,CAAC;IAE5B,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,MAAM,CAAkB,CAAC;IAC7D,yCAAyC;IACzC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAU,EAAE,EAAE;QAC1B,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ;YAAE,OAAQ,CAA6B,CAAC,WAAW,CAAC,CAAC;IACrF,CAAC,CAAC,CAAC;IACH,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAgB,cAAc,CAC5B,EAAY,EACZ,GAAW,EACX,UAAmB,EACnB,QAAiB;IAEjB,IAAI,GAAG,GAAG;;;;GAIT,CAAC;IACF,MAAM,MAAM,GAAc,CAAC,GAAG,CAAC,CAAC;IAEhC,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;QACnC,GAAG,IAAI,uBAAuB,CAAC;QAC/B,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC1B,CAAC;IACD,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,GAAG,IAAI,uBAAuB,CAAC;QAC/B,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACxB,CAAC;IAED,GAAG,IAAI,uBAAuB,CAAC;IAC/B,OAAO,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,MAAM,CAAkB,CAAC;AACzD,CAAC;AAED;;;GAGG;AACH,SAAgB,eAAe,CAAC,EAAY,EAAE,SAAiB;IAC7D,MAAM,IAAI,GAAG,EAAE;SACZ,OAAO,CAAC,sEAAsE,CAAC;SAC/E,GAAG,CAAC,SAAS,CAA2B,CAAC;IAC5C,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;AAChC,CAAC;AAgBD;;;GAGG;AACH,SAAgB,YAAY,CAAC,EAAY,EAAE,SAAwB,EAAE;IACnE,IAAI,GAAG,GAAG;;;;;;;;;;;;GAYT,CAAC;IACF,MAAM,MAAM,GAAc,EAAE,CAAC;IAE7B,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,GAAG,IAAI,mBAAmB,CAAC;QAC3B,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC;IACD,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACxC,GAAG,IAAI,wBAAwB,CAAC;QAChC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC;IACD,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QACtC,GAAG,IAAI,wBAAwB,CAAC;QAChC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC;IAED,GAAG,IAAI,mDAAmD,CAAC;IAE3D,OAAO,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,MAAM,CAAiB,CAAC;AACxD,CAAC;AAYD;;GAEG;AACH,SAAgB,uBAAuB,CAAC,EAAY,EAAE,SAAiB;IACrE,OAAO,EAAE,CAAC,OAAO,CAAC;;;;;GAKjB,CAAC,CAAC,GAAG,CAAC,SAAS,CAAe,CAAC;AAClC,CAAC;AAED;;;GAGG;AACH,SAAgB,aAAa,CAAC,EAAY,EAAE,SAAiB;IAC3D,MAAM,YAAY,GAAG,EAAE,CAAC,OAAO,CAAC,4CAA4C,CAAC,CAAC;IAC9E,MAAM,UAAU,GAAK,EAAE,CAAC,OAAO,CAAC,gDAAgD,CAAC,CAAC;IAElF,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;QAClB,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC3C,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC;QAC5B,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC5B,CAAC,CAAC,EAAE,CAAC;IAEL,OAAO,UAAU,CAAC;AACpB,CAAC"}
1
+ {"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/database.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Entry point for Cursor session indexing.
4
+ *
5
+ * Called by the Cursor stop hook. Receives JSON on stdin:
6
+ * {
7
+ * conversation_id: string, // the composerId
8
+ * workspace_roots: string[], // project directories
9
+ * transcript_path: string, // path to the JSONL transcript (always complete)
10
+ * model: string,
11
+ * status: "completed" | "aborted" | "error",
12
+ * ...
13
+ * }
14
+ *
15
+ * Strategy:
16
+ * - Read messages from transcript_path (JSONL written by Cursor before the
17
+ * hook fires — always complete and race-condition-free).
18
+ * - Read session title from state.vscdb (best-effort, falls back to first
19
+ * user message).
20
+ * - Index new messages into the shared sqlite-vec DB incrementally.
21
+ *
22
+ * No retries needed: the transcript file is the authoritative source.
23
+ */
24
+ export {};
25
+ //# sourceMappingURL=indexer-cli-cursor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexer-cli-cursor.d.ts","sourceRoot":"","sources":["../../src/indexer-cli-cursor.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;GAqBG"}