@tznthou/ccrecall 0.1.2

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 (87) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +290 -0
  3. package/README_ZH.md +288 -0
  4. package/dist/api/routes.d.ts +13 -0
  5. package/dist/api/routes.d.ts.map +1 -0
  6. package/dist/api/routes.js +428 -0
  7. package/dist/api/routes.js.map +1 -0
  8. package/dist/api/server.d.ts +7 -0
  9. package/dist/api/server.d.ts.map +1 -0
  10. package/dist/api/server.js +44 -0
  11. package/dist/api/server.js.map +1 -0
  12. package/dist/cli/daemon.d.ts +35 -0
  13. package/dist/cli/daemon.d.ts.map +1 -0
  14. package/dist/cli/daemon.js +163 -0
  15. package/dist/cli/daemon.js.map +1 -0
  16. package/dist/core/compression.d.ts +37 -0
  17. package/dist/core/compression.d.ts.map +1 -0
  18. package/dist/core/compression.js +129 -0
  19. package/dist/core/compression.js.map +1 -0
  20. package/dist/core/database.d.ts +219 -0
  21. package/dist/core/database.d.ts.map +1 -0
  22. package/dist/core/database.js +1513 -0
  23. package/dist/core/database.js.map +1 -0
  24. package/dist/core/index.d.ts +9 -0
  25. package/dist/core/index.d.ts.map +1 -0
  26. package/dist/core/index.js +8 -0
  27. package/dist/core/index.js.map +1 -0
  28. package/dist/core/indexer.d.ts +15 -0
  29. package/dist/core/indexer.d.ts.map +1 -0
  30. package/dist/core/indexer.js +224 -0
  31. package/dist/core/indexer.js.map +1 -0
  32. package/dist/core/lint.d.ts +17 -0
  33. package/dist/core/lint.d.ts.map +1 -0
  34. package/dist/core/lint.js +51 -0
  35. package/dist/core/lint.js.map +1 -0
  36. package/dist/core/log-safe.d.ts +6 -0
  37. package/dist/core/log-safe.d.ts.map +1 -0
  38. package/dist/core/log-safe.js +11 -0
  39. package/dist/core/log-safe.js.map +1 -0
  40. package/dist/core/maintenance-coordinator.d.ts +26 -0
  41. package/dist/core/maintenance-coordinator.d.ts.map +1 -0
  42. package/dist/core/maintenance-coordinator.js +67 -0
  43. package/dist/core/maintenance-coordinator.js.map +1 -0
  44. package/dist/core/memory-service.d.ts +31 -0
  45. package/dist/core/memory-service.d.ts.map +1 -0
  46. package/dist/core/memory-service.js +47 -0
  47. package/dist/core/memory-service.js.map +1 -0
  48. package/dist/core/parser.d.ts +17 -0
  49. package/dist/core/parser.d.ts.map +1 -0
  50. package/dist/core/parser.js +205 -0
  51. package/dist/core/parser.js.map +1 -0
  52. package/dist/core/scanner.d.ts +8 -0
  53. package/dist/core/scanner.d.ts.map +1 -0
  54. package/dist/core/scanner.js +123 -0
  55. package/dist/core/scanner.js.map +1 -0
  56. package/dist/core/summarizer.d.ts +12 -0
  57. package/dist/core/summarizer.d.ts.map +1 -0
  58. package/dist/core/summarizer.js +430 -0
  59. package/dist/core/summarizer.js.map +1 -0
  60. package/dist/core/topic-extractor.d.ts +11 -0
  61. package/dist/core/topic-extractor.d.ts.map +1 -0
  62. package/dist/core/topic-extractor.js +51 -0
  63. package/dist/core/topic-extractor.js.map +1 -0
  64. package/dist/core/types.d.ts +329 -0
  65. package/dist/core/types.d.ts.map +1 -0
  66. package/dist/core/types.js +12 -0
  67. package/dist/core/types.js.map +1 -0
  68. package/dist/core/watcher.d.ts +30 -0
  69. package/dist/core/watcher.d.ts.map +1 -0
  70. package/dist/core/watcher.js +146 -0
  71. package/dist/core/watcher.js.map +1 -0
  72. package/dist/index.d.ts +3 -0
  73. package/dist/index.d.ts.map +1 -0
  74. package/dist/index.js +116 -0
  75. package/dist/index.js.map +1 -0
  76. package/dist/mcp/server.d.ts +3 -0
  77. package/dist/mcp/server.d.ts.map +1 -0
  78. package/dist/mcp/server.js +32 -0
  79. package/dist/mcp/server.js.map +1 -0
  80. package/dist/mcp/tools.d.ts +39 -0
  81. package/dist/mcp/tools.d.ts.map +1 -0
  82. package/dist/mcp/tools.js +215 -0
  83. package/dist/mcp/tools.js.map +1 -0
  84. package/hooks/README.md +78 -0
  85. package/hooks/session-end.mjs +92 -0
  86. package/hooks/session-start.mjs +112 -0
  87. package/package.json +54 -0
@@ -0,0 +1,428 @@
1
+ import { URL } from 'node:url';
2
+ import { sendJson, readBody } from './server.js';
3
+ import { MemoryService } from '../core/memory-service.js';
4
+ import { runLint } from '../core/lint.js';
5
+ import { scrubErrorMessage } from '../core/log-safe.js';
6
+ import { deriveDepth } from '../core/types.js';
7
+ const VALID_MEMORY_TYPES = new Set([
8
+ 'decision', 'discovery', 'preference', 'pattern', 'feedback',
9
+ ]);
10
+ const LOOPBACK_HOSTS = new Set(['127.0.0.1', '::1', 'localhost']);
11
+ function isLoopbackOrigin(origin) {
12
+ if (!origin)
13
+ return true;
14
+ try {
15
+ const host = new URL(origin).hostname;
16
+ return LOOPBACK_HOSTS.has(host);
17
+ }
18
+ catch {
19
+ return false;
20
+ }
21
+ }
22
+ function memorySource(m) {
23
+ if (m.sessionId && m.messageId)
24
+ return `${m.sessionId}:msg:${m.messageId}`;
25
+ if (m.sessionId)
26
+ return `${m.sessionId}:session`;
27
+ return `memory:${m.id}`;
28
+ }
29
+ function optionalString(value, field) {
30
+ if (value == null)
31
+ return { value: null };
32
+ if (typeof value === 'string')
33
+ return { value };
34
+ return { error: `${field} must be string or null` };
35
+ }
36
+ function validateSessionEndBody(raw) {
37
+ if (!raw || typeof raw !== 'object')
38
+ return { error: 'body must be JSON object' };
39
+ const b = raw;
40
+ if (typeof b.sessionId !== 'string' || b.sessionId.trim() === '') {
41
+ return { error: 'sessionId must be non-empty string' };
42
+ }
43
+ if (b.dryRun != null && typeof b.dryRun !== 'boolean') {
44
+ return { error: 'dryRun must be boolean' };
45
+ }
46
+ return { sessionId: b.sessionId, dryRun: b.dryRun === true };
47
+ }
48
+ export function inferMemoryType(outcome) {
49
+ if (outcome === 'committed')
50
+ return 'decision';
51
+ return 'discovery';
52
+ }
53
+ export function inferConfidence(outcome) {
54
+ if (outcome === 'committed')
55
+ return 0.9;
56
+ if (outcome === 'tested')
57
+ return 0.8;
58
+ return 0.7;
59
+ }
60
+ export function buildMemoryFromSession(session) {
61
+ const summary = session.summaryText?.trim();
62
+ if (!summary)
63
+ return null;
64
+ const parts = [];
65
+ const intent = session.intentText?.trim();
66
+ if (intent)
67
+ parts.push(`[intent] ${intent}`);
68
+ parts.push(summary);
69
+ return {
70
+ sessionId: session.id,
71
+ messageId: null,
72
+ content: parts.join('\n'),
73
+ type: inferMemoryType(session.outcomeStatus),
74
+ confidence: inferConfidence(session.outcomeStatus),
75
+ };
76
+ }
77
+ function validateSaveBody(raw) {
78
+ if (!raw || typeof raw !== 'object')
79
+ return { error: 'body must be JSON object' };
80
+ const b = raw;
81
+ if (typeof b.content !== 'string' || b.content.trim() === '') {
82
+ return { error: 'content must be non-empty string' };
83
+ }
84
+ if (typeof b.type !== 'string' || !VALID_MEMORY_TYPES.has(b.type)) {
85
+ return { error: `type must be one of: ${[...VALID_MEMORY_TYPES].join(', ')}` };
86
+ }
87
+ const sessionIdResult = optionalString(b.sessionId, 'sessionId');
88
+ if ('error' in sessionIdResult)
89
+ return sessionIdResult;
90
+ const messageIdResult = optionalString(b.messageId, 'messageId');
91
+ if ('error' in messageIdResult)
92
+ return messageIdResult;
93
+ const projectIdResult = optionalString(b.projectId, 'projectId');
94
+ if ('error' in projectIdResult)
95
+ return projectIdResult;
96
+ let confidence;
97
+ if (b.confidence != null) {
98
+ if (typeof b.confidence !== 'number' || b.confidence < 0 || b.confidence > 1) {
99
+ return { error: 'confidence must be number in [0, 1]' };
100
+ }
101
+ confidence = b.confidence;
102
+ }
103
+ return {
104
+ content: b.content,
105
+ type: b.type,
106
+ sessionId: sessionIdResult.value,
107
+ messageId: messageIdResult.value,
108
+ confidence,
109
+ projectId: projectIdResult.value,
110
+ };
111
+ }
112
+ function topicWithDepth(t) {
113
+ return { ...t, depth: deriveDepth(t.mentionCount) };
114
+ }
115
+ const SNAPSHOT_MAX_BYTES = 64 * 1024;
116
+ function validateCheckpointBody(raw) {
117
+ if (!raw || typeof raw !== 'object')
118
+ return { error: 'body must be JSON object' };
119
+ const b = raw;
120
+ if (typeof b.sessionId !== 'string' || b.sessionId.trim() === '') {
121
+ return { error: 'sessionId must be non-empty string' };
122
+ }
123
+ if (typeof b.snapshot !== 'string' || b.snapshot.trim() === '') {
124
+ return { error: 'snapshot must be non-empty string' };
125
+ }
126
+ if (Buffer.byteLength(b.snapshot, 'utf8') > SNAPSHOT_MAX_BYTES) {
127
+ return { error: `snapshot must be <= ${SNAPSHOT_MAX_BYTES} bytes` };
128
+ }
129
+ return { sessionId: b.sessionId, snapshot: b.snapshot };
130
+ }
131
+ const startTime = Date.now();
132
+ export function createRequestHandler(db, opts = {}) {
133
+ const memoryService = new MemoryService(db);
134
+ return async function handleRequest(req, res) {
135
+ const url = new URL(req.url ?? '/', `http://${req.headers.host}`);
136
+ const path = url.pathname;
137
+ // GET /health
138
+ if (req.method === 'GET' && path === '/health') {
139
+ const result = {
140
+ status: 'ok',
141
+ version: '0.1.0',
142
+ dbPath: '', // TODO: expose from Database
143
+ sessionCount: db.getMainSessionCount(),
144
+ memoryCount: db.getMemoryCount(),
145
+ topicCount: db.getTopicCount(),
146
+ uptime: Math.floor((Date.now() - startTime) / 1000),
147
+ };
148
+ sendJson(res, 200, result);
149
+ return;
150
+ }
151
+ // GET /memory/query?q=...&limit=...&project=...
152
+ if (req.method === 'GET' && path === '/memory/query') {
153
+ // Phase 4c touch made this a stateful endpoint (access_count / last_accessed).
154
+ // Apply the same origin gate as POST so browser prefetches or CSRF from a
155
+ // non-loopback origin cannot poison recall ranking.
156
+ if (!isLoopbackOrigin(req.headers.origin)) {
157
+ sendJson(res, 403, { error: 'cross-origin requests forbidden' });
158
+ return;
159
+ }
160
+ const q = url.searchParams.get('q') ?? '';
161
+ const rawLimit = parseInt(url.searchParams.get('limit') ?? '5', 10);
162
+ const limit = Number.isNaN(rawLimit) || rawLimit < 1 ? 5 : rawLimit;
163
+ const project = url.searchParams.get('project');
164
+ if (!q) {
165
+ sendJson(res, 200, { memories: [], totalTokenEstimate: 0, query: q, limit });
166
+ return;
167
+ }
168
+ const rows = db.queryMemories(q, limit, project);
169
+ // Phase 4c: touch surfaced memories so their access_count and last_accessed
170
+ // feed into the decay formula at next query time. MemoryService.touch
171
+ // noops on empty input, no need to guard here.
172
+ memoryService.touch(rows.map(m => m.id));
173
+ const memories = rows.map(m => ({
174
+ content: m.content,
175
+ source: memorySource(m),
176
+ confidence: m.confidence,
177
+ depth: null,
178
+ }));
179
+ const totalTokenEstimate = Math.ceil(memories.reduce((sum, m) => sum + m.content.length, 0) / 4);
180
+ sendJson(res, 200, { memories, totalTokenEstimate, query: q, limit });
181
+ return;
182
+ }
183
+ // GET /memory/context?session_id=...
184
+ if (req.method === 'GET' && path === '/memory/context') {
185
+ const sessionId = url.searchParams.get('session_id') ?? '';
186
+ // TODO: integrate with session context lookup
187
+ sendJson(res, 200, { summary: null, decisions: [], filesTouched: [], sessionId });
188
+ return;
189
+ }
190
+ // POST /memory/save
191
+ if (req.method === 'POST' && path === '/memory/save') {
192
+ if (!isLoopbackOrigin(req.headers.origin)) {
193
+ sendJson(res, 403, { error: 'cross-origin requests forbidden' });
194
+ return;
195
+ }
196
+ let bodyText;
197
+ try {
198
+ bodyText = await readBody(req);
199
+ }
200
+ catch (err) {
201
+ const msg = err.message;
202
+ if (msg === 'body too large') {
203
+ sendJson(res, 413, { error: msg });
204
+ return;
205
+ }
206
+ throw err;
207
+ }
208
+ let parsed;
209
+ try {
210
+ parsed = bodyText ? JSON.parse(bodyText) : {};
211
+ }
212
+ catch {
213
+ sendJson(res, 400, { error: 'invalid JSON body' });
214
+ return;
215
+ }
216
+ const v = validateSaveBody(parsed);
217
+ if ('error' in v) {
218
+ sendJson(res, 400, v);
219
+ return;
220
+ }
221
+ const id = db.saveMemory(v);
222
+ sendJson(res, 200, { ok: true, id });
223
+ return;
224
+ }
225
+ // POST /session/end
226
+ if (req.method === 'POST' && path === '/session/end') {
227
+ if (!isLoopbackOrigin(req.headers.origin)) {
228
+ sendJson(res, 403, { error: 'cross-origin requests forbidden' });
229
+ return;
230
+ }
231
+ let bodyText;
232
+ try {
233
+ bodyText = await readBody(req);
234
+ }
235
+ catch (err) {
236
+ const msg = err.message;
237
+ if (msg === 'body too large') {
238
+ sendJson(res, 413, { error: msg });
239
+ return;
240
+ }
241
+ throw err;
242
+ }
243
+ let parsed;
244
+ try {
245
+ parsed = bodyText ? JSON.parse(bodyText) : {};
246
+ }
247
+ catch {
248
+ sendJson(res, 400, { error: 'invalid JSON body' });
249
+ return;
250
+ }
251
+ const v = validateSessionEndBody(parsed);
252
+ if ('error' in v) {
253
+ sendJson(res, 400, v);
254
+ return;
255
+ }
256
+ let session = db.getSessionById(v.sessionId);
257
+ if (!session && opts.rescueReindex) {
258
+ // Fresh-session race: hook fires before the daemon has indexed the
259
+ // JSONL. Run one reindex and retry — watcher will catch subsequent
260
+ // changes but this first harvest can't wait for the next debounce.
261
+ try {
262
+ await opts.rescueReindex();
263
+ }
264
+ catch (err) {
265
+ console.warn('[session-end] rescue reindex failed:', scrubErrorMessage(err));
266
+ }
267
+ session = db.getSessionById(v.sessionId);
268
+ }
269
+ if (!session) {
270
+ sendJson(res, 404, { error: 'session not found' });
271
+ return;
272
+ }
273
+ const candidate = buildMemoryFromSession(session);
274
+ if (!candidate) {
275
+ sendJson(res, 200, {
276
+ ok: true,
277
+ sessionId: v.sessionId,
278
+ memoriesSaved: [],
279
+ dryRun: v.dryRun,
280
+ reason: 'session has no summary',
281
+ });
282
+ return;
283
+ }
284
+ const existing = db.getMemoriesBySessionId(v.sessionId);
285
+ if (existing.length > 0) {
286
+ sendJson(res, 200, {
287
+ ok: true,
288
+ sessionId: v.sessionId,
289
+ memoriesSaved: existing.map(m => m.id),
290
+ dryRun: v.dryRun,
291
+ alreadyHarvested: true,
292
+ candidate: v.dryRun ? candidate : undefined,
293
+ });
294
+ return;
295
+ }
296
+ const savedIds = [];
297
+ if (!v.dryRun) {
298
+ // Atomic:若 saveMemoryTopics 或 rebuildKnowledgeMap 失敗,整個 harvest rollback,
299
+ // 避免 retry 時 existing.length > 0 回 alreadyHarvested 但 topic 關聯缺失的 split-brain
300
+ db.runTransaction(() => {
301
+ const memoryId = db.saveMemory(candidate);
302
+ savedIds.push(memoryId);
303
+ const sessionTopics = db.getSessionTopicKeys(session.id);
304
+ if (sessionTopics.length > 0) {
305
+ db.saveMemoryTopics(memoryId, session.projectId, sessionTopics);
306
+ }
307
+ db.rebuildKnowledgeMap(session.projectId);
308
+ });
309
+ }
310
+ sendJson(res, 200, {
311
+ ok: true,
312
+ sessionId: v.sessionId,
313
+ memoriesSaved: savedIds,
314
+ dryRun: v.dryRun,
315
+ candidate: v.dryRun ? candidate : undefined,
316
+ });
317
+ return;
318
+ }
319
+ // GET /metacognition/check?projectId=X[&topic=Y][&limit=N]
320
+ if (req.method === 'GET' && path === '/metacognition/check') {
321
+ // detail mode returns memory content; loopback gate matches POST mutation endpoints
322
+ if (!isLoopbackOrigin(req.headers.origin)) {
323
+ sendJson(res, 403, { error: 'cross-origin requests forbidden' });
324
+ return;
325
+ }
326
+ const projectId = url.searchParams.get('projectId');
327
+ if (!projectId) {
328
+ sendJson(res, 400, { error: 'projectId query param required' });
329
+ return;
330
+ }
331
+ const topicParam = url.searchParams.get('topic');
332
+ const rawLimit = parseInt(url.searchParams.get('limit') ?? '10', 10);
333
+ const limit = Number.isNaN(rawLimit) || rawLimit < 1 ? 10 : Math.min(rawLimit, 50);
334
+ if (topicParam) {
335
+ // Detail mode
336
+ const topic = db.getTopic(topicParam, projectId);
337
+ if (!topic) {
338
+ sendJson(res, 404, { error: 'topic not found' });
339
+ return;
340
+ }
341
+ const related = db.getRelatedTopics(topicParam, projectId, 10);
342
+ const memories = db.getMemoriesByTopics(projectId, [topicParam], limit);
343
+ const detail = {
344
+ topicKey: topic.topicKey,
345
+ projectId: topic.projectId,
346
+ mentionCount: topic.mentionCount,
347
+ lastTouched: topic.lastTouched,
348
+ depth: deriveDepth(topic.mentionCount),
349
+ memories,
350
+ relatedTopics: related,
351
+ };
352
+ sendJson(res, 200, detail);
353
+ return;
354
+ }
355
+ // Summary mode
356
+ const top = db.getKnowledgeMap(projectId, { limit, sortBy: 'mention' }).map(topicWithDepth);
357
+ const recent = db.getKnowledgeMap(projectId, { limit, sortBy: 'recent' }).map(topicWithDepth);
358
+ const stale = db.getKnowledgeMap(projectId, { limit, sortBy: 'stale' }).map(topicWithDepth);
359
+ const counts = db.getKnowledgeMapCounts(projectId);
360
+ const summary = {
361
+ projectId,
362
+ topTopics: top,
363
+ recentTopics: recent,
364
+ staleTopics: stale,
365
+ counts,
366
+ };
367
+ sendJson(res, 200, summary);
368
+ return;
369
+ }
370
+ // POST /session/checkpoint
371
+ if (req.method === 'POST' && path === '/session/checkpoint') {
372
+ if (!isLoopbackOrigin(req.headers.origin)) {
373
+ sendJson(res, 403, { error: 'cross-origin requests forbidden' });
374
+ return;
375
+ }
376
+ let bodyText;
377
+ try {
378
+ bodyText = await readBody(req);
379
+ }
380
+ catch (err) {
381
+ const msg = err.message;
382
+ if (msg === 'body too large') {
383
+ sendJson(res, 413, { error: msg });
384
+ return;
385
+ }
386
+ throw err;
387
+ }
388
+ let parsed;
389
+ try {
390
+ parsed = bodyText ? JSON.parse(bodyText) : {};
391
+ }
392
+ catch {
393
+ sendJson(res, 400, { error: 'invalid JSON body' });
394
+ return;
395
+ }
396
+ const v = validateCheckpointBody(parsed);
397
+ if ('error' in v) {
398
+ sendJson(res, 400, v);
399
+ return;
400
+ }
401
+ const session = db.getSessionById(v.sessionId);
402
+ if (!session) {
403
+ sendJson(res, 404, { error: 'session not found' });
404
+ return;
405
+ }
406
+ const checkpointId = db.saveCheckpoint(session.id, session.projectId, v.snapshot);
407
+ const result = { ok: true, checkpointId };
408
+ sendJson(res, 200, result);
409
+ return;
410
+ }
411
+ // GET /lint/warnings — orphan / stale memory detection (Phase 4d)
412
+ if (req.method === 'GET' && path === '/lint/warnings') {
413
+ // Reveals memory metadata (ids, session refs, decay numbers) — same
414
+ // loopback gate as other introspection endpoints so a non-loopback
415
+ // origin cannot enumerate recall internals via a browser prefetch.
416
+ if (!isLoopbackOrigin(req.headers.origin)) {
417
+ sendJson(res, 403, { error: 'cross-origin requests forbidden' });
418
+ return;
419
+ }
420
+ const report = runLint(db);
421
+ sendJson(res, 200, report);
422
+ return;
423
+ }
424
+ // 404
425
+ sendJson(res, 404, { error: 'Not found' });
426
+ };
427
+ }
428
+ //# sourceMappingURL=routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/api/routes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import http from 'node:http';
2
+ import type { Database } from '../core/database.js';
3
+ import { type RequestHandlerOptions } from './routes.js';
4
+ export declare function createServer(db: Database, opts?: RequestHandlerOptions): http.Server;
5
+ export declare function sendJson(res: http.ServerResponse, status: number, data: unknown): void;
6
+ export declare function readBody(req: http.IncomingMessage): Promise<string>;
7
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/api/server.ts"],"names":[],"mappings":"AACA,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAwB,KAAK,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAE9E,wBAAgB,YAAY,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,GAAE,qBAA0B,GAAG,IAAI,CAAC,MAAM,CAWxF;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAGtF;AAID,wBAAgB,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAoBnE"}
@@ -0,0 +1,44 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import http from 'node:http';
3
+ import { createRequestHandler } from './routes.js';
4
+ export function createServer(db, opts = {}) {
5
+ const handleRequest = createRequestHandler(db, opts);
6
+ return http.createServer(async (req, res) => {
7
+ try {
8
+ await handleRequest(req, res);
9
+ }
10
+ catch (err) {
11
+ console.error('Unhandled error:', err);
12
+ sendJson(res, 500, { error: 'Internal server error' });
13
+ }
14
+ });
15
+ }
16
+ export function sendJson(res, status, data) {
17
+ res.writeHead(status, { 'Content-Type': 'application/json' });
18
+ res.end(JSON.stringify(data));
19
+ }
20
+ const MAX_BODY_BYTES = 1 * 1024 * 1024; // 1 MB
21
+ export function readBody(req) {
22
+ return new Promise((resolve, reject) => {
23
+ const chunks = [];
24
+ let size = 0;
25
+ let exceeded = false;
26
+ req.on('data', (chunk) => {
27
+ if (exceeded)
28
+ return;
29
+ size += chunk.length;
30
+ if (size > MAX_BODY_BYTES) {
31
+ exceeded = true;
32
+ reject(new Error('body too large'));
33
+ return;
34
+ }
35
+ chunks.push(chunk);
36
+ });
37
+ req.on('end', () => {
38
+ if (!exceeded)
39
+ resolve(Buffer.concat(chunks).toString());
40
+ });
41
+ req.on('error', reject);
42
+ });
43
+ }
44
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/api/server.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,OAAO,EAAE,oBAAoB,EAA8B,MAAM,aAAa,CAAA;AAE9E,MAAM,UAAU,YAAY,CAAC,EAAY,EAAE,OAA8B,EAAE;IACzE,MAAM,aAAa,GAAG,oBAAoB,CAAC,EAAE,EAAE,IAAI,CAAC,CAAA;IAEpD,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QAC1C,IAAI,CAAC;YACH,MAAM,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;QAC/B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAA;YACtC,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC,CAAA;QACxD,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,GAAwB,EAAE,MAAc,EAAE,IAAa;IAC9E,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAA;IAC7D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAA;AAC/B,CAAC;AAED,MAAM,cAAc,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAA,CAAC,OAAO;AAE9C,MAAM,UAAU,QAAQ,CAAC,GAAyB;IAChD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,MAAM,GAAa,EAAE,CAAA;QAC3B,IAAI,IAAI,GAAG,CAAC,CAAA;QACZ,IAAI,QAAQ,GAAG,KAAK,CAAA;QACpB,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YAC/B,IAAI,QAAQ;gBAAE,OAAM;YACpB,IAAI,IAAI,KAAK,CAAC,MAAM,CAAA;YACpB,IAAI,IAAI,GAAG,cAAc,EAAE,CAAC;gBAC1B,QAAQ,GAAG,IAAI,CAAA;gBACf,MAAM,CAAC,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAA;gBACnC,OAAM;YACR,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACpB,CAAC,CAAC,CAAA;QACF,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;YACjB,IAAI,CAAC,QAAQ;gBAAE,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAA;QAC1D,CAAC,CAAC,CAAA;QACF,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;IACzB,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,35 @@
1
+ export interface DaemonPaths {
2
+ launchAgentsDir: string;
3
+ logsDir: string;
4
+ plistPath: string;
5
+ nodeBin: string;
6
+ ccrecallJs: string;
7
+ }
8
+ export interface DaemonPathOverrides {
9
+ home?: string;
10
+ scriptPath?: string;
11
+ nodeBin?: string;
12
+ }
13
+ /** Resolve absolute paths for plist generation. `scriptPath` defaults to the
14
+ * directory-relative dist/index.js so `node dist/index.js install-daemon`
15
+ * plants a plist that re-executes the same binary. */
16
+ export declare function resolveDaemonPaths(overrides?: DaemonPathOverrides): DaemonPaths;
17
+ export interface PlistOptions {
18
+ port?: number;
19
+ dbPath?: string;
20
+ }
21
+ export declare function generatePlist(paths: DaemonPaths, opts?: PlistOptions): string;
22
+ export interface InstallOptions extends PlistOptions {
23
+ dryRun?: boolean;
24
+ /** Skip the launchctl load/unload calls — used by tests so the install flow
25
+ * can be exercised without touching the user's real LaunchAgents state. */
26
+ skipLaunchctl?: boolean;
27
+ overrides?: DaemonPathOverrides;
28
+ }
29
+ export declare function installDaemon(opts?: InstallOptions): Promise<void>;
30
+ export interface UninstallOptions {
31
+ skipLaunchctl?: boolean;
32
+ overrides?: DaemonPathOverrides;
33
+ }
34
+ export declare function uninstallDaemon(opts?: UninstallOptions): Promise<void>;
35
+ //# sourceMappingURL=daemon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../src/cli/daemon.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,WAAW;IAC1B,eAAe,EAAE,MAAM,CAAA;IACvB,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;uDAEuD;AACvD,wBAAgB,kBAAkB,CAAC,SAAS,GAAE,mBAAwB,GAAG,WAAW,CAQnF;AAqBD,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,GAAE,YAAiB,GAAG,MAAM,CAuCjF;AAED,MAAM,WAAW,cAAe,SAAQ,YAAY;IAClD,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB;gFAC4E;IAC5E,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,SAAS,CAAC,EAAE,mBAAmB,CAAA;CAChC;AAsBD,wBAAsB,aAAa,CAAC,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsC5E;AAED,MAAM,WAAW,gBAAgB;IAC/B,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,SAAS,CAAC,EAAE,mBAAmB,CAAA;CAChC;AAED,wBAAsB,eAAe,CAAC,IAAI,GAAE,gBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAWhF"}