@poprobertdaniel/openclaw-memory 0.1.1 → 0.1.3

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 (49) hide show
  1. package/README.md +22 -10
  2. package/dist/{chunk-RFLG2CCR.js → chunk-7DNVIKQ3.js} +100 -10
  3. package/dist/chunk-7DNVIKQ3.js.map +1 -0
  4. package/dist/{chunk-JSQBXYDM.js → chunk-BTR4T5L3.js} +157 -26
  5. package/dist/chunk-BTR4T5L3.js.map +1 -0
  6. package/dist/{chunk-VXULEX3A.cjs → chunk-CSGZH2SG.cjs} +9 -9
  7. package/dist/chunk-CSGZH2SG.cjs.map +1 -0
  8. package/dist/{chunk-JNWCMHOB.js → chunk-ITGUJZUL.js} +2 -2
  9. package/dist/{chunk-JNWCMHOB.js.map → chunk-ITGUJZUL.js.map} +1 -1
  10. package/dist/{chunk-NHFPLDZK.js → chunk-J2C5USXH.js} +3 -3
  11. package/dist/{chunk-CRPEAZ44.cjs → chunk-JYQB2DOK.cjs} +161 -30
  12. package/dist/chunk-JYQB2DOK.cjs.map +1 -0
  13. package/dist/{chunk-ZY2C2CJQ.cjs → chunk-LA5OP5VI.cjs} +2 -2
  14. package/dist/chunk-LA5OP5VI.cjs.map +1 -0
  15. package/dist/{chunk-NMUPGLJW.cjs → chunk-NYZMAY73.cjs} +110 -20
  16. package/dist/chunk-NYZMAY73.cjs.map +1 -0
  17. package/dist/cli/index.cjs +25 -25
  18. package/dist/cli/index.cjs.map +1 -1
  19. package/dist/cli/index.js +7 -7
  20. package/dist/cli/index.js.map +1 -1
  21. package/dist/index.cjs +5 -5
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.d.cts +64 -2
  24. package/dist/index.d.ts +64 -2
  25. package/dist/index.js +4 -4
  26. package/dist/memory-service-B2BAEKR2.cjs +9 -0
  27. package/dist/memory-service-B2BAEKR2.cjs.map +1 -0
  28. package/dist/memory-service-ZTLGPIUH.js +9 -0
  29. package/dist/{server-BTbRv-yX.d.ts → server-CtNlCow7.d.cts} +62 -0
  30. package/dist/{server-BTbRv-yX.d.cts → server-CtNlCow7.d.ts} +62 -0
  31. package/dist/server.cjs +4 -4
  32. package/dist/server.cjs.map +1 -1
  33. package/dist/server.d.cts +1 -1
  34. package/dist/server.d.ts +1 -1
  35. package/dist/server.js +3 -3
  36. package/package.json +2 -2
  37. package/templates/.env.example +1 -1
  38. package/templates/openclaw-memory.config.ts +2 -2
  39. package/dist/chunk-CRPEAZ44.cjs.map +0 -1
  40. package/dist/chunk-JSQBXYDM.js.map +0 -1
  41. package/dist/chunk-NMUPGLJW.cjs.map +0 -1
  42. package/dist/chunk-RFLG2CCR.js.map +0 -1
  43. package/dist/chunk-VXULEX3A.cjs.map +0 -1
  44. package/dist/chunk-ZY2C2CJQ.cjs.map +0 -1
  45. package/dist/memory-service-6WDMF6KX.cjs +0 -9
  46. package/dist/memory-service-6WDMF6KX.cjs.map +0 -1
  47. package/dist/memory-service-GKEG6J2D.js +0 -9
  48. /package/dist/{chunk-NHFPLDZK.js.map → chunk-J2C5USXH.js.map} +0 -0
  49. /package/dist/{memory-service-GKEG6J2D.js.map → memory-service-ZTLGPIUH.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/private/tmp/openclaw-memory-publish/dist/chunk-LA5OP5VI.cjs","../src/config/index.ts","../src/core/errors.ts","../src/config/defaults.ts"],"names":[],"mappings":"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;AACT,EAAA;AACI,EAAA;AACK,IAAA;AACT,EAAA;AAGM,EAAA;AAGA,EAAA;AAGF,EAAA;AACA,EAAA;AACF,IAAA;AACO,MAAA;AACL,MAAA;AACA,MAAA;AACF,IAAA;AACF,EAAA;AAEI,EAAA;AACA,EAAA;AACG,IAAA;AACH,MAAA;AACF,IAAA;AACM,IAAA;AACJ,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACF,IAAA;AACF,EAAA;AAEI,EAAA;AACA,EAAA;AACF,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACF,IAAA;AACF,EAAA;AAEI,EAAA;AACA,EAAA;AACF,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACF,IAAA;AACF,EAAA;AAEO,EAAA;AACL,IAAA;AACM,IAAA;AACA,IAAA;AACA,IAAA;AACJ,MAAA;AACA,MAAA;AACF,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACF,EAAA;AACF;AAIgB;AACP,EAAA;AACT;AAIgB;AACR,EAAA;AACJ,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACF,EAAA;AAEI,EAAA;AACI,IAAA;AACR,EAAA;AACI,EAAA;AACI,IAAA;AACR,EAAA;AACI,EAAA;AACI,IAAA;AACR,EAAA;AACI,EAAA;AACI,IAAA;AACR,EAAA;AAEO,EAAA;AACT;ADZW;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/private/tmp/openclaw-memory-publish/dist/chunk-LA5OP5VI.cjs","sourcesContent":[null,"import path from \"node:path\";\nimport os from \"node:os\";\nimport fs from \"node:fs\";\nimport type { Tier } from \"../core/types.js\";\nimport { ConfigError } from \"../core/errors.js\";\nimport { DEFAULTS } from \"./defaults.js\";\nimport type { Config, ResolvedConfig, QdrantConfig, AgeConfig, EmbeddingConfig, ExtractionConfig } from \"./schema.js\";\n\nexport type { Config, ResolvedConfig } from \"./schema.js\";\n\n// ── Helper: expand ~ to home dir ────────────────────────────────────────\n\nfunction expandHome(p: string): string {\n if (p.startsWith(\"~/\") || p === \"~\") {\n return path.join(os.homedir(), p.slice(1));\n }\n return p;\n}\n\n// ── Data Directory ──────────────────────────────────────────────────────\n\nexport function getDataDir(): string {\n return process.env.OPENCLAW_MEMORY_DATA_DIR || path.join(os.homedir(), \".openclaw-memory\");\n}\n\nexport function getDefaultSqlitePath(): string {\n return path.join(getDataDir(), \"memory.sqlite\");\n}\n\nexport function getPidFilePath(): string {\n return path.join(getDataDir(), \"server.pid\");\n}\n\n// ── Config File Discovery ───────────────────────────────────────────────\n\nfunction getConfigSearchPaths(cwd: string): string[] {\n return [\n path.join(cwd, \"openclaw-memory.config.ts\"),\n path.join(cwd, \"openclaw-memory.config.js\"),\n path.join(cwd, \"openclaw-memory.config.json\"),\n path.join(getDataDir(), \"config.ts\"),\n path.join(getDataDir(), \"config.json\"),\n ];\n}\n\nasync function loadConfigFile(configPath?: string): Promise<Config | null> {\n const searchPaths = configPath ? [configPath] : getConfigSearchPaths(process.cwd());\n\n for (const p of searchPaths) {\n if (fs.existsSync(p)) {\n if (p.endsWith(\".json\")) {\n const content = fs.readFileSync(p, \"utf-8\");\n return JSON.parse(content) as Config;\n }\n // For .ts and .js files, try dynamic import\n try {\n const mod = await import(p);\n return (mod.default || mod) as Config;\n } catch {\n // Can't import .ts outside of Bun — skip\n }\n }\n }\n\n return null;\n}\n\n// ── Environment Variable Loading ────────────────────────────────────────\n\nfunction loadFromEnv(): Partial<Config> {\n const config: Partial<Config> = {};\n\n // Load .env file if dotenv is available\n try {\n const dotenvPath = path.join(process.cwd(), \".env\");\n if (fs.existsSync(dotenvPath)) {\n const envContent = fs.readFileSync(dotenvPath, \"utf-8\");\n for (const line of envContent.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n const eqIdx = trimmed.indexOf(\"=\");\n if (eqIdx === -1) continue;\n const key = trimmed.slice(0, eqIdx).trim();\n const value = trimmed.slice(eqIdx + 1).trim().replace(/^[\"']|[\"']$/g, \"\");\n if (!process.env[key]) {\n process.env[key] = value;\n }\n }\n }\n } catch {\n // No .env file — that's fine\n }\n\n const env = process.env;\n\n // Tier\n const tier = env.OPENCLAW_MEMORY_TIER || env.MEMORY_TIER;\n if (tier && [\"lite\", \"standard\", \"full\"].includes(tier)) {\n config.tier = tier as Tier;\n }\n\n // Port/Host\n const port = env.OPENCLAW_MEMORY_PORT || env.PORT;\n if (port) config.port = parseInt(port, 10);\n\n const host = env.OPENCLAW_MEMORY_HOST;\n if (host) config.host = host;\n\n // Auth\n const authToken = env.OPENCLAW_MEMORY_AUTH__TOKEN || env.AUTH_TOKEN || env.MEMORY_TOKEN;\n if (authToken) {\n config.auth = { token: authToken, enabled: true };\n }\n\n // SQLite\n const sqlitePath = env.OPENCLAW_MEMORY_SQLITE__PATH || env.SQLITE_PATH;\n if (sqlitePath) {\n config.sqlite = { path: sqlitePath };\n }\n\n // Qdrant\n const qdrantUrl = env.OPENCLAW_MEMORY_QDRANT__URL || env.QDRANT_URL;\n if (qdrantUrl) {\n config.qdrant = {\n url: qdrantUrl,\n collection: env.OPENCLAW_MEMORY_QDRANT__COLLECTION || env.QDRANT_COLLECTION || DEFAULTS.qdrant.collection,\n apiKey: env.OPENCLAW_MEMORY_QDRANT__API_KEY,\n };\n }\n\n // AGE\n const ageHost = env.OPENCLAW_MEMORY_AGE__HOST || env.PGHOST;\n if (ageHost) {\n config.age = {\n host: ageHost,\n port: parseInt(env.OPENCLAW_MEMORY_AGE__PORT || env.PGPORT || String(DEFAULTS.age.port), 10),\n user: env.OPENCLAW_MEMORY_AGE__USER || env.PGUSER || \"\",\n password: env.OPENCLAW_MEMORY_AGE__PASSWORD || env.PGPASSWORD || \"\",\n database: env.OPENCLAW_MEMORY_AGE__DATABASE || env.PGDATABASE || \"\",\n graph: env.OPENCLAW_MEMORY_AGE__GRAPH || env.AGE_GRAPH || DEFAULTS.age.graph,\n };\n }\n\n // Embedding\n const embeddingApiKey = env.OPENCLAW_MEMORY_EMBEDDING__API_KEY || env.OPENROUTER_API_KEY || env.OPENAI_API_KEY;\n if (embeddingApiKey) {\n config.embedding = {\n apiKey: embeddingApiKey,\n baseUrl: env.OPENCLAW_MEMORY_EMBEDDING__BASE_URL || env.EMBEDDING_BASE_URL,\n model: env.OPENCLAW_MEMORY_EMBEDDING__MODEL || env.EMBEDDING_MODEL || DEFAULTS.embedding.model,\n dimensions: parseInt(env.OPENCLAW_MEMORY_EMBEDDING__DIMENSIONS || String(DEFAULTS.embedding.dimensions), 10),\n };\n }\n\n // Extraction\n const extractionApiKey = env.OPENCLAW_MEMORY_EXTRACTION__API_KEY || env.OPENROUTER_API_KEY || env.OPENAI_API_KEY;\n if (extractionApiKey) {\n config.extraction = {\n apiKey: extractionApiKey,\n baseUrl: env.OPENCLAW_MEMORY_EXTRACTION__BASE_URL || env.EXTRACTION_BASE_URL,\n model: env.OPENCLAW_MEMORY_EXTRACTION__MODEL || env.EXTRACTION_MODEL || DEFAULTS.extraction.model,\n enabled: env.OPENCLAW_MEMORY_EXTRACTION__ENABLED !== \"false\",\n };\n }\n\n return config;\n}\n\n// ── Tier Inference ──────────────────────────────────────────────────────\n\nfunction inferTier(config: Partial<Config>): Tier {\n if (config.tier) return config.tier;\n if (config.qdrant && config.age) return \"full\";\n if (config.qdrant) return \"standard\";\n return \"lite\";\n}\n\n// ── Config Resolution ───────────────────────────────────────────────────\n\nexport async function loadConfig(configPath?: string): Promise<ResolvedConfig> {\n // 1. Load from file\n const fileConfig = await loadConfigFile(configPath);\n\n // 2. Load from env\n const envConfig = loadFromEnv();\n\n // 3. Merge: file < env (env wins)\n const merged: Partial<Config> = {\n ...fileConfig,\n ...envConfig,\n // Deep merge nested objects\n auth: { ...fileConfig?.auth, ...envConfig.auth },\n sqlite: { ...fileConfig?.sqlite, ...envConfig.sqlite },\n };\n\n if (envConfig.qdrant || fileConfig?.qdrant) {\n merged.qdrant = { ...fileConfig?.qdrant, ...envConfig.qdrant } as Config[\"qdrant\"];\n }\n if (envConfig.age || fileConfig?.age) {\n merged.age = { ...fileConfig?.age, ...envConfig.age } as Config[\"age\"];\n }\n if (envConfig.embedding || fileConfig?.embedding) {\n merged.embedding = { ...fileConfig?.embedding, ...envConfig.embedding } as Config[\"embedding\"];\n }\n if (envConfig.extraction || fileConfig?.extraction) {\n merged.extraction = { ...fileConfig?.extraction, ...envConfig.extraction } as Config[\"extraction\"];\n }\n\n // 4. Infer tier\n const tier = inferTier(merged);\n\n // 5. Resolve defaults\n const sqlitePath = expandHome(merged.sqlite?.path || DEFAULTS.sqlite.path);\n\n // 6. Resolve optional layers based on tier\n let qdrant: QdrantConfig | null = null;\n if (tier !== \"lite\" && merged.qdrant?.url) {\n qdrant = {\n url: merged.qdrant.url,\n collection: merged.qdrant.collection || DEFAULTS.qdrant.collection,\n apiKey: merged.qdrant.apiKey,\n };\n }\n\n let age: AgeConfig | null = null;\n if (tier === \"full\" && merged.age?.host) {\n if (!merged.age.user || !merged.age.password || !merged.age.database) {\n throw new ConfigError(\"Full tier requires age.user, age.password, and age.database\");\n }\n age = {\n host: merged.age.host,\n port: merged.age.port || DEFAULTS.age.port,\n user: merged.age.user,\n password: merged.age.password,\n database: merged.age.database,\n graph: merged.age.graph || DEFAULTS.age.graph,\n };\n }\n\n let embedding: EmbeddingConfig | null = null;\n if (tier !== \"lite\" && merged.embedding?.apiKey) {\n embedding = {\n apiKey: merged.embedding.apiKey,\n baseUrl: merged.embedding.baseUrl,\n model: merged.embedding.model || DEFAULTS.embedding.model,\n dimensions: merged.embedding.dimensions || DEFAULTS.embedding.dimensions,\n };\n }\n\n let extraction: ExtractionConfig | null = null;\n if (tier !== \"lite\" && merged.extraction?.apiKey) {\n extraction = {\n apiKey: merged.extraction.apiKey,\n baseUrl: merged.extraction.baseUrl,\n model: merged.extraction.model || DEFAULTS.extraction.model,\n enabled: merged.extraction.enabled ?? DEFAULTS.extraction.enabled,\n };\n }\n\n return {\n tier,\n port: merged.port || DEFAULTS.port,\n host: merged.host || DEFAULTS.host,\n auth: {\n token: merged.auth?.token,\n enabled: merged.auth?.enabled ?? DEFAULTS.auth.enabled,\n },\n sqlite: { path: sqlitePath },\n qdrant,\n age,\n embedding,\n extraction,\n agents: merged.agents || fileConfig?.agents || [],\n };\n}\n\n// ── defineConfig helper for config files ────────────────────────────────\n\nexport function defineConfig(config: Config): Config {\n return config;\n}\n\n// ── Config summary (redacted) for logging ───────────────────────────────\n\nexport function configSummary(config: ResolvedConfig): string {\n const lines: string[] = [\n `Tier: ${config.tier}`,\n `Port: ${config.port}`,\n `Host: ${config.host}`,\n `SQLite: ${config.sqlite.path}`,\n `Auth: ${config.auth.enabled ? \"enabled\" : \"disabled\"}`,\n ];\n\n if (config.qdrant) {\n lines.push(`Qdrant: ${config.qdrant.url} (collection: ${config.qdrant.collection})`);\n }\n if (config.age) {\n lines.push(`AGE: ${config.age.host}:${config.age.port}/${config.age.database}`);\n }\n if (config.embedding) {\n lines.push(`Embedding: ${config.embedding.model}${config.embedding.baseUrl ? ` via ${config.embedding.baseUrl}` : \"\"}`);\n }\n if (config.extraction) {\n lines.push(`Extraction: ${config.extraction.model}${config.extraction.enabled ? \"\" : \" (disabled)\"}`);\n }\n\n return lines.join(\"\\n\");\n}\n","// ── Custom Error Classes ────────────────────────────────────────────────\n\nexport class MemoryError extends Error {\n constructor(message: string, public readonly code: string) {\n super(message);\n this.name = \"MemoryError\";\n }\n}\n\nexport class ConfigError extends MemoryError {\n constructor(message: string) {\n super(message, \"CONFIG_ERROR\");\n this.name = \"ConfigError\";\n }\n}\n\nexport class StorageError extends MemoryError {\n constructor(message: string, public readonly layer: \"sqlite\" | \"qdrant\" | \"age\") {\n super(message, \"STORAGE_ERROR\");\n this.name = \"StorageError\";\n }\n}\n\nexport class ValidationError extends MemoryError {\n constructor(message: string, public readonly details?: unknown) {\n super(message, \"VALIDATION_ERROR\");\n this.name = \"ValidationError\";\n }\n}\n\nexport class NotFoundError extends MemoryError {\n constructor(resource: string, id: string) {\n super(`${resource} not found: ${id}`, \"NOT_FOUND\");\n this.name = \"NotFoundError\";\n }\n}\n\nexport class AuthError extends MemoryError {\n constructor(message: string = \"Unauthorized\") {\n super(message, \"AUTH_ERROR\");\n this.name = \"AuthError\";\n }\n}\n","// ── Default Configuration Values ────────────────────────────────────────\n\nexport const DEFAULTS = {\n port: 7777,\n host: \"0.0.0.0\",\n sqlite: {\n path: \"~/.openclaw-memory/memory.sqlite\",\n },\n qdrant: {\n collection: \"openclaw_memories\",\n },\n age: {\n port: 5432,\n graph: \"agent_memory\",\n },\n embedding: {\n model: \"text-embedding-3-small\",\n dimensions: 1536,\n },\n extraction: {\n model: \"gpt-5-nano\",\n enabled: true,\n },\n auth: {\n enabled: true,\n },\n} as const;\n"]}
@@ -2,15 +2,16 @@
2
2
 
3
3
 
4
4
 
5
- var _chunkCRPEAZ44cjs = require('./chunk-CRPEAZ44.cjs');
6
5
 
6
+ var _chunkJYQB2DOKcjs = require('./chunk-JYQB2DOK.cjs');
7
7
 
8
8
 
9
9
 
10
10
 
11
11
 
12
12
 
13
- var _chunkZY2C2CJQcjs = require('./chunk-ZY2C2CJQ.cjs');
13
+
14
+ var _chunkLA5OP5VIcjs = require('./chunk-LA5OP5VI.cjs');
14
15
 
15
16
  // src/server.ts
16
17
  var _url = require('url');
@@ -146,7 +147,7 @@ function memoriesRoutes(orchestrator) {
146
147
  // src/api/search.ts
147
148
 
148
149
  function searchRoutes(orchestrator) {
149
- const searchEngine = new (0, _chunkCRPEAZ44cjs.SearchEngine)(orchestrator);
150
+ const searchEngine = new (0, _chunkJYQB2DOKcjs.SearchEngine)(orchestrator);
150
151
  return new (0, _elysia.Elysia)({ prefix: "/api/search" }).post(
151
152
  "/",
152
153
  async ({ body, set }) => {
@@ -296,7 +297,7 @@ function searchRoutes(orchestrator) {
296
297
  // src/api/conversations.ts
297
298
 
298
299
  function conversationRoutes(orchestrator, config) {
299
- const summarizer = config.extraction ? new (0, _chunkCRPEAZ44cjs.ConversationSummarizer)({
300
+ const summarizer = config.extraction ? new (0, _chunkJYQB2DOKcjs.ConversationSummarizer)({
300
301
  apiKey: config.extraction.apiKey,
301
302
  baseUrl: config.extraction.baseUrl,
302
303
  model: config.extraction.model
@@ -489,9 +490,10 @@ function entityRoutes(orchestrator) {
489
490
  var _fs = require('fs'); var _fs2 = _interopRequireDefault(_fs);
490
491
 
491
492
  function adminRoutes(orchestrator) {
492
- return new (0, _elysia.Elysia)().get("/api/health", async () => {
493
+ const healthHandler = async () => {
493
494
  return await orchestrator.healthCheck();
494
- }).post("/api/sync/retry", async ({ set }) => {
495
+ };
496
+ return new (0, _elysia.Elysia)().get("/api/health", healthHandler).get("/health", healthHandler).post("/api/sync/retry", async ({ set }) => {
495
497
  try {
496
498
  const result = await orchestrator.retrySyncQueue();
497
499
  return result;
@@ -502,7 +504,63 @@ function adminRoutes(orchestrator) {
502
504
  details: error instanceof Error ? error.message : String(error)
503
505
  };
504
506
  }
505
- }).get("/api/sync/queue", () => {
507
+ }).post(
508
+ "/api/admin/resync",
509
+ async ({ query, set }) => {
510
+ const layerParam = parseLayerParam(query.layer);
511
+ if (!layerParam) {
512
+ set.status = 400;
513
+ return {
514
+ error: "Invalid layer parameter",
515
+ details: "Use ?layer=qdrant|age|both"
516
+ };
517
+ }
518
+ const batch = parseBatchParam(query.batch);
519
+ if (batch === null) {
520
+ set.status = 400;
521
+ return {
522
+ error: "Invalid batch parameter",
523
+ details: "Use a positive integer for ?batch=50"
524
+ };
525
+ }
526
+ const layers = layerParam === "both" ? ["qdrant", "age"] : [layerParam];
527
+ try {
528
+ const memories = listAllMemories(orchestrator);
529
+ let queuedItems = 0;
530
+ for (const memory of memories) {
531
+ for (const layer of layers) {
532
+ orchestrator.sqlite.addToSyncQueue(memory.id, layer, "upsert");
533
+ queuedItems++;
534
+ }
535
+ }
536
+ const syncResults = await _chunkJYQB2DOKcjs.SyncQueueProcessor.withBatchSize(batch, async () => {
537
+ return await orchestrator.retrySyncQueue();
538
+ });
539
+ return {
540
+ layer: layerParam,
541
+ layers,
542
+ batch,
543
+ memory_count: memories.length,
544
+ queued_items: queuedItems,
545
+ sync_results: syncResults
546
+ };
547
+ } catch (error) {
548
+ set.status = 500;
549
+ return {
550
+ error: "Resync failed",
551
+ details: error instanceof Error ? error.message : String(error)
552
+ };
553
+ }
554
+ },
555
+ {
556
+ query: _elysia.t.Object({
557
+ layer: _elysia.t.Optional(
558
+ _elysia.t.Union([_elysia.t.Literal("qdrant"), _elysia.t.Literal("age"), _elysia.t.Literal("both")])
559
+ ),
560
+ batch: _elysia.t.Optional(_elysia.t.String())
561
+ })
562
+ }
563
+ ).get("/api/sync/queue", () => {
506
564
  const items = orchestrator.sqlite.getSyncQueue(100);
507
565
  return { items, count: items.length };
508
566
  }).post(
@@ -531,6 +589,33 @@ function adminRoutes(orchestrator) {
531
589
  return { error: "Not yet implemented" };
532
590
  });
533
591
  }
592
+ function parseLayerParam(layer) {
593
+ if (!layer) return "both";
594
+ if (layer === "qdrant" || layer === "age" || layer === "both") return layer;
595
+ return null;
596
+ }
597
+ function parseBatchParam(batch) {
598
+ if (!batch) return 50;
599
+ const parsed = Number.parseInt(batch, 10);
600
+ if (!Number.isFinite(parsed) || parsed <= 0) return null;
601
+ return parsed;
602
+ }
603
+ function listAllMemories(orchestrator) {
604
+ const pageSize = 5e3;
605
+ const memories = [];
606
+ let offset = 0;
607
+ while (true) {
608
+ const page = orchestrator.sqlite.listMemories({
609
+ limit: pageSize,
610
+ offset,
611
+ order: "asc"
612
+ });
613
+ memories.push(...page);
614
+ if (page.length < pageSize) break;
615
+ offset += pageSize;
616
+ }
617
+ return memories;
618
+ }
534
619
  async function migrateMarkdownFiles(orchestrator, request) {
535
620
  const { markdown_paths, agent_id, dry_run } = request;
536
621
  let migrated = 0;
@@ -653,34 +738,34 @@ function inferTags(heading, fileName) {
653
738
  // src/api/router.ts
654
739
  function createApp(orchestrator, config) {
655
740
  const app = new (0, _elysia.Elysia)().use(_cors.cors.call(void 0, )).derive(({ headers, set, path: path2 }) => {
656
- if (path2 === "/api/health") return {};
741
+ if (path2 === "/api/health" || path2 === "/health") return {};
657
742
  if (!config.auth.enabled || !config.auth.token) return {};
658
743
  const authHeader = headers.authorization;
659
744
  if (!authHeader || !authHeader.startsWith("Bearer ")) {
660
745
  set.status = 401;
661
- throw new (0, _chunkZY2C2CJQcjs.AuthError)("Missing or invalid Authorization header");
746
+ throw new (0, _chunkLA5OP5VIcjs.AuthError)("Missing or invalid Authorization header");
662
747
  }
663
748
  const token = authHeader.slice(7);
664
749
  if (token !== config.auth.token) {
665
750
  set.status = 403;
666
- throw new (0, _chunkZY2C2CJQcjs.AuthError)("Invalid token");
751
+ throw new (0, _chunkLA5OP5VIcjs.AuthError)("Invalid token");
667
752
  }
668
753
  return {};
669
754
  }).onError(({ code, error, set }) => {
670
- if (error instanceof _chunkZY2C2CJQcjs.AuthError) {
755
+ if (error instanceof _chunkLA5OP5VIcjs.AuthError) {
671
756
  const status = error.message.includes("Invalid token") ? 403 : 401;
672
757
  set.status = status;
673
758
  return { error: error.message, code: error.code };
674
759
  }
675
- if (error instanceof _chunkZY2C2CJQcjs.NotFoundError) {
760
+ if (error instanceof _chunkLA5OP5VIcjs.NotFoundError) {
676
761
  set.status = 404;
677
762
  return { error: error.message, code: error.code };
678
763
  }
679
- if (error instanceof _chunkZY2C2CJQcjs.ValidationError) {
764
+ if (error instanceof _chunkLA5OP5VIcjs.ValidationError) {
680
765
  set.status = 400;
681
766
  return { error: error.message, code: error.code, details: error.details };
682
767
  }
683
- if (error instanceof _chunkZY2C2CJQcjs.MemoryError) {
768
+ if (error instanceof _chunkLA5OP5VIcjs.MemoryError) {
684
769
  set.status = 500;
685
770
  return { error: error.message, code: error.code };
686
771
  }
@@ -689,6 +774,11 @@ function createApp(orchestrator, config) {
689
774
  set.status = 400;
690
775
  return { error: "Validation error", details: msg2 };
691
776
  }
777
+ if (code === "NOT_FOUND") {
778
+ const msg2 = error && "message" in error ? error.message : "Route not found";
779
+ set.status = 404;
780
+ return { error: msg2, code };
781
+ }
692
782
  const msg = error instanceof Error ? error.stack || error.message : String(error);
693
783
  console.error(`[api] Unhandled error: ${msg}`);
694
784
  set.status = 500;
@@ -699,8 +789,8 @@ function createApp(orchestrator, config) {
699
789
 
700
790
  // src/server.ts
701
791
  async function createServer(configPath) {
702
- const config = await _chunkZY2C2CJQcjs.loadConfig.call(void 0, configPath);
703
- const orchestrator = new (0, _chunkCRPEAZ44cjs.StorageOrchestrator)(config);
792
+ const config = await _chunkLA5OP5VIcjs.loadConfig.call(void 0, configPath);
793
+ const orchestrator = new (0, _chunkJYQB2DOKcjs.StorageOrchestrator)(config);
704
794
  await orchestrator.init();
705
795
  const app = createApp(orchestrator, config);
706
796
  return { app, orchestrator, config };
@@ -712,7 +802,7 @@ async function main() {
712
802
  console.log("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518");
713
803
  const { app, orchestrator, config } = await createServer();
714
804
  console.log("[config]");
715
- console.log(_chunkZY2C2CJQcjs.configSummary.call(void 0, config).split("\n").map((l) => ` ${l}`).join("\n"));
805
+ console.log(_chunkLA5OP5VIcjs.configSummary.call(void 0, config).split("\n").map((l) => ` ${l}`).join("\n"));
716
806
  app.listen(config.port);
717
807
  console.log(`[server] Listening on http://${config.host}:${config.port}`);
718
808
  console.log(`[server] Health check: http://localhost:${config.port}/api/health`);
@@ -726,8 +816,8 @@ async function main() {
726
816
  }
727
817
  function isMainModule() {
728
818
  try {
729
- if (typeof globalThis.Bun !== "undefined") {
730
- const bun = globalThis.Bun;
819
+ const bun = globalThis.Bun;
820
+ if (typeof bun !== "undefined") {
731
821
  return bun.main === _url.fileURLToPath.call(void 0, import.meta.url);
732
822
  }
733
823
  if (process.argv[1]) {
@@ -749,4 +839,4 @@ if (isMainModule()) {
749
839
 
750
840
 
751
841
  exports.createApp = createApp; exports.createServer = createServer;
752
- //# sourceMappingURL=chunk-NMUPGLJW.cjs.map
842
+ //# sourceMappingURL=chunk-NYZMAY73.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/private/tmp/openclaw-memory-publish/dist/chunk-NYZMAY73.cjs","../src/server.ts","../src/api/router.ts","../src/api/memories.ts","../src/api/search.ts","../src/api/conversations.ts","../src/api/entities.ts","../src/api/admin.ts"],"names":["Elysia","t","path"],"mappings":"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","file":"/private/tmp/openclaw-memory-publish/dist/chunk-NYZMAY73.cjs","sourcesContent":[null,"import { fileURLToPath } from \"node:url\";\nimport { resolve } from \"node:path\";\nimport { loadConfig, configSummary } from \"./config/index.js\";\nimport { StorageOrchestrator } from \"./storage/orchestrator.js\";\nimport { createApp } from \"./api/router.js\";\n\n// ── Server Entry Point ──────────────────────────────────────────────────\n\nexport async function createServer(configPath?: string) {\n const config = await loadConfig(configPath);\n const orchestrator = new StorageOrchestrator(config);\n await orchestrator.init();\n\n const app = createApp(orchestrator, config);\n\n return { app, orchestrator, config };\n}\n\n// ── Main ────────────────────────────────────────────────────────────────\n\nasync function main() {\n console.log(\"┌──────────────────────────────────────────┐\");\n console.log(\"│ openclaw-memory service v0.1.0 │\");\n console.log(\"│ Triple-Layer Memory System │\");\n console.log(\"└──────────────────────────────────────────┘\");\n\n const { app, orchestrator, config } = await createServer();\n\n console.log(\"[config]\");\n console.log(configSummary(config).split(\"\\n\").map((l) => ` ${l}`).join(\"\\n\"));\n\n app.listen(config.port);\n console.log(`[server] Listening on http://${config.host}:${config.port}`);\n console.log(`[server] Health check: http://localhost:${config.port}/api/health`);\n\n const shutdown = async () => {\n console.log(\"\\n[server] Shutting down...\");\n await orchestrator.close();\n process.exit(0);\n };\n\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n}\n\n// Run if executed directly (works in both Bun and Node ESM)\nfunction isMainModule(): boolean {\n try {\n // Bun runtime\n const bun = (globalThis as typeof globalThis & { Bun?: { main?: string } }).Bun;\n if (typeof bun !== \"undefined\") {\n return bun.main === fileURLToPath(import.meta.url);\n }\n // Node.js\n if (process.argv[1]) {\n return resolve(process.argv[1]) === resolve(fileURLToPath(import.meta.url));\n }\n return false;\n } catch {\n return false;\n }\n}\n\nif (isMainModule()) {\n main().catch((error) => {\n console.error(\"[fatal]\", error);\n process.exit(1);\n });\n}\n","import { Elysia } from \"elysia\";\nimport { cors } from \"@elysiajs/cors\";\nimport type { ResolvedConfig } from \"../config/index.js\";\nimport type { StorageOrchestrator } from \"../storage/orchestrator.js\";\nimport { AuthError, MemoryError, NotFoundError, ValidationError } from \"../core/errors.js\";\nimport { memoriesRoutes } from \"./memories.js\";\nimport { searchRoutes } from \"./search.js\";\nimport { conversationRoutes } from \"./conversations.js\";\nimport { entityRoutes } from \"./entities.js\";\nimport { adminRoutes } from \"./admin.js\";\n\n// ── App Router ──────────────────────────────────────────────────────────\n\nexport function createApp(orchestrator: StorageOrchestrator, config: ResolvedConfig) {\n const app = new Elysia()\n .use(cors())\n\n // ── Auth Middleware ────────────────────────────────────────────────\n .derive(({ headers, set, path }) => {\n // Skip auth for health check\n if (path === \"/api/health\" || path === \"/health\") return {};\n\n // Skip auth if disabled\n if (!config.auth.enabled || !config.auth.token) return {};\n\n const authHeader = headers.authorization;\n if (!authHeader || !authHeader.startsWith(\"Bearer \")) {\n set.status = 401;\n throw new AuthError(\"Missing or invalid Authorization header\");\n }\n\n const token = authHeader.slice(7);\n if (token !== config.auth.token) {\n set.status = 403;\n throw new AuthError(\"Invalid token\");\n }\n\n return {};\n })\n\n // ── Error Handler ─────────────────────────────────────────────────\n .onError(({ code, error, set }) => {\n // Handle AuthError\n if (error instanceof AuthError) {\n const status = error.message.includes(\"Invalid token\") ? 403 : 401;\n set.status = status;\n return { error: error.message, code: error.code };\n }\n\n // Handle other custom errors\n if (error instanceof NotFoundError) {\n set.status = 404;\n return { error: error.message, code: error.code };\n }\n\n if (error instanceof ValidationError) {\n set.status = 400;\n return { error: error.message, code: error.code, details: error.details };\n }\n\n if (error instanceof MemoryError) {\n set.status = 500;\n return { error: error.message, code: error.code };\n }\n\n // Elysia validation errors\n if (code === \"VALIDATION\") {\n const msg = error && \"message\" in error ? (error as Error).message : String(error);\n set.status = 400;\n return { error: \"Validation error\", details: msg };\n }\n\n // Elysia built-in not found errors\n if (code === \"NOT_FOUND\") {\n const msg =\n error && \"message\" in error ? (error as Error).message : \"Route not found\";\n set.status = 404;\n return { error: msg, code };\n }\n\n // Unknown errors\n const msg = error instanceof Error ? error.stack || error.message : String(error);\n console.error(`[api] Unhandled error: ${msg}`);\n set.status = 500;\n return { error: \"Internal server error\" };\n })\n\n // ── Mount Routes ──────────────────────────────────────────────────\n .use(memoriesRoutes(orchestrator))\n .use(searchRoutes(orchestrator))\n .use(conversationRoutes(orchestrator, config))\n .use(entityRoutes(orchestrator))\n .use(adminRoutes(orchestrator));\n\n return app;\n}\n","import { Elysia, t } from \"elysia\";\nimport type { StorageOrchestrator } from \"../storage/orchestrator.js\";\nimport type { CreateMemoryRequest, UpdateMemoryRequest, MemoryScope, MemorySource } from \"../core/types.js\";\n\n// ── Memory CRUD Routes ──────────────────────────────────────────────────\n\nexport function memoriesRoutes(orchestrator: StorageOrchestrator) {\n return new Elysia({ prefix: \"/api/memories\" })\n // POST /api/memories — Create a new memory\n .post(\n \"/\",\n async ({ body, set }) => {\n try {\n const result = await orchestrator.createMemory(body as CreateMemoryRequest);\n set.status = 201;\n return result;\n } catch (error) {\n set.status = 500;\n return {\n error: \"Failed to create memory\",\n details: error instanceof Error ? error.message : String(error),\n };\n }\n },\n {\n body: t.Object({\n agent_id: t.String(),\n scope: t.Union([\n t.Literal(\"user\"),\n t.Literal(\"agent\"),\n t.Literal(\"global\"),\n t.Literal(\"project\"),\n t.Literal(\"session\"),\n ]),\n subject_id: t.Optional(t.Nullable(t.String())),\n content: t.String(),\n tags: t.Optional(t.Array(t.String())),\n source: t.Optional(\n t.Union([\n t.Literal(\"explicit\"),\n t.Literal(\"derived\"),\n t.Literal(\"observation\"),\n t.Literal(\"conversation_summary\"),\n t.Literal(\"entity_extraction\"),\n t.Literal(\"daily_digest\"),\n t.Literal(\"migration\"),\n ])\n ),\n created_by: t.Optional(t.Nullable(t.String())),\n extract_entities: t.Optional(t.Boolean()),\n expires_at: t.Optional(t.Nullable(t.String())),\n }),\n }\n )\n\n // GET /api/memories/:id — Get a memory by ID\n .get(\"/:id\", ({ params, set }) => {\n const memory = orchestrator.sqlite.getMemory(params.id);\n if (!memory) {\n set.status = 404;\n return { error: \"Memory not found\" };\n }\n return memory;\n })\n\n // PUT /api/memories/:id — Update a memory\n .put(\n \"/:id\",\n async ({ params, body, set }) => {\n try {\n const result = await orchestrator.updateMemory(\n params.id,\n body as UpdateMemoryRequest\n );\n if (!result) {\n set.status = 404;\n return { error: \"Memory not found\" };\n }\n return result;\n } catch (error) {\n set.status = 500;\n return {\n error: \"Failed to update memory\",\n details: error instanceof Error ? error.message : String(error),\n };\n }\n },\n {\n body: t.Object({\n content: t.Optional(t.String()),\n tags: t.Optional(t.Array(t.String())),\n scope: t.Optional(\n t.Union([\n t.Literal(\"user\"),\n t.Literal(\"agent\"),\n t.Literal(\"global\"),\n t.Literal(\"project\"),\n t.Literal(\"session\"),\n ])\n ),\n subject_id: t.Optional(t.Nullable(t.String())),\n expires_at: t.Optional(t.Nullable(t.String())),\n extract_entities: t.Optional(t.Boolean()),\n }),\n }\n )\n\n // DELETE /api/memories/:id — Delete a memory\n .delete(\"/:id\", async ({ params, set }) => {\n try {\n const deleted = await orchestrator.deleteMemory(params.id);\n if (!deleted) {\n set.status = 404;\n return { error: \"Memory not found\" };\n }\n return { deleted: true, id: params.id };\n } catch (error) {\n set.status = 500;\n return {\n error: \"Failed to delete memory\",\n details: error instanceof Error ? error.message : String(error),\n };\n }\n })\n\n // GET /api/memories — List memories with filters\n .get(\"/\", ({ query }) => {\n const memories = orchestrator.sqlite.listMemories({\n agent_id: query.agent_id as string | undefined,\n scope: query.scope as MemoryScope | undefined,\n subject_id: query.subject_id as string | undefined,\n source: query.source as MemorySource | undefined,\n tags: query.tags as string | undefined,\n limit: query.limit ? parseInt(String(query.limit), 10) : undefined,\n offset: query.offset ? parseInt(String(query.offset), 10) : undefined,\n order: (query.order as \"asc\" | \"desc\") || \"desc\",\n });\n return { memories, count: memories.length };\n });\n}\n","import { Elysia, t } from \"elysia\";\nimport { SearchEngine } from \"../search/engine.js\";\nimport type { StorageOrchestrator } from \"../storage/orchestrator.js\";\nimport type { SearchRequest } from \"../core/types.js\";\n\n// ── Search Routes ───────────────────────────────────────────────────────\n\nexport function searchRoutes(orchestrator: StorageOrchestrator) {\n const searchEngine = new SearchEngine(orchestrator);\n\n return new Elysia({ prefix: \"/api/search\" })\n // POST /api/search — Smart search (auto-selects layers)\n .post(\n \"/\",\n async ({ body, set }) => {\n try {\n const req = body as SearchRequest;\n if (!req.agent_id) req.cross_agent = true;\n return await searchEngine.search(req);\n } catch (error) {\n set.status = 500;\n return {\n error: \"Search failed\",\n details: error instanceof Error ? error.message : String(error),\n };\n }\n },\n {\n body: t.Object({\n agent_id: t.Optional(t.String()),\n query: t.String(),\n scopes: t.Optional(\n t.Array(\n t.Union([\n t.Literal(\"user\"),\n t.Literal(\"agent\"),\n t.Literal(\"global\"),\n t.Literal(\"project\"),\n t.Literal(\"session\"),\n ])\n )\n ),\n subject_id: t.Optional(t.Nullable(t.String())),\n limit: t.Optional(t.Number()),\n include_graph: t.Optional(t.Boolean()),\n cross_agent: t.Optional(t.Boolean()),\n strategy: t.Optional(\n t.Union([\n t.Literal(\"auto\"),\n t.Literal(\"semantic\"),\n t.Literal(\"fulltext\"),\n t.Literal(\"graph\"),\n t.Literal(\"all\"),\n ])\n ),\n }),\n }\n )\n\n // POST /api/search/semantic — Force Qdrant semantic search\n .post(\n \"/semantic\",\n async ({ body, set }) => {\n try {\n return await searchEngine.search({\n ...(body as SearchRequest),\n strategy: \"semantic\",\n });\n } catch (error) {\n set.status = 500;\n return {\n error: \"Semantic search failed\",\n details: error instanceof Error ? error.message : String(error),\n };\n }\n },\n {\n body: t.Object({\n agent_id: t.Optional(t.String()),\n query: t.String(),\n scopes: t.Optional(\n t.Array(\n t.Union([\n t.Literal(\"user\"),\n t.Literal(\"agent\"),\n t.Literal(\"global\"),\n t.Literal(\"project\"),\n t.Literal(\"session\"),\n ])\n )\n ),\n subject_id: t.Optional(t.Nullable(t.String())),\n limit: t.Optional(t.Number()),\n cross_agent: t.Optional(t.Boolean()),\n }),\n }\n )\n\n // POST /api/search/graph — Force AGE graph traversal\n .post(\n \"/graph\",\n async ({ body, set }) => {\n try {\n return await searchEngine.search({\n ...(body as SearchRequest),\n strategy: \"graph\",\n include_graph: true,\n });\n } catch (error) {\n set.status = 500;\n return {\n error: \"Graph search failed\",\n details: error instanceof Error ? error.message : String(error),\n };\n }\n },\n {\n body: t.Object({\n agent_id: t.Optional(t.String()),\n query: t.String(),\n scopes: t.Optional(\n t.Array(\n t.Union([\n t.Literal(\"user\"),\n t.Literal(\"agent\"),\n t.Literal(\"global\"),\n t.Literal(\"project\"),\n t.Literal(\"session\"),\n ])\n )\n ),\n subject_id: t.Optional(t.Nullable(t.String())),\n limit: t.Optional(t.Number()),\n }),\n }\n )\n\n // POST /api/search/fulltext — Force SQLite FTS search\n .post(\n \"/fulltext\",\n async ({ body, set }) => {\n try {\n return await searchEngine.search({\n ...(body as SearchRequest),\n strategy: \"fulltext\",\n include_graph: false,\n });\n } catch (error) {\n set.status = 500;\n return {\n error: \"Fulltext search failed\",\n details: error instanceof Error ? error.message : String(error),\n };\n }\n },\n {\n body: t.Object({\n agent_id: t.Optional(t.String()),\n query: t.String(),\n scopes: t.Optional(t.Array(t.String())),\n subject_id: t.Optional(t.Nullable(t.String())),\n limit: t.Optional(t.Number()),\n }),\n }\n );\n}\n","import { Elysia, t } from \"elysia\";\nimport type { StorageOrchestrator } from \"../storage/orchestrator.js\";\nimport type { ResolvedConfig } from \"../config/index.js\";\nimport { ConversationSummarizer } from \"../extraction/summarizer.js\";\nimport type { ConversationLogEntry, CreateMemoryRequest, SummarizeResponse } from \"../core/types.js\";\n\n// ── Conversation Routes ─────────────────────────────────────────────────\n\nexport function conversationRoutes(\n orchestrator: StorageOrchestrator,\n config: ResolvedConfig\n) {\n // Summarizer is only available if extraction config is present\n const summarizer = config.extraction\n ? new ConversationSummarizer({\n apiKey: config.extraction.apiKey,\n baseUrl: config.extraction.baseUrl,\n model: config.extraction.model,\n })\n : null;\n\n return new Elysia({ prefix: \"/api/conversations\" })\n // POST /api/conversations/log — Append conversation entry\n .post(\n \"/log\",\n ({ body, set }) => {\n try {\n orchestrator.sqlite.appendConversationLog(body as ConversationLogEntry);\n set.status = 201;\n return { ok: true };\n } catch (error) {\n set.status = 500;\n return {\n error: \"Failed to append conversation log\",\n details: error instanceof Error ? error.message : String(error),\n };\n }\n },\n {\n body: t.Object({\n agent_id: t.String(),\n session_id: t.String(),\n user_id: t.String(),\n channel: t.String(),\n role: t.Union([\n t.Literal(\"user\"),\n t.Literal(\"assistant\"),\n t.Literal(\"system\"),\n ]),\n content: t.String(),\n timestamp: t.String(),\n }),\n }\n )\n\n // POST /api/conversations/summarize — Summarize a session\n .post(\n \"/summarize\",\n async ({ body, set }) => {\n if (!summarizer) {\n set.status = 501;\n return { error: \"Summarization not available — extraction config required\" };\n }\n\n try {\n const { agent_id, session_id, user_id, channel, messages } = body;\n\n const summary = await summarizer.summarize(messages);\n if (!summary) {\n set.status = 422;\n return { error: \"Failed to generate summary\" };\n }\n\n const memoryReq: CreateMemoryRequest = {\n agent_id,\n scope: \"session\",\n subject_id: user_id,\n content: summary,\n tags: [\"conversation_summary\", channel, `session:${session_id}`],\n source: \"conversation_summary\",\n created_by: agent_id,\n extract_entities: true,\n };\n\n const result = await orchestrator.createMemory(memoryReq);\n\n const response: SummarizeResponse = {\n memory_id: result.id,\n summary,\n entities_extracted: result.entities,\n relationships_created: 0,\n };\n\n set.status = 201;\n return response;\n } catch (error) {\n set.status = 500;\n return {\n error: \"Summarization failed\",\n details: error instanceof Error ? error.message : String(error),\n };\n }\n },\n {\n body: t.Object({\n agent_id: t.String(),\n session_id: t.String(),\n user_id: t.String(),\n channel: t.String(),\n messages: t.Array(\n t.Object({\n role: t.Union([\n t.Literal(\"user\"),\n t.Literal(\"assistant\"),\n t.Literal(\"system\"),\n ]),\n content: t.String(),\n timestamp: t.String(),\n })\n ),\n reason: t.Optional(t.String()),\n }),\n }\n );\n}\n","import { Elysia, t } from \"elysia\";\nimport type { StorageOrchestrator } from \"../storage/orchestrator.js\";\n\n// ── Entity Routes ───────────────────────────────────────────────────────\n\nexport function entityRoutes(orchestrator: StorageOrchestrator) {\n return new Elysia({ prefix: \"/api/entities\" })\n // GET /api/entities/:type — List entities by type\n .get(\"/:type\", async ({ params, query, set }) => {\n if (!orchestrator.age) {\n set.status = 501;\n return { error: \"Graph layer not available — requires Full tier\" };\n }\n\n try {\n const entities = await orchestrator.age.listEntities(\n params.type,\n query.agent_id as string | undefined,\n query.limit ? parseInt(String(query.limit), 10) : 50\n );\n return { entities, count: entities.length };\n } catch (error) {\n set.status = 500;\n return {\n error: \"Failed to list entities\",\n details: error instanceof Error ? error.message : String(error),\n };\n }\n })\n\n // GET /api/entities/:type/:id — Get entity with relationships\n .get(\"/:type/:id\", async ({ params, set }) => {\n if (!orchestrator.age) {\n set.status = 501;\n return { error: \"Graph layer not available — requires Full tier\" };\n }\n\n try {\n const result = await orchestrator.age.getEntityWithRelationships(\n params.type,\n params.id\n );\n if (!result.entity) {\n set.status = 404;\n return { error: \"Entity not found\" };\n }\n return result;\n } catch (error) {\n set.status = 500;\n return {\n error: \"Failed to get entity\",\n details: error instanceof Error ? error.message : String(error),\n };\n }\n })\n\n // GET /api/entities/:type/:id/related — Get related entities\n .get(\"/:type/:id/related\", async ({ params, query, set }) => {\n if (!orchestrator.age) {\n set.status = 501;\n return { error: \"Graph layer not available — requires Full tier\" };\n }\n\n try {\n const depth = query.depth ? parseInt(String(query.depth), 10) : 2;\n const related = await orchestrator.age.getRelatedEntities(\n params.id,\n depth\n );\n return { related, count: related.length };\n } catch (error) {\n set.status = 500;\n return {\n error: \"Failed to get related entities\",\n details: error instanceof Error ? error.message : String(error),\n };\n }\n })\n\n // POST /api/entities/extract — Manually trigger entity extraction\n .post(\n \"/extract\",\n async ({ body, set }) => {\n if (!orchestrator.entityExtractor) {\n set.status = 501;\n return { error: \"Entity extraction not available — requires extraction config\" };\n }\n\n try {\n const result = await orchestrator.entityExtractor.extract(body.text);\n return result;\n } catch (error) {\n set.status = 500;\n return {\n error: \"Entity extraction failed\",\n details: error instanceof Error ? error.message : String(error),\n };\n }\n },\n {\n body: t.Object({\n text: t.String(),\n }),\n }\n );\n}\n","import { Elysia, t } from \"elysia\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { StorageOrchestrator } from \"../storage/orchestrator.js\";\nimport type { CreateMemoryRequest, MigrateMarkdownRequest } from \"../core/types.js\";\nimport { SyncQueueProcessor } from \"../storage/sync-queue.js\";\n\n// ── Admin Routes ────────────────────────────────────────────────────────\n\nexport function adminRoutes(orchestrator: StorageOrchestrator) {\n const healthHandler = async () => {\n return await orchestrator.healthCheck();\n };\n\n return new Elysia()\n // GET /api/health and /health — Health checks\n .get(\"/api/health\", healthHandler)\n .get(\"/health\", healthHandler)\n\n // POST /api/sync/retry — Retry failed L2/L3 syncs\n .post(\"/api/sync/retry\", async ({ set }) => {\n try {\n const result = await orchestrator.retrySyncQueue();\n return result;\n } catch (error) {\n set.status = 500;\n return {\n error: \"Sync retry failed\",\n details: error instanceof Error ? error.message : String(error),\n };\n }\n })\n\n // POST /api/admin/resync — Requeue all memories for L2/L3 sync\n .post(\n \"/api/admin/resync\",\n async ({ query, set }) => {\n const layerParam = parseLayerParam(query.layer as string | undefined);\n if (!layerParam) {\n set.status = 400;\n return {\n error: \"Invalid layer parameter\",\n details: \"Use ?layer=qdrant|age|both\",\n };\n }\n\n const batch = parseBatchParam(query.batch as string | undefined);\n if (batch === null) {\n set.status = 400;\n return {\n error: \"Invalid batch parameter\",\n details: \"Use a positive integer for ?batch=50\",\n };\n }\n\n const layers: Array<\"qdrant\" | \"age\"> =\n layerParam === \"both\" ? [\"qdrant\", \"age\"] : [layerParam];\n\n try {\n const memories = listAllMemories(orchestrator);\n let queuedItems = 0;\n\n for (const memory of memories) {\n for (const layer of layers) {\n orchestrator.sqlite.addToSyncQueue(memory.id, layer, \"upsert\");\n queuedItems++;\n }\n }\n\n const syncResults = await SyncQueueProcessor.withBatchSize(batch, async () => {\n return await orchestrator.retrySyncQueue();\n });\n\n return {\n layer: layerParam,\n layers,\n batch,\n memory_count: memories.length,\n queued_items: queuedItems,\n sync_results: syncResults,\n };\n } catch (error) {\n set.status = 500;\n return {\n error: \"Resync failed\",\n details: error instanceof Error ? error.message : String(error),\n };\n }\n },\n {\n query: t.Object({\n layer: t.Optional(\n t.Union([t.Literal(\"qdrant\"), t.Literal(\"age\"), t.Literal(\"both\")])\n ),\n batch: t.Optional(t.String()),\n }),\n }\n )\n\n // GET /api/sync/queue — View pending sync queue\n .get(\"/api/sync/queue\", () => {\n const items = orchestrator.sqlite.getSyncQueue(100);\n return { items, count: items.length };\n })\n\n // POST /api/admin/migrate-markdown — Migrate markdown files\n .post(\n \"/api/admin/migrate-markdown\",\n async ({ body, set }) => {\n try {\n const results = await migrateMarkdownFiles(orchestrator, body);\n return results;\n } catch (error) {\n set.status = 500;\n return {\n error: \"Migration failed\",\n details: error instanceof Error ? error.message : String(error),\n };\n }\n },\n {\n body: t.Object({\n markdown_paths: t.Array(t.String()),\n agent_id: t.String(),\n dry_run: t.Optional(t.Boolean()),\n }),\n }\n )\n\n // POST /api/admin/daily-digest — Trigger daily digest\n .post(\"/api/admin/daily-digest\", async ({ set }) => {\n set.status = 501;\n return { error: \"Not yet implemented\" };\n });\n}\n\ntype ResyncLayer = \"qdrant\" | \"age\" | \"both\";\n\nfunction parseLayerParam(layer: string | undefined): ResyncLayer | null {\n if (!layer) return \"both\";\n if (layer === \"qdrant\" || layer === \"age\" || layer === \"both\") return layer;\n return null;\n}\n\nfunction parseBatchParam(batch: string | undefined): number | null {\n if (!batch) return 50;\n const parsed = Number.parseInt(batch, 10);\n if (!Number.isFinite(parsed) || parsed <= 0) return null;\n return parsed;\n}\n\nfunction listAllMemories(orchestrator: StorageOrchestrator) {\n const pageSize = 5_000;\n const memories: ReturnType<typeof orchestrator.sqlite.listMemories> = [];\n let offset = 0;\n\n while (true) {\n const page = orchestrator.sqlite.listMemories({\n limit: pageSize,\n offset,\n order: \"asc\",\n });\n\n memories.push(...page);\n if (page.length < pageSize) break;\n offset += pageSize;\n }\n\n return memories;\n}\n\n// ── Markdown Migration ──────────────────────────────────────────────────\n\nasync function migrateMarkdownFiles(\n orchestrator: StorageOrchestrator,\n request: MigrateMarkdownRequest\n): Promise<{\n migrated: number;\n skipped: number;\n errors: string[];\n memories: Array<{ id: string; content_preview: string }>;\n}> {\n const { markdown_paths, agent_id, dry_run } = request;\n let migrated = 0;\n let skipped = 0;\n const errors: string[] = [];\n const memories: Array<{ id: string; content_preview: string }> = [];\n\n for (const filePath of markdown_paths) {\n try {\n if (!fs.existsSync(filePath)) {\n errors.push(`File not found: ${filePath}`);\n skipped++;\n continue;\n }\n\n const content = fs.readFileSync(filePath, \"utf-8\");\n const fileName = path.basename(filePath, \".md\");\n const sections = parseMarkdownSections(content);\n\n for (const section of sections) {\n if (section.content.trim().length < 10) {\n skipped++;\n continue;\n }\n\n if (dry_run) {\n memories.push({\n id: \"(dry-run)\",\n content_preview: section.content.slice(0, 100),\n });\n migrated++;\n continue;\n }\n\n const scope = inferScope(section.heading, fileName);\n const source = inferSource(fileName);\n const tags = inferTags(section.heading, fileName);\n\n const req: CreateMemoryRequest = {\n agent_id,\n scope,\n subject_id: null,\n content: section.content.trim(),\n tags,\n source: source || \"migration\",\n created_by: \"migration\",\n extract_entities: true,\n };\n\n try {\n const result = await orchestrator.createMemory(req);\n memories.push({\n id: result.id,\n content_preview: section.content.slice(0, 100),\n });\n migrated++;\n } catch (error) {\n errors.push(\n `Failed to migrate section \"${section.heading}\": ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n } catch (error) {\n errors.push(\n `Failed to process ${filePath}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n return { migrated, skipped, errors, memories };\n}\n\n// ── Markdown Parsing Helpers ────────────────────────────────────────────\n\ninterface MarkdownSection {\n heading: string;\n content: string;\n level: number;\n}\n\nfunction parseMarkdownSections(markdown: string): MarkdownSection[] {\n const lines = markdown.split(\"\\n\");\n const sections: MarkdownSection[] = [];\n let currentHeading = \"root\";\n let currentLevel = 0;\n let currentContent: string[] = [];\n\n for (const line of lines) {\n const headingMatch = line.match(/^(#{1,3})\\s+(.+)/);\n if (headingMatch) {\n if (currentContent.length > 0) {\n sections.push({\n heading: currentHeading,\n content: currentContent.join(\"\\n\").trim(),\n level: currentLevel,\n });\n }\n currentHeading = headingMatch[2].trim();\n currentLevel = headingMatch[1].length;\n currentContent = [];\n } else {\n currentContent.push(line);\n }\n }\n\n if (currentContent.length > 0) {\n sections.push({\n heading: currentHeading,\n content: currentContent.join(\"\\n\").trim(),\n level: currentLevel,\n });\n }\n\n return sections;\n}\n\nfunction inferScope(heading: string, fileName: string): CreateMemoryRequest[\"scope\"] {\n const h = heading.toLowerCase();\n const f = fileName.toLowerCase();\n\n if (h.includes(\"about\") || h.includes(\"personal\")) return \"user\";\n if (h.includes(\"project\")) return \"project\";\n if (h.includes(\"agent\")) return \"agent\";\n if (h.includes(\"session\") || f.match(/^\\d{4}-\\d{2}-\\d{2}/)) return \"session\";\n return \"global\";\n}\n\nfunction inferSource(fileName: string): CreateMemoryRequest[\"source\"] | null {\n if (fileName.match(/^\\d{4}-\\d{2}-\\d{2}/)) return \"daily_digest\";\n return \"migration\";\n}\n\nfunction inferTags(heading: string, fileName: string): string[] {\n const tags: string[] = [\"migration\"];\n if (fileName.match(/^\\d{4}-\\d{2}-\\d{2}/)) {\n tags.push(\"daily\", fileName);\n }\n if (heading !== \"root\") {\n tags.push(heading.toLowerCase().replace(/[^a-z0-9]+/g, \"-\"));\n }\n return tags;\n}\n"]}
@@ -4,7 +4,7 @@
4
4
 
5
5
 
6
6
 
7
- var _chunkZY2C2CJQcjs = require('../chunk-ZY2C2CJQ.cjs');
7
+ var _chunkLA5OP5VIcjs = require('../chunk-LA5OP5VI.cjs');
8
8
 
9
9
  // src/cli/index.ts
10
10
  var _commander = require('commander');
@@ -39,7 +39,7 @@ function bullet(label, value, status) {
39
39
  console.log(` ${dot} ${_picocolors2.default.bold(label)} ${value}`);
40
40
  }
41
41
  function getServerPid() {
42
- const pidPath = _chunkZY2C2CJQcjs.getPidFilePath.call(void 0, );
42
+ const pidPath = _chunkLA5OP5VIcjs.getPidFilePath.call(void 0, );
43
43
  if (!_fs2.default.existsSync(pidPath)) return null;
44
44
  try {
45
45
  const pid = parseInt(_fs2.default.readFileSync(pidPath, "utf-8").trim(), 10);
@@ -113,8 +113,8 @@ function initCommand() {
113
113
  return new (0, _commander.Command)("init").description("Interactive setup wizard").option("--tier <tier>", "Tier: lite, standard, or full").option("--non-interactive", "Skip prompts, use defaults + flags").action(async (opts) => {
114
114
  header("Setup Wizard");
115
115
  const tier = opts.tier || "lite";
116
- const dataDir = _chunkZY2C2CJQcjs.getDataDir.call(void 0, );
117
- const sqlitePath = _chunkZY2C2CJQcjs.getDefaultSqlitePath.call(void 0, );
116
+ const dataDir = _chunkLA5OP5VIcjs.getDataDir.call(void 0, );
117
+ const sqlitePath = _chunkLA5OP5VIcjs.getDefaultSqlitePath.call(void 0, );
118
118
  _fs2.default.mkdirSync(dataDir, { recursive: true });
119
119
  info(`Data directory: ${dataDir}`);
120
120
  let qdrantAvailable = false;
@@ -184,7 +184,7 @@ function initCommand() {
184
184
  }
185
185
  function generateConfig(tier, sqlitePath) {
186
186
  const lines = [
187
- `import { defineConfig } from 'openclaw-memory';`,
187
+ `import { defineConfig } from '@poprobertdaniel/openclaw-memory';`,
188
188
  ``,
189
189
  `export default defineConfig({`,
190
190
  ` tier: '${tier}',`,
@@ -208,7 +208,7 @@ function generateConfig(tier, sqlitePath) {
208
208
  lines.push(` },`);
209
209
  lines.push(` extraction: {`);
210
210
  lines.push(` apiKey: process.env.OPENAI_API_KEY || '',`);
211
- lines.push(` model: 'gpt-4o-mini',`);
211
+ lines.push(` model: 'gpt-5-nano',`);
212
212
  lines.push(` enabled: true,`);
213
213
  lines.push(` },`);
214
214
  }
@@ -251,7 +251,7 @@ function generateEnvExample(tier) {
251
251
  lines.push(`# EMBEDDING_BASE_URL=https://api.openai.com/v1`);
252
252
  lines.push(``);
253
253
  lines.push(`# Entity extraction`);
254
- lines.push(`# EXTRACTION_MODEL=gpt-4o-mini`);
254
+ lines.push(`# EXTRACTION_MODEL=gpt-5-nano`);
255
255
  lines.push(``);
256
256
  }
257
257
  if (tier === "full") {
@@ -290,12 +290,12 @@ async function startForeground(opts) {
290
290
  const port = opts.port ? parseInt(opts.port, 10) : config.port;
291
291
  app.listen(port);
292
292
  console.log(`[server] Listening on http://0.0.0.0:${port}`);
293
- const dataDir = _chunkZY2C2CJQcjs.getDataDir.call(void 0, );
293
+ const dataDir = _chunkLA5OP5VIcjs.getDataDir.call(void 0, );
294
294
  _fs2.default.mkdirSync(dataDir, { recursive: true });
295
- _fs2.default.writeFileSync(_chunkZY2C2CJQcjs.getPidFilePath.call(void 0, ), String(process.pid), "utf-8");
295
+ _fs2.default.writeFileSync(_chunkLA5OP5VIcjs.getPidFilePath.call(void 0, ), String(process.pid), "utf-8");
296
296
  const cleanup = () => {
297
297
  try {
298
- _fs2.default.unlinkSync(_chunkZY2C2CJQcjs.getPidFilePath.call(void 0, ));
298
+ _fs2.default.unlinkSync(_chunkLA5OP5VIcjs.getPidFilePath.call(void 0, ));
299
299
  } catch (e6) {
300
300
  }
301
301
  process.exit(0);
@@ -305,7 +305,7 @@ async function startForeground(opts) {
305
305
  }
306
306
  async function startBackground(opts) {
307
307
  header("Starting Server (background)");
308
- const dataDir = _chunkZY2C2CJQcjs.getDataDir.call(void 0, );
308
+ const dataDir = _chunkLA5OP5VIcjs.getDataDir.call(void 0, );
309
309
  _fs2.default.mkdirSync(dataDir, { recursive: true });
310
310
  const args = ["run", "src/server.ts"];
311
311
  const env = { ...process.env };
@@ -324,9 +324,9 @@ async function startBackground(opts) {
324
324
  });
325
325
  child.unref();
326
326
  if (child.pid) {
327
- _fs2.default.writeFileSync(_chunkZY2C2CJQcjs.getPidFilePath.call(void 0, ), String(child.pid), "utf-8");
327
+ _fs2.default.writeFileSync(_chunkLA5OP5VIcjs.getPidFilePath.call(void 0, ), String(child.pid), "utf-8");
328
328
  success(`Server started in background (PID: ${child.pid})`);
329
- info(`PID file: ${_chunkZY2C2CJQcjs.getPidFilePath.call(void 0, )}`);
329
+ info(`PID file: ${_chunkLA5OP5VIcjs.getPidFilePath.call(void 0, )}`);
330
330
  info(`Stop with: openclaw-memory stop`);
331
331
  } else {
332
332
  error("Failed to start server");
@@ -340,7 +340,7 @@ async function startBackground(opts) {
340
340
  function stopCommand() {
341
341
  return new (0, _commander.Command)("stop").description("Stop the running server").action(async () => {
342
342
  header("Stopping Server");
343
- const pidPath = _chunkZY2C2CJQcjs.getPidFilePath.call(void 0, );
343
+ const pidPath = _chunkLA5OP5VIcjs.getPidFilePath.call(void 0, );
344
344
  if (!_fs2.default.existsSync(pidPath)) {
345
345
  warn("No PID file found \u2014 server may not be running");
346
346
  return;
@@ -393,7 +393,7 @@ function statusCommand() {
393
393
  header("Status");
394
394
  let config;
395
395
  try {
396
- config = await _chunkZY2C2CJQcjs.loadConfig.call(void 0, opts.config);
396
+ config = await _chunkLA5OP5VIcjs.loadConfig.call(void 0, opts.config);
397
397
  } catch (e10) {
398
398
  config = null;
399
399
  }
@@ -503,7 +503,7 @@ function storeCommand() {
503
503
  console.error("Error: content is required (pass as argument or pipe via stdin)");
504
504
  process.exit(1);
505
505
  }
506
- const config = await _chunkZY2C2CJQcjs.loadConfig.call(void 0, opts.config);
506
+ const config = await _chunkLA5OP5VIcjs.loadConfig.call(void 0, opts.config);
507
507
  const baseUrl = getBaseUrl(config.port);
508
508
  const serverUp = await isServerRunning(baseUrl);
509
509
  const body = {
@@ -519,7 +519,7 @@ function storeCommand() {
519
519
  const result = await apiPost(baseUrl, "/api/memories", body, config.auth.token);
520
520
  output(result, opts.format);
521
521
  } else {
522
- const { MemoryService } = await Promise.resolve().then(() => _interopRequireWildcard(require("../memory-service-6WDMF6KX.cjs")));
522
+ const { MemoryService } = await Promise.resolve().then(() => _interopRequireWildcard(require("../memory-service-B2BAEKR2.cjs")));
523
523
  const service = new MemoryService();
524
524
  await service.init();
525
525
  try {
@@ -545,7 +545,7 @@ function storeCommand() {
545
545
  function searchCommand() {
546
546
  const cmd = new (0, _commander.Command)("search").description("Search memories");
547
547
  cmd.argument("<query>", "Search query").requiredOption("--agent <id>", "Agent ID").option("--limit <n>", "Max results", "10").option("--strategy <s>", "Search strategy (auto, semantic, fulltext, graph, all)", "auto").option("--scopes <scopes>", "Comma-separated scopes").option("--subject <id>", "Subject ID filter").option("--cross-agent", "Search across all agents").option("--no-graph", "Exclude graph results").option("--recall", "Format output for LLM context injection").option("--format <fmt>", "Output format (json, text)", "json").option("--config <path>", "Path to config file").action(async (query, opts) => {
548
- const config = await _chunkZY2C2CJQcjs.loadConfig.call(void 0, opts.config);
548
+ const config = await _chunkLA5OP5VIcjs.loadConfig.call(void 0, opts.config);
549
549
  const baseUrl = getBaseUrl(config.port);
550
550
  const serverUp = await isServerRunning(baseUrl);
551
551
  const body = {
@@ -562,7 +562,7 @@ function searchCommand() {
562
562
  if (serverUp) {
563
563
  result = await apiPost(baseUrl, "/api/search", body, config.auth.token);
564
564
  } else {
565
- const { MemoryService } = await Promise.resolve().then(() => _interopRequireWildcard(require("../memory-service-6WDMF6KX.cjs")));
565
+ const { MemoryService } = await Promise.resolve().then(() => _interopRequireWildcard(require("../memory-service-B2BAEKR2.cjs")));
566
566
  const service = new MemoryService();
567
567
  await service.init();
568
568
  try {
@@ -602,7 +602,7 @@ function searchCommand() {
602
602
 
603
603
  function migrateCommand() {
604
604
  return new (0, _commander.Command)("migrate").description("Import memories from markdown files").requiredOption("--paths <paths>", "Comma-separated file paths").requiredOption("--agent <id>", "Agent ID").option("--dry-run", "Preview without writing").option("--format <fmt>", "Output format (json, text)", "json").option("--config <path>", "Path to config file").action(async (opts) => {
605
- const config = await _chunkZY2C2CJQcjs.loadConfig.call(void 0, opts.config);
605
+ const config = await _chunkLA5OP5VIcjs.loadConfig.call(void 0, opts.config);
606
606
  const baseUrl = getBaseUrl(config.port);
607
607
  const serverUp = await isServerRunning(baseUrl);
608
608
  const paths = opts.paths.split(",").map((p) => p.trim());
@@ -618,7 +618,7 @@ function migrateCommand() {
618
618
  if (serverUp) {
619
619
  result = await apiPost(baseUrl, "/api/admin/migrate-markdown", body, config.auth.token);
620
620
  } else {
621
- const { MemoryService } = await Promise.resolve().then(() => _interopRequireWildcard(require("../memory-service-6WDMF6KX.cjs")));
621
+ const { MemoryService } = await Promise.resolve().then(() => _interopRequireWildcard(require("../memory-service-B2BAEKR2.cjs")));
622
622
  const service = new MemoryService();
623
623
  await service.init();
624
624
  try {
@@ -662,7 +662,7 @@ function infraCommand() {
662
662
  let tier = opts.tier;
663
663
  if (!tier) {
664
664
  try {
665
- const config = await _chunkZY2C2CJQcjs.loadConfig.call(void 0, );
665
+ const config = await _chunkLA5OP5VIcjs.loadConfig.call(void 0, );
666
666
  tier = config.tier;
667
667
  } catch (e13) {
668
668
  tier = "standard";
@@ -679,7 +679,7 @@ function infraCommand() {
679
679
  error("Expected in ./docker/ or ./templates/ directory");
680
680
  process.exit(1);
681
681
  }
682
- const dataDir = _chunkZY2C2CJQcjs.getDataDir.call(void 0, );
682
+ const dataDir = _chunkLA5OP5VIcjs.getDataDir.call(void 0, );
683
683
  _fs2.default.mkdirSync(dataDir, { recursive: true });
684
684
  const targetPath = _path2.default.join(dataDir, "docker-compose.yml");
685
685
  _fs2.default.copyFileSync(templatePath, targetPath);
@@ -698,7 +698,7 @@ function infraCommand() {
698
698
  });
699
699
  infra.command("down").description("Stop Docker containers").action(async () => {
700
700
  header("Infrastructure Down");
701
- const dataDir = _chunkZY2C2CJQcjs.getDataDir.call(void 0, );
701
+ const dataDir = _chunkLA5OP5VIcjs.getDataDir.call(void 0, );
702
702
  const composePath = _path2.default.join(dataDir, "docker-compose.yml");
703
703
  if (!_fs2.default.existsSync(composePath)) {
704
704
  warn("No docker-compose.yml found in data directory");
@@ -717,7 +717,7 @@ function infraCommand() {
717
717
  });
718
718
  infra.command("status").description("Show Docker container status").action(async () => {
719
719
  header("Infrastructure Status");
720
- const dataDir = _chunkZY2C2CJQcjs.getDataDir.call(void 0, );
720
+ const dataDir = _chunkLA5OP5VIcjs.getDataDir.call(void 0, );
721
721
  const composePath = _path2.default.join(dataDir, "docker-compose.yml");
722
722
  if (!_fs2.default.existsSync(composePath)) {
723
723
  info("No docker-compose.yml found \u2014 infrastructure not set up");