hippo-memory 0.34.0 → 0.36.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 (64) hide show
  1. package/README.md +17 -0
  2. package/dist/api.d.ts +163 -0
  3. package/dist/api.d.ts.map +1 -0
  4. package/dist/api.js +323 -0
  5. package/dist/api.js.map +1 -0
  6. package/dist/audit.d.ts +26 -0
  7. package/dist/audit.d.ts.map +1 -1
  8. package/dist/audit.js +45 -0
  9. package/dist/audit.js.map +1 -1
  10. package/dist/auth.d.ts +28 -0
  11. package/dist/auth.d.ts.map +1 -0
  12. package/dist/auth.js +65 -0
  13. package/dist/auth.js.map +1 -0
  14. package/dist/cli.js +457 -19
  15. package/dist/cli.js.map +1 -1
  16. package/dist/client.d.ts +54 -0
  17. package/dist/client.d.ts.map +1 -0
  18. package/dist/client.js +181 -0
  19. package/dist/client.js.map +1 -0
  20. package/dist/dashboard.d.ts.map +1 -1
  21. package/dist/dashboard.js +5 -1
  22. package/dist/dashboard.js.map +1 -1
  23. package/dist/db.d.ts.map +1 -1
  24. package/dist/db.js +60 -1
  25. package/dist/db.js.map +1 -1
  26. package/dist/mcp/server.d.ts +46 -1
  27. package/dist/mcp/server.d.ts.map +1 -1
  28. package/dist/mcp/server.js +81 -29
  29. package/dist/mcp/server.js.map +1 -1
  30. package/dist/memory.d.ts +2 -0
  31. package/dist/memory.d.ts.map +1 -1
  32. package/dist/memory.js +1 -0
  33. package/dist/memory.js.map +1 -1
  34. package/dist/raw-archive.d.ts.map +1 -1
  35. package/dist/raw-archive.js +19 -0
  36. package/dist/raw-archive.js.map +1 -1
  37. package/dist/server-detect.d.ts +26 -0
  38. package/dist/server-detect.d.ts.map +1 -0
  39. package/dist/server-detect.js +70 -0
  40. package/dist/server-detect.js.map +1 -0
  41. package/dist/server.d.ts +29 -0
  42. package/dist/server.d.ts.map +1 -0
  43. package/dist/server.js +612 -0
  44. package/dist/server.js.map +1 -0
  45. package/dist/shared.d.ts +5 -1
  46. package/dist/shared.d.ts.map +1 -1
  47. package/dist/shared.js +8 -8
  48. package/dist/shared.js.map +1 -1
  49. package/dist/sso.d.ts +13 -0
  50. package/dist/sso.d.ts.map +1 -0
  51. package/dist/sso.js +22 -0
  52. package/dist/sso.js.map +1 -0
  53. package/dist/store.d.ts +29 -5
  54. package/dist/store.d.ts.map +1 -1
  55. package/dist/store.js +98 -22
  56. package/dist/store.js.map +1 -1
  57. package/dist/tenant.d.ts +7 -0
  58. package/dist/tenant.d.ts.map +1 -0
  59. package/dist/tenant.js +17 -0
  60. package/dist/tenant.js.map +1 -0
  61. package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
  62. package/extensions/openclaw-plugin/package.json +1 -1
  63. package/openclaw.plugin.json +1 -1
  64. package/package.json +1 -1
package/dist/server.js ADDED
@@ -0,0 +1,612 @@
1
+ import { createServer } from 'node:http';
2
+ import { writePidfile, removePidfile } from './server-detect.js';
3
+ import { resolveTenantId } from './tenant.js';
4
+ import { openHippoDb, closeHippoDb } from './db.js';
5
+ import { validateApiKey } from './auth.js';
6
+ import { remember, recall, forget, promote, supersede, archiveRaw, authCreate, authList, authRevoke, auditList, } from './api.js';
7
+ import { handleMcpRequest } from './mcp/server.js';
8
+ const VALID_AUDIT_OPS = new Set([
9
+ 'remember',
10
+ 'recall',
11
+ 'promote',
12
+ 'supersede',
13
+ 'forget',
14
+ 'archive_raw',
15
+ 'auth_revoke',
16
+ ]);
17
+ // Cap on GET /v1/audit?limit=. Matches docs/api.md (when written) and is large
18
+ // enough to dump a small deployment's full audit log without paginating, but
19
+ // small enough that a malicious client can't ask for the world.
20
+ const MAX_AUDIT_LIMIT = 10000;
21
+ const VALID_KINDS = new Set([
22
+ 'raw',
23
+ 'distilled',
24
+ 'superseded',
25
+ 'archived',
26
+ ]);
27
+ // Pinned at module load. Bumped alongside package.json on releases. The
28
+ // HTTP /health response uses this; reading package.json synchronously here
29
+ // would couple the daemon to its on-disk install path, which we want to
30
+ // avoid for tests that mkdtemp a hippoRoot.
31
+ const VERSION = '0.36.0';
32
+ // 1 MB body cap. The CLI never sends payloads near this; anything bigger is
33
+ // almost certainly a misconfigured client or a deliberate memory-blowup attempt.
34
+ const MAX_BODY_BYTES = 1024 * 1024;
35
+ const LOOPBACK_HOSTS = new Set(['127.0.0.1', '::1', 'localhost']);
36
+ const JSON_HEADERS = { 'content-type': 'application/json' };
37
+ class HttpError extends Error {
38
+ status;
39
+ constructor(status, message) {
40
+ super(message);
41
+ this.status = status;
42
+ }
43
+ }
44
+ class BodyTooLargeError extends Error {
45
+ }
46
+ function sendJson(res, status, body) {
47
+ res.writeHead(status, JSON_HEADERS);
48
+ res.end(JSON.stringify(body));
49
+ }
50
+ function sendError(res, status, message) {
51
+ sendJson(res, status, { error: message });
52
+ }
53
+ /**
54
+ * Read the entire request body into a Buffer. Caps at MAX_BODY_BYTES to keep
55
+ * a malicious or buggy client from exhausting memory. The cap is enforced
56
+ * mid-stream so we don't wait for an attacker to finish before erroring out.
57
+ */
58
+ async function readBody(req) {
59
+ const chunks = [];
60
+ let total = 0;
61
+ for await (const chunk of req) {
62
+ const buf = chunk;
63
+ total += buf.length;
64
+ if (total > MAX_BODY_BYTES) {
65
+ throw new BodyTooLargeError('request body exceeds 1MB');
66
+ }
67
+ chunks.push(buf);
68
+ }
69
+ return Buffer.concat(chunks).toString('utf8');
70
+ }
71
+ async function parseJsonBody(req) {
72
+ const raw = await readBody(req);
73
+ if (raw.length === 0)
74
+ return {};
75
+ try {
76
+ const parsed = JSON.parse(raw);
77
+ if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
78
+ throw new HttpError(400, 'request body must be a JSON object');
79
+ }
80
+ return parsed;
81
+ }
82
+ catch (e) {
83
+ if (e instanceof HttpError)
84
+ throw e;
85
+ throw new HttpError(400, 'invalid JSON body');
86
+ }
87
+ }
88
+ /**
89
+ * Map an error thrown by an api.* function into an HTTP status + message.
90
+ * api.* uses plain Error, so we discriminate by message pattern. Stable
91
+ * patterns we rely on:
92
+ * - /not found/i → 404 (forget on unknown id, supersede on unknown old id, etc.)
93
+ * - /unknown/i → 404 (auth_revoke on unknown key_id)
94
+ * - /already superseded/i → 409 (chain conflict)
95
+ * - /not raw/i → 400 (archive_raw on non-raw row)
96
+ * Everything else maps to 400 (bad input).
97
+ */
98
+ function mapApiError(err) {
99
+ const message = err instanceof Error ? err.message : String(err);
100
+ const lower = message.toLowerCase();
101
+ if (/not found/.test(lower) || /^unknown /.test(lower)) {
102
+ return { status: 404, message };
103
+ }
104
+ if (/already superseded/.test(lower)) {
105
+ return { status: 409, message };
106
+ }
107
+ return { status: 400, message };
108
+ }
109
+ function parseRequest(req) {
110
+ const url = new URL(req.url ?? '/', 'http://placeholder');
111
+ return {
112
+ method: req.method ?? 'GET',
113
+ path: url.pathname,
114
+ query: url.searchParams,
115
+ };
116
+ }
117
+ /**
118
+ * Lightweight pattern matcher for /v1/memories/:id/<action>. Avoids pulling
119
+ * in a router dependency for the half-dozen patterns we actually use.
120
+ *
121
+ * Returns null if `path` does not match `pattern`. Otherwise returns an object
122
+ * mapping each :param name to its value. Path segments are exact-matched
123
+ * except for parameter slots.
124
+ */
125
+ function matchPath(pattern, path) {
126
+ const patternParts = pattern.split('/');
127
+ const pathParts = path.split('/');
128
+ if (patternParts.length !== pathParts.length)
129
+ return null;
130
+ const params = {};
131
+ for (let i = 0; i < patternParts.length; i++) {
132
+ const pp = patternParts[i];
133
+ const ap = pathParts[i];
134
+ if (pp.startsWith(':')) {
135
+ if (ap.length === 0)
136
+ return null;
137
+ params[pp.slice(1)] = decodeURIComponent(ap);
138
+ }
139
+ else if (pp !== ap) {
140
+ return null;
141
+ }
142
+ }
143
+ return params;
144
+ }
145
+ /**
146
+ * Recognise loopback remote addresses. Node reports IPv6-mapped IPv4 as
147
+ * '::ffff:127.0.0.1' on dual-stack sockets, so we accept that alongside
148
+ * the bare v4 and v6 loopbacks. Anything else is treated as remote.
149
+ */
150
+ export function isLoopback(remoteAddress) {
151
+ if (!remoteAddress)
152
+ return false;
153
+ if (remoteAddress === '127.0.0.1')
154
+ return true;
155
+ if (remoteAddress === '::1')
156
+ return true;
157
+ if (remoteAddress === '::ffff:127.0.0.1')
158
+ return true;
159
+ return false;
160
+ }
161
+ function readAuthHeader(req) {
162
+ const raw = req.headers['authorization'];
163
+ if (raw === undefined)
164
+ return { kind: 'absent' };
165
+ const value = Array.isArray(raw) ? raw[0] : raw;
166
+ if (typeof value !== 'string' || value.length === 0)
167
+ return { kind: 'malformed' };
168
+ const space = value.indexOf(' ');
169
+ if (space < 0)
170
+ return { kind: 'malformed' };
171
+ const scheme = value.slice(0, space);
172
+ const token = value.slice(space + 1).trim();
173
+ if (scheme.toLowerCase() !== 'bearer')
174
+ return { kind: 'malformed' };
175
+ if (token.length === 0)
176
+ return { kind: 'malformed' };
177
+ return { kind: 'bearer', token };
178
+ }
179
+ /**
180
+ * Build a per-request Context from the Authorization header and remote
181
+ * address. Throws HttpError(401) for invalid / missing credentials. Opens
182
+ * the DB only when a Bearer token is present so loopback no-auth requests
183
+ * stay cheap.
184
+ */
185
+ function buildContextWithAuth(req, hippoRoot) {
186
+ const auth = readAuthHeader(req);
187
+ if (auth.kind === 'malformed') {
188
+ throw new HttpError(401, 'invalid api key');
189
+ }
190
+ if (auth.kind === 'bearer') {
191
+ const db = openHippoDb(hippoRoot);
192
+ try {
193
+ const result = validateApiKey(db, auth.token);
194
+ if (!result.valid || !result.tenantId || !result.keyId) {
195
+ throw new HttpError(401, 'invalid api key');
196
+ }
197
+ return {
198
+ hippoRoot,
199
+ tenantId: result.tenantId,
200
+ actor: `api_key:${result.keyId}`,
201
+ };
202
+ }
203
+ finally {
204
+ closeHippoDb(db);
205
+ }
206
+ }
207
+ // No Authorization header. Loopback-only fallback.
208
+ if (!isLoopback(req.socket.remoteAddress)) {
209
+ throw new HttpError(401, 'auth required');
210
+ }
211
+ return {
212
+ hippoRoot,
213
+ tenantId: resolveTenantId({}),
214
+ actor: 'localhost:cli',
215
+ };
216
+ }
217
+ /**
218
+ * Auth check for routes that do not need a tenant Context (e.g. MCP transport,
219
+ * which builds its own root resolution via findHippoRoot). Throws HttpError
220
+ * 401 the same way buildContextWithAuth does, but skips building the Context
221
+ * envelope. Loopback no-auth still passes.
222
+ */
223
+ function requireAuth(req, hippoRoot) {
224
+ const auth = readAuthHeader(req);
225
+ if (auth.kind === 'malformed') {
226
+ throw new HttpError(401, 'invalid api key');
227
+ }
228
+ if (auth.kind === 'bearer') {
229
+ const db = openHippoDb(hippoRoot);
230
+ try {
231
+ const result = validateApiKey(db, auth.token);
232
+ if (!result.valid) {
233
+ throw new HttpError(401, 'invalid api key');
234
+ }
235
+ }
236
+ finally {
237
+ closeHippoDb(db);
238
+ }
239
+ return;
240
+ }
241
+ if (!isLoopback(req.socket.remoteAddress)) {
242
+ throw new HttpError(401, 'auth required');
243
+ }
244
+ }
245
+ function getString(obj, key) {
246
+ const v = obj[key];
247
+ return typeof v === 'string' ? v : undefined;
248
+ }
249
+ function getStringArray(obj, key) {
250
+ const v = obj[key];
251
+ if (!Array.isArray(v))
252
+ return undefined;
253
+ if (!v.every((x) => typeof x === 'string'))
254
+ return undefined;
255
+ return v;
256
+ }
257
+ async function handleRequest(req, res, opts, startedAt) {
258
+ const { method, path, query } = parseRequest(req);
259
+ if (method === 'GET' && path === '/health') {
260
+ sendJson(res, 200, {
261
+ ok: true,
262
+ version: VERSION,
263
+ started_at: startedAt,
264
+ pid: process.pid,
265
+ });
266
+ return;
267
+ }
268
+ // POST /v1/memories
269
+ if (method === 'POST' && path === '/v1/memories') {
270
+ const body = await parseJsonBody(req);
271
+ const content = getString(body, 'content');
272
+ if (!content) {
273
+ throw new HttpError(400, 'content is required');
274
+ }
275
+ const kindRaw = getString(body, 'kind');
276
+ if (kindRaw !== undefined && !VALID_KINDS.has(kindRaw)) {
277
+ throw new HttpError(400, `invalid kind: ${kindRaw}`);
278
+ }
279
+ const ctx = buildContextWithAuth(req, opts.hippoRoot);
280
+ const result = remember(ctx, {
281
+ content,
282
+ kind: kindRaw,
283
+ scope: getString(body, 'scope'),
284
+ owner: getString(body, 'owner'),
285
+ artifactRef: getString(body, 'artifactRef'),
286
+ tags: getStringArray(body, 'tags'),
287
+ });
288
+ sendJson(res, 200, result);
289
+ return;
290
+ }
291
+ // GET /v1/memories?q=...&limit=...&mode=...
292
+ if (method === 'GET' && path === '/v1/memories') {
293
+ const q = query.get('q');
294
+ if (!q) {
295
+ throw new HttpError(400, 'q is required');
296
+ }
297
+ const limitRaw = query.get('limit');
298
+ const limit = limitRaw === null ? undefined : Number(limitRaw);
299
+ if (limit !== undefined && (!Number.isFinite(limit) || limit <= 0)) {
300
+ throw new HttpError(400, 'limit must be a positive number');
301
+ }
302
+ const mode = query.get('mode');
303
+ if (mode !== null && mode !== 'bm25' && mode !== 'hybrid' && mode !== 'physics') {
304
+ throw new HttpError(400, "mode must be 'bm25', 'hybrid', or 'physics'");
305
+ }
306
+ const ctx = buildContextWithAuth(req, opts.hippoRoot);
307
+ const result = recall(ctx, {
308
+ query: q,
309
+ limit,
310
+ mode: (mode ?? undefined),
311
+ });
312
+ sendJson(res, 200, result);
313
+ return;
314
+ }
315
+ // /v1/memories/:id/* and DELETE /v1/memories/:id
316
+ const archiveMatch = matchPath('/v1/memories/:id/archive', path);
317
+ if (method === 'POST' && archiveMatch) {
318
+ const body = await parseJsonBody(req);
319
+ const reason = getString(body, 'reason');
320
+ if (!reason) {
321
+ throw new HttpError(400, 'reason is required');
322
+ }
323
+ const ctx = buildContextWithAuth(req, opts.hippoRoot);
324
+ const result = archiveRaw(ctx, archiveMatch.id, reason);
325
+ sendJson(res, 200, result);
326
+ return;
327
+ }
328
+ const supersedeMatch = matchPath('/v1/memories/:id/supersede', path);
329
+ if (method === 'POST' && supersedeMatch) {
330
+ const body = await parseJsonBody(req);
331
+ const content = getString(body, 'content');
332
+ if (!content) {
333
+ throw new HttpError(400, 'content is required');
334
+ }
335
+ const ctx = buildContextWithAuth(req, opts.hippoRoot);
336
+ const result = supersede(ctx, supersedeMatch.id, content);
337
+ sendJson(res, 200, result);
338
+ return;
339
+ }
340
+ const promoteMatch = matchPath('/v1/memories/:id/promote', path);
341
+ if (method === 'POST' && promoteMatch) {
342
+ const ctx = buildContextWithAuth(req, opts.hippoRoot);
343
+ const result = promote(ctx, promoteMatch.id);
344
+ sendJson(res, 200, result);
345
+ return;
346
+ }
347
+ const idMatch = matchPath('/v1/memories/:id', path);
348
+ if (method === 'DELETE' && idMatch) {
349
+ const ctx = buildContextWithAuth(req, opts.hippoRoot);
350
+ const result = forget(ctx, idMatch.id);
351
+ sendJson(res, 200, result);
352
+ return;
353
+ }
354
+ // POST /v1/auth/keys — mint a new API key. Plaintext lands in the response
355
+ // body (Task 8): the HTTP layer hands it to the client; the user-facing
356
+ // "store this somewhere safe" warning belongs in the CLI client, not here.
357
+ if (method === 'POST' && path === '/v1/auth/keys') {
358
+ const body = await parseJsonBody(req);
359
+ const labelRaw = body['label'];
360
+ if (labelRaw !== undefined && typeof labelRaw !== 'string') {
361
+ throw new HttpError(400, 'label must be a string');
362
+ }
363
+ const tenantIdRaw = body['tenantId'];
364
+ if (tenantIdRaw !== undefined && typeof tenantIdRaw !== 'string') {
365
+ throw new HttpError(400, 'tenantId must be a string');
366
+ }
367
+ const ctx = buildContextWithAuth(req, opts.hippoRoot);
368
+ const result = authCreate(ctx, {
369
+ label: labelRaw,
370
+ tenantId: tenantIdRaw,
371
+ });
372
+ sendJson(res, 200, result);
373
+ return;
374
+ }
375
+ // GET /v1/auth/keys?active=true — list keys visible to ctx.tenantId.
376
+ // `active` defaults to true so the common case (show me usable keys) is
377
+ // a single GET; ?active=false includes revoked rows.
378
+ if (method === 'GET' && path === '/v1/auth/keys') {
379
+ const activeRaw = query.get('active');
380
+ let active = true;
381
+ if (activeRaw !== null) {
382
+ if (activeRaw === 'true')
383
+ active = true;
384
+ else if (activeRaw === 'false')
385
+ active = false;
386
+ else
387
+ throw new HttpError(400, "active must be 'true' or 'false'");
388
+ }
389
+ const ctx = buildContextWithAuth(req, opts.hippoRoot);
390
+ const result = authList(ctx, { active });
391
+ sendJson(res, 200, result);
392
+ return;
393
+ }
394
+ // DELETE /v1/auth/keys/:keyId — revoke. authRevoke throws "Unknown key_id"
395
+ // for missing OR cross-tenant keys (no info leak), which mapApiError
396
+ // converts to 404. We return 200 with the result body rather than 204 to
397
+ // surface revokedAt to the caller.
398
+ const keyMatch = matchPath('/v1/auth/keys/:keyId', path);
399
+ if (method === 'DELETE' && keyMatch) {
400
+ const ctx = buildContextWithAuth(req, opts.hippoRoot);
401
+ const result = authRevoke(ctx, keyMatch.keyId);
402
+ sendJson(res, 200, result);
403
+ return;
404
+ }
405
+ // GET /v1/audit?op=&since=&limit= — read audit events. All three filters
406
+ // validated at the route boundary so an invalid value lands a 400 before
407
+ // we hit the DB.
408
+ if (method === 'GET' && path === '/v1/audit') {
409
+ const opRaw = query.get('op');
410
+ let op;
411
+ if (opRaw !== null) {
412
+ if (!VALID_AUDIT_OPS.has(opRaw)) {
413
+ throw new HttpError(400, `invalid op: ${opRaw}`);
414
+ }
415
+ op = opRaw;
416
+ }
417
+ const sinceRaw = query.get('since');
418
+ let since;
419
+ if (sinceRaw !== null) {
420
+ const parsed = Date.parse(sinceRaw);
421
+ if (!Number.isFinite(parsed)) {
422
+ throw new HttpError(400, `invalid since: ${sinceRaw}`);
423
+ }
424
+ since = sinceRaw;
425
+ }
426
+ const limitRaw = query.get('limit');
427
+ let limit;
428
+ if (limitRaw !== null) {
429
+ const parsed = Number(limitRaw);
430
+ if (!Number.isFinite(parsed) || !Number.isInteger(parsed) || parsed < 1 || parsed > MAX_AUDIT_LIMIT) {
431
+ throw new HttpError(400, `limit must be an integer between 1 and ${MAX_AUDIT_LIMIT}`);
432
+ }
433
+ limit = parsed;
434
+ }
435
+ const ctx = buildContextWithAuth(req, opts.hippoRoot);
436
+ const result = auditList(ctx, { op, since, limit });
437
+ sendJson(res, 200, result);
438
+ return;
439
+ }
440
+ // ── MCP-over-HTTP/SSE transport (Task 11) ──
441
+ //
442
+ // Two routes implement an MCP HTTP transport alongside the stdio one. Both
443
+ // dispatch to the same `handleMcpRequest` as the stdio loop in src/mcp/server.ts.
444
+ //
445
+ // POST /mcp — Send a JSON-RPC request, get a JSON-RPC response synchronously
446
+ // in the body. Content-type: application/json both ways.
447
+ // GET /mcp/stream — Open an SSE stream for server-initiated messages.
448
+ // v1 simplification: this stream is keepalive-only. Clients
449
+ // that need server-pushed notifications/progress will see
450
+ // only `: ping` comments every 30s. All real responses come
451
+ // back synchronously on POST /mcp. This matches the
452
+ // "synchronous JSON in body" leg of the MCP HTTP spec and
453
+ // is enough for `tools/list` / `tools/call` round-trips.
454
+ // Server-initiated SSE messages will be wired in a later task.
455
+ //
456
+ // Auth: same as /v1/* — Bearer token validated via `requireAuth`, with the
457
+ // loopback no-auth fallback. SSE check runs once at stream-open.
458
+ if (method === 'POST' && path === '/mcp') {
459
+ // Build the same Context the /v1/* routes use so MCP tool calls inherit
460
+ // the server's bound hippoRoot and the auth-resolved tenantId / actor.
461
+ // Without this, executeTool would walk from cwd via findHippoRoot() and
462
+ // pull tenant from HIPPO_TENANT, dropping a valid Bearer for tenant B
463
+ // back to whatever the env says.
464
+ const ctx = buildContextWithAuth(req, opts.hippoRoot);
465
+ const raw = await readBody(req);
466
+ let mcpReq;
467
+ try {
468
+ mcpReq = JSON.parse(raw);
469
+ }
470
+ catch {
471
+ throw new HttpError(400, 'invalid JSON-RPC body');
472
+ }
473
+ if (!mcpReq || typeof mcpReq !== 'object' || typeof mcpReq.method !== 'string') {
474
+ throw new HttpError(400, 'JSON-RPC body must include a method string');
475
+ }
476
+ let mcpRes;
477
+ try {
478
+ mcpRes = await handleMcpRequest(mcpReq, {
479
+ hippoRoot: ctx.hippoRoot,
480
+ tenantId: ctx.tenantId,
481
+ actor: ctx.actor,
482
+ });
483
+ }
484
+ catch (err) {
485
+ mcpRes = {
486
+ jsonrpc: '2.0',
487
+ id: mcpReq.id,
488
+ error: { code: -32603, message: err instanceof Error ? err.message : 'internal error' },
489
+ };
490
+ }
491
+ if (mcpRes === null) {
492
+ // Notification — no body, 202 Accepted.
493
+ res.writeHead(202);
494
+ res.end();
495
+ return;
496
+ }
497
+ sendJson(res, 200, mcpRes);
498
+ return;
499
+ }
500
+ if (method === 'GET' && path === '/mcp/stream') {
501
+ requireAuth(req, opts.hippoRoot);
502
+ res.writeHead(200, {
503
+ 'content-type': 'text/event-stream',
504
+ 'cache-control': 'no-cache',
505
+ connection: 'keep-alive',
506
+ });
507
+ // Initial ping so smoke tests can confirm the stream is live without
508
+ // waiting 30s for the first keepalive interval.
509
+ res.write(': ping\n\n');
510
+ const ping = setInterval(() => {
511
+ try {
512
+ res.write(': ping\n\n');
513
+ }
514
+ catch {
515
+ clearInterval(ping);
516
+ }
517
+ }, 30000);
518
+ // Don't keep the event loop alive just for this timer — the server's
519
+ // listener already does that, and tests want the process to exit cleanly.
520
+ if (typeof ping.unref === 'function')
521
+ ping.unref();
522
+ req.on('close', () => clearInterval(ping));
523
+ return;
524
+ }
525
+ res.writeHead(404, JSON_HEADERS);
526
+ res.end(JSON.stringify({ error: 'not found' }));
527
+ }
528
+ /**
529
+ * Boot the HTTP daemon on host:port and write the pidfile under hippoRoot.
530
+ *
531
+ * Refuses non-loopback hosts at boot (Footgun #3 from the A1 plan): without
532
+ * the A5 v2 auth middleware we have no way to gate remote requests, so we
533
+ * fail fast rather than expose the DB to the network. Task 9 will lift this
534
+ * restriction once Bearer-token validation lands.
535
+ *
536
+ * Use port: 0 in tests to bind to an ephemeral port and read the actual
537
+ * port back via server.address() after listen.
538
+ */
539
+ export async function serve(opts) {
540
+ const host = opts.host ?? '127.0.0.1';
541
+ const requestedPort = opts.port ?? Number(process.env.HIPPO_PORT ?? 6789);
542
+ if (!LOOPBACK_HOSTS.has(host)) {
543
+ throw new Error(`Refusing to bind hippo serve to non-loopback host '${host}' without auth. ` +
544
+ `Remote-host serving requires the A5 v2 auth middleware (Task 9 of the A1 plan). ` +
545
+ `Bind to 127.0.0.1 / ::1 / localhost, or wait for auth support.`);
546
+ }
547
+ const startedAt = new Date().toISOString();
548
+ const server = createServer((req, res) => {
549
+ handleRequest(req, res, opts, startedAt).catch((err) => {
550
+ if (res.headersSent) {
551
+ try {
552
+ res.end();
553
+ }
554
+ catch { /* socket already gone */ }
555
+ return;
556
+ }
557
+ if (err instanceof BodyTooLargeError) {
558
+ sendError(res, 413, err.message);
559
+ return;
560
+ }
561
+ if (err instanceof HttpError) {
562
+ sendError(res, err.status, err.message);
563
+ return;
564
+ }
565
+ const mapped = mapApiError(err);
566
+ sendError(res, mapped.status, mapped.message);
567
+ });
568
+ });
569
+ await new Promise((resolve, reject) => {
570
+ const onError = (err) => {
571
+ server.removeListener('listening', onListening);
572
+ reject(err);
573
+ };
574
+ const onListening = () => {
575
+ server.removeListener('error', onError);
576
+ resolve();
577
+ };
578
+ server.once('error', onError);
579
+ server.once('listening', onListening);
580
+ server.listen(requestedPort, host);
581
+ });
582
+ const address = server.address();
583
+ if (!address || typeof address === 'string') {
584
+ throw new Error('server.address() returned unexpected shape');
585
+ }
586
+ const actualPort = address.port;
587
+ const url = `http://${host}:${actualPort}`;
588
+ writePidfile(opts.hippoRoot, { port: actualPort, url });
589
+ let stopping = false;
590
+ const stop = async () => {
591
+ if (stopping)
592
+ return;
593
+ stopping = true;
594
+ removePidfile(opts.hippoRoot);
595
+ // Force-close any long-lived idle connections (e.g. SSE keepalive streams
596
+ // on /mcp/stream) so server.close() can resolve. Without this, SIGTERM
597
+ // would hang the process until the SSE client cancels. Available on
598
+ // Node 18.2+; gate via optional chaining to avoid crashing on older runtimes.
599
+ server.closeAllConnections?.();
600
+ await new Promise((resolve) => {
601
+ server.close(() => resolve());
602
+ });
603
+ };
604
+ // Skip signal handlers under vitest so each test run does not register a
605
+ // stray SIGTERM/SIGINT listener that survives until the runner exits.
606
+ if (!process.env.VITEST) {
607
+ process.once('SIGTERM', () => { void stop(); });
608
+ process.once('SIGINT', () => { void stop(); });
609
+ }
610
+ return { port: actualPort, url, stop };
611
+ }
612
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
package/dist/shared.d.ts CHANGED
@@ -20,11 +20,15 @@ export declare function initGlobal(): void;
20
20
  * Assigns a new ID (prefixed with 'g_') to avoid collisions.
21
21
  * Returns the new global entry.
22
22
  */
23
- export declare function promoteToGlobal(localRoot: string, id: string): MemoryEntry;
23
+ export declare function promoteToGlobal(localRoot: string, id: string, opts?: {
24
+ actor?: string;
25
+ }): MemoryEntry;
24
26
  export interface SearchOptions {
25
27
  budget?: number;
26
28
  now?: Date;
27
29
  minResults?: number;
30
+ /** Tenant scope for both stores. Undefined = no filter (legacy single-tenant). */
31
+ tenantId?: string;
28
32
  }
29
33
  /**
30
34
  * Search across both local and global stores, merging results.
@@ -1 +1 @@
1
- {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../src/shared.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAAE,WAAW,EAAc,MAAM,aAAa,CAAC;AAStD,OAAO,EAAwB,YAAY,EAAE,MAAM,aAAa,CAAC;AAEjE;;;GAGG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAMtC;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,IAAI,CAQjC;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,WAAW,CAgB1E;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,aAAkB,GAC1B,YAAY,EAAE,CAkDhB;AAED,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACxD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;kFAC8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,6DAA6D;IAC7D,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,0DAA0D;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,YAAY,EAAE,CAAC,CAoDzB;AAmBD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAqBxD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,EACV,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAChC,WAAW,GAAG,IAAI,CAmBpB;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAgCxG;AAED;;;GAGG;AACH,wBAAgB,SAAS,CACvB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACpD,WAAW,EAAE,CAiCf;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAgB/E"}
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../src/shared.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAAE,WAAW,EAAc,MAAM,aAAa,CAAC;AAStD,OAAO,EAAwB,YAAY,EAAE,MAAM,aAAa,CAAC;AAEjE;;;GAGG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAMtC;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,IAAI,CAQjC;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,EACV,IAAI,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACxB,WAAW,CAgBb;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kFAAkF;IAClF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,aAAkB,GAC1B,YAAY,EAAE,CAkDhB;AAED,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACxD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;kFAC8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,6DAA6D;IAC7D,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,0DAA0D;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,YAAY,EAAE,CAAC,CAoDzB;AAmBD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAqBxD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,EACV,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAChC,WAAW,GAAG,IAAI,CAmBpB;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAgCxG;AAED;;;GAGG;AACH,wBAAgB,SAAS,CACvB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACpD,WAAW,EAAE,CAiCf;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAgB/E"}