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.
Files changed (52) hide show
  1. package/README.md +290 -0
  2. package/dist/mcp/index.d.ts +15 -0
  3. package/dist/mcp/index.d.ts.map +1 -0
  4. package/dist/mcp/index.js +140 -0
  5. package/dist/mcp/index.js.map +1 -0
  6. package/dist/mcp/server.d.ts +60 -0
  7. package/dist/mcp/server.d.ts.map +1 -0
  8. package/dist/mcp/server.js +192 -0
  9. package/dist/mcp/server.js.map +1 -0
  10. package/dist/src/chunker.d.ts +18 -0
  11. package/dist/src/chunker.d.ts.map +1 -0
  12. package/dist/src/chunker.js +149 -0
  13. package/dist/src/chunker.js.map +1 -0
  14. package/dist/src/cli.d.ts +11 -0
  15. package/dist/src/cli.d.ts.map +1 -0
  16. package/dist/src/cli.js +514 -0
  17. package/dist/src/cli.js.map +1 -0
  18. package/dist/src/database.d.ts +50 -0
  19. package/dist/src/database.d.ts.map +1 -0
  20. package/dist/src/database.js +238 -0
  21. package/dist/src/database.js.map +1 -0
  22. package/dist/src/embedder.d.ts +19 -0
  23. package/dist/src/embedder.d.ts.map +1 -0
  24. package/dist/src/embedder.js +80 -0
  25. package/dist/src/embedder.js.map +1 -0
  26. package/dist/src/indexer-cli-claude.d.ts +14 -0
  27. package/dist/src/indexer-cli-claude.d.ts.map +1 -0
  28. package/dist/src/indexer-cli-claude.js +67 -0
  29. package/dist/src/indexer-cli-claude.js.map +1 -0
  30. package/dist/src/indexer-cli.d.ts +16 -0
  31. package/dist/src/indexer-cli.d.ts.map +1 -0
  32. package/dist/src/indexer-cli.js +53 -0
  33. package/dist/src/indexer-cli.js.map +1 -0
  34. package/dist/src/indexer.d.ts +44 -0
  35. package/dist/src/indexer.d.ts.map +1 -0
  36. package/dist/src/indexer.js +129 -0
  37. package/dist/src/indexer.js.map +1 -0
  38. package/dist/src/session-to-md.d.ts +15 -0
  39. package/dist/src/session-to-md.d.ts.map +1 -0
  40. package/dist/src/session-to-md.js +148 -0
  41. package/dist/src/session-to-md.js.map +1 -0
  42. package/dist/src/transcript-to-messages.d.ts +32 -0
  43. package/dist/src/transcript-to-messages.d.ts.map +1 -0
  44. package/dist/src/transcript-to-messages.js +230 -0
  45. package/dist/src/transcript-to-messages.js.map +1 -0
  46. package/dist/src/types.d.ts +91 -0
  47. package/dist/src/types.d.ts.map +1 -0
  48. package/dist/src/types.js +3 -0
  49. package/dist/src/types.js.map +1 -0
  50. package/package.json +59 -0
  51. package/plugin/memory.ts +42 -0
  52. package/skill/memory.md +61 -0
@@ -0,0 +1,192 @@
1
+ "use strict";
2
+ /**
3
+ * MCP query handlers for opencode-memory.
4
+ *
5
+ * Adapted from doc2vec/mcp/src/server.ts — simplified to:
6
+ * - SQLite-vec only (no Qdrant)
7
+ * - Fixed single DB path (no multi-DB resolution)
8
+ * - Two tools: query_sessions + get_session_chunks
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.createSqliteProvider = createSqliteProvider;
12
+ exports.createToolHandlers = createToolHandlers;
13
+ // ---------------------------------------------------------------------------
14
+ // Provider factory
15
+ // ---------------------------------------------------------------------------
16
+ function createSqliteProvider(deps) {
17
+ const { dbPath, sqliteVec, Database, fs } = deps;
18
+ /**
19
+ * Opens a short-lived connection, runs the callback, closes the connection.
20
+ */
21
+ function withDb(fn) {
22
+ if (!fs.existsSync(dbPath)) {
23
+ throw new Error(`Database not found at ${dbPath}. Run "code-session-memory install" first.`);
24
+ }
25
+ const db = new Database(dbPath);
26
+ sqliteVec.load(db);
27
+ try {
28
+ return fn(db);
29
+ }
30
+ finally {
31
+ db.close();
32
+ }
33
+ }
34
+ // ---- query_sessions -------------------------------------------------------
35
+ async function querySessions(queryEmbedding, topK = 10, projectFilter, sourceFilter) {
36
+ return withDb((db) => {
37
+ let sql = `
38
+ WITH knn AS (
39
+ SELECT
40
+ chunk_id, content, url, section, heading_hierarchy,
41
+ chunk_index, total_chunks, session_id, session_title, project,
42
+ distance
43
+ FROM vec_items
44
+ WHERE embedding MATCH ?
45
+ AND k = ?
46
+ )
47
+ SELECT knn.*, m.source
48
+ FROM knn
49
+ LEFT JOIN sessions_meta m ON knn.session_id = m.session_id
50
+ WHERE 1=1
51
+ `;
52
+ const params = [new Float32Array(queryEmbedding), topK];
53
+ if (projectFilter) {
54
+ sql += " AND knn.project = ?";
55
+ params.push(projectFilter);
56
+ }
57
+ if (sourceFilter) {
58
+ sql += " AND m.source = ?";
59
+ params.push(sourceFilter);
60
+ }
61
+ sql += " ORDER BY distance";
62
+ const rows = db.prepare(sql).all(...params);
63
+ rows.forEach((r) => {
64
+ delete r["embedding"];
65
+ });
66
+ return rows;
67
+ });
68
+ }
69
+ // ---- get_session_chunks ---------------------------------------------------
70
+ async function getSessionChunks(url, startIndex, endIndex) {
71
+ return withDb((db) => {
72
+ let sql = `
73
+ SELECT chunk_id, content, url, section, heading_hierarchy, chunk_index, total_chunks
74
+ FROM vec_items
75
+ WHERE url = ?
76
+ `;
77
+ const params = [url];
78
+ if (typeof startIndex === "number") {
79
+ sql += " AND chunk_index >= ?";
80
+ params.push(startIndex);
81
+ }
82
+ if (typeof endIndex === "number") {
83
+ sql += " AND chunk_index <= ?";
84
+ params.push(endIndex);
85
+ }
86
+ sql += " ORDER BY chunk_index";
87
+ return db.prepare(sql).all(...params);
88
+ });
89
+ }
90
+ return { querySessions, getSessionChunks };
91
+ }
92
+ // ---------------------------------------------------------------------------
93
+ // MCP tool handlers
94
+ // ---------------------------------------------------------------------------
95
+ function createToolHandlers(deps) {
96
+ const { createEmbedding, querySessions, getSessionChunks } = deps;
97
+ // ---- query_sessions handler -----------------------------------------------
98
+ const querySessionsHandler = async (args) => {
99
+ const limit = args.limit ?? 5;
100
+ console.error(`[query_sessions] text="${args.queryText}" project="${args.project ?? "any"}" source="${args.source ?? "any"}" limit=${limit}`);
101
+ try {
102
+ const embedding = await createEmbedding(args.queryText);
103
+ const results = await querySessions(embedding, limit, args.project, args.source);
104
+ if (results.length === 0) {
105
+ return {
106
+ content: [
107
+ {
108
+ type: "text",
109
+ text: `No sessions found matching "${args.queryText}"${args.project ? ` in project "${args.project}"` : ""}.`,
110
+ },
111
+ ],
112
+ };
113
+ }
114
+ const formatted = results
115
+ .map((r, i) => {
116
+ const lines = [
117
+ `Result ${i + 1}:`,
118
+ ` Content: ${r.content}`,
119
+ typeof r.distance === "number" ? ` Distance: ${r.distance.toFixed(4)}` : null,
120
+ r.url ? ` URL: ${r.url}` : null,
121
+ r.section ? ` Section: ${r.section}` : null,
122
+ typeof r.chunk_index === "number" && typeof r.total_chunks === "number"
123
+ ? ` Chunk: ${r.chunk_index + 1} of ${r.total_chunks}`
124
+ : null,
125
+ "---",
126
+ ].filter(Boolean);
127
+ return lines.join("\n");
128
+ })
129
+ .join("\n");
130
+ return {
131
+ content: [
132
+ {
133
+ type: "text",
134
+ text: `Found ${results.length} result(s) for "${args.queryText}":\n\n${formatted}`,
135
+ },
136
+ ],
137
+ };
138
+ }
139
+ catch (err) {
140
+ const msg = err instanceof Error ? err.message : String(err);
141
+ console.error("[query_sessions] error:", err);
142
+ return { content: [{ type: "text", text: `Error: ${msg}` }] };
143
+ }
144
+ };
145
+ // ---- get_session_chunks handler -------------------------------------------
146
+ const getSessionChunksHandler = async (args) => {
147
+ console.error(`[get_session_chunks] url="${args.sessionUrl}" start=${args.startIndex} end=${args.endIndex}`);
148
+ try {
149
+ const results = await getSessionChunks(args.sessionUrl, args.startIndex, args.endIndex);
150
+ if (results.length === 0) {
151
+ return {
152
+ content: [
153
+ {
154
+ type: "text",
155
+ text: `No chunks found for "${args.sessionUrl}".`,
156
+ },
157
+ ],
158
+ };
159
+ }
160
+ const formatted = results
161
+ .map((r) => {
162
+ const chunkLabel = typeof r.chunk_index === "number" && typeof r.total_chunks === "number"
163
+ ? `Chunk ${r.chunk_index + 1} of ${r.total_chunks}`
164
+ : "Chunk";
165
+ return [
166
+ chunkLabel,
167
+ ` Content: ${r.content}`,
168
+ r.section ? ` Section: ${r.section}` : null,
169
+ "---",
170
+ ]
171
+ .filter(Boolean)
172
+ .join("\n");
173
+ })
174
+ .join("\n");
175
+ return {
176
+ content: [
177
+ {
178
+ type: "text",
179
+ text: `Retrieved ${results.length} chunk(s) for "${args.sessionUrl}":\n\n${formatted}`,
180
+ },
181
+ ],
182
+ };
183
+ }
184
+ catch (err) {
185
+ const msg = err instanceof Error ? err.message : String(err);
186
+ console.error("[get_session_chunks] error:", err);
187
+ return { content: [{ type: "text", text: `Error: ${msg}` }] };
188
+ }
189
+ };
190
+ return { querySessionsHandler, getSessionChunksHandler };
191
+ }
192
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../mcp/server.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;AA2BH,oDAoGC;AAMD,gDA0IC;AAxPD,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,SAAgB,oBAAoB,CAAC,IAKpC;IACC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;IAEjD;;OAEG;IACH,SAAS,MAAM,CAAI,EAA6B;QAC9C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,yBAAyB,MAAM,4CAA4C,CAAC,CAAC;QAC/F,CAAC;QACD,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC;QAChC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACnB,IAAI,CAAC;YACH,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;QAChB,CAAC;gBAAS,CAAC;YACT,EAAE,CAAC,KAAK,EAAE,CAAC;QACb,CAAC;IACH,CAAC;IAED,8EAA8E;IAE9E,KAAK,UAAU,aAAa,CAC1B,cAAwB,EACxB,IAAI,GAAG,EAAE,EACT,aAAsB,EACtB,YAAqB;QAErB,OAAO,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE;YACnB,IAAI,GAAG,GAAG;;;;;;;;;;;;;;OAcT,CAAC;YACF,MAAM,MAAM,GAAc,CAAC,IAAI,YAAY,CAAC,cAAc,CAAC,EAAE,IAAI,CAAC,CAAC;YAEnE,IAAI,aAAa,EAAE,CAAC;gBAClB,GAAG,IAAI,sBAAsB,CAAC;gBAC9B,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAC7B,CAAC;YAED,IAAI,YAAY,EAAE,CAAC;gBACjB,GAAG,IAAI,mBAAmB,CAAC;gBAC3B,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC5B,CAAC;YAED,GAAG,IAAI,oBAAoB,CAAC;YAE5B,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,MAAM,CAAkB,CAAC;YAC7D,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;gBACjB,OAAQ,CAAwC,CAAC,WAAW,CAAC,CAAC;YAChE,CAAC,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC;IAED,8EAA8E;IAE9E,KAAK,UAAU,gBAAgB,CAC7B,GAAW,EACX,UAAmB,EACnB,QAAiB;QAEjB,OAAO,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE;YACnB,IAAI,GAAG,GAAG;;;;OAIT,CAAC;YACF,MAAM,MAAM,GAAc,CAAC,GAAG,CAAC,CAAC;YAEhC,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;gBACnC,GAAG,IAAI,uBAAuB,CAAC;gBAC/B,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC1B,CAAC;YACD,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBACjC,GAAG,IAAI,uBAAuB,CAAC;gBAC/B,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACxB,CAAC;YAED,GAAG,IAAI,uBAAuB,CAAC;YAC/B,OAAO,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,MAAM,CAAkB,CAAC;QACzD,CAAC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,CAAC;AAC7C,CAAC;AAED,8EAA8E;AAC9E,oBAAoB;AACpB,8EAA8E;AAE9E,SAAgB,kBAAkB,CAAC,IAalC;IACC,MAAM,EAAE,eAAe,EAAE,aAAa,EAAE,gBAAgB,EAAE,GAAG,IAAI,CAAC;IAElE,8EAA8E;IAE9E,MAAM,oBAAoB,GAAG,KAAK,EAAE,IAKnC,EAAE,EAAE;QACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;QAC9B,OAAO,CAAC,KAAK,CACX,0BAA0B,IAAI,CAAC,SAAS,cAAc,IAAI,CAAC,OAAO,IAAI,KAAK,aAAa,IAAI,CAAC,MAAM,IAAI,KAAK,WAAW,KAAK,EAAE,CAC/H,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACxD,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YAEjF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,+BAA+B,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG;yBAC9G;qBACF;iBACF,CAAC;YACJ,CAAC;YAED,MAAM,SAAS,GAAG,OAAO;iBACtB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;gBACZ,MAAM,KAAK,GAAG;oBACZ,UAAU,CAAC,GAAG,CAAC,GAAG;oBAClB,cAAc,CAAC,CAAC,OAAO,EAAE;oBACzB,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI;oBAC9E,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI;oBAChC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI;oBAC5C,OAAO,CAAC,CAAC,WAAW,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,YAAY,KAAK,QAAQ;wBACrE,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,GAAG,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE;wBACtD,CAAC,CAAC,IAAI;oBACR,KAAK;iBACN,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBAClB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1B,CAAC,CAAC;iBACD,IAAI,CAAC,IAAI,CAAC,CAAC;YAEd,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,SAAS,OAAO,CAAC,MAAM,mBAAmB,IAAI,CAAC,SAAS,SAAS,SAAS,EAAE;qBACnF;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,GAAG,CAAC,CAAC;YAC9C,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC;QACzE,CAAC;IACH,CAAC,CAAC;IAEF,8EAA8E;IAE9E,MAAM,uBAAuB,GAAG,KAAK,EAAE,IAItC,EAAE,EAAE;QACH,OAAO,CAAC,KAAK,CACX,6BAA6B,IAAI,CAAC,UAAU,WAAW,IAAI,CAAC,UAAU,QAAQ,IAAI,CAAC,QAAQ,EAAE,CAC9F,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,gBAAgB,CACpC,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,QAAQ,CACd,CAAC;YAEF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,wBAAwB,IAAI,CAAC,UAAU,IAAI;yBAClD;qBACF;iBACF,CAAC;YACJ,CAAC;YAED,MAAM,SAAS,GAAG,OAAO;iBACtB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;gBACT,MAAM,UAAU,GACd,OAAO,CAAC,CAAC,WAAW,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,YAAY,KAAK,QAAQ;oBACrE,CAAC,CAAC,SAAS,CAAC,CAAC,WAAW,GAAG,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE;oBACnD,CAAC,CAAC,OAAO,CAAC;gBACd,OAAO;oBACL,UAAU;oBACV,cAAc,CAAC,CAAC,OAAO,EAAE;oBACzB,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI;oBAC5C,KAAK;iBACN;qBACE,MAAM,CAAC,OAAO,CAAC;qBACf,IAAI,CAAC,IAAI,CAAC,CAAC;YAChB,CAAC,CAAC;iBACD,IAAI,CAAC,IAAI,CAAC,CAAC;YAEd,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,aAAa,OAAO,CAAC,MAAM,kBAAkB,IAAI,CAAC,UAAU,SAAS,SAAS,EAAE;qBACvF;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC;YAClD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC;QACzE,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,CAAC;AAC3D,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { DocumentChunk } from "./types";
2
+ export declare function hashContent(content: string): string;
3
+ export interface ChunkOptions {
4
+ sessionId: string;
5
+ sessionTitle: string;
6
+ project: string;
7
+ /** Base URL for the message, e.g. "session://ses_xxx#msg_yyy" */
8
+ baseUrl: string;
9
+ }
10
+ /**
11
+ * Splits a markdown string into semantically meaningful, heading-aware chunks.
12
+ * Adapted from doc2vec's ContentProcessor.chunkMarkdown().
13
+ *
14
+ * @param markdown Full markdown text to chunk
15
+ * @param options Metadata to attach to each chunk
16
+ */
17
+ export declare function chunkMarkdown(markdown: string, options: ChunkOptions): DocumentChunk[];
18
+ //# sourceMappingURL=chunker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunker.d.ts","sourceRoot":"","sources":["../../src/chunker.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAa7C,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnD;AAMD,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,OAAO,EAAE,MAAM,CAAC;CACjB;AA8DD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,YAAY,GACpB,aAAa,EAAE,CA6EjB"}
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.hashContent = hashContent;
7
+ exports.chunkMarkdown = chunkMarkdown;
8
+ const crypto_1 = __importDefault(require("crypto"));
9
+ // ---------------------------------------------------------------------------
10
+ // Constants (matching doc2vec defaults)
11
+ // ---------------------------------------------------------------------------
12
+ const MAX_TOKENS = 1000;
13
+ const MIN_TOKENS = 150;
14
+ const OVERLAP_PERCENT = 0.1;
15
+ // ---------------------------------------------------------------------------
16
+ // Hashing
17
+ // ---------------------------------------------------------------------------
18
+ function hashContent(content) {
19
+ return crypto_1.default.createHash("sha256").update(content).digest("hex");
20
+ }
21
+ function countTokens(text) {
22
+ return text.trim().split(/\s+/).filter(Boolean).length;
23
+ }
24
+ function buildBreadcrumb(headingHierarchy) {
25
+ return headingHierarchy.filter(Boolean).join(" > ");
26
+ }
27
+ /**
28
+ * Splits an oversized buffer into overlapping sub-chunks.
29
+ */
30
+ function splitWithOverlap(lines) {
31
+ const words = lines.join("\n").split(/\s+/).filter(Boolean);
32
+ const overlapCount = Math.floor(MAX_TOKENS * OVERLAP_PERCENT);
33
+ const chunks = [];
34
+ let start = 0;
35
+ while (start < words.length) {
36
+ const end = Math.min(start + MAX_TOKENS, words.length);
37
+ chunks.push(words.slice(start, end));
38
+ if (end >= words.length)
39
+ break;
40
+ start = end - overlapCount;
41
+ }
42
+ return chunks;
43
+ }
44
+ function createChunk(content, headingHierarchy, chunkIndex, options) {
45
+ const breadcrumb = buildBreadcrumb(headingHierarchy);
46
+ const prefixedContent = breadcrumb
47
+ ? `[Session: ${breadcrumb}]\n\n${content}`
48
+ : content;
49
+ const hash = hashContent(prefixedContent);
50
+ const chunkId = hashContent(`${options.baseUrl}::${chunkIndex}::${prefixedContent}`);
51
+ return {
52
+ content: prefixedContent,
53
+ metadata: {
54
+ session_id: options.sessionId,
55
+ session_title: options.sessionTitle,
56
+ project: options.project,
57
+ heading_hierarchy: headingHierarchy,
58
+ section: headingHierarchy[headingHierarchy.length - 1] ?? "",
59
+ chunk_id: chunkId,
60
+ url: options.baseUrl,
61
+ hash,
62
+ chunk_index: chunkIndex,
63
+ },
64
+ };
65
+ }
66
+ // ---------------------------------------------------------------------------
67
+ // Main chunker
68
+ // ---------------------------------------------------------------------------
69
+ /**
70
+ * Splits a markdown string into semantically meaningful, heading-aware chunks.
71
+ * Adapted from doc2vec's ContentProcessor.chunkMarkdown().
72
+ *
73
+ * @param markdown Full markdown text to chunk
74
+ * @param options Metadata to attach to each chunk
75
+ */
76
+ function chunkMarkdown(markdown, options) {
77
+ const lines = markdown.split("\n");
78
+ const headingHierarchy = [];
79
+ let buffer = [];
80
+ const pendingChunks = [];
81
+ function flushBuffer(hierarchy) {
82
+ if (buffer.length === 0)
83
+ return;
84
+ const tokenCount = countTokens(buffer.join("\n"));
85
+ if (tokenCount > MAX_TOKENS) {
86
+ // Split with overlap
87
+ const subChunks = splitWithOverlap(buffer);
88
+ for (const wordBatch of subChunks) {
89
+ pendingChunks.push({
90
+ lines: [wordBatch.join(" ")],
91
+ hierarchy: [...hierarchy],
92
+ });
93
+ }
94
+ }
95
+ else {
96
+ pendingChunks.push({ lines: [...buffer], hierarchy: [...hierarchy] });
97
+ }
98
+ buffer = [];
99
+ }
100
+ for (const line of lines) {
101
+ const headingMatch = line.match(/^(#{1,6})\s+(.*)/);
102
+ if (headingMatch) {
103
+ const level = headingMatch[1].length;
104
+ const title = headingMatch[2].trim();
105
+ // Flush before updating the heading stack
106
+ const tokenCount = countTokens(buffer.join("\n"));
107
+ if (tokenCount >= MIN_TOKENS) {
108
+ flushBuffer([...headingHierarchy]);
109
+ }
110
+ else if (buffer.length > 0) {
111
+ // Merge small buffer into next section
112
+ // keep it in buffer
113
+ }
114
+ // Update heading hierarchy
115
+ headingHierarchy[level - 1] = title;
116
+ // Clear deeper levels
117
+ headingHierarchy.splice(level);
118
+ }
119
+ else {
120
+ buffer.push(line);
121
+ }
122
+ }
123
+ // Flush remaining
124
+ flushBuffer([...headingHierarchy]);
125
+ // Merge tiny trailing chunks into the previous one
126
+ const merged = [];
127
+ for (const chunk of pendingChunks) {
128
+ const tokens = countTokens(chunk.lines.join("\n"));
129
+ if (tokens < MIN_TOKENS && merged.length > 0) {
130
+ const prev = merged[merged.length - 1];
131
+ prev.lines = [...prev.lines, "", ...chunk.lines];
132
+ }
133
+ else {
134
+ merged.push(chunk);
135
+ }
136
+ }
137
+ // Filter out empty/whitespace-only chunks before finalizing
138
+ const nonEmpty = merged.filter((m) => m.lines.join("\n").trim().length > 0);
139
+ // Build final DocumentChunks with correct total_chunks
140
+ const total = nonEmpty.length;
141
+ return nonEmpty.map((m, idx) => {
142
+ const partial = createChunk(m.lines.join("\n"), m.hierarchy, idx, options);
143
+ return {
144
+ ...partial,
145
+ metadata: { ...partial.metadata, total_chunks: total },
146
+ };
147
+ });
148
+ }
149
+ //# sourceMappingURL=chunker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunker.js","sourceRoot":"","sources":["../../src/chunker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * code-session-memory CLI
4
+ *
5
+ * Usage:
6
+ * npx code-session-memory install — install for OpenCode + Claude Code
7
+ * npx code-session-memory status — show installation status
8
+ * npx code-session-memory uninstall — remove all installed components
9
+ */
10
+ export {};
11
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;GAOG"}