@poprobertdaniel/openclaw-memory 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -10
- package/dist/{chunk-NHFPLDZK.js → chunk-5SZWJKD5.js} +3 -3
- package/dist/{chunk-CRPEAZ44.cjs → chunk-HPGHPKK3.cjs} +3 -2
- package/dist/chunk-HPGHPKK3.cjs.map +1 -0
- package/dist/{chunk-JNWCMHOB.js → chunk-ITGUJZUL.js} +2 -2
- package/dist/{chunk-JNWCMHOB.js.map → chunk-ITGUJZUL.js.map} +1 -1
- package/dist/{chunk-VXULEX3A.cjs → chunk-L2KRIMDA.cjs} +9 -9
- package/dist/{chunk-VXULEX3A.cjs.map → chunk-L2KRIMDA.cjs.map} +1 -1
- package/dist/{chunk-ZY2C2CJQ.cjs → chunk-LA5OP5VI.cjs} +2 -2
- package/dist/{chunk-ZY2C2CJQ.cjs.map → chunk-LA5OP5VI.cjs.map} +1 -1
- package/dist/{chunk-NMUPGLJW.cjs → chunk-MQEBVCH5.cjs} +25 -19
- package/dist/chunk-MQEBVCH5.cjs.map +1 -0
- package/dist/{chunk-JSQBXYDM.js → chunk-RZPYOMPO.js} +3 -2
- package/dist/chunk-RZPYOMPO.js.map +1 -0
- package/dist/{chunk-RFLG2CCR.js → chunk-VB5GGBGB.js} +14 -8
- package/dist/chunk-VB5GGBGB.js.map +1 -0
- package/dist/cli/index.cjs +25 -25
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +7 -7
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +5 -5
- package/dist/index.d.cts +14 -2
- package/dist/index.d.ts +14 -2
- package/dist/index.js +4 -4
- package/dist/memory-service-4ZPYUN4L.js +9 -0
- package/dist/memory-service-LURM3FBB.cjs +9 -0
- package/dist/{memory-service-6WDMF6KX.cjs.map → memory-service-LURM3FBB.cjs.map} +1 -1
- package/dist/{server-BTbRv-yX.d.ts → server-D-3OqU-T.d.cts} +12 -0
- package/dist/{server-BTbRv-yX.d.cts → server-D-3OqU-T.d.ts} +12 -0
- package/dist/server.cjs +4 -4
- package/dist/server.d.cts +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +3 -3
- package/package.json +2 -2
- package/templates/.env.example +1 -1
- package/templates/openclaw-memory.config.ts +2 -2
- package/dist/chunk-CRPEAZ44.cjs.map +0 -1
- package/dist/chunk-JSQBXYDM.js.map +0 -1
- package/dist/chunk-NMUPGLJW.cjs.map +0 -1
- package/dist/chunk-RFLG2CCR.js.map +0 -1
- package/dist/memory-service-6WDMF6KX.cjs +0 -9
- package/dist/memory-service-GKEG6J2D.js +0 -9
- /package/dist/{chunk-NHFPLDZK.js.map → chunk-5SZWJKD5.js.map} +0 -0
- /package/dist/{memory-service-GKEG6J2D.js.map → memory-service-4ZPYUN4L.js.map} +0 -0
package/dist/cli/index.cjs
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
var
|
|
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 =
|
|
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 =
|
|
117
|
-
const sqlitePath =
|
|
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-
|
|
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-
|
|
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 =
|
|
293
|
+
const dataDir = _chunkLA5OP5VIcjs.getDataDir.call(void 0, );
|
|
294
294
|
_fs2.default.mkdirSync(dataDir, { recursive: true });
|
|
295
|
-
_fs2.default.writeFileSync(
|
|
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(
|
|
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 =
|
|
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(
|
|
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: ${
|
|
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 =
|
|
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
|
|
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
|
|
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-
|
|
522
|
+
const { MemoryService } = await Promise.resolve().then(() => _interopRequireWildcard(require("../memory-service-LURM3FBB.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
|
|
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-
|
|
565
|
+
const { MemoryService } = await Promise.resolve().then(() => _interopRequireWildcard(require("../memory-service-LURM3FBB.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
|
|
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-
|
|
621
|
+
const { MemoryService } = await Promise.resolve().then(() => _interopRequireWildcard(require("../memory-service-LURM3FBB.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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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");
|
package/dist/cli/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/robertpop/work/personal/openclaw-memory/dist/cli/index.cjs","../../src/cli/index.ts","../../src/cli/commands/init.ts","../../src/cli/utils.ts","../../src/cli/commands/start.ts","../../src/cli/commands/stop.ts","../../src/cli/commands/status.ts","../../src/cli/commands/store.ts","../../src/cli/commands/search.ts","../../src/cli/commands/migrate.ts","../../src/cli/commands/infra.ts"],"names":[],"mappings":"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","file":"/Users/robertpop/work/personal/openclaw-memory/dist/cli/index.cjs","sourcesContent":[null,"#!/usr/bin/env node\n\nimport { Command } from \"commander\";\nimport { initCommand } from \"./commands/init.js\";\nimport { startCommand } from \"./commands/start.js\";\nimport { stopCommand } from \"./commands/stop.js\";\nimport { statusCommand } from \"./commands/status.js\";\nimport { storeCommand } from \"./commands/store.js\";\nimport { searchCommand } from \"./commands/search.js\";\nimport { migrateCommand } from \"./commands/migrate.js\";\nimport { infraCommand } from \"./commands/infra.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"openclaw-memory\")\n .description(\"Triple-layer memory system for AI agents — SQLite + Qdrant + Postgres/AGE\")\n .version(\"0.1.0\");\n\n// Register commands\nprogram.addCommand(initCommand());\nprogram.addCommand(startCommand());\nprogram.addCommand(stopCommand());\nprogram.addCommand(statusCommand());\nprogram.addCommand(storeCommand());\nprogram.addCommand(searchCommand());\nprogram.addCommand(migrateCommand());\nprogram.addCommand(infraCommand());\n\nprogram.parse();\n","import { Command } from \"commander\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { header, success, info, warn, error as logError } from \"../utils.js\";\nimport { getDataDir, getDefaultSqlitePath } from \"../../config/index.js\";\n\nexport function initCommand(): Command {\n return new Command(\"init\")\n .description(\"Interactive setup wizard\")\n .option(\"--tier <tier>\", \"Tier: lite, standard, or full\")\n .option(\"--non-interactive\", \"Skip prompts, use defaults + flags\")\n .action(async (opts) => {\n header(\"Setup Wizard\");\n\n // For non-interactive mode, generate config from flags/defaults\n const tier = opts.tier || \"lite\";\n const dataDir = getDataDir();\n const sqlitePath = getDefaultSqlitePath();\n\n // Ensure data directory exists\n fs.mkdirSync(dataDir, { recursive: true });\n info(`Data directory: ${dataDir}`);\n\n // Auto-detect available services\n let qdrantAvailable = false;\n let ageAvailable = false;\n\n if (tier !== \"lite\") {\n info(\"Checking Qdrant connectivity...\");\n try {\n const res = await fetch(\"http://localhost:6333/collections\", {\n signal: AbortSignal.timeout(2000),\n });\n qdrantAvailable = res.ok;\n } catch { /* not available */ }\n\n if (qdrantAvailable) {\n success(\"Qdrant is reachable at http://localhost:6333\");\n } else {\n warn(\"Qdrant not reachable at http://localhost:6333\");\n }\n }\n\n if (tier === \"full\") {\n info(\"Checking PostgreSQL/AGE connectivity...\");\n try {\n // Simple TCP check\n const net = await import(\"node:net\");\n ageAvailable = await new Promise<boolean>((resolve) => {\n const socket = new net.Socket();\n socket.setTimeout(2000);\n socket.connect(5432, \"localhost\", () => {\n socket.destroy();\n resolve(true);\n });\n socket.on(\"error\", () => resolve(false));\n socket.on(\"timeout\", () => { socket.destroy(); resolve(false); });\n });\n } catch { /* not available */ }\n\n if (ageAvailable) {\n success(\"PostgreSQL is reachable at localhost:5432\");\n } else {\n warn(\"PostgreSQL not reachable at localhost:5432\");\n }\n }\n\n // Determine effective tier\n let effectiveTier = tier;\n if (tier === \"full\" && !ageAvailable) {\n effectiveTier = qdrantAvailable ? \"standard\" : \"lite\";\n warn(`Downgrading to ${effectiveTier} tier (missing dependencies)`);\n } else if (tier === \"standard\" && !qdrantAvailable) {\n effectiveTier = \"lite\";\n warn(\"Downgrading to lite tier (Qdrant not available)\");\n }\n\n // Generate config file\n const configContent = generateConfig(effectiveTier, sqlitePath);\n const configPath = path.join(process.cwd(), \"openclaw-memory.config.ts\");\n\n fs.writeFileSync(configPath, configContent, \"utf-8\");\n success(`Config written to ${configPath}`);\n\n // Generate .env.example\n const envExample = generateEnvExample(effectiveTier);\n const envPath = path.join(process.cwd(), \".env.example\");\n fs.writeFileSync(envPath, envExample, \"utf-8\");\n success(`Environment template written to ${envPath}`);\n\n console.log();\n info(\"Next steps:\");\n console.log(\" openclaw-memory start # Start the server\");\n console.log(\" openclaw-memory status # Check all layers\");\n console.log();\n });\n}\n\nfunction generateConfig(tier: string, sqlitePath: string): string {\n const lines = [\n `import { defineConfig } from 'openclaw-memory';`,\n ``,\n `export default defineConfig({`,\n ` tier: '${tier}',`,\n ` port: 7777,`,\n ` auth: {`,\n ` token: process.env.MEMORY_AUTH_TOKEN || 'change-me',`,\n ` },`,\n ` sqlite: {`,\n ` path: '${sqlitePath}',`,\n ` },`,\n ];\n\n if (tier === \"standard\" || tier === \"full\") {\n lines.push(` qdrant: {`);\n lines.push(` url: process.env.QDRANT_URL || 'http://localhost:6333',`);\n lines.push(` collection: 'openclaw_memories',`);\n lines.push(` },`);\n lines.push(` embedding: {`);\n lines.push(` apiKey: process.env.OPENAI_API_KEY || '',`);\n lines.push(` model: 'text-embedding-3-small',`);\n lines.push(` dimensions: 1536,`);\n lines.push(` },`);\n lines.push(` extraction: {`);\n lines.push(` apiKey: process.env.OPENAI_API_KEY || '',`);\n lines.push(` model: 'gpt-4o-mini',`);\n lines.push(` enabled: true,`);\n lines.push(` },`);\n }\n\n if (tier === \"full\") {\n lines.push(` age: {`);\n lines.push(` host: process.env.PGHOST || 'localhost',`);\n lines.push(` port: parseInt(process.env.PGPORT || '5432', 10),`);\n lines.push(` user: process.env.PGUSER || 'openclaw',`);\n lines.push(` password: process.env.PGPASSWORD || '',`);\n lines.push(` database: process.env.PGDATABASE || 'agent_memory',`);\n lines.push(` graph: 'agent_memory',`);\n lines.push(` },`);\n }\n\n lines.push(`});`);\n lines.push(``);\n\n return lines.join(\"\\n\");\n}\n\nfunction generateEnvExample(tier: string): string {\n const lines = [\n `# openclaw-memory environment variables`,\n ``,\n `# Server`,\n `# OPENCLAW_MEMORY_PORT=7777`,\n `# OPENCLAW_MEMORY_HOST=0.0.0.0`,\n ``,\n `# Authentication`,\n `MEMORY_AUTH_TOKEN=change-me-to-a-secure-token`,\n ``,\n `# SQLite (always required)`,\n `# SQLITE_PATH=~/.openclaw-memory/memory.sqlite`,\n ``,\n ];\n\n if (tier === \"standard\" || tier === \"full\") {\n lines.push(`# Qdrant (Standard/Full tier)`);\n lines.push(`QDRANT_URL=http://localhost:6333`);\n lines.push(``);\n lines.push(`# Embedding provider`);\n lines.push(`OPENAI_API_KEY=sk-your-key-here`);\n lines.push(`# EMBEDDING_MODEL=text-embedding-3-small`);\n lines.push(`# EMBEDDING_BASE_URL=https://api.openai.com/v1`);\n lines.push(``);\n lines.push(`# Entity extraction`);\n lines.push(`# EXTRACTION_MODEL=gpt-4o-mini`);\n lines.push(``);\n }\n\n if (tier === \"full\") {\n lines.push(`# PostgreSQL + Apache AGE (Full tier)`);\n lines.push(`PGHOST=localhost`);\n lines.push(`PGPORT=5432`);\n lines.push(`PGUSER=openclaw`);\n lines.push(`PGPASSWORD=your-password`);\n lines.push(`PGDATABASE=agent_memory`);\n lines.push(`# AGE_GRAPH=agent_memory`);\n lines.push(``);\n }\n\n return lines.join(\"\\n\");\n}\n","import pc from \"picocolors\";\nimport fs from \"node:fs\";\nimport { getPidFilePath } from \"../config/index.js\";\n\n// ── CLI Utilities ───────────────────────────────────────────────────────\n\nexport function log(msg: string): void {\n console.log(msg);\n}\n\nexport function info(msg: string): void {\n console.log(pc.blue(\"ℹ\") + \" \" + msg);\n}\n\nexport function success(msg: string): void {\n console.log(pc.green(\"✓\") + \" \" + msg);\n}\n\nexport function warn(msg: string): void {\n console.log(pc.yellow(\"⚠\") + \" \" + msg);\n}\n\nexport function error(msg: string): void {\n console.error(pc.red(\"✗\") + \" \" + msg);\n}\n\nexport function header(title: string): void {\n console.log();\n console.log(pc.bold(` 🧠 OpenClaw Memory — ${title}`));\n console.log();\n}\n\nexport function bullet(label: string, value: string, status?: \"ok\" | \"error\" | \"disabled\" | \"degraded\"): void {\n const dot = status === \"ok\" ? pc.green(\"●\")\n : status === \"error\" ? pc.red(\"●\")\n : status === \"degraded\" ? pc.yellow(\"●\")\n : status === \"disabled\" ? pc.dim(\"○\")\n : \" \";\n console.log(` ${dot} ${pc.bold(label)} ${value}`);\n}\n\n// ── Server Detection ────────────────────────────────────────────────────\n\nexport function getServerPid(): number | null {\n const pidPath = getPidFilePath();\n if (!fs.existsSync(pidPath)) return null;\n\n try {\n const pid = parseInt(fs.readFileSync(pidPath, \"utf-8\").trim(), 10);\n if (isNaN(pid)) return null;\n\n // Check if process is alive\n try {\n process.kill(pid, 0);\n return pid;\n } catch {\n // Process not running, clean up stale PID file\n fs.unlinkSync(pidPath);\n return null;\n }\n } catch {\n return null;\n }\n}\n\nexport async function isServerRunning(baseUrl: string = \"http://localhost:7777\"): Promise<boolean> {\n try {\n const res = await fetch(`${baseUrl}/api/health`, {\n signal: AbortSignal.timeout(2000),\n });\n return res.ok;\n } catch {\n return false;\n }\n}\n\nexport function getBaseUrl(port?: number): string {\n return `http://localhost:${port || 7777}`;\n}\n\n// ── HTTP Client ─────────────────────────────────────────────────────────\n\nexport async function apiGet(baseUrl: string, path: string, token?: string): Promise<unknown> {\n const headers: Record<string, string> = {};\n if (token) headers.Authorization = `Bearer ${token}`;\n\n const res = await fetch(`${baseUrl}${path}`, { headers });\n if (!res.ok) {\n const text = await res.text();\n throw new Error(`HTTP ${res.status}: ${text}`);\n }\n return res.json();\n}\n\nexport async function apiPost(baseUrl: string, path: string, body: unknown, token?: string): Promise<unknown> {\n const headers: Record<string, string> = { \"Content-Type\": \"application/json\" };\n if (token) headers.Authorization = `Bearer ${token}`;\n\n const res = await fetch(`${baseUrl}${path}`, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n });\n if (!res.ok) {\n const text = await res.text();\n throw new Error(`HTTP ${res.status}: ${text}`);\n }\n return res.json();\n}\n\nexport async function apiDelete(baseUrl: string, path: string, token?: string): Promise<unknown> {\n const headers: Record<string, string> = {};\n if (token) headers.Authorization = `Bearer ${token}`;\n\n const res = await fetch(`${baseUrl}${path}`, {\n method: \"DELETE\",\n headers,\n });\n if (!res.ok) {\n const text = await res.text();\n throw new Error(`HTTP ${res.status}: ${text}`);\n }\n return res.json();\n}\n\n// ── Output Formatting ───────────────────────────────────────────────────\n\nexport function output(data: unknown, format: \"json\" | \"text\" = \"json\"): void {\n if (format === \"text\") {\n console.log(JSON.stringify(data, null, 2));\n } else {\n console.log(JSON.stringify(data));\n }\n}\n\n// ── Stdin Reading ───────────────────────────────────────────────────────\n\nexport async function readStdin(): Promise<string> {\n if (process.stdin.isTTY) return \"\";\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(Buffer.from(chunk));\n }\n return Buffer.concat(chunks).toString(\"utf-8\").trim();\n}\n","import { Command } from \"commander\";\nimport fs from \"node:fs\";\nimport { spawn } from \"node:child_process\";\nimport { header, success, info, error as logError } from \"../utils.js\";\nimport { getPidFilePath, getDataDir } from \"../../config/index.js\";\n\nexport function startCommand(): Command {\n return new Command(\"start\")\n .description(\"Start the HTTP server\")\n .option(\"-p, --port <port>\", \"Server port\")\n .option(\"--bg\", \"Run in background (daemon mode)\")\n .option(\"--config <path>\", \"Path to config file\")\n .action(async (opts) => {\n if (opts.bg) {\n await startBackground(opts);\n } else {\n await startForeground(opts);\n }\n });\n}\n\nasync function startForeground(opts: { port?: string; config?: string }): Promise<void> {\n // Set port if specified\n if (opts.port) {\n process.env.OPENCLAW_MEMORY_PORT = opts.port;\n process.env.PORT = opts.port;\n }\n\n // Import and run server directly\n const { createServer } = await import(\"../../server.js\");\n const { app, config } = await createServer(opts.config);\n\n const port = opts.port ? parseInt(opts.port, 10) : config.port;\n app.listen(port);\n\n console.log(`[server] Listening on http://0.0.0.0:${port}`);\n\n // Write PID file for status/stop commands\n const dataDir = getDataDir();\n fs.mkdirSync(dataDir, { recursive: true });\n fs.writeFileSync(getPidFilePath(), String(process.pid), \"utf-8\");\n\n const cleanup = () => {\n try { fs.unlinkSync(getPidFilePath()); } catch {}\n process.exit(0);\n };\n\n process.on(\"SIGINT\", cleanup);\n process.on(\"SIGTERM\", cleanup);\n}\n\nasync function startBackground(opts: { port?: string; config?: string }): Promise<void> {\n header(\"Starting Server (background)\");\n\n const dataDir = getDataDir();\n fs.mkdirSync(dataDir, { recursive: true });\n\n // Build the command to run\n const args = [\"run\", \"src/server.ts\"];\n const env = { ...process.env };\n\n if (opts.port) {\n env.OPENCLAW_MEMORY_PORT = opts.port;\n env.PORT = opts.port;\n }\n\n // Detect runtime\n const runtime = typeof Bun !== \"undefined\" ? \"bun\" : \"node\";\n const execPath = runtime === \"bun\" ? \"bun\" : process.execPath;\n const execArgs = runtime === \"bun\" ? args : [\"--import\", \"tsx\", ...args];\n\n const child = spawn(execPath, execArgs, {\n env,\n detached: true,\n stdio: \"ignore\",\n cwd: process.cwd(),\n });\n\n child.unref();\n\n if (child.pid) {\n fs.writeFileSync(getPidFilePath(), String(child.pid), \"utf-8\");\n success(`Server started in background (PID: ${child.pid})`);\n info(`PID file: ${getPidFilePath()}`);\n info(`Stop with: openclaw-memory stop`);\n } else {\n logError(\"Failed to start server\");\n process.exit(1);\n }\n}\n","import { Command } from \"commander\";\nimport fs from \"node:fs\";\nimport { header, success, warn, error as logError } from \"../utils.js\";\nimport { getPidFilePath } from \"../../config/index.js\";\n\nexport function stopCommand(): Command {\n return new Command(\"stop\")\n .description(\"Stop the running server\")\n .action(async () => {\n header(\"Stopping Server\");\n\n const pidPath = getPidFilePath();\n if (!fs.existsSync(pidPath)) {\n warn(\"No PID file found — server may not be running\");\n return;\n }\n\n const pidStr = fs.readFileSync(pidPath, \"utf-8\").trim();\n const pid = parseInt(pidStr, 10);\n\n if (isNaN(pid)) {\n logError(`Invalid PID in ${pidPath}: ${pidStr}`);\n return;\n }\n\n try {\n // Send SIGTERM for graceful shutdown\n process.kill(pid, \"SIGTERM\");\n success(`Sent SIGTERM to PID ${pid}`);\n\n // Wait up to 3 seconds for graceful shutdown\n let alive = true;\n for (let i = 0; i < 30; i++) {\n await new Promise((r) => setTimeout(r, 100));\n try {\n process.kill(pid, 0);\n } catch {\n alive = false;\n break;\n }\n }\n\n if (alive) {\n warn(\"Process still running after 3s, sending SIGKILL...\");\n try {\n process.kill(pid, \"SIGKILL\");\n } catch {}\n }\n\n success(\"Server stopped\");\n } catch (err: unknown) {\n if ((err as NodeJS.ErrnoException).code === \"ESRCH\") {\n warn(`Process ${pid} not found — may have already stopped`);\n } else {\n logError(`Failed to stop process ${pid}: ${err}`);\n }\n }\n\n // Clean up PID file\n try {\n fs.unlinkSync(pidPath);\n } catch {}\n });\n}\n","import { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { header, bullet, info, getServerPid, isServerRunning, getBaseUrl, apiGet } from \"../utils.js\";\nimport { loadConfig } from \"../../config/index.js\";\n\nexport function statusCommand(): Command {\n return new Command(\"status\")\n .description(\"Show server and layer health status\")\n .option(\"-p, --port <port>\", \"Server port to check\")\n .option(\"--config <path>\", \"Path to config file\")\n .action(async (opts) => {\n header(\"Status\");\n\n let config;\n try {\n config = await loadConfig(opts.config);\n } catch {\n config = null;\n }\n\n const port = opts.port ? parseInt(opts.port, 10) : config?.port || 7777;\n const baseUrl = getBaseUrl(port);\n const pid = getServerPid();\n const running = await isServerRunning(baseUrl);\n\n // Server status\n if (running && pid) {\n bullet(\"Server\", `Running (PID ${pid}, port ${port})`, \"ok\");\n } else if (running) {\n bullet(\"Server\", `Running (port ${port})`, \"ok\");\n } else if (pid) {\n bullet(\"Server\", `PID file exists (${pid}) but not responding`, \"error\");\n } else {\n bullet(\"Server\", \"Not running\", \"disabled\");\n }\n\n if (config) {\n bullet(\"Tier\", config.tier, undefined);\n }\n\n console.log();\n\n // If server is running, get health from API\n if (running) {\n try {\n const health = await apiGet(baseUrl, \"/api/health\", config?.auth?.token) as Record<string, unknown>;\n\n info(\"Layers:\");\n const sqliteStatus = health.sqlite === \"ok\" ? \"ok\" as const : \"error\" as const;\n bullet(\"L1 SQLite\", String(health.sqlite), sqliteStatus);\n\n if (health.qdrant !== \"disabled\") {\n const qdrantStatus = health.qdrant === \"ok\" ? \"ok\" as const : \"error\" as const;\n bullet(\"L2 Qdrant\", String(health.qdrant), qdrantStatus);\n } else {\n bullet(\"L2 Qdrant\", \"disabled\", \"disabled\");\n }\n\n if (health.age !== \"disabled\") {\n const ageStatus = health.age === \"ok\" ? \"ok\" as const : \"error\" as const;\n bullet(\"L3 AGE\", String(health.age), ageStatus);\n } else {\n bullet(\"L3 AGE\", \"disabled\", \"disabled\");\n }\n\n if (health.uptime !== undefined) {\n const uptime = formatUptime(Number(health.uptime));\n console.log();\n info(`Uptime: ${uptime}`);\n }\n } catch (error) {\n info(\"Could not fetch health status from server\");\n }\n } else {\n // Server not running — try direct layer checks\n if (config) {\n info(\"Server not running. Checking layers directly...\");\n console.log();\n\n // SQLite — always available\n bullet(\"L1 SQLite\", config.sqlite.path, \"ok\");\n\n // Qdrant\n if (config.qdrant) {\n try {\n const res = await fetch(`${config.qdrant.url}/collections`, {\n signal: AbortSignal.timeout(2000),\n });\n bullet(\"L2 Qdrant\", config.qdrant.url, res.ok ? \"ok\" : \"error\");\n } catch {\n bullet(\"L2 Qdrant\", `${config.qdrant.url} (unreachable)`, \"error\");\n }\n } else {\n bullet(\"L2 Qdrant\", \"not configured\", \"disabled\");\n }\n\n // AGE\n if (config.age) {\n try {\n const net = await import(\"node:net\");\n const reachable = await new Promise<boolean>((resolve) => {\n const socket = new net.Socket();\n socket.setTimeout(2000);\n socket.connect(config!.age!.port, config!.age!.host, () => {\n socket.destroy();\n resolve(true);\n });\n socket.on(\"error\", () => resolve(false));\n socket.on(\"timeout\", () => { socket.destroy(); resolve(false); });\n });\n bullet(\"L3 AGE\", `${config.age.host}:${config.age.port}`, reachable ? \"ok\" : \"error\");\n } catch {\n bullet(\"L3 AGE\", \"unreachable\", \"error\");\n }\n } else {\n bullet(\"L3 AGE\", \"not configured\", \"disabled\");\n }\n }\n }\n\n console.log();\n });\n}\n\nfunction formatUptime(seconds: number): string {\n const h = Math.floor(seconds / 3600);\n const m = Math.floor((seconds % 3600) / 60);\n const s = seconds % 60;\n if (h > 0) return `${h}h ${m}m`;\n if (m > 0) return `${m}m ${s}s`;\n return `${s}s`;\n}\n","import { Command } from \"commander\";\nimport { output, readStdin, apiPost, isServerRunning, getBaseUrl } from \"../utils.js\";\nimport { loadConfig } from \"../../config/index.js\";\n\nexport function storeCommand(): Command {\n return new Command(\"store\")\n .description(\"Store a new memory\")\n .argument(\"[content]\", \"Memory content (or pipe via stdin)\")\n .requiredOption(\"--agent <id>\", \"Agent ID\")\n .requiredOption(\"--scope <scope>\", \"Memory scope (user, agent, global, project, session)\")\n .option(\"--subject <id>\", \"Subject ID\")\n .option(\"--tags <tags>\", \"Comma-separated tags\")\n .option(\"--source <source>\", \"Memory source\", \"explicit\")\n .option(\"--no-extract\", \"Skip entity extraction\")\n .option(\"--format <fmt>\", \"Output format (json, text)\", \"json\")\n .option(\"--config <path>\", \"Path to config file\")\n .action(async (contentArg, opts) => {\n const content = contentArg || await readStdin();\n if (!content) {\n console.error(\"Error: content is required (pass as argument or pipe via stdin)\");\n process.exit(1);\n }\n\n const config = await loadConfig(opts.config);\n const baseUrl = getBaseUrl(config.port);\n const serverUp = await isServerRunning(baseUrl);\n\n const body = {\n agent_id: opts.agent,\n scope: opts.scope,\n subject_id: opts.subject || null,\n content,\n tags: opts.tags ? opts.tags.split(\",\").map((t: string) => t.trim()) : [],\n source: opts.source,\n extract_entities: opts.extract !== false,\n };\n\n if (serverUp) {\n // Use HTTP API\n const result = await apiPost(baseUrl, \"/api/memories\", body, config.auth.token);\n output(result, opts.format);\n } else {\n // Direct mode — instantiate MemoryService in-process\n const { MemoryService } = await import(\"../../core/memory-service.js\");\n const service = new MemoryService();\n await service.init();\n\n try {\n const result = await service.store({\n agentId: opts.agent,\n scope: opts.scope,\n subjectId: opts.subject || null,\n content,\n tags: body.tags,\n source: opts.source,\n extractEntities: opts.extract !== false,\n });\n output(result, opts.format);\n } finally {\n await service.close();\n }\n }\n });\n}\n","import { Command } from \"commander\";\nimport { output, apiPost, isServerRunning, getBaseUrl } from \"../utils.js\";\nimport { loadConfig } from \"../../config/index.js\";\n\nexport function searchCommand(): Command {\n const cmd = new Command(\"search\")\n .description(\"Search memories\");\n\n // Default search (smart auto-select)\n cmd\n .argument(\"<query>\", \"Search query\")\n .requiredOption(\"--agent <id>\", \"Agent ID\")\n .option(\"--limit <n>\", \"Max results\", \"10\")\n .option(\"--strategy <s>\", \"Search strategy (auto, semantic, fulltext, graph, all)\", \"auto\")\n .option(\"--scopes <scopes>\", \"Comma-separated scopes\")\n .option(\"--subject <id>\", \"Subject ID filter\")\n .option(\"--cross-agent\", \"Search across all agents\")\n .option(\"--no-graph\", \"Exclude graph results\")\n .option(\"--recall\", \"Format output for LLM context injection\")\n .option(\"--format <fmt>\", \"Output format (json, text)\", \"json\")\n .option(\"--config <path>\", \"Path to config file\")\n .action(async (query, opts) => {\n const config = await loadConfig(opts.config);\n const baseUrl = getBaseUrl(config.port);\n const serverUp = await isServerRunning(baseUrl);\n\n const body = {\n agent_id: opts.agent,\n query,\n limit: parseInt(opts.limit, 10),\n strategy: opts.strategy,\n scopes: opts.scopes ? opts.scopes.split(\",\") : undefined,\n subject_id: opts.subject || null,\n cross_agent: opts.crossAgent || false,\n include_graph: opts.graph !== false,\n };\n\n let result: unknown;\n if (serverUp) {\n result = await apiPost(baseUrl, \"/api/search\", body, config.auth.token);\n } else {\n const { MemoryService } = await import(\"../../core/memory-service.js\");\n const service = new MemoryService();\n await service.init();\n try {\n result = await service.search({\n agentId: opts.agent,\n query,\n limit: parseInt(opts.limit, 10),\n strategy: opts.strategy,\n scopes: opts.scopes ? opts.scopes.split(\",\") : undefined,\n subjectId: opts.subject || null,\n crossAgent: opts.crossAgent || false,\n includeGraph: opts.graph !== false,\n });\n } finally {\n await service.close();\n }\n }\n\n // Recall mode — format for LLM\n if (opts.recall) {\n const data = result as { results?: Array<{ memory: { content: string; scope: string; created_at: string } }> };\n if (data.results && data.results.length > 0) {\n console.log(\"## Relevant Memories\");\n for (const r of data.results) {\n const date = new Date(r.memory.created_at).toLocaleDateString();\n console.log(`- ${r.memory.content} (${r.memory.scope}, ${date})`);\n }\n } else {\n console.log(\"No relevant memories found.\");\n }\n } else {\n output(result, opts.format);\n }\n });\n\n return cmd;\n}\n","import { Command } from \"commander\";\nimport { output, apiPost, isServerRunning, getBaseUrl, success, info, header } from \"../utils.js\";\nimport { loadConfig } from \"../../config/index.js\";\n\nexport function migrateCommand(): Command {\n return new Command(\"migrate\")\n .description(\"Import memories from markdown files\")\n .requiredOption(\"--paths <paths>\", \"Comma-separated file paths\")\n .requiredOption(\"--agent <id>\", \"Agent ID\")\n .option(\"--dry-run\", \"Preview without writing\")\n .option(\"--format <fmt>\", \"Output format (json, text)\", \"json\")\n .option(\"--config <path>\", \"Path to config file\")\n .action(async (opts) => {\n const config = await loadConfig(opts.config);\n const baseUrl = getBaseUrl(config.port);\n const serverUp = await isServerRunning(baseUrl);\n\n const paths = opts.paths.split(\",\").map((p: string) => p.trim());\n\n if (opts.dryRun) {\n header(\"Migration (dry run)\");\n }\n\n const body = {\n markdown_paths: paths,\n agent_id: opts.agent,\n dry_run: opts.dryRun || false,\n };\n\n let result: unknown;\n if (serverUp) {\n result = await apiPost(baseUrl, \"/api/admin/migrate-markdown\", body, config.auth.token);\n } else {\n // Direct mode\n const { MemoryService } = await import(\"../../core/memory-service.js\");\n const service = new MemoryService();\n await service.init();\n try {\n const migrated = await service.migrateMarkdown(paths, opts.agent);\n result = migrated;\n } finally {\n await service.close();\n }\n }\n\n if (opts.format === \"text\") {\n const data = result as { migrated?: number; skipped?: number; errors?: string[] };\n if (data.migrated !== undefined) {\n success(`Migrated ${data.migrated} memories`);\n }\n if (data.skipped) {\n info(`Skipped ${data.skipped} sections`);\n }\n if (data.errors && data.errors.length > 0) {\n for (const err of data.errors) {\n console.error(` ✗ ${err}`);\n }\n }\n } else {\n output(result, opts.format);\n }\n });\n}\n","import { Command } from \"commander\";\nimport { execSync } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { header, success, info, warn, error as logError } from \"../utils.js\";\nimport { getDataDir, loadConfig } from \"../../config/index.js\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nexport function infraCommand(): Command {\n const infra = new Command(\"infra\")\n .description(\"Manage Docker infrastructure\");\n\n infra\n .command(\"up\")\n .description(\"Start Docker containers for the configured tier\")\n .option(\"--tier <tier>\", \"Override tier (standard, full)\")\n .action(async (opts) => {\n header(\"Infrastructure Up\");\n\n let tier = opts.tier;\n if (!tier) {\n try {\n const config = await loadConfig();\n tier = config.tier;\n } catch {\n tier = \"standard\";\n }\n }\n\n if (tier === \"lite\") {\n info(\"Lite tier uses only SQLite — no Docker infrastructure needed.\");\n return;\n }\n\n const templateFile = tier === \"full\" ? \"full.yml\" : \"standard.yml\";\n const templatePath = findTemplate(templateFile);\n\n if (!templatePath) {\n logError(`Template not found: ${templateFile}`);\n logError(\"Expected in ./docker/ or ./templates/ directory\");\n process.exit(1);\n }\n\n const dataDir = getDataDir();\n fs.mkdirSync(dataDir, { recursive: true });\n\n const targetPath = path.join(dataDir, \"docker-compose.yml\");\n fs.copyFileSync(templatePath, targetPath);\n info(`Using template: ${templatePath}`);\n\n try {\n execSync(`docker compose -f ${targetPath} up -d`, {\n stdio: \"inherit\",\n cwd: dataDir,\n });\n success(\"Docker containers started\");\n } catch (error) {\n logError(\"Failed to start Docker containers\");\n logError(\"Make sure Docker is installed and running\");\n process.exit(1);\n }\n });\n\n infra\n .command(\"down\")\n .description(\"Stop Docker containers\")\n .action(async () => {\n header(\"Infrastructure Down\");\n\n const dataDir = getDataDir();\n const composePath = path.join(dataDir, \"docker-compose.yml\");\n\n if (!fs.existsSync(composePath)) {\n warn(\"No docker-compose.yml found in data directory\");\n return;\n }\n\n try {\n execSync(`docker compose -f ${composePath} down`, {\n stdio: \"inherit\",\n cwd: dataDir,\n });\n success(\"Docker containers stopped\");\n } catch (error) {\n logError(\"Failed to stop Docker containers\");\n process.exit(1);\n }\n });\n\n infra\n .command(\"status\")\n .description(\"Show Docker container status\")\n .action(async () => {\n header(\"Infrastructure Status\");\n\n const dataDir = getDataDir();\n const composePath = path.join(dataDir, \"docker-compose.yml\");\n\n if (!fs.existsSync(composePath)) {\n info(\"No docker-compose.yml found — infrastructure not set up\");\n info(\"Run: openclaw-memory infra up\");\n return;\n }\n\n try {\n execSync(`docker compose -f ${composePath} ps`, {\n stdio: \"inherit\",\n cwd: dataDir,\n });\n } catch {\n logError(\"Failed to get container status\");\n }\n });\n\n return infra;\n}\n\nfunction findTemplate(filename: string): string | null {\n const searchPaths = [\n path.join(process.cwd(), \"docker\", filename),\n path.join(process.cwd(), \"templates\", filename),\n // Look in the package's installed location\n path.join(__dirname, \"../../docker\", filename),\n path.join(__dirname, \"../../templates\", filename),\n ];\n\n for (const p of searchPaths) {\n if (fs.existsSync(p)) return p;\n }\n\n return null;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["/Users/robertpop/work/personal/openclaw-memory/dist/cli/index.cjs","../../src/cli/index.ts","../../src/cli/commands/init.ts","../../src/cli/utils.ts","../../src/cli/commands/start.ts","../../src/cli/commands/stop.ts","../../src/cli/commands/status.ts","../../src/cli/commands/store.ts","../../src/cli/commands/search.ts","../../src/cli/commands/migrate.ts","../../src/cli/commands/infra.ts"],"names":[],"mappings":"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","file":"/Users/robertpop/work/personal/openclaw-memory/dist/cli/index.cjs","sourcesContent":[null,"#!/usr/bin/env node\n\nimport { Command } from \"commander\";\nimport { initCommand } from \"./commands/init.js\";\nimport { startCommand } from \"./commands/start.js\";\nimport { stopCommand } from \"./commands/stop.js\";\nimport { statusCommand } from \"./commands/status.js\";\nimport { storeCommand } from \"./commands/store.js\";\nimport { searchCommand } from \"./commands/search.js\";\nimport { migrateCommand } from \"./commands/migrate.js\";\nimport { infraCommand } from \"./commands/infra.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"openclaw-memory\")\n .description(\"Triple-layer memory system for AI agents — SQLite + Qdrant + Postgres/AGE\")\n .version(\"0.1.0\");\n\n// Register commands\nprogram.addCommand(initCommand());\nprogram.addCommand(startCommand());\nprogram.addCommand(stopCommand());\nprogram.addCommand(statusCommand());\nprogram.addCommand(storeCommand());\nprogram.addCommand(searchCommand());\nprogram.addCommand(migrateCommand());\nprogram.addCommand(infraCommand());\n\nprogram.parse();\n","import { Command } from \"commander\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { header, success, info, warn, error as logError } from \"../utils.js\";\nimport { getDataDir, getDefaultSqlitePath } from \"../../config/index.js\";\n\nexport function initCommand(): Command {\n return new Command(\"init\")\n .description(\"Interactive setup wizard\")\n .option(\"--tier <tier>\", \"Tier: lite, standard, or full\")\n .option(\"--non-interactive\", \"Skip prompts, use defaults + flags\")\n .action(async (opts) => {\n header(\"Setup Wizard\");\n\n // For non-interactive mode, generate config from flags/defaults\n const tier = opts.tier || \"lite\";\n const dataDir = getDataDir();\n const sqlitePath = getDefaultSqlitePath();\n\n // Ensure data directory exists\n fs.mkdirSync(dataDir, { recursive: true });\n info(`Data directory: ${dataDir}`);\n\n // Auto-detect available services\n let qdrantAvailable = false;\n let ageAvailable = false;\n\n if (tier !== \"lite\") {\n info(\"Checking Qdrant connectivity...\");\n try {\n const res = await fetch(\"http://localhost:6333/collections\", {\n signal: AbortSignal.timeout(2000),\n });\n qdrantAvailable = res.ok;\n } catch { /* not available */ }\n\n if (qdrantAvailable) {\n success(\"Qdrant is reachable at http://localhost:6333\");\n } else {\n warn(\"Qdrant not reachable at http://localhost:6333\");\n }\n }\n\n if (tier === \"full\") {\n info(\"Checking PostgreSQL/AGE connectivity...\");\n try {\n // Simple TCP check\n const net = await import(\"node:net\");\n ageAvailable = await new Promise<boolean>((resolve) => {\n const socket = new net.Socket();\n socket.setTimeout(2000);\n socket.connect(5432, \"localhost\", () => {\n socket.destroy();\n resolve(true);\n });\n socket.on(\"error\", () => resolve(false));\n socket.on(\"timeout\", () => { socket.destroy(); resolve(false); });\n });\n } catch { /* not available */ }\n\n if (ageAvailable) {\n success(\"PostgreSQL is reachable at localhost:5432\");\n } else {\n warn(\"PostgreSQL not reachable at localhost:5432\");\n }\n }\n\n // Determine effective tier\n let effectiveTier = tier;\n if (tier === \"full\" && !ageAvailable) {\n effectiveTier = qdrantAvailable ? \"standard\" : \"lite\";\n warn(`Downgrading to ${effectiveTier} tier (missing dependencies)`);\n } else if (tier === \"standard\" && !qdrantAvailable) {\n effectiveTier = \"lite\";\n warn(\"Downgrading to lite tier (Qdrant not available)\");\n }\n\n // Generate config file\n const configContent = generateConfig(effectiveTier, sqlitePath);\n const configPath = path.join(process.cwd(), \"openclaw-memory.config.ts\");\n\n fs.writeFileSync(configPath, configContent, \"utf-8\");\n success(`Config written to ${configPath}`);\n\n // Generate .env.example\n const envExample = generateEnvExample(effectiveTier);\n const envPath = path.join(process.cwd(), \".env.example\");\n fs.writeFileSync(envPath, envExample, \"utf-8\");\n success(`Environment template written to ${envPath}`);\n\n console.log();\n info(\"Next steps:\");\n console.log(\" openclaw-memory start # Start the server\");\n console.log(\" openclaw-memory status # Check all layers\");\n console.log();\n });\n}\n\nfunction generateConfig(tier: string, sqlitePath: string): string {\n const lines = [\n `import { defineConfig } from '@poprobertdaniel/openclaw-memory';`,\n ``,\n `export default defineConfig({`,\n ` tier: '${tier}',`,\n ` port: 7777,`,\n ` auth: {`,\n ` token: process.env.MEMORY_AUTH_TOKEN || 'change-me',`,\n ` },`,\n ` sqlite: {`,\n ` path: '${sqlitePath}',`,\n ` },`,\n ];\n\n if (tier === \"standard\" || tier === \"full\") {\n lines.push(` qdrant: {`);\n lines.push(` url: process.env.QDRANT_URL || 'http://localhost:6333',`);\n lines.push(` collection: 'openclaw_memories',`);\n lines.push(` },`);\n lines.push(` embedding: {`);\n lines.push(` apiKey: process.env.OPENAI_API_KEY || '',`);\n lines.push(` model: 'text-embedding-3-small',`);\n lines.push(` dimensions: 1536,`);\n lines.push(` },`);\n lines.push(` extraction: {`);\n lines.push(` apiKey: process.env.OPENAI_API_KEY || '',`);\n lines.push(` model: 'gpt-5-nano',`);\n lines.push(` enabled: true,`);\n lines.push(` },`);\n }\n\n if (tier === \"full\") {\n lines.push(` age: {`);\n lines.push(` host: process.env.PGHOST || 'localhost',`);\n lines.push(` port: parseInt(process.env.PGPORT || '5432', 10),`);\n lines.push(` user: process.env.PGUSER || 'openclaw',`);\n lines.push(` password: process.env.PGPASSWORD || '',`);\n lines.push(` database: process.env.PGDATABASE || 'agent_memory',`);\n lines.push(` graph: 'agent_memory',`);\n lines.push(` },`);\n }\n\n lines.push(`});`);\n lines.push(``);\n\n return lines.join(\"\\n\");\n}\n\nfunction generateEnvExample(tier: string): string {\n const lines = [\n `# openclaw-memory environment variables`,\n ``,\n `# Server`,\n `# OPENCLAW_MEMORY_PORT=7777`,\n `# OPENCLAW_MEMORY_HOST=0.0.0.0`,\n ``,\n `# Authentication`,\n `MEMORY_AUTH_TOKEN=change-me-to-a-secure-token`,\n ``,\n `# SQLite (always required)`,\n `# SQLITE_PATH=~/.openclaw-memory/memory.sqlite`,\n ``,\n ];\n\n if (tier === \"standard\" || tier === \"full\") {\n lines.push(`# Qdrant (Standard/Full tier)`);\n lines.push(`QDRANT_URL=http://localhost:6333`);\n lines.push(``);\n lines.push(`# Embedding provider`);\n lines.push(`OPENAI_API_KEY=sk-your-key-here`);\n lines.push(`# EMBEDDING_MODEL=text-embedding-3-small`);\n lines.push(`# EMBEDDING_BASE_URL=https://api.openai.com/v1`);\n lines.push(``);\n lines.push(`# Entity extraction`);\n lines.push(`# EXTRACTION_MODEL=gpt-5-nano`);\n lines.push(``);\n }\n\n if (tier === \"full\") {\n lines.push(`# PostgreSQL + Apache AGE (Full tier)`);\n lines.push(`PGHOST=localhost`);\n lines.push(`PGPORT=5432`);\n lines.push(`PGUSER=openclaw`);\n lines.push(`PGPASSWORD=your-password`);\n lines.push(`PGDATABASE=agent_memory`);\n lines.push(`# AGE_GRAPH=agent_memory`);\n lines.push(``);\n }\n\n return lines.join(\"\\n\");\n}\n","import pc from \"picocolors\";\nimport fs from \"node:fs\";\nimport { getPidFilePath } from \"../config/index.js\";\n\n// ── CLI Utilities ───────────────────────────────────────────────────────\n\nexport function log(msg: string): void {\n console.log(msg);\n}\n\nexport function info(msg: string): void {\n console.log(pc.blue(\"ℹ\") + \" \" + msg);\n}\n\nexport function success(msg: string): void {\n console.log(pc.green(\"✓\") + \" \" + msg);\n}\n\nexport function warn(msg: string): void {\n console.log(pc.yellow(\"⚠\") + \" \" + msg);\n}\n\nexport function error(msg: string): void {\n console.error(pc.red(\"✗\") + \" \" + msg);\n}\n\nexport function header(title: string): void {\n console.log();\n console.log(pc.bold(` 🧠 OpenClaw Memory — ${title}`));\n console.log();\n}\n\nexport function bullet(label: string, value: string, status?: \"ok\" | \"error\" | \"disabled\" | \"degraded\"): void {\n const dot = status === \"ok\" ? pc.green(\"●\")\n : status === \"error\" ? pc.red(\"●\")\n : status === \"degraded\" ? pc.yellow(\"●\")\n : status === \"disabled\" ? pc.dim(\"○\")\n : \" \";\n console.log(` ${dot} ${pc.bold(label)} ${value}`);\n}\n\n// ── Server Detection ────────────────────────────────────────────────────\n\nexport function getServerPid(): number | null {\n const pidPath = getPidFilePath();\n if (!fs.existsSync(pidPath)) return null;\n\n try {\n const pid = parseInt(fs.readFileSync(pidPath, \"utf-8\").trim(), 10);\n if (isNaN(pid)) return null;\n\n // Check if process is alive\n try {\n process.kill(pid, 0);\n return pid;\n } catch {\n // Process not running, clean up stale PID file\n fs.unlinkSync(pidPath);\n return null;\n }\n } catch {\n return null;\n }\n}\n\nexport async function isServerRunning(baseUrl: string = \"http://localhost:7777\"): Promise<boolean> {\n try {\n const res = await fetch(`${baseUrl}/api/health`, {\n signal: AbortSignal.timeout(2000),\n });\n return res.ok;\n } catch {\n return false;\n }\n}\n\nexport function getBaseUrl(port?: number): string {\n return `http://localhost:${port || 7777}`;\n}\n\n// ── HTTP Client ─────────────────────────────────────────────────────────\n\nexport async function apiGet(baseUrl: string, path: string, token?: string): Promise<unknown> {\n const headers: Record<string, string> = {};\n if (token) headers.Authorization = `Bearer ${token}`;\n\n const res = await fetch(`${baseUrl}${path}`, { headers });\n if (!res.ok) {\n const text = await res.text();\n throw new Error(`HTTP ${res.status}: ${text}`);\n }\n return res.json();\n}\n\nexport async function apiPost(baseUrl: string, path: string, body: unknown, token?: string): Promise<unknown> {\n const headers: Record<string, string> = { \"Content-Type\": \"application/json\" };\n if (token) headers.Authorization = `Bearer ${token}`;\n\n const res = await fetch(`${baseUrl}${path}`, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n });\n if (!res.ok) {\n const text = await res.text();\n throw new Error(`HTTP ${res.status}: ${text}`);\n }\n return res.json();\n}\n\nexport async function apiDelete(baseUrl: string, path: string, token?: string): Promise<unknown> {\n const headers: Record<string, string> = {};\n if (token) headers.Authorization = `Bearer ${token}`;\n\n const res = await fetch(`${baseUrl}${path}`, {\n method: \"DELETE\",\n headers,\n });\n if (!res.ok) {\n const text = await res.text();\n throw new Error(`HTTP ${res.status}: ${text}`);\n }\n return res.json();\n}\n\n// ── Output Formatting ───────────────────────────────────────────────────\n\nexport function output(data: unknown, format: \"json\" | \"text\" = \"json\"): void {\n if (format === \"text\") {\n console.log(JSON.stringify(data, null, 2));\n } else {\n console.log(JSON.stringify(data));\n }\n}\n\n// ── Stdin Reading ───────────────────────────────────────────────────────\n\nexport async function readStdin(): Promise<string> {\n if (process.stdin.isTTY) return \"\";\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(Buffer.from(chunk));\n }\n return Buffer.concat(chunks).toString(\"utf-8\").trim();\n}\n","import { Command } from \"commander\";\nimport fs from \"node:fs\";\nimport { spawn } from \"node:child_process\";\nimport { header, success, info, error as logError } from \"../utils.js\";\nimport { getPidFilePath, getDataDir } from \"../../config/index.js\";\n\nexport function startCommand(): Command {\n return new Command(\"start\")\n .description(\"Start the HTTP server\")\n .option(\"-p, --port <port>\", \"Server port\")\n .option(\"--bg\", \"Run in background (daemon mode)\")\n .option(\"--config <path>\", \"Path to config file\")\n .action(async (opts) => {\n if (opts.bg) {\n await startBackground(opts);\n } else {\n await startForeground(opts);\n }\n });\n}\n\nasync function startForeground(opts: { port?: string; config?: string }): Promise<void> {\n // Set port if specified\n if (opts.port) {\n process.env.OPENCLAW_MEMORY_PORT = opts.port;\n process.env.PORT = opts.port;\n }\n\n // Import and run server directly\n const { createServer } = await import(\"../../server.js\");\n const { app, config } = await createServer(opts.config);\n\n const port = opts.port ? parseInt(opts.port, 10) : config.port;\n app.listen(port);\n\n console.log(`[server] Listening on http://0.0.0.0:${port}`);\n\n // Write PID file for status/stop commands\n const dataDir = getDataDir();\n fs.mkdirSync(dataDir, { recursive: true });\n fs.writeFileSync(getPidFilePath(), String(process.pid), \"utf-8\");\n\n const cleanup = () => {\n try { fs.unlinkSync(getPidFilePath()); } catch {}\n process.exit(0);\n };\n\n process.on(\"SIGINT\", cleanup);\n process.on(\"SIGTERM\", cleanup);\n}\n\nasync function startBackground(opts: { port?: string; config?: string }): Promise<void> {\n header(\"Starting Server (background)\");\n\n const dataDir = getDataDir();\n fs.mkdirSync(dataDir, { recursive: true });\n\n // Build the command to run\n const args = [\"run\", \"src/server.ts\"];\n const env = { ...process.env };\n\n if (opts.port) {\n env.OPENCLAW_MEMORY_PORT = opts.port;\n env.PORT = opts.port;\n }\n\n // Detect runtime\n const runtime = typeof Bun !== \"undefined\" ? \"bun\" : \"node\";\n const execPath = runtime === \"bun\" ? \"bun\" : process.execPath;\n const execArgs = runtime === \"bun\" ? args : [\"--import\", \"tsx\", ...args];\n\n const child = spawn(execPath, execArgs, {\n env,\n detached: true,\n stdio: \"ignore\",\n cwd: process.cwd(),\n });\n\n child.unref();\n\n if (child.pid) {\n fs.writeFileSync(getPidFilePath(), String(child.pid), \"utf-8\");\n success(`Server started in background (PID: ${child.pid})`);\n info(`PID file: ${getPidFilePath()}`);\n info(`Stop with: openclaw-memory stop`);\n } else {\n logError(\"Failed to start server\");\n process.exit(1);\n }\n}\n","import { Command } from \"commander\";\nimport fs from \"node:fs\";\nimport { header, success, warn, error as logError } from \"../utils.js\";\nimport { getPidFilePath } from \"../../config/index.js\";\n\nexport function stopCommand(): Command {\n return new Command(\"stop\")\n .description(\"Stop the running server\")\n .action(async () => {\n header(\"Stopping Server\");\n\n const pidPath = getPidFilePath();\n if (!fs.existsSync(pidPath)) {\n warn(\"No PID file found — server may not be running\");\n return;\n }\n\n const pidStr = fs.readFileSync(pidPath, \"utf-8\").trim();\n const pid = parseInt(pidStr, 10);\n\n if (isNaN(pid)) {\n logError(`Invalid PID in ${pidPath}: ${pidStr}`);\n return;\n }\n\n try {\n // Send SIGTERM for graceful shutdown\n process.kill(pid, \"SIGTERM\");\n success(`Sent SIGTERM to PID ${pid}`);\n\n // Wait up to 3 seconds for graceful shutdown\n let alive = true;\n for (let i = 0; i < 30; i++) {\n await new Promise((r) => setTimeout(r, 100));\n try {\n process.kill(pid, 0);\n } catch {\n alive = false;\n break;\n }\n }\n\n if (alive) {\n warn(\"Process still running after 3s, sending SIGKILL...\");\n try {\n process.kill(pid, \"SIGKILL\");\n } catch {}\n }\n\n success(\"Server stopped\");\n } catch (err: unknown) {\n if ((err as NodeJS.ErrnoException).code === \"ESRCH\") {\n warn(`Process ${pid} not found — may have already stopped`);\n } else {\n logError(`Failed to stop process ${pid}: ${err}`);\n }\n }\n\n // Clean up PID file\n try {\n fs.unlinkSync(pidPath);\n } catch {}\n });\n}\n","import { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { header, bullet, info, getServerPid, isServerRunning, getBaseUrl, apiGet } from \"../utils.js\";\nimport { loadConfig } from \"../../config/index.js\";\n\nexport function statusCommand(): Command {\n return new Command(\"status\")\n .description(\"Show server and layer health status\")\n .option(\"-p, --port <port>\", \"Server port to check\")\n .option(\"--config <path>\", \"Path to config file\")\n .action(async (opts) => {\n header(\"Status\");\n\n let config;\n try {\n config = await loadConfig(opts.config);\n } catch {\n config = null;\n }\n\n const port = opts.port ? parseInt(opts.port, 10) : config?.port || 7777;\n const baseUrl = getBaseUrl(port);\n const pid = getServerPid();\n const running = await isServerRunning(baseUrl);\n\n // Server status\n if (running && pid) {\n bullet(\"Server\", `Running (PID ${pid}, port ${port})`, \"ok\");\n } else if (running) {\n bullet(\"Server\", `Running (port ${port})`, \"ok\");\n } else if (pid) {\n bullet(\"Server\", `PID file exists (${pid}) but not responding`, \"error\");\n } else {\n bullet(\"Server\", \"Not running\", \"disabled\");\n }\n\n if (config) {\n bullet(\"Tier\", config.tier, undefined);\n }\n\n console.log();\n\n // If server is running, get health from API\n if (running) {\n try {\n const health = await apiGet(baseUrl, \"/api/health\", config?.auth?.token) as Record<string, unknown>;\n\n info(\"Layers:\");\n const sqliteStatus = health.sqlite === \"ok\" ? \"ok\" as const : \"error\" as const;\n bullet(\"L1 SQLite\", String(health.sqlite), sqliteStatus);\n\n if (health.qdrant !== \"disabled\") {\n const qdrantStatus = health.qdrant === \"ok\" ? \"ok\" as const : \"error\" as const;\n bullet(\"L2 Qdrant\", String(health.qdrant), qdrantStatus);\n } else {\n bullet(\"L2 Qdrant\", \"disabled\", \"disabled\");\n }\n\n if (health.age !== \"disabled\") {\n const ageStatus = health.age === \"ok\" ? \"ok\" as const : \"error\" as const;\n bullet(\"L3 AGE\", String(health.age), ageStatus);\n } else {\n bullet(\"L3 AGE\", \"disabled\", \"disabled\");\n }\n\n if (health.uptime !== undefined) {\n const uptime = formatUptime(Number(health.uptime));\n console.log();\n info(`Uptime: ${uptime}`);\n }\n } catch (error) {\n info(\"Could not fetch health status from server\");\n }\n } else {\n // Server not running — try direct layer checks\n if (config) {\n info(\"Server not running. Checking layers directly...\");\n console.log();\n\n // SQLite — always available\n bullet(\"L1 SQLite\", config.sqlite.path, \"ok\");\n\n // Qdrant\n if (config.qdrant) {\n try {\n const res = await fetch(`${config.qdrant.url}/collections`, {\n signal: AbortSignal.timeout(2000),\n });\n bullet(\"L2 Qdrant\", config.qdrant.url, res.ok ? \"ok\" : \"error\");\n } catch {\n bullet(\"L2 Qdrant\", `${config.qdrant.url} (unreachable)`, \"error\");\n }\n } else {\n bullet(\"L2 Qdrant\", \"not configured\", \"disabled\");\n }\n\n // AGE\n if (config.age) {\n try {\n const net = await import(\"node:net\");\n const reachable = await new Promise<boolean>((resolve) => {\n const socket = new net.Socket();\n socket.setTimeout(2000);\n socket.connect(config!.age!.port, config!.age!.host, () => {\n socket.destroy();\n resolve(true);\n });\n socket.on(\"error\", () => resolve(false));\n socket.on(\"timeout\", () => { socket.destroy(); resolve(false); });\n });\n bullet(\"L3 AGE\", `${config.age.host}:${config.age.port}`, reachable ? \"ok\" : \"error\");\n } catch {\n bullet(\"L3 AGE\", \"unreachable\", \"error\");\n }\n } else {\n bullet(\"L3 AGE\", \"not configured\", \"disabled\");\n }\n }\n }\n\n console.log();\n });\n}\n\nfunction formatUptime(seconds: number): string {\n const h = Math.floor(seconds / 3600);\n const m = Math.floor((seconds % 3600) / 60);\n const s = seconds % 60;\n if (h > 0) return `${h}h ${m}m`;\n if (m > 0) return `${m}m ${s}s`;\n return `${s}s`;\n}\n","import { Command } from \"commander\";\nimport { output, readStdin, apiPost, isServerRunning, getBaseUrl } from \"../utils.js\";\nimport { loadConfig } from \"../../config/index.js\";\n\nexport function storeCommand(): Command {\n return new Command(\"store\")\n .description(\"Store a new memory\")\n .argument(\"[content]\", \"Memory content (or pipe via stdin)\")\n .requiredOption(\"--agent <id>\", \"Agent ID\")\n .requiredOption(\"--scope <scope>\", \"Memory scope (user, agent, global, project, session)\")\n .option(\"--subject <id>\", \"Subject ID\")\n .option(\"--tags <tags>\", \"Comma-separated tags\")\n .option(\"--source <source>\", \"Memory source\", \"explicit\")\n .option(\"--no-extract\", \"Skip entity extraction\")\n .option(\"--format <fmt>\", \"Output format (json, text)\", \"json\")\n .option(\"--config <path>\", \"Path to config file\")\n .action(async (contentArg, opts) => {\n const content = contentArg || await readStdin();\n if (!content) {\n console.error(\"Error: content is required (pass as argument or pipe via stdin)\");\n process.exit(1);\n }\n\n const config = await loadConfig(opts.config);\n const baseUrl = getBaseUrl(config.port);\n const serverUp = await isServerRunning(baseUrl);\n\n const body = {\n agent_id: opts.agent,\n scope: opts.scope,\n subject_id: opts.subject || null,\n content,\n tags: opts.tags ? opts.tags.split(\",\").map((t: string) => t.trim()) : [],\n source: opts.source,\n extract_entities: opts.extract !== false,\n };\n\n if (serverUp) {\n // Use HTTP API\n const result = await apiPost(baseUrl, \"/api/memories\", body, config.auth.token);\n output(result, opts.format);\n } else {\n // Direct mode — instantiate MemoryService in-process\n const { MemoryService } = await import(\"../../core/memory-service.js\");\n const service = new MemoryService();\n await service.init();\n\n try {\n const result = await service.store({\n agentId: opts.agent,\n scope: opts.scope,\n subjectId: opts.subject || null,\n content,\n tags: body.tags,\n source: opts.source,\n extractEntities: opts.extract !== false,\n });\n output(result, opts.format);\n } finally {\n await service.close();\n }\n }\n });\n}\n","import { Command } from \"commander\";\nimport { output, apiPost, isServerRunning, getBaseUrl } from \"../utils.js\";\nimport { loadConfig } from \"../../config/index.js\";\n\nexport function searchCommand(): Command {\n const cmd = new Command(\"search\")\n .description(\"Search memories\");\n\n // Default search (smart auto-select)\n cmd\n .argument(\"<query>\", \"Search query\")\n .requiredOption(\"--agent <id>\", \"Agent ID\")\n .option(\"--limit <n>\", \"Max results\", \"10\")\n .option(\"--strategy <s>\", \"Search strategy (auto, semantic, fulltext, graph, all)\", \"auto\")\n .option(\"--scopes <scopes>\", \"Comma-separated scopes\")\n .option(\"--subject <id>\", \"Subject ID filter\")\n .option(\"--cross-agent\", \"Search across all agents\")\n .option(\"--no-graph\", \"Exclude graph results\")\n .option(\"--recall\", \"Format output for LLM context injection\")\n .option(\"--format <fmt>\", \"Output format (json, text)\", \"json\")\n .option(\"--config <path>\", \"Path to config file\")\n .action(async (query, opts) => {\n const config = await loadConfig(opts.config);\n const baseUrl = getBaseUrl(config.port);\n const serverUp = await isServerRunning(baseUrl);\n\n const body = {\n agent_id: opts.agent,\n query,\n limit: parseInt(opts.limit, 10),\n strategy: opts.strategy,\n scopes: opts.scopes ? opts.scopes.split(\",\") : undefined,\n subject_id: opts.subject || null,\n cross_agent: opts.crossAgent || false,\n include_graph: opts.graph !== false,\n };\n\n let result: unknown;\n if (serverUp) {\n result = await apiPost(baseUrl, \"/api/search\", body, config.auth.token);\n } else {\n const { MemoryService } = await import(\"../../core/memory-service.js\");\n const service = new MemoryService();\n await service.init();\n try {\n result = await service.search({\n agentId: opts.agent,\n query,\n limit: parseInt(opts.limit, 10),\n strategy: opts.strategy,\n scopes: opts.scopes ? opts.scopes.split(\",\") : undefined,\n subjectId: opts.subject || null,\n crossAgent: opts.crossAgent || false,\n includeGraph: opts.graph !== false,\n });\n } finally {\n await service.close();\n }\n }\n\n // Recall mode — format for LLM\n if (opts.recall) {\n const data = result as { results?: Array<{ memory: { content: string; scope: string; created_at: string } }> };\n if (data.results && data.results.length > 0) {\n console.log(\"## Relevant Memories\");\n for (const r of data.results) {\n const date = new Date(r.memory.created_at).toLocaleDateString();\n console.log(`- ${r.memory.content} (${r.memory.scope}, ${date})`);\n }\n } else {\n console.log(\"No relevant memories found.\");\n }\n } else {\n output(result, opts.format);\n }\n });\n\n return cmd;\n}\n","import { Command } from \"commander\";\nimport { output, apiPost, isServerRunning, getBaseUrl, success, info, header } from \"../utils.js\";\nimport { loadConfig } from \"../../config/index.js\";\n\nexport function migrateCommand(): Command {\n return new Command(\"migrate\")\n .description(\"Import memories from markdown files\")\n .requiredOption(\"--paths <paths>\", \"Comma-separated file paths\")\n .requiredOption(\"--agent <id>\", \"Agent ID\")\n .option(\"--dry-run\", \"Preview without writing\")\n .option(\"--format <fmt>\", \"Output format (json, text)\", \"json\")\n .option(\"--config <path>\", \"Path to config file\")\n .action(async (opts) => {\n const config = await loadConfig(opts.config);\n const baseUrl = getBaseUrl(config.port);\n const serverUp = await isServerRunning(baseUrl);\n\n const paths = opts.paths.split(\",\").map((p: string) => p.trim());\n\n if (opts.dryRun) {\n header(\"Migration (dry run)\");\n }\n\n const body = {\n markdown_paths: paths,\n agent_id: opts.agent,\n dry_run: opts.dryRun || false,\n };\n\n let result: unknown;\n if (serverUp) {\n result = await apiPost(baseUrl, \"/api/admin/migrate-markdown\", body, config.auth.token);\n } else {\n // Direct mode\n const { MemoryService } = await import(\"../../core/memory-service.js\");\n const service = new MemoryService();\n await service.init();\n try {\n const migrated = await service.migrateMarkdown(paths, opts.agent);\n result = migrated;\n } finally {\n await service.close();\n }\n }\n\n if (opts.format === \"text\") {\n const data = result as { migrated?: number; skipped?: number; errors?: string[] };\n if (data.migrated !== undefined) {\n success(`Migrated ${data.migrated} memories`);\n }\n if (data.skipped) {\n info(`Skipped ${data.skipped} sections`);\n }\n if (data.errors && data.errors.length > 0) {\n for (const err of data.errors) {\n console.error(` ✗ ${err}`);\n }\n }\n } else {\n output(result, opts.format);\n }\n });\n}\n","import { Command } from \"commander\";\nimport { execSync } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { header, success, info, warn, error as logError } from \"../utils.js\";\nimport { getDataDir, loadConfig } from \"../../config/index.js\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nexport function infraCommand(): Command {\n const infra = new Command(\"infra\")\n .description(\"Manage Docker infrastructure\");\n\n infra\n .command(\"up\")\n .description(\"Start Docker containers for the configured tier\")\n .option(\"--tier <tier>\", \"Override tier (standard, full)\")\n .action(async (opts) => {\n header(\"Infrastructure Up\");\n\n let tier = opts.tier;\n if (!tier) {\n try {\n const config = await loadConfig();\n tier = config.tier;\n } catch {\n tier = \"standard\";\n }\n }\n\n if (tier === \"lite\") {\n info(\"Lite tier uses only SQLite — no Docker infrastructure needed.\");\n return;\n }\n\n const templateFile = tier === \"full\" ? \"full.yml\" : \"standard.yml\";\n const templatePath = findTemplate(templateFile);\n\n if (!templatePath) {\n logError(`Template not found: ${templateFile}`);\n logError(\"Expected in ./docker/ or ./templates/ directory\");\n process.exit(1);\n }\n\n const dataDir = getDataDir();\n fs.mkdirSync(dataDir, { recursive: true });\n\n const targetPath = path.join(dataDir, \"docker-compose.yml\");\n fs.copyFileSync(templatePath, targetPath);\n info(`Using template: ${templatePath}`);\n\n try {\n execSync(`docker compose -f ${targetPath} up -d`, {\n stdio: \"inherit\",\n cwd: dataDir,\n });\n success(\"Docker containers started\");\n } catch (error) {\n logError(\"Failed to start Docker containers\");\n logError(\"Make sure Docker is installed and running\");\n process.exit(1);\n }\n });\n\n infra\n .command(\"down\")\n .description(\"Stop Docker containers\")\n .action(async () => {\n header(\"Infrastructure Down\");\n\n const dataDir = getDataDir();\n const composePath = path.join(dataDir, \"docker-compose.yml\");\n\n if (!fs.existsSync(composePath)) {\n warn(\"No docker-compose.yml found in data directory\");\n return;\n }\n\n try {\n execSync(`docker compose -f ${composePath} down`, {\n stdio: \"inherit\",\n cwd: dataDir,\n });\n success(\"Docker containers stopped\");\n } catch (error) {\n logError(\"Failed to stop Docker containers\");\n process.exit(1);\n }\n });\n\n infra\n .command(\"status\")\n .description(\"Show Docker container status\")\n .action(async () => {\n header(\"Infrastructure Status\");\n\n const dataDir = getDataDir();\n const composePath = path.join(dataDir, \"docker-compose.yml\");\n\n if (!fs.existsSync(composePath)) {\n info(\"No docker-compose.yml found — infrastructure not set up\");\n info(\"Run: openclaw-memory infra up\");\n return;\n }\n\n try {\n execSync(`docker compose -f ${composePath} ps`, {\n stdio: \"inherit\",\n cwd: dataDir,\n });\n } catch {\n logError(\"Failed to get container status\");\n }\n });\n\n return infra;\n}\n\nfunction findTemplate(filename: string): string | null {\n const searchPaths = [\n path.join(process.cwd(), \"docker\", filename),\n path.join(process.cwd(), \"templates\", filename),\n // Look in the package's installed location\n path.join(__dirname, \"../../docker\", filename),\n path.join(__dirname, \"../../templates\", filename),\n ];\n\n for (const p of searchPaths) {\n if (fs.existsSync(p)) return p;\n }\n\n return null;\n}\n"]}
|
package/dist/cli/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
getDefaultSqlitePath,
|
|
5
5
|
getPidFilePath,
|
|
6
6
|
loadConfig
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-ITGUJZUL.js";
|
|
8
8
|
|
|
9
9
|
// src/cli/index.ts
|
|
10
10
|
import { Command as Command9 } from "commander";
|
|
@@ -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-
|
|
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-
|
|
254
|
+
lines.push(`# EXTRACTION_MODEL=gpt-5-nano`);
|
|
255
255
|
lines.push(``);
|
|
256
256
|
}
|
|
257
257
|
if (tier === "full") {
|
|
@@ -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 import("../memory-service-
|
|
522
|
+
const { MemoryService } = await import("../memory-service-4ZPYUN4L.js");
|
|
523
523
|
const service = new MemoryService();
|
|
524
524
|
await service.init();
|
|
525
525
|
try {
|
|
@@ -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 import("../memory-service-
|
|
565
|
+
const { MemoryService } = await import("../memory-service-4ZPYUN4L.js");
|
|
566
566
|
const service = new MemoryService();
|
|
567
567
|
await service.init();
|
|
568
568
|
try {
|
|
@@ -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 import("../memory-service-
|
|
621
|
+
const { MemoryService } = await import("../memory-service-4ZPYUN4L.js");
|
|
622
622
|
const service = new MemoryService();
|
|
623
623
|
await service.init();
|
|
624
624
|
try {
|