memoclaw 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +381 -62
- package/package.json +2 -1
package/dist/cli.mjs
CHANGED
|
@@ -5208,8 +5208,124 @@ function privateKeyToAccount(privateKey, options = {}) {
|
|
|
5208
5208
|
source: "privateKey"
|
|
5209
5209
|
};
|
|
5210
5210
|
}
|
|
5211
|
+
// src/args.ts
|
|
5212
|
+
var BOOLEAN_FLAGS = new Set([
|
|
5213
|
+
"help",
|
|
5214
|
+
"version",
|
|
5215
|
+
"raw",
|
|
5216
|
+
"json",
|
|
5217
|
+
"quiet",
|
|
5218
|
+
"dryRun",
|
|
5219
|
+
"verbose",
|
|
5220
|
+
"noColor"
|
|
5221
|
+
]);
|
|
5222
|
+
var SHORT_FLAGS = {
|
|
5223
|
+
"-h": "help",
|
|
5224
|
+
"-v": "version",
|
|
5225
|
+
"-j": "json",
|
|
5226
|
+
"-q": "quiet",
|
|
5227
|
+
"-n": "namespace",
|
|
5228
|
+
"-l": "limit",
|
|
5229
|
+
"-t": "tags",
|
|
5230
|
+
"-o": "output"
|
|
5231
|
+
};
|
|
5232
|
+
function parseArgs(args) {
|
|
5233
|
+
const result = { _: [] };
|
|
5234
|
+
let i = 0;
|
|
5235
|
+
while (i < args.length) {
|
|
5236
|
+
const arg = args[i];
|
|
5237
|
+
if (arg[0] === "-" && arg[1] !== "-" && arg.length >= 2) {
|
|
5238
|
+
if (arg.length === 2 && SHORT_FLAGS[arg]) {
|
|
5239
|
+
const key = SHORT_FLAGS[arg];
|
|
5240
|
+
if (BOOLEAN_FLAGS.has(key)) {
|
|
5241
|
+
result[key] = true;
|
|
5242
|
+
i++;
|
|
5243
|
+
} else {
|
|
5244
|
+
const next = args[i + 1];
|
|
5245
|
+
if (next !== undefined && !next.startsWith("-")) {
|
|
5246
|
+
result[key] = next;
|
|
5247
|
+
i += 2;
|
|
5248
|
+
} else {
|
|
5249
|
+
result[key] = true;
|
|
5250
|
+
i++;
|
|
5251
|
+
}
|
|
5252
|
+
}
|
|
5253
|
+
} else if (arg.length > 2 && !SHORT_FLAGS[arg]) {
|
|
5254
|
+
const chars = arg.slice(1).split("");
|
|
5255
|
+
let allValid = true;
|
|
5256
|
+
for (const ch of chars) {
|
|
5257
|
+
const flag = `-${ch}`;
|
|
5258
|
+
if (!SHORT_FLAGS[flag]) {
|
|
5259
|
+
allValid = false;
|
|
5260
|
+
break;
|
|
5261
|
+
}
|
|
5262
|
+
}
|
|
5263
|
+
if (allValid) {
|
|
5264
|
+
for (let ci = 0;ci < chars.length; ci++) {
|
|
5265
|
+
const flag = `-${chars[ci]}`;
|
|
5266
|
+
const key = SHORT_FLAGS[flag];
|
|
5267
|
+
if (BOOLEAN_FLAGS.has(key)) {
|
|
5268
|
+
result[key] = true;
|
|
5269
|
+
} else if (ci === chars.length - 1) {
|
|
5270
|
+
const next = args[i + 1];
|
|
5271
|
+
if (next !== undefined && !next.startsWith("-")) {
|
|
5272
|
+
result[key] = next;
|
|
5273
|
+
i++;
|
|
5274
|
+
} else {
|
|
5275
|
+
result[key] = true;
|
|
5276
|
+
}
|
|
5277
|
+
} else {
|
|
5278
|
+
result[key] = true;
|
|
5279
|
+
}
|
|
5280
|
+
}
|
|
5281
|
+
i++;
|
|
5282
|
+
} else {
|
|
5283
|
+
result._.push(arg);
|
|
5284
|
+
i++;
|
|
5285
|
+
}
|
|
5286
|
+
} else {
|
|
5287
|
+
result._.push(arg);
|
|
5288
|
+
i++;
|
|
5289
|
+
}
|
|
5290
|
+
} else if (arg === "--") {
|
|
5291
|
+
result._.push(...args.slice(i + 1));
|
|
5292
|
+
break;
|
|
5293
|
+
} else if (arg.startsWith("--")) {
|
|
5294
|
+
const eqIdx = arg.indexOf("=");
|
|
5295
|
+
let key;
|
|
5296
|
+
let inlineValue;
|
|
5297
|
+
if (eqIdx !== -1) {
|
|
5298
|
+
key = arg.slice(2, eqIdx).replace(/-([a-z])/g, (_, ch) => ch.toUpperCase());
|
|
5299
|
+
inlineValue = arg.slice(eqIdx + 1);
|
|
5300
|
+
} else {
|
|
5301
|
+
key = arg.slice(2).replace(/-([a-z])/g, (_, ch) => ch.toUpperCase());
|
|
5302
|
+
}
|
|
5303
|
+
if (inlineValue !== undefined) {
|
|
5304
|
+
result[key] = inlineValue;
|
|
5305
|
+
i++;
|
|
5306
|
+
} else if (BOOLEAN_FLAGS.has(key)) {
|
|
5307
|
+
result[key] = true;
|
|
5308
|
+
i++;
|
|
5309
|
+
} else {
|
|
5310
|
+
const next = args[i + 1];
|
|
5311
|
+
if (next !== undefined && (!next.startsWith("--") || /^--?\d/.test(next))) {
|
|
5312
|
+
result[key] = next;
|
|
5313
|
+
i += 2;
|
|
5314
|
+
} else {
|
|
5315
|
+
result[key] = true;
|
|
5316
|
+
i++;
|
|
5317
|
+
}
|
|
5318
|
+
}
|
|
5319
|
+
} else {
|
|
5320
|
+
result._.push(arg);
|
|
5321
|
+
i++;
|
|
5322
|
+
}
|
|
5323
|
+
}
|
|
5324
|
+
return result;
|
|
5325
|
+
}
|
|
5326
|
+
|
|
5211
5327
|
// src/cli.ts
|
|
5212
|
-
var VERSION = "1.
|
|
5328
|
+
var VERSION = "1.6.0";
|
|
5213
5329
|
var API_URL = process.env.MEMOCLAW_URL || "https://api.memoclaw.com";
|
|
5214
5330
|
var PRIVATE_KEY = process.env.MEMOCLAW_PRIVATE_KEY;
|
|
5215
5331
|
var NO_COLOR = !!process.env.NO_COLOR || !process.stdout.isTTY;
|
|
@@ -5260,57 +5376,6 @@ async function getWalletAuthHeader() {
|
|
|
5260
5376
|
const signature = await account.signMessage({ message });
|
|
5261
5377
|
return `${account.address}:${timestamp}:${signature}`;
|
|
5262
5378
|
}
|
|
5263
|
-
var BOOLEAN_FLAGS = new Set([
|
|
5264
|
-
"help",
|
|
5265
|
-
"version",
|
|
5266
|
-
"raw",
|
|
5267
|
-
"json",
|
|
5268
|
-
"quiet",
|
|
5269
|
-
"dryRun",
|
|
5270
|
-
"verbose"
|
|
5271
|
-
]);
|
|
5272
|
-
function parseArgs(args) {
|
|
5273
|
-
const result = { _: [] };
|
|
5274
|
-
let i = 0;
|
|
5275
|
-
while (i < args.length) {
|
|
5276
|
-
const arg = args[i];
|
|
5277
|
-
if (arg === "-h" || arg === "--help") {
|
|
5278
|
-
result.help = true;
|
|
5279
|
-
i++;
|
|
5280
|
-
} else if (arg === "-v" || arg === "--version") {
|
|
5281
|
-
result.version = true;
|
|
5282
|
-
i++;
|
|
5283
|
-
} else if (arg === "-q" || arg === "--quiet") {
|
|
5284
|
-
result.quiet = true;
|
|
5285
|
-
i++;
|
|
5286
|
-
} else if (arg === "-j" || arg === "--json") {
|
|
5287
|
-
result.json = true;
|
|
5288
|
-
i++;
|
|
5289
|
-
} else if (arg === "--") {
|
|
5290
|
-
result._.push(...args.slice(i + 1));
|
|
5291
|
-
break;
|
|
5292
|
-
} else if (arg.startsWith("--")) {
|
|
5293
|
-
const key = arg.slice(2).replace(/-([a-z])/g, (_, ch) => ch.toUpperCase());
|
|
5294
|
-
if (BOOLEAN_FLAGS.has(key)) {
|
|
5295
|
-
result[key] = true;
|
|
5296
|
-
i++;
|
|
5297
|
-
} else {
|
|
5298
|
-
const next = args[i + 1];
|
|
5299
|
-
if (next !== undefined && !next.startsWith("--")) {
|
|
5300
|
-
result[key] = next;
|
|
5301
|
-
i += 2;
|
|
5302
|
-
} else {
|
|
5303
|
-
result[key] = true;
|
|
5304
|
-
i++;
|
|
5305
|
-
}
|
|
5306
|
-
}
|
|
5307
|
-
} else {
|
|
5308
|
-
result._.push(arg);
|
|
5309
|
-
i++;
|
|
5310
|
-
}
|
|
5311
|
-
}
|
|
5312
|
-
return result;
|
|
5313
|
-
}
|
|
5314
5379
|
async function readStdin() {
|
|
5315
5380
|
if (process.stdin.isTTY)
|
|
5316
5381
|
return null;
|
|
@@ -5374,6 +5439,11 @@ function table(rows, columns) {
|
|
|
5374
5439
|
console.log(line);
|
|
5375
5440
|
}
|
|
5376
5441
|
}
|
|
5442
|
+
function progressBar(current, total, width = 30) {
|
|
5443
|
+
const pct = Math.min(current / total, 1);
|
|
5444
|
+
const filled = Math.round(pct * width);
|
|
5445
|
+
return `${c.green}${"█".repeat(filled)}${c.dim}${"░".repeat(width - filled)}${c.reset} ${current}/${total}`;
|
|
5446
|
+
}
|
|
5377
5447
|
async function request(method, path, body = null) {
|
|
5378
5448
|
const url = `${API_URL}${path}`;
|
|
5379
5449
|
const headers = { "Content-Type": "application/json" };
|
|
@@ -5426,7 +5496,7 @@ async function request(method, path, body = null) {
|
|
|
5426
5496
|
}
|
|
5427
5497
|
async function cmdStore(content, opts) {
|
|
5428
5498
|
const body = { content };
|
|
5429
|
-
if (opts.importance)
|
|
5499
|
+
if (opts.importance != null && opts.importance !== true)
|
|
5430
5500
|
body.importance = parseFloat(opts.importance);
|
|
5431
5501
|
if (opts.tags)
|
|
5432
5502
|
body.metadata = { tags: opts.tags.split(",").map((t) => t.trim()) };
|
|
@@ -5443,9 +5513,9 @@ async function cmdStore(content, opts) {
|
|
|
5443
5513
|
}
|
|
5444
5514
|
async function cmdRecall(query, opts) {
|
|
5445
5515
|
const body = { query };
|
|
5446
|
-
if (opts.limit)
|
|
5516
|
+
if (opts.limit != null && opts.limit !== true)
|
|
5447
5517
|
body.limit = parseInt(opts.limit);
|
|
5448
|
-
if (opts.minSimilarity)
|
|
5518
|
+
if (opts.minSimilarity != null && opts.minSimilarity !== true)
|
|
5449
5519
|
body.min_similarity = parseFloat(opts.minSimilarity);
|
|
5450
5520
|
if (opts.namespace)
|
|
5451
5521
|
body.namespace = opts.namespace;
|
|
@@ -5454,6 +5524,11 @@ async function cmdRecall(query, opts) {
|
|
|
5454
5524
|
const result = await request("POST", "/v1/recall", body);
|
|
5455
5525
|
if (outputJson) {
|
|
5456
5526
|
out(result);
|
|
5527
|
+
} else if (opts.raw) {
|
|
5528
|
+
const memories = result.memories || [];
|
|
5529
|
+
for (const mem of memories) {
|
|
5530
|
+
console.log(mem.content);
|
|
5531
|
+
}
|
|
5457
5532
|
} else {
|
|
5458
5533
|
const memories = result.memories || [];
|
|
5459
5534
|
if (memories.length === 0) {
|
|
@@ -5476,9 +5551,9 @@ async function cmdRecall(query, opts) {
|
|
|
5476
5551
|
}
|
|
5477
5552
|
async function cmdList(opts) {
|
|
5478
5553
|
const params = new URLSearchParams;
|
|
5479
|
-
if (opts.limit)
|
|
5554
|
+
if (opts.limit != null && opts.limit !== true)
|
|
5480
5555
|
params.set("limit", opts.limit);
|
|
5481
|
-
if (opts.offset)
|
|
5556
|
+
if (opts.offset != null && opts.offset !== true)
|
|
5482
5557
|
params.set("offset", opts.offset);
|
|
5483
5558
|
if (opts.namespace)
|
|
5484
5559
|
params.set("namespace", opts.namespace);
|
|
@@ -5510,6 +5585,30 @@ async function cmdList(opts) {
|
|
|
5510
5585
|
}
|
|
5511
5586
|
}
|
|
5512
5587
|
}
|
|
5588
|
+
async function cmdGet(id) {
|
|
5589
|
+
const result = await request("GET", `/v1/memories/${id}`);
|
|
5590
|
+
if (outputJson) {
|
|
5591
|
+
out(result);
|
|
5592
|
+
} else {
|
|
5593
|
+
const mem = result.memory || result;
|
|
5594
|
+
console.log(`${c.bold}ID:${c.reset} ${mem.id || id}`);
|
|
5595
|
+
console.log(`${c.bold}Content:${c.reset} ${mem.content}`);
|
|
5596
|
+
if (mem.importance !== undefined)
|
|
5597
|
+
console.log(`${c.bold}Importance:${c.reset} ${mem.importance}`);
|
|
5598
|
+
if (mem.namespace)
|
|
5599
|
+
console.log(`${c.bold}Namespace:${c.reset} ${mem.namespace}`);
|
|
5600
|
+
if (mem.metadata?.tags?.length)
|
|
5601
|
+
console.log(`${c.bold}Tags:${c.reset} ${mem.metadata.tags.join(", ")}`);
|
|
5602
|
+
if (mem.memory_type)
|
|
5603
|
+
console.log(`${c.bold}Type:${c.reset} ${mem.memory_type}`);
|
|
5604
|
+
if (mem.created_at)
|
|
5605
|
+
console.log(`${c.bold}Created:${c.reset} ${new Date(mem.created_at).toLocaleString()}`);
|
|
5606
|
+
if (mem.updated_at)
|
|
5607
|
+
console.log(`${c.bold}Updated:${c.reset} ${new Date(mem.updated_at).toLocaleString()}`);
|
|
5608
|
+
if (mem.pinned)
|
|
5609
|
+
console.log(`${c.bold}Pinned:${c.reset} ${c.green}yes${c.reset}`);
|
|
5610
|
+
}
|
|
5611
|
+
}
|
|
5513
5612
|
async function cmdDelete(id) {
|
|
5514
5613
|
const result = await request("DELETE", `/v1/memories/${id}`);
|
|
5515
5614
|
if (outputJson) {
|
|
@@ -5520,7 +5619,7 @@ async function cmdDelete(id) {
|
|
|
5520
5619
|
}
|
|
5521
5620
|
async function cmdSuggested(opts) {
|
|
5522
5621
|
const params = new URLSearchParams;
|
|
5523
|
-
if (opts.limit)
|
|
5622
|
+
if (opts.limit != null && opts.limit !== true)
|
|
5524
5623
|
params.set("limit", opts.limit);
|
|
5525
5624
|
if (opts.namespace)
|
|
5526
5625
|
params.set("namespace", opts.namespace);
|
|
@@ -5555,7 +5654,7 @@ async function cmdUpdate(id, opts) {
|
|
|
5555
5654
|
const body = {};
|
|
5556
5655
|
if (opts.content)
|
|
5557
5656
|
body.content = opts.content;
|
|
5558
|
-
if (opts.importance)
|
|
5657
|
+
if (opts.importance != null && opts.importance !== true)
|
|
5559
5658
|
body.importance = parseFloat(opts.importance);
|
|
5560
5659
|
if (opts.memoryType)
|
|
5561
5660
|
body.memory_type = opts.memoryType;
|
|
@@ -5621,7 +5720,7 @@ async function cmdConsolidate(opts) {
|
|
|
5621
5720
|
const body = {};
|
|
5622
5721
|
if (opts.namespace)
|
|
5623
5722
|
body.namespace = opts.namespace;
|
|
5624
|
-
if (opts.minSimilarity)
|
|
5723
|
+
if (opts.minSimilarity != null && opts.minSimilarity !== true)
|
|
5625
5724
|
body.min_similarity = parseFloat(opts.minSimilarity);
|
|
5626
5725
|
if (opts.mode)
|
|
5627
5726
|
body.mode = opts.mode;
|
|
@@ -5779,7 +5878,7 @@ async function cmdImport(opts) {
|
|
|
5779
5878
|
await request("POST", "/v1/store", body);
|
|
5780
5879
|
imported++;
|
|
5781
5880
|
if (!outputQuiet) {
|
|
5782
|
-
process.stderr.write(
|
|
5881
|
+
process.stderr.write(`\r ${progressBar(imported, memories.length)}`);
|
|
5783
5882
|
}
|
|
5784
5883
|
} catch (e) {
|
|
5785
5884
|
failed++;
|
|
@@ -5838,6 +5937,7 @@ async function cmdCompletions(shell) {
|
|
|
5838
5937
|
"store",
|
|
5839
5938
|
"recall",
|
|
5840
5939
|
"list",
|
|
5940
|
+
"get",
|
|
5841
5941
|
"update",
|
|
5842
5942
|
"delete",
|
|
5843
5943
|
"ingest",
|
|
@@ -5849,7 +5949,9 @@ async function cmdCompletions(shell) {
|
|
|
5849
5949
|
"export",
|
|
5850
5950
|
"import",
|
|
5851
5951
|
"stats",
|
|
5852
|
-
"
|
|
5952
|
+
"browse",
|
|
5953
|
+
"completions",
|
|
5954
|
+
"config"
|
|
5853
5955
|
];
|
|
5854
5956
|
if (shell === "bash") {
|
|
5855
5957
|
console.log(`# Add to ~/.bashrc:
|
|
@@ -5878,6 +5980,186 @@ ${commands.map((cmd) => `complete -c memoclaw -n '__fish_use_subcommand' -a '${c
|
|
|
5878
5980
|
throw new Error(`Unknown shell: ${shell}. Supported: bash, zsh, fish`);
|
|
5879
5981
|
}
|
|
5880
5982
|
}
|
|
5983
|
+
async function cmdConfig(subcmd, rest) {
|
|
5984
|
+
if (subcmd === "show" || !subcmd) {
|
|
5985
|
+
const config = {
|
|
5986
|
+
MEMOCLAW_URL: API_URL,
|
|
5987
|
+
MEMOCLAW_PRIVATE_KEY: PRIVATE_KEY ? `${PRIVATE_KEY.slice(0, 6)}…${PRIVATE_KEY.slice(-4)}` : "(not set)",
|
|
5988
|
+
NO_COLOR: process.env.NO_COLOR || "(not set)",
|
|
5989
|
+
DEBUG: process.env.DEBUG || "(not set)"
|
|
5990
|
+
};
|
|
5991
|
+
if (outputJson) {
|
|
5992
|
+
out(config);
|
|
5993
|
+
} else {
|
|
5994
|
+
console.log(`${c.bold}MemoClaw Configuration${c.reset}`);
|
|
5995
|
+
console.log(`${c.dim}${"─".repeat(50)}${c.reset}`);
|
|
5996
|
+
for (const [key, val] of Object.entries(config)) {
|
|
5997
|
+
const isSet = !val.includes("not set");
|
|
5998
|
+
console.log(` ${c.cyan}${key.padEnd(24)}${c.reset} ${isSet ? val : `${c.dim}${val}${c.reset}`}`);
|
|
5999
|
+
}
|
|
6000
|
+
console.log(`
|
|
6001
|
+
${c.dim}Set via environment variables or .env file${c.reset}`);
|
|
6002
|
+
}
|
|
6003
|
+
} else if (subcmd === "check") {
|
|
6004
|
+
const issues = [];
|
|
6005
|
+
if (!PRIVATE_KEY)
|
|
6006
|
+
issues.push("MEMOCLAW_PRIVATE_KEY is not set");
|
|
6007
|
+
else if (!PRIVATE_KEY.startsWith("0x"))
|
|
6008
|
+
issues.push("MEMOCLAW_PRIVATE_KEY should start with 0x");
|
|
6009
|
+
else if (PRIVATE_KEY.length !== 66)
|
|
6010
|
+
issues.push(`MEMOCLAW_PRIVATE_KEY has wrong length (${PRIVATE_KEY.length}, expected 66)`);
|
|
6011
|
+
if (outputJson) {
|
|
6012
|
+
out({ valid: issues.length === 0, issues });
|
|
6013
|
+
} else {
|
|
6014
|
+
if (issues.length === 0) {
|
|
6015
|
+
success("Configuration looks good!");
|
|
6016
|
+
try {
|
|
6017
|
+
const acct = getAccount();
|
|
6018
|
+
info(`Wallet address: ${acct.address}`);
|
|
6019
|
+
} catch {}
|
|
6020
|
+
} else {
|
|
6021
|
+
for (const issue of issues) {
|
|
6022
|
+
console.log(`${c.red}✗${c.reset} ${issue}`);
|
|
6023
|
+
}
|
|
6024
|
+
}
|
|
6025
|
+
}
|
|
6026
|
+
} else {
|
|
6027
|
+
throw new Error("Usage: config [show|check]");
|
|
6028
|
+
}
|
|
6029
|
+
}
|
|
6030
|
+
async function cmdBrowse(opts) {
|
|
6031
|
+
const readline = await import("readline");
|
|
6032
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
6033
|
+
const prompt = (q) => new Promise((r) => rl.question(q, r));
|
|
6034
|
+
console.log(`${c.bold}MemoClaw Interactive Browser${c.reset} ${c.dim}(type "help" or "q" to quit)${c.reset}`);
|
|
6035
|
+
if (opts.namespace)
|
|
6036
|
+
console.log(`${c.dim}Namespace: ${opts.namespace}${c.reset}`);
|
|
6037
|
+
console.log();
|
|
6038
|
+
let offset = 0;
|
|
6039
|
+
const limit = 10;
|
|
6040
|
+
while (true) {
|
|
6041
|
+
const input = (await prompt(`${c.cyan}memoclaw>${c.reset} `)).trim();
|
|
6042
|
+
if (!input)
|
|
6043
|
+
continue;
|
|
6044
|
+
if (input === "q" || input === "quit" || input === "exit")
|
|
6045
|
+
break;
|
|
6046
|
+
const parts = input.split(/\s+/);
|
|
6047
|
+
const browsCmd = parts[0];
|
|
6048
|
+
const browseArgs = parts.slice(1).join(" ");
|
|
6049
|
+
try {
|
|
6050
|
+
switch (browsCmd) {
|
|
6051
|
+
case "help":
|
|
6052
|
+
console.log(`${c.bold}Commands:${c.reset}
|
|
6053
|
+
list / ls List memories (paginated)
|
|
6054
|
+
next / n Next page
|
|
6055
|
+
prev / p Previous page
|
|
6056
|
+
get <id> Show memory details
|
|
6057
|
+
recall <query> Search memories
|
|
6058
|
+
store <content> Store a new memory
|
|
6059
|
+
delete <id> Delete a memory
|
|
6060
|
+
stats Show stats
|
|
6061
|
+
q / quit Exit browser`);
|
|
6062
|
+
break;
|
|
6063
|
+
case "list":
|
|
6064
|
+
case "ls": {
|
|
6065
|
+
offset = 0;
|
|
6066
|
+
const params = new URLSearchParams({ limit: String(limit), offset: String(offset) });
|
|
6067
|
+
if (opts.namespace)
|
|
6068
|
+
params.set("namespace", opts.namespace);
|
|
6069
|
+
const result = await request("GET", `/v1/memories?${params}`);
|
|
6070
|
+
const memories = result.memories || result.data || [];
|
|
6071
|
+
if (memories.length === 0) {
|
|
6072
|
+
console.log(`${c.dim}No memories.${c.reset}`);
|
|
6073
|
+
break;
|
|
6074
|
+
}
|
|
6075
|
+
for (const m of memories) {
|
|
6076
|
+
const text = m.content?.length > 60 ? m.content.slice(0, 60) + "…" : m.content || "";
|
|
6077
|
+
console.log(` ${c.cyan}${(m.id || "?").slice(0, 8)}${c.reset} ${text}`);
|
|
6078
|
+
}
|
|
6079
|
+
console.log(`${c.dim}─ showing ${offset + 1}-${offset + memories.length}${result.total ? ` of ${result.total}` : ""}${c.reset}`);
|
|
6080
|
+
break;
|
|
6081
|
+
}
|
|
6082
|
+
case "next":
|
|
6083
|
+
case "n":
|
|
6084
|
+
offset += limit;
|
|
6085
|
+
{
|
|
6086
|
+
const params = new URLSearchParams({ limit: String(limit), offset: String(offset) });
|
|
6087
|
+
if (opts.namespace)
|
|
6088
|
+
params.set("namespace", opts.namespace);
|
|
6089
|
+
const result = await request("GET", `/v1/memories?${params}`);
|
|
6090
|
+
const memories = result.memories || result.data || [];
|
|
6091
|
+
if (memories.length === 0) {
|
|
6092
|
+
console.log(`${c.dim}No more memories.${c.reset}`);
|
|
6093
|
+
offset = Math.max(0, offset - limit);
|
|
6094
|
+
break;
|
|
6095
|
+
}
|
|
6096
|
+
for (const m of memories) {
|
|
6097
|
+
const text = m.content?.length > 60 ? m.content.slice(0, 60) + "…" : m.content || "";
|
|
6098
|
+
console.log(` ${c.cyan}${(m.id || "?").slice(0, 8)}${c.reset} ${text}`);
|
|
6099
|
+
}
|
|
6100
|
+
console.log(`${c.dim}─ showing ${offset + 1}-${offset + memories.length}${result.total ? ` of ${result.total}` : ""}${c.reset}`);
|
|
6101
|
+
}
|
|
6102
|
+
break;
|
|
6103
|
+
case "prev":
|
|
6104
|
+
case "p":
|
|
6105
|
+
offset = Math.max(0, offset - limit);
|
|
6106
|
+
{
|
|
6107
|
+
const params = new URLSearchParams({ limit: String(limit), offset: String(offset) });
|
|
6108
|
+
if (opts.namespace)
|
|
6109
|
+
params.set("namespace", opts.namespace);
|
|
6110
|
+
const result = await request("GET", `/v1/memories?${params}`);
|
|
6111
|
+
const memories = result.memories || result.data || [];
|
|
6112
|
+
for (const m of memories) {
|
|
6113
|
+
const text = m.content?.length > 60 ? m.content.slice(0, 60) + "…" : m.content || "";
|
|
6114
|
+
console.log(` ${c.cyan}${(m.id || "?").slice(0, 8)}${c.reset} ${text}`);
|
|
6115
|
+
}
|
|
6116
|
+
console.log(`${c.dim}─ showing ${offset + 1}-${offset + memories.length}${result.total ? ` of ${result.total}` : ""}${c.reset}`);
|
|
6117
|
+
}
|
|
6118
|
+
break;
|
|
6119
|
+
case "get":
|
|
6120
|
+
if (!browseArgs) {
|
|
6121
|
+
console.log(`${c.red}Usage: get <id>${c.reset}`);
|
|
6122
|
+
break;
|
|
6123
|
+
}
|
|
6124
|
+
await cmdGet(browseArgs);
|
|
6125
|
+
break;
|
|
6126
|
+
case "recall":
|
|
6127
|
+
case "search":
|
|
6128
|
+
if (!browseArgs) {
|
|
6129
|
+
console.log(`${c.red}Usage: recall <query>${c.reset}`);
|
|
6130
|
+
break;
|
|
6131
|
+
}
|
|
6132
|
+
await cmdRecall(browseArgs, opts);
|
|
6133
|
+
break;
|
|
6134
|
+
case "store":
|
|
6135
|
+
if (!browseArgs) {
|
|
6136
|
+
console.log(`${c.red}Usage: store <content>${c.reset}`);
|
|
6137
|
+
break;
|
|
6138
|
+
}
|
|
6139
|
+
await cmdStore(browseArgs, opts);
|
|
6140
|
+
break;
|
|
6141
|
+
case "delete":
|
|
6142
|
+
case "rm":
|
|
6143
|
+
if (!browseArgs) {
|
|
6144
|
+
console.log(`${c.red}Usage: delete <id>${c.reset}`);
|
|
6145
|
+
break;
|
|
6146
|
+
}
|
|
6147
|
+
await cmdDelete(browseArgs);
|
|
6148
|
+
break;
|
|
6149
|
+
case "stats":
|
|
6150
|
+
await cmdStats(opts);
|
|
6151
|
+
break;
|
|
6152
|
+
default:
|
|
6153
|
+
console.log(`${c.dim}Unknown command. Type "help" for available commands.${c.reset}`);
|
|
6154
|
+
}
|
|
6155
|
+
} catch (e) {
|
|
6156
|
+
console.log(`${c.red}Error:${c.reset} ${e.message}`);
|
|
6157
|
+
}
|
|
6158
|
+
console.log();
|
|
6159
|
+
}
|
|
6160
|
+
rl.close();
|
|
6161
|
+
console.log(`${c.dim}Bye!${c.reset}`);
|
|
6162
|
+
}
|
|
5881
6163
|
function printHelp(command) {
|
|
5882
6164
|
if (command) {
|
|
5883
6165
|
const subHelp = {
|
|
@@ -5932,6 +6214,25 @@ Show memory statistics and account info.
|
|
|
5932
6214
|
|
|
5933
6215
|
Options:
|
|
5934
6216
|
--namespace <name> Filter by namespace`,
|
|
6217
|
+
get: `${c.bold}memoclaw get${c.reset} <id>
|
|
6218
|
+
|
|
6219
|
+
Retrieve a single memory by its ID.`,
|
|
6220
|
+
config: `${c.bold}memoclaw config${c.reset} [show|check]
|
|
6221
|
+
|
|
6222
|
+
Show or validate your MemoClaw configuration.
|
|
6223
|
+
|
|
6224
|
+
Subcommands:
|
|
6225
|
+
show Display current configuration (default)
|
|
6226
|
+
check Validate configuration and test connectivity`,
|
|
6227
|
+
browse: `${c.bold}memoclaw browse${c.reset} [options]
|
|
6228
|
+
|
|
6229
|
+
Interactive memory browser (REPL). Explore, search, and manage
|
|
6230
|
+
memories in a persistent session.
|
|
6231
|
+
|
|
6232
|
+
Options:
|
|
6233
|
+
--namespace <name> Filter by namespace
|
|
6234
|
+
|
|
6235
|
+
Commands inside browser: list, get, recall, store, delete, stats, next, prev`,
|
|
5935
6236
|
completions: `${c.bold}memoclaw completions${c.reset} <bash|zsh|fish>
|
|
5936
6237
|
|
|
5937
6238
|
Generate shell completion scripts.
|
|
@@ -5956,6 +6257,7 @@ ${c.bold}Commands:${c.reset}
|
|
|
5956
6257
|
${c.cyan}store${c.reset} "content" Store a memory (also accepts stdin)
|
|
5957
6258
|
${c.cyan}recall${c.reset} "query" Search memories by similarity
|
|
5958
6259
|
${c.cyan}list${c.reset} List memories in a table
|
|
6260
|
+
${c.cyan}get${c.reset} <id> Get a single memory by ID
|
|
5959
6261
|
${c.cyan}update${c.reset} <id> Update a memory
|
|
5960
6262
|
${c.cyan}delete${c.reset} <id> Delete a memory
|
|
5961
6263
|
${c.cyan}ingest${c.reset} Ingest raw text into memories
|
|
@@ -5968,12 +6270,18 @@ ${c.bold}Commands:${c.reset}
|
|
|
5968
6270
|
${c.cyan}export${c.reset} Export all memories as JSON
|
|
5969
6271
|
${c.cyan}import${c.reset} Import memories from JSON
|
|
5970
6272
|
${c.cyan}completions${c.reset} <shell> Generate shell completions
|
|
6273
|
+
${c.cyan}browse${c.reset} Interactive memory browser (REPL)
|
|
6274
|
+
${c.cyan}config${c.reset} [show|check] Show or validate configuration
|
|
5971
6275
|
|
|
5972
6276
|
${c.bold}Global Options:${c.reset}
|
|
5973
6277
|
-h, --help Show help (use with command for details)
|
|
5974
6278
|
-v, --version Show version
|
|
5975
6279
|
-j, --json Output as JSON (machine-readable)
|
|
5976
6280
|
-q, --quiet Suppress non-essential output
|
|
6281
|
+
-n, --namespace <name> Filter/set namespace
|
|
6282
|
+
-l, --limit <n> Limit results
|
|
6283
|
+
-t, --tags <a,b> Comma-separated tags
|
|
6284
|
+
--raw Raw output (content only, for piping)
|
|
5977
6285
|
|
|
5978
6286
|
${c.bold}Environment:${c.reset}
|
|
5979
6287
|
MEMOCLAW_PRIVATE_KEY Wallet private key for auth + payments
|
|
@@ -6031,6 +6339,11 @@ try {
|
|
|
6031
6339
|
case "list":
|
|
6032
6340
|
await cmdList(args);
|
|
6033
6341
|
break;
|
|
6342
|
+
case "get":
|
|
6343
|
+
if (!rest[0])
|
|
6344
|
+
throw new Error("Memory ID required");
|
|
6345
|
+
await cmdGet(rest[0]);
|
|
6346
|
+
break;
|
|
6034
6347
|
case "update":
|
|
6035
6348
|
if (!rest[0])
|
|
6036
6349
|
throw new Error("Memory ID required");
|
|
@@ -6086,6 +6399,12 @@ try {
|
|
|
6086
6399
|
throw new Error("Shell required: bash, zsh, or fish");
|
|
6087
6400
|
await cmdCompletions(rest[0]);
|
|
6088
6401
|
break;
|
|
6402
|
+
case "browse":
|
|
6403
|
+
await cmdBrowse(args);
|
|
6404
|
+
break;
|
|
6405
|
+
case "config":
|
|
6406
|
+
await cmdConfig(rest[0], rest.slice(1));
|
|
6407
|
+
break;
|
|
6089
6408
|
case "help":
|
|
6090
6409
|
printHelp(rest[0]);
|
|
6091
6410
|
break;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "memoclaw",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "MemoClaw CLI - Memory-as-a-Service for AI agents. 1000 free calls, then x402 micropayments.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
],
|
|
12
12
|
"scripts": {
|
|
13
13
|
"build": "bun build src/cli.ts --outfile=dist/cli.mjs --target=node",
|
|
14
|
+
"test": "bun test",
|
|
14
15
|
"prepublishOnly": "bun run build"
|
|
15
16
|
},
|
|
16
17
|
"keywords": [
|