clawmem 0.3.0 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/clawmem.ts +87 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawmem",
3
- "version": "0.3.0",
3
+ "version": "0.3.3",
4
4
  "description": "On-device context engine and memory for AI agents. Claude Code and OpenClaw. Hooks + MCP server + hybrid RAG search.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/clawmem.ts CHANGED
@@ -461,6 +461,81 @@ async function cmdStatus() {
461
461
  }
462
462
  }
463
463
 
464
+ async function cmdList(args: string[]) {
465
+ const { values } = parseArgs({
466
+ args,
467
+ options: {
468
+ num: { type: "string", short: "n", default: "10" },
469
+ limit: { type: "string" }, // alias for --num (matches issue request)
470
+ collection: { type: "string", short: "c" },
471
+ json: { type: "boolean", default: false },
472
+ },
473
+ allowPositionals: false,
474
+ });
475
+
476
+ const limit = parseInt(values.limit || values.num!, 10);
477
+ if (isNaN(limit) || limit < 1) die("--num must be a positive integer");
478
+
479
+ const s = getStore();
480
+ const col = values.collection || null;
481
+
482
+ const rows = s.db.prepare(`
483
+ SELECT
484
+ substr(hash, 1, 6) AS docid,
485
+ title,
486
+ collection,
487
+ path,
488
+ content_type,
489
+ modified_at,
490
+ confidence,
491
+ access_count
492
+ FROM documents
493
+ WHERE active = 1
494
+ AND invalidated_at IS NULL
495
+ AND (? IS NULL OR collection = ?)
496
+ ORDER BY COALESCE(modified_at, created_at) DESC, id DESC
497
+ LIMIT ?
498
+ `).all(col, col, limit) as {
499
+ docid: string;
500
+ title: string | null;
501
+ collection: string;
502
+ path: string;
503
+ content_type: string | null;
504
+ modified_at: string | null;
505
+ confidence: number | null;
506
+ access_count: number | null;
507
+ }[];
508
+
509
+ if (rows.length === 0) {
510
+ console.log(col ? `No documents in collection "${col}".` : "No documents in vault.");
511
+ return;
512
+ }
513
+
514
+ if (values.json) {
515
+ console.log(JSON.stringify(rows.map(r => ({
516
+ docid: r.docid,
517
+ title: r.title || null,
518
+ collection: r.collection,
519
+ path: r.path,
520
+ contentType: r.content_type || "note",
521
+ modifiedAt: r.modified_at || null,
522
+ confidence: r.confidence ?? 1.0,
523
+ accessCount: r.access_count ?? 0,
524
+ })), null, 2));
525
+ return;
526
+ }
527
+
528
+ console.log(`${c.bold}Recent documents${col ? ` (${col})` : ""}:${c.reset}\n`);
529
+ for (const r of rows) {
530
+ const date = r.modified_at?.slice(0, 10) || "-";
531
+ const type = r.content_type || "note";
532
+ const raw = r.title || r.path;
533
+ const title = raw.length > 60 ? raw.slice(0, 57) + "..." : raw;
534
+ console.log(` ${c.dim}${r.docid}${c.reset} ${date} ${c.dim}[${type}]${c.reset} ${r.collection} ${title}`);
535
+ }
536
+ console.log(`\n${rows.length} document${rows.length !== 1 ? "s" : ""} shown.`);
537
+ }
538
+
464
539
  async function cmdSearch(args: string[]) {
465
540
  const { values, positionals } = parseArgs({
466
541
  args,
@@ -970,11 +1045,15 @@ async function cmdSetupHooks(args: string[]) {
970
1045
  Stop: ["decision-extractor", "handoff-generator", "feedback-loop"],
971
1046
  };
972
1047
 
1048
+ // Use Claude Code's native timeout property instead of shell `timeout` wrapper.
1049
+ // Shell `timeout` kills the process with SIGTERM (exit 124) which produces
1050
+ // "Stop hook error: Failed with non-blocking status code" in Claude Code.
1051
+ // Native timeout is handled gracefully by the hook runner.
973
1052
  const timeouts: Record<string, number> = {
974
1053
  UserPromptSubmit: 8,
975
1054
  SessionStart: 5,
976
1055
  PreCompact: 5,
977
- Stop: 10,
1056
+ Stop: 30, // LLM-based extraction hooks need more time
978
1057
  };
979
1058
 
980
1059
  for (const [event, hooks] of Object.entries(hookConfig)) {
@@ -987,12 +1066,13 @@ async function cmdSetupHooks(args: string[]) {
987
1066
 
988
1067
  const timeout = timeouts[event] || 5;
989
1068
 
990
- // Add new entries with timeout wrappers
1069
+ // Add new entries with native timeout property
991
1070
  settings.hooks[event].push({
992
1071
  matcher: "",
993
1072
  hooks: hooks.map(name => ({
994
1073
  type: "command",
995
- command: `timeout ${timeout} ${binPath} hook ${name}`,
1074
+ command: `${binPath} hook ${name}`,
1075
+ timeout,
996
1076
  })),
997
1077
  });
998
1078
  }
@@ -1621,6 +1701,9 @@ async function main() {
1621
1701
  case "status":
1622
1702
  await cmdStatus();
1623
1703
  break;
1704
+ case "list":
1705
+ await cmdList(subArgs);
1706
+ break;
1624
1707
  case "search":
1625
1708
  await cmdSearch(subArgs);
1626
1709
  break;
@@ -2217,6 +2300,7 @@ ${c.bold}Search:${c.reset}
2217
2300
  clawmem query <query> [-n N] Hybrid + rerank (best)
2218
2301
 
2219
2302
  ${c.bold}Memory:${c.reset}
2303
+ clawmem list [-n/--limit N] [-c col] Browse recent documents (--json for machine output)
2220
2304
  clawmem budget [--session ID] Token utilization
2221
2305
  clawmem log [--last N] Session history
2222
2306
  clawmem profile Show user profile