@tom2012/cc-web 2026.6.12-a → 2026.6.12-c

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 (44) hide show
  1. package/backend/dist/__tests__/claude-mem-store.test.d.ts +2 -0
  2. package/backend/dist/__tests__/claude-mem-store.test.d.ts.map +1 -0
  3. package/backend/dist/__tests__/claude-mem-store.test.js +202 -0
  4. package/backend/dist/__tests__/claude-mem-store.test.js.map +1 -0
  5. package/backend/dist/claude-mem-store.d.ts +66 -0
  6. package/backend/dist/claude-mem-store.d.ts.map +1 -0
  7. package/backend/dist/claude-mem-store.js +242 -0
  8. package/backend/dist/claude-mem-store.js.map +1 -0
  9. package/backend/dist/index.d.ts.map +1 -1
  10. package/backend/dist/index.js +5 -0
  11. package/backend/dist/index.js.map +1 -1
  12. package/backend/dist/routes/claude-mem.d.ts +10 -0
  13. package/backend/dist/routes/claude-mem.d.ts.map +1 -0
  14. package/backend/dist/routes/claude-mem.js +80 -0
  15. package/backend/dist/routes/claude-mem.js.map +1 -0
  16. package/backend/package-lock.json +344 -2
  17. package/backend/package.json +2 -0
  18. package/frontend/dist/assets/{ChatOverlay-C6RdSj9e.js → ChatOverlay-BYHxECck.js} +3 -3
  19. package/frontend/dist/assets/ClaudeMemPage-AeBcDyNZ.js +1 -0
  20. package/frontend/dist/assets/{GraphPreview-Dw1vaeAh.js → GraphPreview-CraKSWzy.js} +2 -2
  21. package/frontend/dist/assets/MobilePage-FMVoG0Pl.js +14 -0
  22. package/frontend/dist/assets/{OfficePreview-D0_TpLvk.js → OfficePreview-DQ8oitRF.js} +2 -2
  23. package/frontend/dist/assets/{PdfPreview-8gw66dXT.js → PdfPreview-BX-q3oXm.js} +1 -1
  24. package/frontend/dist/assets/{ProjectPage-3_GsDNjW.js → ProjectPage-DbVFAUzJ.js} +5 -5
  25. package/frontend/dist/assets/{SettingsPage-BImUEDUD.js → SettingsPage-CoyFVnCz.js} +2 -2
  26. package/frontend/dist/assets/{SkillHubPage-TJxZNqMT.js → SkillHubPage-CjFCt8dE.js} +1 -1
  27. package/frontend/dist/assets/check-circle-2-DqS6oPDV.js +7 -0
  28. package/frontend/dist/assets/{chevron-down-CTVvTLhb.js → chevron-down-BPnYeDMC.js} +1 -1
  29. package/frontend/dist/assets/file-text-CPajDnww.js +7 -0
  30. package/frontend/dist/assets/index-2wJikgEX.js +75 -0
  31. package/frontend/dist/assets/index-61v6oszV.css +1 -0
  32. package/frontend/dist/assets/{index-D5PscqpS.js → index-Di5Ntujm.js} +1 -1
  33. package/frontend/dist/assets/index-DrpeVVUe.js +7 -0
  34. package/frontend/dist/assets/{jszip.min-GIboMR_6.js → jszip.min-BxSvgCaf.js} +1 -1
  35. package/frontend/dist/assets/{search-sJdiRvSJ.js → search-1chGdDoe.js} +1 -1
  36. package/frontend/dist/assets/select-YkUpG7ZI.js +1 -0
  37. package/frontend/dist/assets/tabs-C3yC9N14.js +13 -0
  38. package/frontend/dist/index.html +2 -2
  39. package/package.json +1 -1
  40. package/frontend/dist/assets/MobilePage-CDeNNMvX.js +0 -14
  41. package/frontend/dist/assets/index-CMlFtaTa.js +0 -75
  42. package/frontend/dist/assets/index-Czlx_FcC.css +0 -1
  43. package/frontend/dist/assets/index-o8xpeYuN.js +0 -13
  44. package/frontend/dist/assets/select-DGBcT103.js +0 -13
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=claude-mem-store.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-mem-store.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/claude-mem-store.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,202 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ /**
40
+ * Unit tests for the read-only claude-mem store against a synthetic temp DB
41
+ * (minimal subset of the real claude-mem schema). No hardcoded counts against
42
+ * the real DB — everything is built fresh here.
43
+ *
44
+ * Run: npx vitest run src/__tests__/claude-mem-store.test.ts
45
+ */
46
+ const vitest_1 = require("vitest");
47
+ const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
48
+ const fs_1 = __importDefault(require("fs"));
49
+ const os_1 = __importDefault(require("os"));
50
+ const path_1 = __importDefault(require("path"));
51
+ let tmpDir;
52
+ let dbPath;
53
+ let store;
54
+ const BASE = 1700000000000;
55
+ (0, vitest_1.beforeAll)(async () => {
56
+ tmpDir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'ccweb-cm-test-'));
57
+ dbPath = path_1.default.join(tmpDir, 'claude-mem.db');
58
+ const db = new better_sqlite3_1.default(dbPath);
59
+ db.pragma('journal_mode = wal');
60
+ db.exec(`
61
+ CREATE TABLE observations (
62
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
63
+ memory_session_id TEXT,
64
+ project TEXT NOT NULL,
65
+ text TEXT,
66
+ type TEXT NOT NULL,
67
+ title TEXT, subtitle TEXT, narrative TEXT,
68
+ facts TEXT, concepts TEXT, files_read TEXT, files_modified TEXT,
69
+ agent_type TEXT,
70
+ created_at TEXT NOT NULL,
71
+ created_at_epoch INTEGER NOT NULL
72
+ );
73
+ CREATE VIRTUAL TABLE observations_fts USING fts5(
74
+ title, subtitle, narrative, text, facts, concepts,
75
+ content='observations', content_rowid='id'
76
+ );
77
+ CREATE TABLE session_summaries (
78
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
79
+ project TEXT NOT NULL,
80
+ request TEXT, investigated TEXT, learned TEXT, completed TEXT, next_steps TEXT,
81
+ files_read TEXT, files_edited TEXT, notes TEXT,
82
+ created_at TEXT NOT NULL, created_at_epoch INTEGER NOT NULL
83
+ );
84
+ `);
85
+ const insObs = db.prepare(`INSERT INTO observations
86
+ (project,text,type,title,subtitle,narrative,facts,concepts,files_read,files_modified,agent_type,created_at,created_at_epoch)
87
+ VALUES (@project,@text,@type,@title,@subtitle,@narrative,@facts,@concepts,@files_read,@files_modified,@agent_type,@created_at,@created_at_epoch)`);
88
+ insObs.run({
89
+ project: 'cc-web', text: 'host stats endpoint added', type: 'feature',
90
+ title: 'Add host stats', subtitle: 'CPU mem disk', narrative: 'n1',
91
+ facts: JSON.stringify(['fact a', 'fact b']), concepts: JSON.stringify(['how-it-works']),
92
+ files_read: '[]', files_modified: JSON.stringify(['a.ts']), agent_type: null,
93
+ created_at: new Date(BASE + 3000).toISOString(), created_at_epoch: BASE + 3000,
94
+ });
95
+ insObs.run({
96
+ project: 'cc-web', text: 'fix the race', type: 'bugfix',
97
+ title: 'Fix race', subtitle: null, narrative: 'n2',
98
+ facts: 'THIS IS NOT VALID JSON', concepts: '[]', files_read: '[]', files_modified: '[]',
99
+ agent_type: 'Explore',
100
+ created_at: new Date(BASE + 2000).toISOString(), created_at_epoch: BASE + 2000,
101
+ });
102
+ insObs.run({
103
+ project: 'other-proj', text: 'unrelated work', type: 'discovery',
104
+ title: 'Other thing', subtitle: null, narrative: 'n3',
105
+ facts: '[]', concepts: '[]', files_read: '[]', files_modified: '[]', agent_type: null,
106
+ created_at: new Date(BASE + 1000).toISOString(), created_at_epoch: BASE + 1000,
107
+ });
108
+ // Repopulate FTS from the (external-content) observations table.
109
+ db.prepare(`INSERT INTO observations_fts(observations_fts) VALUES('rebuild')`).run();
110
+ db.prepare(`INSERT INTO session_summaries
111
+ (project,request,learned,next_steps,files_read,files_edited,notes,created_at,created_at_epoch)
112
+ VALUES (?,?,?,?,?,?,?,?,?)`)
113
+ .run('cc-web', 'req', 'learned things', 'do next', '[]', JSON.stringify(['b.ts']), 'note', new Date(BASE).toISOString(), BASE);
114
+ db.close();
115
+ process.env.CCWEB_CLAUDE_MEM_DB = dbPath;
116
+ store = await Promise.resolve().then(() => __importStar(require('../claude-mem-store')));
117
+ });
118
+ (0, vitest_1.afterAll)(() => {
119
+ store.closeClaudeMemStore();
120
+ fs_1.default.rmSync(tmpDir, { recursive: true, force: true });
121
+ });
122
+ (0, vitest_1.describe)('claude-mem-store', () => {
123
+ (0, vitest_1.it)('reports available with counts', () => {
124
+ const s = store.getStatus();
125
+ (0, vitest_1.expect)(s.available).toBe(true);
126
+ (0, vitest_1.expect)(s.degraded).toBe(false);
127
+ (0, vitest_1.expect)(s.counts).toEqual({ observations: 3, summaries: 1, projects: 2 });
128
+ });
129
+ (0, vitest_1.it)('lists all observations newest-first', () => {
130
+ const r = store.listObservations({ limit: 30, offset: 0 });
131
+ (0, vitest_1.expect)(r.total).toBe(3);
132
+ (0, vitest_1.expect)(r.items.map((o) => o.title)).toEqual(['Add host stats', 'Fix race', 'Other thing']);
133
+ });
134
+ (0, vitest_1.it)('parses JSON array fields and tolerates bad JSON', () => {
135
+ const r = store.listObservations({ limit: 30, offset: 0 });
136
+ const feature = r.items.find((o) => o.title === 'Add host stats');
137
+ (0, vitest_1.expect)(feature.facts).toEqual(['fact a', 'fact b']);
138
+ (0, vitest_1.expect)(feature.filesModified).toEqual(['a.ts']);
139
+ const bug = r.items.find((o) => o.title === 'Fix race');
140
+ (0, vitest_1.expect)(bug.facts).toEqual([]); // invalid JSON degrades to []
141
+ });
142
+ (0, vitest_1.it)('filters by project', () => {
143
+ const r = store.listObservations({ project: 'cc-web', limit: 30, offset: 0 });
144
+ (0, vitest_1.expect)(r.total).toBe(2);
145
+ (0, vitest_1.expect)(r.items.every((o) => o.project === 'cc-web')).toBe(true);
146
+ });
147
+ (0, vitest_1.it)('filters by type', () => {
148
+ const r = store.listObservations({ types: ['bugfix'], limit: 30, offset: 0 });
149
+ (0, vitest_1.expect)(r.total).toBe(1);
150
+ (0, vitest_1.expect)(r.items[0].title).toBe('Fix race');
151
+ });
152
+ (0, vitest_1.it)('FTS prefix search matches on indexed columns incl. text', () => {
153
+ const exact = store.listObservations({ q: 'host', limit: 30, offset: 0 });
154
+ (0, vitest_1.expect)(exact.total).toBe(1);
155
+ (0, vitest_1.expect)(exact.items[0].title).toBe('Add host stats');
156
+ // prefix: "hos" should still match "host" via the trailing *
157
+ const prefix = store.listObservations({ q: 'hos', limit: 30, offset: 0 });
158
+ (0, vitest_1.expect)(prefix.total).toBe(1);
159
+ });
160
+ (0, vitest_1.it)('whitespace/punctuation-only query falls back to plain list (no MATCH error)', () => {
161
+ (0, vitest_1.expect)(store.listObservations({ q: ' ', limit: 30, offset: 0 }).total).toBe(3);
162
+ (0, vitest_1.expect)(store.listObservations({ q: '""', limit: 30, offset: 0 }).total).toBe(3);
163
+ });
164
+ (0, vitest_1.it)('paginates', () => {
165
+ const p0 = store.listObservations({ limit: 1, offset: 0 });
166
+ (0, vitest_1.expect)(p0.items).toHaveLength(1);
167
+ (0, vitest_1.expect)(p0.total).toBe(3);
168
+ const p1 = store.listObservations({ limit: 1, offset: 1 });
169
+ (0, vitest_1.expect)(p1.items[0].title).toBe('Fix race');
170
+ });
171
+ (0, vitest_1.it)('gets a single observation, null for missing', () => {
172
+ const all = store.listObservations({ limit: 30, offset: 0 });
173
+ const one = store.getObservation(all.items[0].id);
174
+ (0, vitest_1.expect)(one?.title).toBe('Add host stats');
175
+ (0, vitest_1.expect)(store.getObservation(999999)).toBeNull();
176
+ });
177
+ (0, vitest_1.it)('lists projects with counts', () => {
178
+ const projects = store.listProjects();
179
+ (0, vitest_1.expect)(projects.map((p) => p.project).sort()).toEqual(['cc-web', 'other-proj']);
180
+ (0, vitest_1.expect)(projects.find((p) => p.project === 'cc-web').count).toBe(2);
181
+ });
182
+ (0, vitest_1.it)('lists session summaries with parsed file arrays', () => {
183
+ const r = store.listSessionSummaries({ limit: 30, offset: 0 });
184
+ (0, vitest_1.expect)(r.total).toBe(1);
185
+ (0, vitest_1.expect)(r.items[0].nextSteps).toBe('do next');
186
+ (0, vitest_1.expect)(r.items[0].filesEdited).toEqual(['b.ts']);
187
+ });
188
+ });
189
+ (0, vitest_1.describe)('claude-mem-store (missing db)', () => {
190
+ (0, vitest_1.it)('reports unavailable and returns empty, no throw', async () => {
191
+ vitest_1.vi.resetModules();
192
+ const prev = process.env.CCWEB_CLAUDE_MEM_DB;
193
+ process.env.CCWEB_CLAUDE_MEM_DB = path_1.default.join(tmpDir, 'nope.db');
194
+ const fresh = await Promise.resolve().then(() => __importStar(require('../claude-mem-store')));
195
+ (0, vitest_1.expect)(fresh.getStatus().available).toBe(false);
196
+ (0, vitest_1.expect)(fresh.listObservations({ limit: 30, offset: 0 })).toEqual({ items: [], total: 0 });
197
+ (0, vitest_1.expect)(fresh.listProjects()).toEqual([]);
198
+ process.env.CCWEB_CLAUDE_MEM_DB = prev;
199
+ vitest_1.vi.resetModules();
200
+ });
201
+ });
202
+ //# sourceMappingURL=claude-mem-store.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-mem-store.test.js","sourceRoot":"","sources":["../../src/__tests__/claude-mem-store.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;GAMG;AACH,mCAAuE;AACvE,oEAAsC;AACtC,4CAAoB;AACpB,4CAAoB;AACpB,gDAAwB;AAExB,IAAI,MAAc,CAAC;AACnB,IAAI,MAAc,CAAC;AACnB,IAAI,KAA2C,CAAC;AAEhD,MAAM,IAAI,GAAG,aAAa,CAAC;AAE3B,IAAA,kBAAS,EAAC,KAAK,IAAI,EAAE;IACnB,MAAM,GAAG,YAAE,CAAC,WAAW,CAAC,cAAI,CAAC,IAAI,CAAC,YAAE,CAAC,MAAM,EAAE,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAClE,MAAM,GAAG,cAAI,CAAC,IAAI,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAE5C,MAAM,EAAE,GAAG,IAAI,wBAAQ,CAAC,MAAM,CAAC,CAAC;IAChC,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAChC,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;GAwBP,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC;;qJAEyH,CAAC,CAAC;IAErJ,MAAM,CAAC,GAAG,CAAC;QACT,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,2BAA2B,EAAE,IAAI,EAAE,SAAS;QACrE,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,cAAc,EAAE,SAAS,EAAE,IAAI;QAClE,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,cAAc,CAAC,CAAC;QACvF,UAAU,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI;QAC5E,UAAU,EAAE,IAAI,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,gBAAgB,EAAE,IAAI,GAAG,IAAI;KAC/E,CAAC,CAAC;IACH,MAAM,CAAC,GAAG,CAAC;QACT,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,QAAQ;QACvD,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI;QAClD,KAAK,EAAE,wBAAwB,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI;QACvF,UAAU,EAAE,SAAS;QACrB,UAAU,EAAE,IAAI,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,gBAAgB,EAAE,IAAI,GAAG,IAAI;KAC/E,CAAC,CAAC;IACH,MAAM,CAAC,GAAG,CAAC;QACT,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW;QAChE,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI;QACrD,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI;QACrF,UAAU,EAAE,IAAI,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,gBAAgB,EAAE,IAAI,GAAG,IAAI;KAC/E,CAAC,CAAC;IACH,iEAAiE;IACjE,EAAE,CAAC,OAAO,CAAC,kEAAkE,CAAC,CAAC,GAAG,EAAE,CAAC;IAErF,EAAE,CAAC,OAAO,CAAC;;+BAEkB,CAAC;SAC3B,GAAG,CAAC,QAAQ,EAAE,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,EACvF,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,IAAI,CAAC,CAAC;IAExC,EAAE,CAAC,KAAK,EAAE,CAAC;IAEX,OAAO,CAAC,GAAG,CAAC,mBAAmB,GAAG,MAAM,CAAC;IACzC,KAAK,GAAG,wDAAa,qBAAqB,GAAC,CAAC;AAC9C,CAAC,CAAC,CAAC;AAEH,IAAA,iBAAQ,EAAC,GAAG,EAAE;IACZ,KAAK,CAAC,mBAAmB,EAAE,CAAC;IAC5B,YAAE,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACtD,CAAC,CAAC,CAAC;AAEH,IAAA,iBAAQ,EAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,IAAA,WAAE,EAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,CAAC,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;QAC5B,IAAA,eAAM,EAAC,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAA,eAAM,EAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAA,eAAM,EAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,CAAC,GAAG,KAAK,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;QAC3D,IAAA,eAAM,EAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACxB,IAAA,eAAM,EAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,gBAAgB,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC;IAC7F,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,CAAC,GAAG,KAAK,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;QAC3D,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,gBAAgB,CAAE,CAAC;QACnE,IAAA,eAAM,EAAC,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;QACpD,IAAA,eAAM,EAAC,OAAO,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QAChD,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,UAAU,CAAE,CAAC;QACzD,IAAA,eAAM,EAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,8BAA8B;IAC/D,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,oBAAoB,EAAE,GAAG,EAAE;QAC5B,MAAM,CAAC,GAAG,KAAK,CAAC,gBAAgB,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;QAC9E,IAAA,eAAM,EAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACxB,IAAA,eAAM,EAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,iBAAiB,EAAE,GAAG,EAAE;QACzB,MAAM,CAAC,GAAG,KAAK,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;QAC9E,IAAA,eAAM,EAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACxB,IAAA,eAAM,EAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,MAAM,KAAK,GAAG,KAAK,CAAC,gBAAgB,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;QAC1E,IAAA,eAAM,EAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAA,eAAM,EAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACpD,6DAA6D;QAC7D,MAAM,MAAM,GAAG,KAAK,CAAC,gBAAgB,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;QAC1E,IAAA,eAAM,EAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,6EAA6E,EAAE,GAAG,EAAE;QACrF,IAAA,eAAM,EAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjF,IAAA,eAAM,EAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClF,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,WAAW,EAAE,GAAG,EAAE;QACnB,MAAM,EAAE,GAAG,KAAK,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;QAC3D,IAAA,eAAM,EAAC,EAAE,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACjC,IAAA,eAAM,EAAC,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACzB,MAAM,EAAE,GAAG,KAAK,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;QAC3D,IAAA,eAAM,EAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,GAAG,GAAG,KAAK,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;QAC7D,MAAM,GAAG,GAAG,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAClD,IAAA,eAAM,EAAC,GAAG,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC1C,IAAA,eAAM,EAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,MAAM,QAAQ,GAAG,KAAK,CAAC,YAAY,EAAE,CAAC;QACtC,IAAA,eAAM,EAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC;QAChF,IAAA,eAAM,EAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAE,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,CAAC,GAAG,KAAK,CAAC,oBAAoB,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;QAC/D,IAAA,eAAM,EAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACxB,IAAA,eAAM,EAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC7C,IAAA,eAAM,EAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAA,iBAAQ,EAAC,+BAA+B,EAAE,GAAG,EAAE;IAC7C,IAAA,WAAE,EAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC/D,WAAE,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;QAC7C,OAAO,CAAC,GAAG,CAAC,mBAAmB,GAAG,cAAI,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAC/D,MAAM,KAAK,GAAG,wDAAa,qBAAqB,GAAC,CAAC;QAClD,IAAA,eAAM,EAAC,KAAK,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChD,IAAA,eAAM,EAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QAC1F,IAAA,eAAM,EAAC,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACzC,OAAO,CAAC,GAAG,CAAC,mBAAmB,GAAG,IAAI,CAAC;QACvC,WAAE,CAAC,YAAY,EAAE,CAAC;IACpB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,66 @@
1
+ export interface Observation {
2
+ id: number;
3
+ project: string;
4
+ type: string;
5
+ title: string | null;
6
+ subtitle: string | null;
7
+ narrative: string | null;
8
+ facts: string[];
9
+ concepts: string[];
10
+ filesRead: string[];
11
+ filesModified: string[];
12
+ agentType: string | null;
13
+ createdAt: string;
14
+ }
15
+ export interface SessionSummary {
16
+ id: number;
17
+ project: string;
18
+ request: string | null;
19
+ investigated: string | null;
20
+ learned: string | null;
21
+ completed: string | null;
22
+ nextSteps: string | null;
23
+ filesRead: string[];
24
+ filesEdited: string[];
25
+ notes: string | null;
26
+ createdAt: string;
27
+ }
28
+ export interface ProjectEntry {
29
+ project: string;
30
+ count: number;
31
+ lastAt: string;
32
+ }
33
+ export interface StoreStatus {
34
+ available: boolean;
35
+ degraded: boolean;
36
+ dbPath: string;
37
+ counts?: {
38
+ observations: number;
39
+ summaries: number;
40
+ projects: number;
41
+ };
42
+ }
43
+ export declare function listObservations(opts: {
44
+ project?: string;
45
+ types?: string[];
46
+ q?: string;
47
+ limit: number;
48
+ offset: number;
49
+ }): {
50
+ items: Observation[];
51
+ total: number;
52
+ };
53
+ export declare function getObservation(id: number): Observation | null;
54
+ export declare function listSessionSummaries(opts: {
55
+ project?: string;
56
+ limit: number;
57
+ offset: number;
58
+ }): {
59
+ items: SessionSummary[];
60
+ total: number;
61
+ };
62
+ export declare function listProjects(): ProjectEntry[];
63
+ export declare function getStatus(): StoreStatus;
64
+ /** For graceful shutdown. */
65
+ export declare function closeClaudeMemStore(): void;
66
+ //# sourceMappingURL=claude-mem-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-mem-store.d.ts","sourceRoot":"","sources":["../src/claude-mem-store.ts"],"names":[],"mappings":"AA6BA,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CACxE;AAkJD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG;IAAE,KAAK,EAAE,WAAW,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAkC1C;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAO7D;AAgBD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG;IAAE,KAAK,EAAE,cAAc,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAiC7C;AAED,wBAAgB,YAAY,IAAI,YAAY,EAAE,CAU7C;AAED,wBAAgB,SAAS,IAAI,WAAW,CAevC;AAED,6BAA6B;AAC7B,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C"}
@@ -0,0 +1,242 @@
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.listObservations = listObservations;
7
+ exports.getObservation = getObservation;
8
+ exports.listSessionSummaries = listSessionSummaries;
9
+ exports.listProjects = listProjects;
10
+ exports.getStatus = getStatus;
11
+ exports.closeClaudeMemStore = closeClaudeMemStore;
12
+ const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
13
+ const fs_1 = __importDefault(require("fs"));
14
+ const os_1 = __importDefault(require("os"));
15
+ const path_1 = __importDefault(require("path"));
16
+ const logger_1 = require("./logger");
17
+ const log = (0, logger_1.modLogger)('claude-mem');
18
+ /**
19
+ * Read-only view into the claude-mem plugin's SQLite database
20
+ * (`~/.claude-mem/claude-mem.db`). All access is readonly + query_only; ccweb
21
+ * never writes. Everything claude-mem-version-specific lives in this one module
22
+ * so schema drift across plugin versions is contained (treat as best-effort).
23
+ *
24
+ * Connection lifecycle: lazy open, reused across requests. The DB is live in
25
+ * WAL mode, so a readonly connection sees committed writes without reopening.
26
+ * BUT claude-mem rebuilds the DB on upgrade (backup + replace), which renames
27
+ * the inode — a held handle would then silently read the stale unlinked inode.
28
+ * So each access cheaply stats the path and reopens if the inode changed.
29
+ */
30
+ const DB_PATH = process.env.CCWEB_CLAUDE_MEM_DB || path_1.default.join(os_1.default.homedir(), '.claude-mem', 'claude-mem.db');
31
+ let db = null;
32
+ let openedInode = null;
33
+ /** A query threw after a successful open → schema drift / partial corruption. */
34
+ let degraded = false;
35
+ function close() {
36
+ if (db) {
37
+ try {
38
+ db.close();
39
+ }
40
+ catch {
41
+ /* ignore */
42
+ }
43
+ }
44
+ db = null;
45
+ openedInode = null;
46
+ }
47
+ /**
48
+ * Return a usable readonly DB handle, or null if the file is absent/unopenable.
49
+ * Reopens transparently if the on-disk inode changed since we opened (rebuild).
50
+ */
51
+ function getDb() {
52
+ let ino;
53
+ try {
54
+ ino = fs_1.default.statSync(DB_PATH).ino;
55
+ }
56
+ catch {
57
+ // File missing → feature simply unavailable. Drop any stale handle.
58
+ close();
59
+ return null;
60
+ }
61
+ if (db && openedInode === ino)
62
+ return db;
63
+ if (db && openedInode !== ino)
64
+ close(); // rebuilt under us → reopen
65
+ try {
66
+ db = new better_sqlite3_1.default(DB_PATH, { readonly: true, fileMustExist: true });
67
+ db.pragma('query_only = true');
68
+ openedInode = ino;
69
+ degraded = false;
70
+ return db;
71
+ }
72
+ catch (err) {
73
+ log.warn({ err, dbPath: DB_PATH }, 'failed to open claude-mem db');
74
+ close();
75
+ return null;
76
+ }
77
+ }
78
+ /** Run a read query, degrading (not throwing) on schema drift / IO error. */
79
+ function safeQuery(fn, fallback) {
80
+ const d = getDb();
81
+ if (!d)
82
+ return fallback;
83
+ try {
84
+ return fn(d);
85
+ }
86
+ catch (err) {
87
+ log.warn({ err }, 'claude-mem query failed — degrading');
88
+ degraded = true;
89
+ // An IO-class failure may mean the handle went bad; drop it so the next
90
+ // call reopens.
91
+ if (err instanceof Error && /SQLITE_(IOERR|CORRUPT|NOTADB|READONLY)/.test(err.message))
92
+ close();
93
+ return fallback;
94
+ }
95
+ }
96
+ function safeJsonArray(s) {
97
+ if (typeof s !== 'string' || s.length === 0)
98
+ return [];
99
+ try {
100
+ const a = JSON.parse(s);
101
+ return Array.isArray(a) ? a.filter((x) => typeof x === 'string') : [];
102
+ }
103
+ catch {
104
+ return [];
105
+ }
106
+ }
107
+ function mapObs(r) {
108
+ return {
109
+ id: r.id,
110
+ project: r.project,
111
+ type: r.type,
112
+ title: r.title,
113
+ subtitle: r.subtitle,
114
+ narrative: r.narrative,
115
+ facts: safeJsonArray(r.facts),
116
+ concepts: safeJsonArray(r.concepts),
117
+ filesRead: safeJsonArray(r.files_read),
118
+ filesModified: safeJsonArray(r.files_modified),
119
+ agentType: r.agent_type,
120
+ createdAt: r.created_at,
121
+ };
122
+ }
123
+ const OBS_COLS = 'o.id, o.project, o.type, o.title, o.subtitle, o.narrative, o.facts, o.concepts, o.files_read, o.files_modified, o.agent_type, o.created_at';
124
+ /**
125
+ * Build the shared WHERE fragment + bound params for both the list and the
126
+ * COUNT query so they can never drift. When `q` is given the caller adds the
127
+ * FTS join; the fragment below only covers project/type equality filters.
128
+ */
129
+ function buildFilters(opts) {
130
+ const parts = [];
131
+ const params = {};
132
+ if (opts.project) {
133
+ parts.push('o.project = @project');
134
+ params.project = opts.project;
135
+ }
136
+ if (opts.types && opts.types.length > 0) {
137
+ const placeholders = opts.types.map((_, i) => `@type${i}`);
138
+ opts.types.forEach((t, i) => {
139
+ params[`type${i}`] = t;
140
+ });
141
+ parts.push(`o.type IN (${placeholders.join(', ')})`);
142
+ }
143
+ return { clause: parts.length ? parts.join(' AND ') : '', params };
144
+ }
145
+ /**
146
+ * Turn raw user text into a safe FTS5 prefix query, or null if nothing usable.
147
+ * Each token is double-quoted (escaping `"`) THEN suffixed with `*` for prefix
148
+ * matching — `"<tok>"*`. Quoting alone is an exact term; the trailing `*` is
149
+ * what makes it a prefix. Returns null for empty/whitespace/punctuation-only
150
+ * input so callers fall back to a plain list (never `MATCH ''`, which throws).
151
+ */
152
+ function buildFtsMatch(q) {
153
+ const tokens = q
154
+ .split(/\s+/)
155
+ .map((t) => t.replace(/"/g, '').trim())
156
+ .filter((t) => t.length > 0);
157
+ if (tokens.length === 0)
158
+ return null;
159
+ return tokens.map((t) => `"${t}"*`).join(' ');
160
+ }
161
+ function listObservations(opts) {
162
+ return safeQuery((d) => {
163
+ const { clause, params } = buildFilters(opts);
164
+ const match = opts.q ? buildFtsMatch(opts.q) : null;
165
+ const where = [];
166
+ const p = { ...params };
167
+ let join = '';
168
+ if (match) {
169
+ join = 'JOIN observations_fts f ON f.rowid = o.id';
170
+ where.push('observations_fts MATCH @match');
171
+ p.match = match;
172
+ }
173
+ if (clause)
174
+ where.push(clause);
175
+ const whereSql = where.length ? `WHERE ${where.join(' AND ')}` : '';
176
+ const total = d.prepare(`SELECT COUNT(*) AS c FROM observations o ${join} ${whereSql}`).get(p).c;
177
+ const rows = d
178
+ .prepare(`SELECT ${OBS_COLS} FROM observations o ${join} ${whereSql}
179
+ ORDER BY o.created_at_epoch DESC LIMIT @limit OFFSET @offset`)
180
+ .all({ ...p, limit: opts.limit, offset: opts.offset });
181
+ return { items: rows.map(mapObs), total };
182
+ }, { items: [], total: 0 });
183
+ }
184
+ function getObservation(id) {
185
+ return safeQuery((d) => {
186
+ const row = d.prepare(`SELECT ${OBS_COLS} FROM observations o WHERE o.id = @id`).get({ id });
187
+ return row ? mapObs(row) : null;
188
+ }, null);
189
+ }
190
+ function listSessionSummaries(opts) {
191
+ return safeQuery((d) => {
192
+ const whereSql = opts.project ? 'WHERE project = @project' : '';
193
+ const p = opts.project ? { project: opts.project } : {};
194
+ const total = d.prepare(`SELECT COUNT(*) AS c FROM session_summaries ${whereSql}`).get(p).c;
195
+ const rows = d
196
+ .prepare(`SELECT id, project, request, investigated, learned, completed, next_steps,
197
+ files_read, files_edited, notes, created_at
198
+ FROM session_summaries ${whereSql}
199
+ ORDER BY created_at_epoch DESC LIMIT @limit OFFSET @offset`)
200
+ .all({ ...p, limit: opts.limit, offset: opts.offset });
201
+ const items = rows.map((r) => ({
202
+ id: r.id,
203
+ project: r.project,
204
+ request: r.request,
205
+ investigated: r.investigated,
206
+ learned: r.learned,
207
+ completed: r.completed,
208
+ nextSteps: r.next_steps,
209
+ filesRead: safeJsonArray(r.files_read),
210
+ filesEdited: safeJsonArray(r.files_edited),
211
+ notes: r.notes,
212
+ createdAt: r.created_at,
213
+ }));
214
+ return { items, total };
215
+ }, { items: [], total: 0 });
216
+ }
217
+ function listProjects() {
218
+ return safeQuery((d) => {
219
+ const rows = d
220
+ .prepare(`SELECT project, COUNT(*) AS count, MAX(created_at) AS lastAt
221
+ FROM observations GROUP BY project ORDER BY MAX(created_at_epoch) DESC`)
222
+ .all();
223
+ return rows;
224
+ }, []);
225
+ }
226
+ function getStatus() {
227
+ const d = getDb();
228
+ if (!d)
229
+ return { available: false, degraded: false, dbPath: DB_PATH };
230
+ const counts = safeQuery((db2) => ({
231
+ observations: db2.prepare('SELECT COUNT(*) AS c FROM observations').get().c,
232
+ summaries: db2.prepare('SELECT COUNT(*) AS c FROM session_summaries').get()
233
+ .c,
234
+ projects: db2.prepare('SELECT COUNT(DISTINCT project) AS c FROM observations').get().c,
235
+ }), { observations: 0, summaries: 0, projects: 0 });
236
+ return { available: true, degraded, dbPath: DB_PATH, counts };
237
+ }
238
+ /** For graceful shutdown. */
239
+ function closeClaudeMemStore() {
240
+ close();
241
+ }
242
+ //# sourceMappingURL=claude-mem-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-mem-store.js","sourceRoot":"","sources":["../src/claude-mem-store.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA8FA,QAAA,MAAM,GAAG,6CAAY,CAAC;AAy7BtB,eAAe,GAAG,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAiGA,QAAA,MAAM,GAAG,6CAAY,CAAC;AA27BtB,eAAe,GAAG,CAAC"}
@@ -65,6 +65,9 @@ const track_flow_1 = require("./track-flow");
65
65
  const update_1 = __importDefault(require("./routes/update"));
66
66
  const user_prefs_1 = __importDefault(require("./routes/user-prefs"));
67
67
  const host_stats_1 = __importDefault(require("./routes/host-stats"));
68
+ const claude_mem_1 = __importDefault(require("./routes/claude-mem"));
69
+ const claude_mem_store_1 = require("./claude-mem-store");
70
+ const authz_1 = require("./middleware/authz");
68
71
  const skillhub_1 = __importDefault(require("./routes/skillhub"));
69
72
  const session_manager_1 = require("./session-manager");
70
73
  const logger_1 = require("./logger");
@@ -224,6 +227,7 @@ app.use('/api/memory', auth_1.authMiddleware, memory_prompts_1.default);
224
227
  app.use('/api/update', auth_1.authMiddleware, update_1.default);
225
228
  app.use('/api/user-prefs', auth_1.authMiddleware, user_prefs_1.default);
226
229
  app.use('/api/host-stats', auth_1.authMiddleware, host_stats_1.default);
230
+ app.use('/api/claude-mem', auth_1.authMiddleware, authz_1.requireAdmin, claude_mem_1.default);
227
231
  app.use('/api/skillhub', auth_1.authMiddleware, skillhub_1.default);
228
232
  app.use('/api/notify', auth_1.authMiddleware, notify_1.default);
229
233
  app.use('/api/projects', auth_1.authMiddleware, git_1.default);
@@ -1077,6 +1081,7 @@ function shutdown() {
1077
1081
  // Kill all headless chromium instances — daemon-side babysitter; without
1078
1082
  // this, child chrome processes survive daemon SIGTERM (zombie processes).
1079
1083
  session_manager_2.browserChromeSessions.destroyAll().catch((err) => log.warn({ err }, 'browser-chrome destroyAll failed'));
1084
+ (0, claude_mem_store_1.closeClaudeMemStore)();
1080
1085
  server.close(async () => {
1081
1086
  log.info('shutdown closed');
1082
1087
  await (0, logger_1.flushLogger)();