memoclaw 1.6.0 → 1.7.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 +153 -4
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -5217,7 +5217,10 @@ var BOOLEAN_FLAGS = new Set([
|
|
|
5217
5217
|
"quiet",
|
|
5218
5218
|
"dryRun",
|
|
5219
5219
|
"verbose",
|
|
5220
|
-
"noColor"
|
|
5220
|
+
"noColor",
|
|
5221
|
+
"force",
|
|
5222
|
+
"count",
|
|
5223
|
+
"wide"
|
|
5221
5224
|
]);
|
|
5222
5225
|
var SHORT_FLAGS = {
|
|
5223
5226
|
"-h": "help",
|
|
@@ -5325,7 +5328,7 @@ function parseArgs(args) {
|
|
|
5325
5328
|
}
|
|
5326
5329
|
|
|
5327
5330
|
// src/cli.ts
|
|
5328
|
-
var VERSION = "1.
|
|
5331
|
+
var VERSION = "1.7.0";
|
|
5329
5332
|
var API_URL = process.env.MEMOCLAW_URL || "https://api.memoclaw.com";
|
|
5330
5333
|
var PRIVATE_KEY = process.env.MEMOCLAW_PRIVATE_KEY;
|
|
5331
5334
|
var NO_COLOR = !!process.env.NO_COLOR || !process.stdout.isTTY;
|
|
@@ -5452,7 +5455,21 @@ async function request(method, path, body = null) {
|
|
|
5452
5455
|
options.body = JSON.stringify(body);
|
|
5453
5456
|
const walletAuth = await getWalletAuthHeader();
|
|
5454
5457
|
headers["x-wallet-auth"] = walletAuth;
|
|
5455
|
-
let res
|
|
5458
|
+
let res;
|
|
5459
|
+
try {
|
|
5460
|
+
res = await fetch(url, { ...options, headers });
|
|
5461
|
+
} catch (e) {
|
|
5462
|
+
if (e.code === "ECONNREFUSED" || e.cause?.code === "ECONNREFUSED") {
|
|
5463
|
+
throw new Error(`Cannot connect to ${API_URL} — is the server running?`);
|
|
5464
|
+
}
|
|
5465
|
+
if (e.code === "ENOTFOUND" || e.cause?.code === "ENOTFOUND") {
|
|
5466
|
+
throw new Error(`DNS lookup failed for ${API_URL} — check your internet connection`);
|
|
5467
|
+
}
|
|
5468
|
+
if (e.name === "AbortError") {
|
|
5469
|
+
throw new Error(`Request timed out`);
|
|
5470
|
+
}
|
|
5471
|
+
throw new Error(`Network error: ${e.message}`);
|
|
5472
|
+
}
|
|
5456
5473
|
const freeTierRemaining = res.headers.get("x-free-tier-remaining");
|
|
5457
5474
|
if (freeTierRemaining !== null && process.env.DEBUG) {
|
|
5458
5475
|
console.error(`${c.dim}Free tier remaining: ${freeTierRemaining}${c.reset}`);
|
|
@@ -5932,6 +5949,93 @@ async function cmdStats(opts) {
|
|
|
5932
5949
|
}
|
|
5933
5950
|
}
|
|
5934
5951
|
}
|
|
5952
|
+
async function cmdGraph(id, opts) {
|
|
5953
|
+
const result = await request("GET", `/v1/memories/${id}`);
|
|
5954
|
+
const mem = result.memory || result;
|
|
5955
|
+
const relResult = await request("GET", `/v1/memories/${id}/relations`);
|
|
5956
|
+
const relations = relResult.relations || [];
|
|
5957
|
+
if (outputJson) {
|
|
5958
|
+
out({ memory: mem, relations });
|
|
5959
|
+
return;
|
|
5960
|
+
}
|
|
5961
|
+
const label = (m) => {
|
|
5962
|
+
const text = (m.content || "").slice(0, 40);
|
|
5963
|
+
return text.length < (m.content || "").length ? text + "…" : text;
|
|
5964
|
+
};
|
|
5965
|
+
const shortId = (s) => s?.slice(0, 8) || "?";
|
|
5966
|
+
console.log();
|
|
5967
|
+
console.log(` ${c.bold}${c.cyan}[${shortId(mem.id)}]${c.reset} ${label(mem)}`);
|
|
5968
|
+
if (relations.length === 0) {
|
|
5969
|
+
console.log(` ${c.dim} └── (no relations)${c.reset}`);
|
|
5970
|
+
} else {
|
|
5971
|
+
for (let i = 0;i < relations.length; i++) {
|
|
5972
|
+
const r = relations[i];
|
|
5973
|
+
const isLast = i === relations.length - 1;
|
|
5974
|
+
const branch = isLast ? "└" : "├";
|
|
5975
|
+
const typeColor = {
|
|
5976
|
+
contradicts: c.red,
|
|
5977
|
+
supersedes: c.yellow,
|
|
5978
|
+
supports: c.green,
|
|
5979
|
+
derived_from: c.magenta,
|
|
5980
|
+
related_to: c.blue
|
|
5981
|
+
}[r.relation_type] || c.dim;
|
|
5982
|
+
console.log(` ${c.dim} ${branch}──${c.reset} ${typeColor}${r.relation_type}${c.reset} ${c.dim}→${c.reset} ${c.cyan}[${shortId(r.target_id)}]${c.reset}`);
|
|
5983
|
+
}
|
|
5984
|
+
}
|
|
5985
|
+
console.log();
|
|
5986
|
+
}
|
|
5987
|
+
async function cmdPurge(opts) {
|
|
5988
|
+
if (!opts.force) {
|
|
5989
|
+
if (!process.stdin.isTTY) {
|
|
5990
|
+
throw new Error("Use --force to confirm purge in non-interactive mode");
|
|
5991
|
+
}
|
|
5992
|
+
const readline = await import("readline");
|
|
5993
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
5994
|
+
const answer = await new Promise((r) => rl.question(`${c.red}⚠ Delete ALL memories${opts.namespace ? ` in namespace "${opts.namespace}"` : ""}? Type "yes" to confirm: ${c.reset}`, r));
|
|
5995
|
+
rl.close();
|
|
5996
|
+
if (answer.trim().toLowerCase() !== "yes") {
|
|
5997
|
+
console.log(`${c.dim}Aborted.${c.reset}`);
|
|
5998
|
+
return;
|
|
5999
|
+
}
|
|
6000
|
+
}
|
|
6001
|
+
const params = new URLSearchParams({ limit: "100" });
|
|
6002
|
+
if (opts.namespace)
|
|
6003
|
+
params.set("namespace", opts.namespace);
|
|
6004
|
+
let deleted = 0;
|
|
6005
|
+
while (true) {
|
|
6006
|
+
params.set("offset", "0");
|
|
6007
|
+
const result = await request("GET", `/v1/memories?${params}`);
|
|
6008
|
+
const memories = result.memories || result.data || [];
|
|
6009
|
+
if (memories.length === 0)
|
|
6010
|
+
break;
|
|
6011
|
+
for (const mem of memories) {
|
|
6012
|
+
await request("DELETE", `/v1/memories/${mem.id}`);
|
|
6013
|
+
deleted++;
|
|
6014
|
+
if (!outputQuiet)
|
|
6015
|
+
process.stderr.write(`\r ${progressBar(deleted, result.total || deleted)}`);
|
|
6016
|
+
}
|
|
6017
|
+
}
|
|
6018
|
+
if (!outputQuiet)
|
|
6019
|
+
process.stderr.write(`
|
|
6020
|
+
`);
|
|
6021
|
+
if (outputJson) {
|
|
6022
|
+
out({ deleted });
|
|
6023
|
+
} else {
|
|
6024
|
+
success(`Purged ${deleted} memories`);
|
|
6025
|
+
}
|
|
6026
|
+
}
|
|
6027
|
+
async function cmdCount(opts) {
|
|
6028
|
+
const params = new URLSearchParams({ limit: "1" });
|
|
6029
|
+
if (opts.namespace)
|
|
6030
|
+
params.set("namespace", opts.namespace);
|
|
6031
|
+
const result = await request("GET", `/v1/memories?${params}`);
|
|
6032
|
+
const total = result.total ?? "?";
|
|
6033
|
+
if (outputJson) {
|
|
6034
|
+
out({ count: total, namespace: opts.namespace || null });
|
|
6035
|
+
} else {
|
|
6036
|
+
console.log(String(total));
|
|
6037
|
+
}
|
|
6038
|
+
}
|
|
5935
6039
|
async function cmdCompletions(shell) {
|
|
5936
6040
|
const commands = [
|
|
5937
6041
|
"store",
|
|
@@ -5951,7 +6055,10 @@ async function cmdCompletions(shell) {
|
|
|
5951
6055
|
"stats",
|
|
5952
6056
|
"browse",
|
|
5953
6057
|
"completions",
|
|
5954
|
-
"config"
|
|
6058
|
+
"config",
|
|
6059
|
+
"graph",
|
|
6060
|
+
"purge",
|
|
6061
|
+
"count"
|
|
5955
6062
|
];
|
|
5956
6063
|
if (shell === "bash") {
|
|
5957
6064
|
console.log(`# Add to ~/.bashrc:
|
|
@@ -6233,6 +6340,31 @@ Options:
|
|
|
6233
6340
|
--namespace <name> Filter by namespace
|
|
6234
6341
|
|
|
6235
6342
|
Commands inside browser: list, get, recall, store, delete, stats, next, prev`,
|
|
6343
|
+
graph: `${c.bold}memoclaw graph${c.reset} <id>
|
|
6344
|
+
|
|
6345
|
+
Show an ASCII tree of a memory and its relations.
|
|
6346
|
+
|
|
6347
|
+
Options:
|
|
6348
|
+
--json Output as JSON`,
|
|
6349
|
+
purge: `${c.bold}memoclaw purge${c.reset} [options]
|
|
6350
|
+
|
|
6351
|
+
Delete ALL memories. Requires confirmation or --force.
|
|
6352
|
+
|
|
6353
|
+
${c.dim}memoclaw purge --force${c.reset}
|
|
6354
|
+
${c.dim}memoclaw purge --namespace old-project --force${c.reset}
|
|
6355
|
+
|
|
6356
|
+
Options:
|
|
6357
|
+
--force Skip confirmation prompt
|
|
6358
|
+
--namespace <name> Only purge memories in namespace`,
|
|
6359
|
+
count: `${c.bold}memoclaw count${c.reset} [options]
|
|
6360
|
+
|
|
6361
|
+
Print the total number of memories (pipe-friendly).
|
|
6362
|
+
|
|
6363
|
+
${c.dim}memoclaw count${c.reset}
|
|
6364
|
+
${c.dim}memoclaw count --namespace project1${c.reset}
|
|
6365
|
+
|
|
6366
|
+
Options:
|
|
6367
|
+
--namespace <name> Count only in namespace`,
|
|
6236
6368
|
completions: `${c.bold}memoclaw completions${c.reset} <bash|zsh|fish>
|
|
6237
6369
|
|
|
6238
6370
|
Generate shell completion scripts.
|
|
@@ -6272,6 +6404,9 @@ ${c.bold}Commands:${c.reset}
|
|
|
6272
6404
|
${c.cyan}completions${c.reset} <shell> Generate shell completions
|
|
6273
6405
|
${c.cyan}browse${c.reset} Interactive memory browser (REPL)
|
|
6274
6406
|
${c.cyan}config${c.reset} [show|check] Show or validate configuration
|
|
6407
|
+
${c.cyan}graph${c.reset} <id> ASCII visualization of memory relations
|
|
6408
|
+
${c.cyan}purge${c.reset} Delete ALL memories (requires --force or confirm)
|
|
6409
|
+
${c.cyan}count${c.reset} Quick memory count
|
|
6275
6410
|
|
|
6276
6411
|
${c.bold}Global Options:${c.reset}
|
|
6277
6412
|
-h, --help Show help (use with command for details)
|
|
@@ -6282,6 +6417,8 @@ ${c.bold}Global Options:${c.reset}
|
|
|
6282
6417
|
-l, --limit <n> Limit results
|
|
6283
6418
|
-t, --tags <a,b> Comma-separated tags
|
|
6284
6419
|
--raw Raw output (content only, for piping)
|
|
6420
|
+
--force Skip confirmation prompts
|
|
6421
|
+
--timeout <seconds> Request timeout (default: 30)
|
|
6285
6422
|
|
|
6286
6423
|
${c.bold}Environment:${c.reset}
|
|
6287
6424
|
MEMOCLAW_PRIVATE_KEY Wallet private key for auth + payments
|
|
@@ -6317,6 +6454,7 @@ if (args.help) {
|
|
|
6317
6454
|
printHelp(cmd);
|
|
6318
6455
|
process.exit(0);
|
|
6319
6456
|
}
|
|
6457
|
+
var TIMEOUT_MS = args.timeout ? parseInt(args.timeout) * 1000 : 30000;
|
|
6320
6458
|
try {
|
|
6321
6459
|
switch (cmd) {
|
|
6322
6460
|
case "store": {
|
|
@@ -6405,6 +6543,17 @@ try {
|
|
|
6405
6543
|
case "config":
|
|
6406
6544
|
await cmdConfig(rest[0], rest.slice(1));
|
|
6407
6545
|
break;
|
|
6546
|
+
case "graph":
|
|
6547
|
+
if (!rest[0])
|
|
6548
|
+
throw new Error("Memory ID required");
|
|
6549
|
+
await cmdGraph(rest[0], args);
|
|
6550
|
+
break;
|
|
6551
|
+
case "purge":
|
|
6552
|
+
await cmdPurge(args);
|
|
6553
|
+
break;
|
|
6554
|
+
case "count":
|
|
6555
|
+
await cmdCount(args);
|
|
6556
|
+
break;
|
|
6408
6557
|
case "help":
|
|
6409
6558
|
printHelp(rest[0]);
|
|
6410
6559
|
break;
|