@agentmemory/agentmemory 0.9.2 → 0.9.4
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 +8 -3
- package/dist/cli.mjs +235 -26
- package/dist/cli.mjs.map +1 -1
- package/dist/image-refs-BfT7XAa-.mjs +3 -0
- package/dist/{image-store-BLOkD0xV.mjs → image-store-Cn9eD-7D.mjs} +1 -1
- package/dist/index.mjs +231 -36
- package/dist/index.mjs.map +1 -1
- package/dist/{src-tmuZyobT.mjs → src-uDy2jLO-.mjs} +226 -43
- package/dist/src-uDy2jLO-.mjs.map +1 -0
- package/dist/{standalone-BiwX0rdC.mjs → standalone-CqqEcfNR.mjs} +2 -2
- package/dist/{standalone-BiwX0rdC.mjs.map → standalone-CqqEcfNR.mjs.map} +1 -1
- package/dist/standalone.mjs +9 -2
- package/dist/standalone.mjs.map +1 -1
- package/dist/{tools-registry-CHH84gIQ.mjs → tools-registry-Co8VIL4t.mjs} +16 -4
- package/dist/tools-registry-Co8VIL4t.mjs.map +1 -0
- package/dist/viewer/index.html +283 -10
- package/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/dist/image-refs-Dq5wcV-a.mjs +0 -3
- package/dist/src-tmuZyobT.mjs.map +0 -1
- package/dist/tools-registry-CHH84gIQ.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
</p>
|
|
9
9
|
|
|
10
10
|
<p align="center">
|
|
11
|
-
<a href="https://gist.github.com/rohitg00/2067ab416f7bbe447c1977edaaa681e2"><img src="https://img.shields.io/badge/Viral%20GitHub%20Gist-
|
|
11
|
+
<a href="https://gist.github.com/rohitg00/2067ab416f7bbe447c1977edaaa681e2"><img src="https://img.shields.io/badge/Viral%20GitHub%20Gist-1050%20stars%20%2F%20150%20forks-FF6B35?style=for-the-badge&logo=github&logoColor=white&labelColor=1a1a1a" alt="Design doc: 1050 stars / 150 forks on the gist" /></a>
|
|
12
12
|
</p>
|
|
13
13
|
|
|
14
14
|
<p align="center">
|
|
@@ -370,7 +370,7 @@ mcp_servers:
|
|
|
370
370
|
command: npx
|
|
371
371
|
args: ["-y", "@agentmemory/mcp"]
|
|
372
372
|
|
|
373
|
-
Verify with `curl http://localhost:3111/agentmemory/health`. Open http://localhost:3113 for the real-time viewer. For deeper 6-hook memory provider integration (pre-LLM context injection, turn capture, MEMORY.md mirroring, system prompt block), copy integrations/hermes from the agentmemory repo to ~/.hermes/plugins/
|
|
373
|
+
Verify with `curl http://localhost:3111/agentmemory/health`. Open http://localhost:3113 for the real-time viewer. For deeper 6-hook memory provider integration (pre-LLM context injection, turn capture, MEMORY.md mirroring, system prompt block), copy integrations/hermes from the agentmemory repo to ~/.hermes/plugins/agentmemory.
|
|
374
374
|
```
|
|
375
375
|
|
|
376
376
|
Full guide: [`integrations/hermes/`](integrations/hermes/)
|
|
@@ -506,7 +506,12 @@ PostToolUse hook fires
|
|
|
506
506
|
-> Store raw observation
|
|
507
507
|
-> LLM compress -> structured facts + concepts + narrative
|
|
508
508
|
-> Vector embedding (6 providers + local)
|
|
509
|
-
-> Index in BM25 + vector
|
|
509
|
+
-> Index in BM25 + vector
|
|
510
|
+
|
|
511
|
+
Stop / SessionEnd hook fires
|
|
512
|
+
-> Summarize session
|
|
513
|
+
-> Knowledge graph extraction (if GRAPH_EXTRACTION_ENABLED=true)
|
|
514
|
+
-> Slot reflection (if SLOT_REFLECT_ENABLED=true)
|
|
510
515
|
|
|
511
516
|
SessionStart hook fires
|
|
512
517
|
-> Load project profile (top concepts, files, patterns)
|
package/dist/cli.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { execFileSync, spawn, spawnSync } from "node:child_process";
|
|
3
|
-
import { existsSync } from "node:fs";
|
|
3
|
+
import { existsSync, readFileSync, readdirSync, readlinkSync, statSync } from "node:fs";
|
|
4
4
|
import { delimiter, dirname, join } from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
|
-
import { platform } from "node:os";
|
|
6
|
+
import { homedir, platform } from "node:os";
|
|
7
7
|
import * as p from "@clack/prompts";
|
|
8
8
|
import { createHash } from "node:crypto";
|
|
9
9
|
|
|
@@ -92,11 +92,14 @@ Usage: agentmemory [command] [options]
|
|
|
92
92
|
|
|
93
93
|
Commands:
|
|
94
94
|
(default) Start agentmemory worker
|
|
95
|
-
status Show connection status, memory count, and health
|
|
95
|
+
status Show connection status, memory count, flags, and health
|
|
96
|
+
doctor Run diagnostic checks (server, flags, graph, providers)
|
|
96
97
|
demo Seed sample sessions and show recall in action
|
|
97
98
|
upgrade Upgrade local deps + iii runtime (best effort)
|
|
98
99
|
mcp Start standalone MCP server (no engine required)
|
|
99
100
|
import-jsonl [p] Import Claude Code JSONL transcripts (default: ~/.claude/projects)
|
|
101
|
+
--max-files <N> | --max-files=<N>: override scan cap (default 200, max 1000;
|
|
102
|
+
out-of-range is rejected; for trees >1000 files, batch by subdirectory)
|
|
100
103
|
|
|
101
104
|
Options:
|
|
102
105
|
--help, -h Show this help
|
|
@@ -105,10 +108,15 @@ Options:
|
|
|
105
108
|
--no-engine Skip auto-starting iii-engine
|
|
106
109
|
--port <N> Override REST port (default: 3111)
|
|
107
110
|
|
|
111
|
+
Environment:
|
|
112
|
+
AGENTMEMORY_URL Full REST base URL (e.g. http://localhost:3111).
|
|
113
|
+
Honored by status, doctor, and MCP shim commands.
|
|
114
|
+
|
|
108
115
|
Quick start:
|
|
109
116
|
npx @agentmemory/agentmemory # start with local iii-engine or Docker
|
|
110
|
-
npx @agentmemory/agentmemory
|
|
111
|
-
npx @agentmemory/agentmemory
|
|
117
|
+
npx @agentmemory/agentmemory demo # see semantic recall in 30 seconds
|
|
118
|
+
npx @agentmemory/agentmemory doctor # diagnose config + feature flags
|
|
119
|
+
npx @agentmemory/agentmemory status # health + memory count + flags
|
|
112
120
|
npx @agentmemory/agentmemory upgrade # upgrade agentmemory + iii runtime
|
|
113
121
|
npx @agentmemory/agentmemory mcp # standalone MCP server (no engine)
|
|
114
122
|
npx @agentmemory/mcp # same as above (shim package)
|
|
@@ -121,11 +129,32 @@ const portIdx = args.indexOf("--port");
|
|
|
121
129
|
if (portIdx !== -1 && args[portIdx + 1]) process.env["III_REST_PORT"] = args[portIdx + 1];
|
|
122
130
|
const skipEngine = args.includes("--no-engine");
|
|
123
131
|
function getRestPort() {
|
|
132
|
+
const url = process.env["AGENTMEMORY_URL"];
|
|
133
|
+
if (url) try {
|
|
134
|
+
const parsed = new URL(url).port;
|
|
135
|
+
if (parsed) return parseInt(parsed, 10);
|
|
136
|
+
} catch {}
|
|
124
137
|
return parseInt(process.env["III_REST_PORT"] || "3111", 10) || 3111;
|
|
125
138
|
}
|
|
139
|
+
function getBaseUrl() {
|
|
140
|
+
const url = process.env["AGENTMEMORY_URL"];
|
|
141
|
+
if (url) return url.replace(/\/+$/, "");
|
|
142
|
+
return `http://localhost:${getRestPort()}`;
|
|
143
|
+
}
|
|
144
|
+
function getViewerUrl() {
|
|
145
|
+
const envUrl = process.env["AGENTMEMORY_VIEWER_URL"];
|
|
146
|
+
if (envUrl) return envUrl.replace(/\/+$/, "");
|
|
147
|
+
try {
|
|
148
|
+
const u = new URL(getBaseUrl());
|
|
149
|
+
const vPort = (parseInt(u.port || "3111", 10) || 3111) + 2;
|
|
150
|
+
return `${u.protocol}//${u.hostname}:${vPort}`;
|
|
151
|
+
} catch {
|
|
152
|
+
return `http://localhost:${getRestPort() + 2}`;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
126
155
|
async function isEngineRunning() {
|
|
127
156
|
try {
|
|
128
|
-
await fetch(
|
|
157
|
+
await fetch(`${getBaseUrl()}/`, { signal: AbortSignal.timeout(2e3) });
|
|
129
158
|
return true;
|
|
130
159
|
} catch {
|
|
131
160
|
return false;
|
|
@@ -133,7 +162,7 @@ async function isEngineRunning() {
|
|
|
133
162
|
}
|
|
134
163
|
async function isAgentmemoryReady() {
|
|
135
164
|
try {
|
|
136
|
-
return (await fetch(
|
|
165
|
+
return (await fetch(`${getBaseUrl()}/agentmemory/livez`, { signal: AbortSignal.timeout(2e3) })).ok;
|
|
137
166
|
} catch {
|
|
138
167
|
return false;
|
|
139
168
|
}
|
|
@@ -299,12 +328,12 @@ async function main() {
|
|
|
299
328
|
p.intro("agentmemory");
|
|
300
329
|
if (skipEngine) {
|
|
301
330
|
p.log.info("Skipping engine check (--no-engine)");
|
|
302
|
-
await import("./src-
|
|
331
|
+
await import("./src-uDy2jLO-.mjs");
|
|
303
332
|
return;
|
|
304
333
|
}
|
|
305
334
|
if (await isEngineRunning()) {
|
|
306
335
|
p.log.success("iii-engine is running");
|
|
307
|
-
await import("./src-
|
|
336
|
+
await import("./src-uDy2jLO-.mjs");
|
|
308
337
|
return;
|
|
309
338
|
}
|
|
310
339
|
if (!await startEngine()) {
|
|
@@ -348,30 +377,38 @@ async function main() {
|
|
|
348
377
|
process.exit(1);
|
|
349
378
|
}
|
|
350
379
|
s.stop("iii-engine is ready");
|
|
351
|
-
await import("./src-
|
|
380
|
+
await import("./src-uDy2jLO-.mjs");
|
|
381
|
+
}
|
|
382
|
+
async function apiFetch(base, path, timeoutMs = 5e3) {
|
|
383
|
+
try {
|
|
384
|
+
return await (await fetch(`${base}/agentmemory/${path}`, { signal: AbortSignal.timeout(timeoutMs) })).json();
|
|
385
|
+
} catch {
|
|
386
|
+
return null;
|
|
387
|
+
}
|
|
352
388
|
}
|
|
353
389
|
async function runStatus() {
|
|
354
|
-
|
|
355
|
-
const base =
|
|
390
|
+
getRestPort();
|
|
391
|
+
const base = getBaseUrl();
|
|
356
392
|
p.intro("agentmemory status");
|
|
357
393
|
if (!await isEngineRunning()) {
|
|
358
|
-
p.log.error(`Not running — no response
|
|
394
|
+
p.log.error(`Not running — no response at ${base}`);
|
|
359
395
|
p.log.info("Start with: npx @agentmemory/agentmemory");
|
|
360
396
|
process.exit(1);
|
|
361
397
|
}
|
|
362
398
|
try {
|
|
363
|
-
const [healthRes, sessionsRes, graphRes, memoriesRes] = await Promise.all([
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
399
|
+
const [healthRes, sessionsRes, graphRes, memoriesRes, flagsRes] = await Promise.all([
|
|
400
|
+
apiFetch(base, "health"),
|
|
401
|
+
apiFetch(base, "sessions"),
|
|
402
|
+
apiFetch(base, "graph/stats"),
|
|
403
|
+
apiFetch(base, "export"),
|
|
404
|
+
apiFetch(base, "config/flags")
|
|
368
405
|
]);
|
|
369
406
|
const h = healthRes?.health;
|
|
370
407
|
const status = healthRes?.status || "unknown";
|
|
371
408
|
const version = healthRes?.version || "?";
|
|
372
409
|
const sessions = Array.isArray(sessionsRes?.sessions) ? sessionsRes.sessions.length : 0;
|
|
373
|
-
const nodes = graphRes?.nodes
|
|
374
|
-
const edges = graphRes?.edges
|
|
410
|
+
const nodes = Number(graphRes?.totalNodes ?? graphRes?.nodes ?? graphRes?.nodeCount ?? 0);
|
|
411
|
+
const edges = Number(graphRes?.totalEdges ?? graphRes?.edges ?? graphRes?.edgeCount ?? 0);
|
|
375
412
|
const cb = healthRes?.circuitBreaker?.state || "closed";
|
|
376
413
|
const heapMB = h?.memory ? Math.round(h.memory.heapUsed / 1048576) : 0;
|
|
377
414
|
const uptime = h?.uptimeSeconds ? Math.round(h.uptimeSeconds) : 0;
|
|
@@ -381,7 +418,7 @@ async function runStatus() {
|
|
|
381
418
|
const estInjectedTokens = Math.min(obsCount, 50) * 38;
|
|
382
419
|
const tokensSaved = estFullTokens - estInjectedTokens;
|
|
383
420
|
const pctSaved = estFullTokens > 0 ? Math.round(tokensSaved / estFullTokens * 100) : 0;
|
|
384
|
-
p.log.success(`Connected — v${version}
|
|
421
|
+
p.log.success(`Connected — v${version} at ${base}`);
|
|
385
422
|
const lines = [
|
|
386
423
|
`Health: ${status === "healthy" ? "✓ healthy" : status}`,
|
|
387
424
|
`Sessions: ${sessions}`,
|
|
@@ -391,7 +428,7 @@ async function runStatus() {
|
|
|
391
428
|
`Circuit: ${cb}`,
|
|
392
429
|
`Heap: ${heapMB} MB`,
|
|
393
430
|
`Uptime: ${uptime}s`,
|
|
394
|
-
`Viewer:
|
|
431
|
+
`Viewer: ${getViewerUrl()}`
|
|
395
432
|
];
|
|
396
433
|
if (obsCount > 0) {
|
|
397
434
|
lines.push("");
|
|
@@ -399,12 +436,143 @@ async function runStatus() {
|
|
|
399
436
|
lines.push(` Full context: ~${estFullTokens.toLocaleString()} tokens`);
|
|
400
437
|
lines.push(` Injected: ~${estInjectedTokens.toLocaleString()} tokens`);
|
|
401
438
|
}
|
|
439
|
+
if (flagsRes) {
|
|
440
|
+
const provider = flagsRes.provider === "llm" ? "✓ llm" : "✗ noop (no key)";
|
|
441
|
+
const embed = flagsRes.embeddingProvider === "embeddings" ? "✓ embeddings" : "bm25-only";
|
|
442
|
+
const flagRows = (flagsRes.flags || []).map((f) => ` ${f.enabled ? "✓" : "✗"} ${f.key.padEnd(32)} ${f.label}`);
|
|
443
|
+
lines.push("");
|
|
444
|
+
lines.push(`Provider: ${provider}`);
|
|
445
|
+
lines.push(`Embeddings: ${embed}`);
|
|
446
|
+
lines.push(`Flags:`);
|
|
447
|
+
flagRows.forEach((r) => lines.push(r));
|
|
448
|
+
}
|
|
402
449
|
p.note(lines.join("\n"), "agentmemory");
|
|
403
450
|
} catch (err) {
|
|
404
451
|
p.log.error(err instanceof Error ? err.message : String(err));
|
|
405
452
|
process.exit(1);
|
|
406
453
|
}
|
|
407
454
|
}
|
|
455
|
+
function formatChecks(checks) {
|
|
456
|
+
return checks.map((c) => `${c.ok ? "✓" : "✗"} ${c.name}${c.hint ? `\n ${c.hint}` : ""}`).join("\n");
|
|
457
|
+
}
|
|
458
|
+
function findLatestDebugLog(debugDir) {
|
|
459
|
+
const latestLink = join(debugDir, "latest");
|
|
460
|
+
try {
|
|
461
|
+
if (existsSync(latestLink)) {
|
|
462
|
+
const target = readlinkSync(latestLink);
|
|
463
|
+
const resolved = target.startsWith("/") ? target : join(debugDir, target);
|
|
464
|
+
if (existsSync(resolved)) return resolved;
|
|
465
|
+
}
|
|
466
|
+
} catch {}
|
|
467
|
+
try {
|
|
468
|
+
const newest = readdirSync(debugDir).filter((f) => f.endsWith(".txt")).map((f) => ({
|
|
469
|
+
f,
|
|
470
|
+
m: statSync(join(debugDir, f)).mtimeMs
|
|
471
|
+
})).sort((a, b) => b.m - a.m)[0];
|
|
472
|
+
if (newest) return join(debugDir, newest.f);
|
|
473
|
+
} catch {}
|
|
474
|
+
}
|
|
475
|
+
function checkClaudeCodeHooks() {
|
|
476
|
+
const debugDir = join(homedir(), ".claude", "debug");
|
|
477
|
+
if (!existsSync(debugDir)) return { state: "no-cc-dir" };
|
|
478
|
+
const logPath = findLatestDebugLog(debugDir);
|
|
479
|
+
if (!logPath) return { state: "no-debug-log" };
|
|
480
|
+
let content;
|
|
481
|
+
try {
|
|
482
|
+
content = readFileSync(logPath, "utf8");
|
|
483
|
+
} catch {
|
|
484
|
+
return { state: "no-debug-log" };
|
|
485
|
+
}
|
|
486
|
+
const match = content.match(/Loaded hooks from standard location for plugin agentmemory:\s*(\S+)/);
|
|
487
|
+
if (match) return {
|
|
488
|
+
state: "loaded",
|
|
489
|
+
manifestPath: match[1]
|
|
490
|
+
};
|
|
491
|
+
if (content.includes("Loading hooks from plugin: agentmemory")) return { state: "loaded" };
|
|
492
|
+
return { state: "not-loaded" };
|
|
493
|
+
}
|
|
494
|
+
async function runDoctor() {
|
|
495
|
+
p.intro("agentmemory doctor");
|
|
496
|
+
const base = getBaseUrl();
|
|
497
|
+
const viewerUrl = getViewerUrl();
|
|
498
|
+
const checks = [];
|
|
499
|
+
const serverUp = await isEngineRunning();
|
|
500
|
+
checks.push({
|
|
501
|
+
name: "Server reachable",
|
|
502
|
+
ok: serverUp,
|
|
503
|
+
hint: serverUp ? void 0 : `Start with: npx @agentmemory/agentmemory (tried ${base})`
|
|
504
|
+
});
|
|
505
|
+
if (!serverUp) {
|
|
506
|
+
p.note(formatChecks(checks), "server unreachable");
|
|
507
|
+
process.exit(1);
|
|
508
|
+
}
|
|
509
|
+
const [health, flags, graph] = await Promise.all([
|
|
510
|
+
apiFetch(base, "health", 3e3),
|
|
511
|
+
apiFetch(base, "config/flags", 3e3),
|
|
512
|
+
apiFetch(base, "graph/stats", 3e3)
|
|
513
|
+
]);
|
|
514
|
+
const viewerUp = await fetch(viewerUrl, { signal: AbortSignal.timeout(2e3) }).then((r) => r.ok).catch(() => false);
|
|
515
|
+
const hasLlm = flags?.provider === "llm";
|
|
516
|
+
const hasEmbed = flags?.embeddingProvider === "embeddings";
|
|
517
|
+
const graphHas = Number(graph?.totalNodes ?? graph?.nodes ?? graph?.nodeCount ?? 0) > 0;
|
|
518
|
+
checks.push({
|
|
519
|
+
name: "Health status",
|
|
520
|
+
ok: health?.status === "healthy",
|
|
521
|
+
hint: health?.status === "healthy" ? void 0 : `Status: ${health?.status || "unknown"}`
|
|
522
|
+
}, {
|
|
523
|
+
name: "Viewer reachable",
|
|
524
|
+
ok: viewerUp,
|
|
525
|
+
hint: viewerUp ? void 0 : `${viewerUrl} not responding`
|
|
526
|
+
}, {
|
|
527
|
+
name: "LLM provider",
|
|
528
|
+
ok: hasLlm,
|
|
529
|
+
hint: hasLlm ? void 0 : "export ANTHROPIC_API_KEY=sk-ant-... (or GEMINI/OPENROUTER/MINIMAX) then restart"
|
|
530
|
+
}, {
|
|
531
|
+
name: "Embedding provider",
|
|
532
|
+
ok: hasEmbed,
|
|
533
|
+
hint: hasEmbed ? void 0 : "Running BM25-only. Add OPENAI_API_KEY / VOYAGE_API_KEY / COHERE_API_KEY / OLLAMA_HOST for semantic recall"
|
|
534
|
+
});
|
|
535
|
+
for (const f of flags?.flags || []) checks.push({
|
|
536
|
+
name: f.label,
|
|
537
|
+
ok: f.enabled,
|
|
538
|
+
hint: f.enabled ? void 0 : f.enableHow
|
|
539
|
+
});
|
|
540
|
+
const cc = checkClaudeCodeHooks();
|
|
541
|
+
const ccCheck = (() => {
|
|
542
|
+
switch (cc.state) {
|
|
543
|
+
case "loaded": return {
|
|
544
|
+
ok: true,
|
|
545
|
+
hint: cc.manifestPath ? `manifest: ${cc.manifestPath}` : void 0
|
|
546
|
+
};
|
|
547
|
+
case "not-loaded": return {
|
|
548
|
+
ok: false,
|
|
549
|
+
hint: "Plugin enabled but hooks not loaded by Claude Code. Try: /plugin uninstall agentmemory@agentmemory && /plugin install agentmemory@agentmemory, then restart the session. CC must be >= 2.1.x for plugin-hook auto-load."
|
|
550
|
+
};
|
|
551
|
+
case "no-debug-log": return {
|
|
552
|
+
ok: false,
|
|
553
|
+
hint: "Cannot verify — no Claude Code debug log found. Run once with `claude --debug -p \"x\"`, then re-run doctor."
|
|
554
|
+
};
|
|
555
|
+
case "no-cc-dir": return;
|
|
556
|
+
}
|
|
557
|
+
})();
|
|
558
|
+
if (ccCheck) checks.push({
|
|
559
|
+
name: "Claude Code plugin hooks registered",
|
|
560
|
+
...ccCheck
|
|
561
|
+
});
|
|
562
|
+
checks.push({
|
|
563
|
+
name: "Knowledge graph populated",
|
|
564
|
+
ok: graphHas,
|
|
565
|
+
hint: graphHas ? void 0 : "Graph is empty. Run a session with GRAPH_EXTRACTION_ENABLED=true, or POST /agentmemory/graph/extract"
|
|
566
|
+
});
|
|
567
|
+
const passed = checks.filter((c) => c.ok).length;
|
|
568
|
+
const total = checks.length;
|
|
569
|
+
p.note(formatChecks(checks), `${passed}/${total} checks passing`);
|
|
570
|
+
if (passed === total) p.outro("✓ All checks passed. agentmemory is healthy.");
|
|
571
|
+
else {
|
|
572
|
+
p.outro(`${total - passed} issue(s) — follow hints above to fix.`);
|
|
573
|
+
process.exit(1);
|
|
574
|
+
}
|
|
575
|
+
}
|
|
408
576
|
function buildDemoSessions() {
|
|
409
577
|
return [
|
|
410
578
|
{
|
|
@@ -565,7 +733,7 @@ async function runDemo() {
|
|
|
565
733
|
`Notice: searching "database performance optimization"`,
|
|
566
734
|
`found the N+1 query fix — keyword matching can't do that.`,
|
|
567
735
|
"",
|
|
568
|
-
`Viewer:
|
|
736
|
+
`Viewer: ${getViewerUrl()}`,
|
|
569
737
|
`Clean up with: curl -X DELETE "${base}/agentmemory/sessions?project=${demoProject}"`
|
|
570
738
|
];
|
|
571
739
|
p.note(lines.join("\n"), "demo complete");
|
|
@@ -657,10 +825,38 @@ async function runUpgrade() {
|
|
|
657
825
|
].join("\n"), "agentmemory upgrade");
|
|
658
826
|
}
|
|
659
827
|
async function runMcp() {
|
|
660
|
-
await import("./standalone-
|
|
828
|
+
await import("./standalone-CqqEcfNR.mjs");
|
|
661
829
|
}
|
|
662
830
|
async function runImportJsonl() {
|
|
663
|
-
const
|
|
831
|
+
const VALUE_FLAGS = new Set(["--port", "--tools"]);
|
|
832
|
+
let maxFiles;
|
|
833
|
+
const tail = args.slice(1);
|
|
834
|
+
const positional = [];
|
|
835
|
+
for (let i = 0; i < tail.length; i++) {
|
|
836
|
+
const a = tail[i];
|
|
837
|
+
if (a === "--max-files") {
|
|
838
|
+
const raw = tail[i + 1];
|
|
839
|
+
const parsed = raw !== void 0 ? parseInt(raw, 10) : NaN;
|
|
840
|
+
if (Number.isInteger(parsed) && parsed > 0) maxFiles = parsed;
|
|
841
|
+
else if (raw !== void 0) p.log.warn(`Ignoring --max-files ${raw}: expected a positive integer.`);
|
|
842
|
+
i++;
|
|
843
|
+
continue;
|
|
844
|
+
}
|
|
845
|
+
if (a.startsWith("--max-files=")) {
|
|
846
|
+
const raw = a.slice(12);
|
|
847
|
+
const parsed = parseInt(raw, 10);
|
|
848
|
+
if (Number.isInteger(parsed) && parsed > 0) maxFiles = parsed;
|
|
849
|
+
else p.log.warn(`Ignoring --max-files=${raw}: expected a positive integer.`);
|
|
850
|
+
continue;
|
|
851
|
+
}
|
|
852
|
+
if (VALUE_FLAGS.has(a)) {
|
|
853
|
+
i++;
|
|
854
|
+
continue;
|
|
855
|
+
}
|
|
856
|
+
if (a.startsWith("-")) continue;
|
|
857
|
+
positional.push(a);
|
|
858
|
+
}
|
|
859
|
+
const pathArg = positional[0];
|
|
664
860
|
const port = getRestPort();
|
|
665
861
|
const base = `http://localhost:${port}`;
|
|
666
862
|
let probeOk = false;
|
|
@@ -682,6 +878,7 @@ async function runImportJsonl() {
|
|
|
682
878
|
}
|
|
683
879
|
const body = {};
|
|
684
880
|
if (pathArg) body["path"] = pathArg;
|
|
881
|
+
if (maxFiles !== void 0) body["maxFiles"] = maxFiles;
|
|
685
882
|
const headers = { "content-type": "application/json" };
|
|
686
883
|
const secret = process.env["AGENTMEMORY_SECRET"];
|
|
687
884
|
if (secret) headers["authorization"] = `Bearer ${secret}`;
|
|
@@ -713,7 +910,18 @@ async function runImportJsonl() {
|
|
|
713
910
|
process.exit(1);
|
|
714
911
|
}
|
|
715
912
|
spinner.stop(`imported ${json.imported ?? 0} file(s), ${json.observations ?? 0} observation(s) across ${json.sessionIds?.length || 0} session(s)`);
|
|
716
|
-
if (json.
|
|
913
|
+
if (json.truncated) {
|
|
914
|
+
const cap = json.maxFiles ?? 200;
|
|
915
|
+
const upper = json.maxFilesUpperBound ?? 1e3;
|
|
916
|
+
const discovered = json.discovered ?? 0;
|
|
917
|
+
const baseMsg = `Hit the ${cap}-file scan cap; ${discovered - (json.imported ?? 0)} of ${json.traversalCapped ? `${discovered}+ (traversal halted at safety cap)` : String(discovered)} discovered file(s) were skipped.`;
|
|
918
|
+
if (discovered > upper || json.traversalCapped) p.log.warn(`${baseMsg} Tree exceeds the server's --max-files limit of ${upper}; batch by subdirectory (run import-jsonl once per project under ~/.claude/projects).`);
|
|
919
|
+
else {
|
|
920
|
+
const suggested = Math.min(Math.max((discovered || cap) + 100, cap * 2), upper);
|
|
921
|
+
p.log.warn(`${baseMsg} Re-run with --max-files=${suggested} (max ${upper}) or batch by subdirectory.`);
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
if (json.sessionIds && json.sessionIds.length > 0) p.log.info(`View at ${getViewerUrl()} → Replay tab`);
|
|
717
925
|
} catch (err) {
|
|
718
926
|
spinner.stop("failed");
|
|
719
927
|
if (err instanceof Error && err.name === "TimeoutError") p.log.error("import timed out after 2 minutes");
|
|
@@ -723,6 +931,7 @@ async function runImportJsonl() {
|
|
|
723
931
|
}
|
|
724
932
|
({
|
|
725
933
|
status: runStatus,
|
|
934
|
+
doctor: runDoctor,
|
|
726
935
|
demo: runDemo,
|
|
727
936
|
upgrade: runUpgrade,
|
|
728
937
|
mcp: runMcp,
|