@agentmemory/agentmemory 0.8.12 → 0.9.1
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 +70 -3
- package/dist/cli.mjs +80 -15
- package/dist/cli.mjs.map +1 -1
- package/dist/index.mjs +627 -31
- package/dist/index.mjs.map +1 -1
- package/dist/{src-68MXysnV.mjs → src-Dw_gJcCy.mjs} +619 -27
- package/dist/src-Dw_gJcCy.mjs.map +1 -0
- package/dist/standalone-BEWvWM5P.mjs +457 -0
- package/dist/standalone-BEWvWM5P.mjs.map +1 -0
- package/dist/standalone.d.mts.map +1 -1
- package/dist/standalone.mjs +210 -67
- package/dist/standalone.mjs.map +1 -1
- package/dist/{tools-registry-D96ukJg4.mjs → tools-registry-BvWNlj6u.mjs} +11 -7
- package/dist/tools-registry-BvWNlj6u.mjs.map +1 -0
- package/dist/viewer/index.html +265 -1
- package/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/dist/src-68MXysnV.mjs.map +0 -1
- package/dist/standalone-c2xiEQJ9.mjs +0 -314
- package/dist/standalone-c2xiEQJ9.mjs.map +0 -1
- package/dist/tools-registry-D96ukJg4.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-825%20stars%20%2F%20110%20forks-FF6B35?style=for-the-badge&logo=github&logoColor=white&labelColor=1a1a1a" alt="Design doc: 825 stars / 110 forks on the gist" /></a>
|
|
12
12
|
</p>
|
|
13
13
|
|
|
14
14
|
<p align="center">
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
<a href="#how-it-works">How It Works</a> •
|
|
44
44
|
<a href="#mcp-server">MCP</a> •
|
|
45
45
|
<a href="#real-time-viewer">Viewer</a> •
|
|
46
|
+
<a href="#iii-console--trace-level-engine-inspection">iii Console</a> •
|
|
46
47
|
<a href="#configuration">Config</a> •
|
|
47
48
|
<a href="#api">API</a>
|
|
48
49
|
</p>
|
|
@@ -154,7 +155,7 @@ You explain the same architecture every session. You re-discover the same bugs.
|
|
|
154
155
|
npx @agentmemory/agentmemory
|
|
155
156
|
```
|
|
156
157
|
|
|
157
|
-
> **New in v0.
|
|
158
|
+
> **New in v0.9.0** — Landing site at [agent-memory.dev](https://agent-memory.dev), filesystem connector (`@agentmemory/fs-watcher`), standalone MCP now proxies to the running server so hooks and the viewer agree, audit policy codified across every delete path, health stops flagging `memory_critical` on tiny Node processes. Full notes in [CHANGELOG.md](CHANGELOG.md#090--2026-04-18).
|
|
158
159
|
|
|
159
160
|
---
|
|
160
161
|
|
|
@@ -302,6 +303,22 @@ npx @agentmemory/agentmemory demo
|
|
|
302
303
|
|
|
303
304
|
Open `http://localhost:3113` to watch the memory build live.
|
|
304
305
|
|
|
306
|
+
### Session Replay
|
|
307
|
+
|
|
308
|
+
Every session agentmemory records is replayable. Open the viewer, pick the **Replay** tab, and scrub through the timeline: prompts, tool calls, tool results, and responses render as discrete events with play/pause, speed control (0.5×–4×), and keyboard shortcuts (space to toggle, arrows to step).
|
|
309
|
+
|
|
310
|
+
Already have older Claude Code JSONL transcripts you want to bring in?
|
|
311
|
+
|
|
312
|
+
```bash
|
|
313
|
+
# Import everything under the default ~/.claude/projects
|
|
314
|
+
npx @agentmemory/agentmemory import-jsonl
|
|
315
|
+
|
|
316
|
+
# Or import a single file
|
|
317
|
+
npx @agentmemory/agentmemory import-jsonl ~/.claude/projects/-my-project/abc123.jsonl
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
Imported sessions show up in the Replay picker alongside native ones. Under the hood each entry routes through the `mem::replay::load`, `mem::replay::sessions`, and `mem::replay::import-jsonl` iii functions — no side-channel servers.
|
|
321
|
+
|
|
305
322
|
### Upgrade / Maintenance
|
|
306
323
|
|
|
307
324
|
Use the maintenance command when you intentionally want to update your local runtime:
|
|
@@ -702,6 +719,56 @@ open http://localhost:3113
|
|
|
702
719
|
|
|
703
720
|
The viewer server binds to `127.0.0.1` by default. The REST-served `/agentmemory/viewer` endpoint follows the normal `AGENTMEMORY_SECRET` bearer-token rules. CSP headers use a per-response script nonce and disable inline handler attributes (`script-src-attr 'none'`).
|
|
704
721
|
|
|
722
|
+
### iii console — trace-level engine inspection
|
|
723
|
+
|
|
724
|
+
agentmemory runs on the [iii engine](https://iii.dev), so the official [iii console](https://iii.dev/docs/console) gives you OpenTelemetry traces, the raw key/value state store, the stream monitor, and a direct function invoker for every piece of memory machinery. Use it to watch a `memory.search` call hit BM25 → embeddings → reranker in real time, replay a hook invocation, or poke individual functions without going through MCP.
|
|
725
|
+
|
|
726
|
+
<p align="center">
|
|
727
|
+
<img src="assets/iii-console/dashboard.png" alt="iii console dashboard — system counters, application flow, registered triggers, live WebSocket status" width="720" />
|
|
728
|
+
<br/>
|
|
729
|
+
<em>Dashboard: functions, triggers, workers, streams, live flow graph. Screenshot from <a href="https://iii.dev/docs/console">iii.dev/docs/console</a>.</em>
|
|
730
|
+
</p>
|
|
731
|
+
|
|
732
|
+
**Install once:**
|
|
733
|
+
|
|
734
|
+
```bash
|
|
735
|
+
curl -fsSL https://install.iii.dev/console/main/install.sh | sh
|
|
736
|
+
```
|
|
737
|
+
|
|
738
|
+
**Launch alongside agentmemory:**
|
|
739
|
+
|
|
740
|
+
```bash
|
|
741
|
+
# The agentmemory viewer already holds port 3113, so run the console on 3114.
|
|
742
|
+
iii-console --port 3114 --engine-port 3111 --ws-port 3112
|
|
743
|
+
```
|
|
744
|
+
|
|
745
|
+
Then open `http://localhost:3114`.
|
|
746
|
+
|
|
747
|
+
**What you can do from the console:**
|
|
748
|
+
|
|
749
|
+
| Page | Use it to |
|
|
750
|
+
|------|-----------|
|
|
751
|
+
| **Functions** | Invoke any of agentmemory's ~33 functions directly with a JSON payload — handy for testing `memory.recall`, `memory.consolidate`, `graph.query` without wiring a client. |
|
|
752
|
+
| **Triggers** | Replay HTTP triggers (the agentmemory REST endpoints), fire the consolidation cron manually, or emit queue events. |
|
|
753
|
+
| **States** | Browse the KV store — sessions, memory slots, lifecycle timers, embeddings index — and edit values in place. |
|
|
754
|
+
| **Streams** | Watch live memory writes, hook events, and observation updates as they flow through iii's WebSocket stream. |
|
|
755
|
+
| **Traces** | OpenTelemetry waterfall / flame / service-breakdown views. Filter by `trace_id` to see exactly which functions, DB calls, and embedding requests a single `memory.search` produced. |
|
|
756
|
+
| **Logs** | Structured OTEL logs correlated to trace/span IDs. |
|
|
757
|
+
|
|
758
|
+
<p align="center">
|
|
759
|
+
<img src="assets/iii-console/traces-waterfall.png" alt="iii console trace waterfall view showing per-span duration" width="720" />
|
|
760
|
+
<br/>
|
|
761
|
+
<em>Traces: waterfall / flame / service breakdown for every memory operation.</em>
|
|
762
|
+
</p>
|
|
763
|
+
|
|
764
|
+
**Traces are already on:**
|
|
765
|
+
|
|
766
|
+
`iii-config.yaml` ships with the `iii-observability` worker enabled (`exporter: memory`, `sampling_ratio: 1.0`, metrics + logs). No extra config needed — the moment agentmemory starts, every memory operation emits a trace span and a structured log the console can read.
|
|
767
|
+
|
|
768
|
+
If you want to export to Jaeger/Honeycomb/Grafana Tempo instead, change `exporter: memory` to `exporter: otlp` and set the collector endpoint per iii's observability docs.
|
|
769
|
+
|
|
770
|
+
> **Heads-up:** no auth is enforced on the console itself — keep it bound to `127.0.0.1` (the default) and never expose it publicly.
|
|
771
|
+
|
|
705
772
|
---
|
|
706
773
|
|
|
707
774
|
<h2 id="configuration"><picture><source media="(prefers-color-scheme: dark)" srcset="assets/tags/light/section-config.svg"><img src="assets/tags/section-config.svg" alt="Configuration" height="32" /></picture></h2>
|
|
@@ -784,7 +851,7 @@ Create `~/.agentmemory/.env`:
|
|
|
784
851
|
|
|
785
852
|
<h2 id="api"><picture><source media="(prefers-color-scheme: dark)" srcset="assets/tags/light/section-api.svg"><img src="assets/tags/section-api.svg" alt="API" height="32" /></picture></h2>
|
|
786
853
|
|
|
787
|
-
|
|
854
|
+
107 endpoints on port `3111`. The REST API binds to `127.0.0.1` by default. Protected endpoints require `Authorization: Bearer <secret>` when `AGENTMEMORY_SECRET` is set, and mesh sync endpoints require `AGENTMEMORY_SECRET` on both peers.
|
|
788
855
|
|
|
789
856
|
<details>
|
|
790
857
|
<summary>Key endpoints</summary>
|
package/dist/cli.mjs
CHANGED
|
@@ -91,6 +91,7 @@ Commands:
|
|
|
91
91
|
demo Seed sample sessions and show recall in action
|
|
92
92
|
upgrade Upgrade local deps + iii runtime (best effort)
|
|
93
93
|
mcp Start standalone MCP server (no engine required)
|
|
94
|
+
import-jsonl [p] Import Claude Code JSONL transcripts (default: ~/.claude/projects)
|
|
94
95
|
|
|
95
96
|
Options:
|
|
96
97
|
--help, -h Show this help
|
|
@@ -286,12 +287,12 @@ async function main() {
|
|
|
286
287
|
p.intro("agentmemory");
|
|
287
288
|
if (skipEngine) {
|
|
288
289
|
p.log.info("Skipping engine check (--no-engine)");
|
|
289
|
-
await import("./src-
|
|
290
|
+
await import("./src-Dw_gJcCy.mjs");
|
|
290
291
|
return;
|
|
291
292
|
}
|
|
292
293
|
if (await isEngineRunning()) {
|
|
293
294
|
p.log.success("iii-engine is running");
|
|
294
|
-
await import("./src-
|
|
295
|
+
await import("./src-Dw_gJcCy.mjs");
|
|
295
296
|
return;
|
|
296
297
|
}
|
|
297
298
|
if (!await startEngine()) {
|
|
@@ -335,7 +336,7 @@ async function main() {
|
|
|
335
336
|
process.exit(1);
|
|
336
337
|
}
|
|
337
338
|
s.stop("iii-engine is ready");
|
|
338
|
-
await import("./src-
|
|
339
|
+
await import("./src-Dw_gJcCy.mjs");
|
|
339
340
|
}
|
|
340
341
|
async function runStatus() {
|
|
341
342
|
const port = getRestPort();
|
|
@@ -589,7 +590,6 @@ async function runUpgrade() {
|
|
|
589
590
|
const hasPnpmLock = existsSync(join(cwd, "pnpm-lock.yaml"));
|
|
590
591
|
const pnpmBin = whichBinary("pnpm");
|
|
591
592
|
const npmBin = whichBinary("npm");
|
|
592
|
-
const cargoBin = whichBinary("cargo");
|
|
593
593
|
const dockerBin = whichBinary("docker");
|
|
594
594
|
p.log.info(`Working directory: ${cwd}`);
|
|
595
595
|
const requireSuccess = (ok, label) => {
|
|
@@ -612,22 +612,24 @@ async function runUpgrade() {
|
|
|
612
612
|
});
|
|
613
613
|
} else p.log.warn("No package manager found (pnpm/npm). Skipping JS dependency upgrade.");
|
|
614
614
|
else p.log.warn("No package.json in current directory. Skipping JS dependency upgrade.");
|
|
615
|
-
|
|
615
|
+
const shBin = whichBinary("sh");
|
|
616
|
+
const curlBin = whichBinary("curl");
|
|
617
|
+
if (shBin && curlBin) {
|
|
616
618
|
const upgradeEngine = await p.confirm({
|
|
617
|
-
message: "
|
|
619
|
+
message: "Re-run the iii-engine install script (curl | sh)?",
|
|
618
620
|
initialValue: true
|
|
619
621
|
});
|
|
620
622
|
if (p.isCancel(upgradeEngine)) {
|
|
621
623
|
p.cancel("Cancelled.");
|
|
622
624
|
return process.exit(0);
|
|
623
625
|
}
|
|
624
|
-
if (upgradeEngine === true)
|
|
625
|
-
"install",
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
else p.log.info("Skipped
|
|
630
|
-
} else p.log.warn("
|
|
626
|
+
if (upgradeEngine === true) {
|
|
627
|
+
if (!runCommand(shBin, ["-c", "curl -fsSL https://install.iii.dev/iii/main/install.sh | sh"], {
|
|
628
|
+
label: "Upgrading iii-engine via installer",
|
|
629
|
+
optional: true
|
|
630
|
+
})) p.log.warn("iii-engine installer failed. Fallbacks: Docker (`docker pull iiidev/iii:latest`) or releases at https://github.com/iii-hq/iii/releases/latest.");
|
|
631
|
+
} else p.log.info("Skipped iii-engine installer.");
|
|
632
|
+
} else p.log.warn("curl or sh not found. Skipping iii-engine installer.");
|
|
631
633
|
if (dockerBin) runCommand(dockerBin, ["pull", "iiidev/iii:latest"], {
|
|
632
634
|
label: "Pulling latest iii Docker image",
|
|
633
635
|
optional: true
|
|
@@ -643,13 +645,76 @@ async function runUpgrade() {
|
|
|
643
645
|
].join("\n"), "agentmemory upgrade");
|
|
644
646
|
}
|
|
645
647
|
async function runMcp() {
|
|
646
|
-
await import("./standalone-
|
|
648
|
+
await import("./standalone-BEWvWM5P.mjs");
|
|
649
|
+
}
|
|
650
|
+
async function runImportJsonl() {
|
|
651
|
+
const pathArg = args.slice(1).filter((a) => !a.startsWith("-"))[0];
|
|
652
|
+
const port = getRestPort();
|
|
653
|
+
const base = `http://localhost:${port}`;
|
|
654
|
+
let probeOk = false;
|
|
655
|
+
let probeDetail = "";
|
|
656
|
+
try {
|
|
657
|
+
const probe = await fetch(`${base}/agentmemory/livez`, { signal: AbortSignal.timeout(2e3) });
|
|
658
|
+
probeOk = probe.ok;
|
|
659
|
+
if (!probeOk) {
|
|
660
|
+
const probeBody = await probe.text().catch(() => "");
|
|
661
|
+
probeDetail = `reachable but unhealthy (HTTP ${probe.status}${probeBody ? `: ${probeBody.slice(0, 200)}` : ""})`;
|
|
662
|
+
}
|
|
663
|
+
} catch (err) {
|
|
664
|
+
probeOk = false;
|
|
665
|
+
probeDetail = `unreachable (${err instanceof Error ? err.message : String(err)})`;
|
|
666
|
+
}
|
|
667
|
+
if (!probeOk) {
|
|
668
|
+
p.log.error(`agentmemory livez probe failed on port ${port}: ${probeDetail}. Start it with \`npx @agentmemory/agentmemory\` in another terminal, then re-run this command.`);
|
|
669
|
+
process.exit(1);
|
|
670
|
+
}
|
|
671
|
+
const body = {};
|
|
672
|
+
if (pathArg) body["path"] = pathArg;
|
|
673
|
+
const headers = { "content-type": "application/json" };
|
|
674
|
+
const secret = process.env["AGENTMEMORY_SECRET"];
|
|
675
|
+
if (secret) headers["authorization"] = `Bearer ${secret}`;
|
|
676
|
+
p.log.info(`Importing JSONL from ${pathArg || "~/.claude/projects"}…`);
|
|
677
|
+
const spinner = p.spinner();
|
|
678
|
+
spinner.start("scanning files");
|
|
679
|
+
try {
|
|
680
|
+
const res = await fetch(`${base}/agentmemory/replay/import-jsonl`, {
|
|
681
|
+
method: "POST",
|
|
682
|
+
headers,
|
|
683
|
+
body: JSON.stringify(body),
|
|
684
|
+
signal: AbortSignal.timeout(12e4)
|
|
685
|
+
});
|
|
686
|
+
const text = await res.text();
|
|
687
|
+
let json = {};
|
|
688
|
+
if (text.length > 0) try {
|
|
689
|
+
json = JSON.parse(text);
|
|
690
|
+
} catch {
|
|
691
|
+
spinner.stop("failed");
|
|
692
|
+
p.log.error(`server returned non-JSON response (HTTP ${res.status}): ${text.slice(0, 200)}`);
|
|
693
|
+
process.exit(1);
|
|
694
|
+
}
|
|
695
|
+
if (!res.ok || json.success !== true) {
|
|
696
|
+
spinner.stop("failed");
|
|
697
|
+
const detail = json.error || (text.length === 0 ? "empty response body" : json.success === void 0 ? `HTTP ${res.status} (response missing success field)` : `HTTP ${res.status}`);
|
|
698
|
+
if (res.status === 401) p.log.error(`${detail}. Set AGENTMEMORY_SECRET to match the server's secret and re-run.`);
|
|
699
|
+
else if (res.status === 404) p.log.error(`${detail}. The running agentmemory server does not expose /agentmemory/replay/import-jsonl — upgrade to v0.8.13 or later.`);
|
|
700
|
+
else p.log.error(detail);
|
|
701
|
+
process.exit(1);
|
|
702
|
+
}
|
|
703
|
+
spinner.stop(`imported ${json.imported ?? 0} file(s), ${json.observations ?? 0} observation(s) across ${json.sessionIds?.length || 0} session(s)`);
|
|
704
|
+
if (json.sessionIds && json.sessionIds.length > 0) p.log.info(`View at http://localhost:${port + 2} → Replay tab`);
|
|
705
|
+
} catch (err) {
|
|
706
|
+
spinner.stop("failed");
|
|
707
|
+
if (err instanceof Error && err.name === "TimeoutError") p.log.error("import timed out after 2 minutes");
|
|
708
|
+
else p.log.error(err instanceof Error ? err.message : String(err));
|
|
709
|
+
process.exit(1);
|
|
710
|
+
}
|
|
647
711
|
}
|
|
648
712
|
({
|
|
649
713
|
status: runStatus,
|
|
650
714
|
demo: runDemo,
|
|
651
715
|
upgrade: runUpgrade,
|
|
652
|
-
mcp: runMcp
|
|
716
|
+
mcp: runMcp,
|
|
717
|
+
"import-jsonl": runImportJsonl
|
|
653
718
|
}[args[0] ?? ""] ?? main)().catch((err) => {
|
|
654
719
|
p.log.error(err instanceof Error ? err.message : String(err));
|
|
655
720
|
process.exit(1);
|
package/dist/cli.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.mjs","names":["PATH_DELIMITER"],"sources":["../src/state/schema.ts","../src/cli.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\n\nexport const KV = {\n sessions: \"mem:sessions\",\n observations: (sessionId: string) => `mem:obs:${sessionId}`,\n memories: \"mem:memories\",\n summaries: \"mem:summaries\",\n config: \"mem:config\",\n metrics: \"mem:metrics\",\n health: \"mem:health\",\n embeddings: (obsId: string) => `mem:emb:${obsId}`,\n bm25Index: \"mem:index:bm25\",\n relations: \"mem:relations\",\n profiles: \"mem:profiles\",\n claudeBridge: \"mem:claude-bridge\",\n graphNodes: \"mem:graph:nodes\",\n graphEdges: \"mem:graph:edges\",\n semantic: \"mem:semantic\",\n procedural: \"mem:procedural\",\n teamShared: (teamId: string) => `mem:team:${teamId}:shared`,\n teamUsers: (teamId: string, userId: string) =>\n `mem:team:${teamId}:users:${userId}`,\n teamProfile: (teamId: string) => `mem:team:${teamId}:profile`,\n audit: \"mem:audit\",\n actions: \"mem:actions\",\n actionEdges: \"mem:action-edges\",\n leases: \"mem:leases\",\n routines: \"mem:routines\",\n routineRuns: \"mem:routine-runs\",\n signals: \"mem:signals\",\n checkpoints: \"mem:checkpoints\",\n mesh: \"mem:mesh\",\n sketches: \"mem:sketches\",\n facets: \"mem:facets\",\n sentinels: \"mem:sentinels\",\n crystals: \"mem:crystals\",\n lessons: \"mem:lessons\",\n insights: \"mem:insights\",\n graphEdgeHistory: \"mem:graph:edge-history\",\n enrichedChunks: (sessionId: string) => `mem:enriched:${sessionId}`,\n latentEmbeddings: (obsId: string) => `mem:latent:${obsId}`,\n retentionScores: \"mem:retention\",\n accessLog: \"mem:access\",\n} as const;\n\nexport const STREAM = {\n name: \"mem-live\",\n group: (sessionId: string) => sessionId,\n viewerGroup: \"viewer\",\n} as const;\n\nexport function generateId(prefix: string): string {\n const ts = Date.now().toString(36);\n const rand = crypto.randomUUID().replace(/-/g, \"\").slice(0, 12);\n return `${prefix}_${ts}_${rand}`;\n}\n\nexport function fingerprintId(prefix: string, content: string): string {\n const hash = createHash(\"sha256\").update(content).digest(\"hex\");\n return `${prefix}_${hash.slice(0, 16)}`;\n}\n\nexport function jaccardSimilarity(a: string, b: string): number {\n const setA = new Set(a.split(/\\s+/).filter((t) => t.length > 2));\n const setB = new Set(b.split(/\\s+/).filter((t) => t.length > 2));\n if (setA.size === 0 && setB.size === 0) return 1;\n if (setA.size === 0 || setB.size === 0) return 0;\n let intersection = 0;\n for (const word of setA) {\n if (setB.has(word)) intersection++;\n }\n return intersection / (setA.size + setB.size - intersection);\n}\n","#!/usr/bin/env node\n\nimport {\n spawn,\n execFileSync,\n spawnSync,\n type ChildProcess,\n} from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { join, dirname, delimiter as PATH_DELIMITER } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { platform } from \"node:os\";\nimport * as p from \"@clack/prompts\";\nimport { generateId } from \"./state/schema.js\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst args = process.argv.slice(2);\nconst IS_WINDOWS = platform() === \"win32\";\nconst IS_VERBOSE = args.includes(\"--verbose\") || args.includes(\"-v\");\n\nfunction vlog(msg: string): void {\n if (IS_VERBOSE) p.log.info(`[verbose] ${msg}`);\n}\n\nif (args.includes(\"--help\") || args.includes(\"-h\")) {\n console.log(`\nagentmemory — persistent memory for AI coding agents\n\nUsage: agentmemory [command] [options]\n\nCommands:\n (default) Start agentmemory worker\n status Show connection status, memory count, and health\n demo Seed sample sessions and show recall in action\n upgrade Upgrade local deps + iii runtime (best effort)\n mcp Start standalone MCP server (no engine required)\n\nOptions:\n --help, -h Show this help\n --verbose, -v Show engine stderr and diagnostic info on startup\n --tools all|core Tool visibility (default: core = 7 tools)\n --no-engine Skip auto-starting iii-engine\n --port <N> Override REST port (default: 3111)\n\nQuick start:\n npx @agentmemory/agentmemory # start with local iii-engine or Docker\n npx @agentmemory/agentmemory status # check health\n npx @agentmemory/agentmemory demo # try it in 30 seconds (needs server running)\n npx @agentmemory/agentmemory upgrade # upgrade agentmemory + iii runtime\n npx @agentmemory/agentmemory mcp # standalone MCP server (no engine)\n npx @agentmemory/mcp # same as above (shim package)\n`);\n process.exit(0);\n}\n\nconst toolsIdx = args.indexOf(\"--tools\");\nif (toolsIdx !== -1 && args[toolsIdx + 1]) {\n process.env[\"AGENTMEMORY_TOOLS\"] = args[toolsIdx + 1];\n}\n\nconst portIdx = args.indexOf(\"--port\");\nif (portIdx !== -1 && args[portIdx + 1]) {\n process.env[\"III_REST_PORT\"] = args[portIdx + 1];\n}\n\nconst skipEngine = args.includes(\"--no-engine\");\n\nfunction getRestPort(): number {\n return parseInt(process.env[\"III_REST_PORT\"] || \"3111\", 10) || 3111;\n}\n\nasync function isEngineRunning(): Promise<boolean> {\n try {\n await fetch(`http://localhost:${getRestPort()}/`, {\n signal: AbortSignal.timeout(2000),\n });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction findIiiConfig(): string {\n const candidates = [\n join(__dirname, \"iii-config.yaml\"),\n join(__dirname, \"..\", \"iii-config.yaml\"),\n join(process.cwd(), \"iii-config.yaml\"),\n ];\n for (const c of candidates) {\n if (existsSync(c)) return c;\n }\n return \"\";\n}\n\nfunction whichBinary(name: string): string | null {\n const cmd = IS_WINDOWS ? \"where\" : \"which\";\n try {\n const out = execFileSync(cmd, [name], { encoding: \"utf-8\" });\n const first = out\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .find((line) => line.length > 0);\n return first ?? null;\n } catch {\n return null;\n }\n}\n\nfunction fallbackIiiPaths(): string[] {\n if (IS_WINDOWS) {\n const userProfile = process.env[\"USERPROFILE\"];\n if (!userProfile) return [];\n return [\n join(userProfile, \".local\", \"bin\", \"iii.exe\"),\n join(userProfile, \"bin\", \"iii.exe\"),\n ];\n }\n const home = process.env[\"HOME\"];\n if (!home) return [\"/usr/local/bin/iii\"];\n return [join(home, \".local\", \"bin\", \"iii\"), \"/usr/local/bin/iii\"];\n}\n\ntype StartupFailure = {\n kind: \"no-engine\" | \"no-docker-compose\" | \"engine-crashed\" | \"docker-crashed\";\n stderr?: string;\n binary?: string;\n};\n\nlet startupFailure: StartupFailure | null = null;\n\n// Spawn a background engine and collect any startup stderr for a short\n// window. The process is unref'd so the CLI parent can exit cleanly; we\n// only care about stderr that shows up BEFORE the health check succeeds,\n// which is what surfaces early crash/config-parse errors on all platforms.\nfunction spawnEngineBackground(\n bin: string,\n spawnArgs: string[],\n label: string,\n): ChildProcess {\n vlog(`spawn: ${bin} ${spawnArgs.join(\" \")}`);\n const child = spawn(bin, spawnArgs, {\n detached: true,\n stdio: [\"ignore\", \"ignore\", \"pipe\"],\n windowsHide: true,\n });\n const stderrChunks: Buffer[] = [];\n let stderrBytes = 0;\n const MAX_STDERR_CAPTURE = 16 * 1024;\n child.stderr?.on(\"data\", (chunk: Buffer) => {\n if (stderrBytes >= MAX_STDERR_CAPTURE) return;\n const slice = chunk.subarray(0, MAX_STDERR_CAPTURE - stderrBytes);\n stderrChunks.push(slice);\n stderrBytes += slice.length;\n });\n child.on(\"exit\", (code, signal) => {\n const abnormal =\n (code !== null && code !== 0) || (code === null && signal !== null);\n if (abnormal) {\n const stderr = Buffer.concat(stderrChunks).toString(\"utf-8\");\n startupFailure = {\n kind: label.includes(\"Docker\") ? \"docker-crashed\" : \"engine-crashed\",\n stderr:\n stderr.trim() ||\n (signal\n ? `process killed by signal ${signal}`\n : `process exited with code ${code}`),\n binary: bin,\n };\n vlog(`engine exited early: code=${code} signal=${signal}`);\n if (IS_VERBOSE && stderr.trim()) {\n p.log.error(`engine stderr:\\n${stderr}`);\n }\n }\n });\n child.unref();\n return child;\n}\n\nasync function startEngine(): Promise<boolean> {\n const configPath = findIiiConfig();\n let iiiBin = whichBinary(\"iii\");\n vlog(`iii binary: ${iiiBin ?? \"(not on PATH)\"}, config: ${configPath || \"(not found)\"}`);\n\n if (iiiBin && configPath) {\n const s = p.spinner();\n s.start(`Starting iii-engine: ${iiiBin}`);\n spawnEngineBackground(iiiBin, [\"--config\", configPath], \"iii-engine\");\n s.stop(\"iii-engine process started\");\n return true;\n }\n\n const dockerBin = whichBinary(\"docker\");\n vlog(`docker binary: ${dockerBin ?? \"(not on PATH)\"}`);\n const dockerComposeCandidates = [\n join(__dirname, \"..\", \"docker-compose.yml\"),\n join(__dirname, \"docker-compose.yml\"),\n join(process.cwd(), \"docker-compose.yml\"),\n ];\n const composeFile = dockerComposeCandidates.find((c) => existsSync(c));\n vlog(`docker-compose.yml: ${composeFile ?? \"(not found)\"}`);\n\n if (dockerBin && composeFile) {\n const s = p.spinner();\n s.start(\"Starting iii-engine via Docker...\");\n spawnEngineBackground(\n dockerBin,\n [\"compose\", \"-f\", composeFile, \"up\", \"-d\"],\n \"iii-engine via Docker\",\n );\n s.stop(\"Docker compose started\");\n return true;\n }\n\n for (const iiiPath of fallbackIiiPaths()) {\n if (existsSync(iiiPath)) {\n p.log.info(`Found iii at: ${iiiPath}`);\n process.env[\"PATH\"] = `${dirname(iiiPath)}${PATH_DELIMITER}${process.env[\"PATH\"] ?? \"\"}`;\n iiiBin = iiiPath;\n break;\n }\n }\n\n if (iiiBin && configPath) {\n const s = p.spinner();\n s.start(`Starting iii-engine: ${iiiBin}`);\n spawnEngineBackground(iiiBin, [\"--config\", configPath], \"iii-engine\");\n s.stop(\"iii-engine process started\");\n return true;\n }\n\n if (!iiiBin && (!dockerBin || !composeFile)) {\n startupFailure = { kind: \"no-engine\" };\n } else if (!composeFile && dockerBin) {\n startupFailure = { kind: \"no-docker-compose\" };\n }\n return false;\n}\n\nasync function waitForEngine(timeoutMs: number): Promise<boolean> {\n const start = Date.now();\n while (Date.now() - start < timeoutMs) {\n if (await isEngineRunning()) return true;\n await new Promise((r) => setTimeout(r, 500));\n }\n return false;\n}\n\nfunction installInstructions(): string[] {\n if (IS_WINDOWS) {\n return [\n \"agentmemory requires the `iii-engine` runtime. Pick one:\",\n \"\",\n \" A) Download the prebuilt Windows binary:\",\n \" 1. Open https://github.com/iii-hq/iii/releases/latest\",\n \" 2. Download iii-x86_64-pc-windows-msvc.zip\",\n \" (or iii-aarch64-pc-windows-msvc.zip on ARM)\",\n \" 3. Extract iii.exe and either add its folder to PATH\",\n \" or move it to %USERPROFILE%\\\\.local\\\\bin\\\\iii.exe\",\n \" 4. Re-run: npx @agentmemory/agentmemory\",\n \"\",\n \" B) Docker Desktop:\",\n \" 1. Install Docker Desktop for Windows\",\n \" 2. Start Docker Desktop (engine must be running)\",\n \" 3. Re-run: npx @agentmemory/agentmemory\",\n \"\",\n \"Or skip the engine entirely for standalone MCP:\",\n \" npx @agentmemory/agentmemory mcp\",\n ];\n }\n return [\n \"agentmemory requires the `iii-engine` runtime. Pick one:\",\n \"\",\n \" A) curl -fsSL https://install.iii.dev/iii/main/install.sh | sh\",\n \" (installs the prebuilt iii binary into ~/.local/bin/iii)\",\n \"\",\n \" B) Docker: install Docker Desktop or docker-ce, then re-run\",\n \"\",\n \"Or skip the engine entirely for standalone MCP:\",\n \" npx @agentmemory/agentmemory mcp\",\n \"\",\n \"Docs: https://iii.dev/docs\",\n ];\n}\n\nfunction portInUseDiagnostic(port: number): string {\n return IS_WINDOWS\n ? ` netstat -ano | findstr :${port}`\n : ` lsof -i :${port} # or: ss -tlnp | grep :${port}`;\n}\n\nasync function main() {\n p.intro(\"agentmemory\");\n\n if (skipEngine) {\n p.log.info(\"Skipping engine check (--no-engine)\");\n await import(\"./index.js\");\n return;\n }\n\n if (await isEngineRunning()) {\n p.log.success(\"iii-engine is running\");\n await import(\"./index.js\");\n return;\n }\n\n const started = await startEngine();\n if (!started) {\n p.log.error(\"Could not start iii-engine.\");\n const lines = installInstructions();\n if (startupFailure?.kind === \"no-docker-compose\") {\n lines.unshift(\n \"Docker is installed but docker-compose.yml is missing from this\",\n \"install. Re-install with: npm install -g @agentmemory/agentmemory\",\n \"\",\n );\n }\n p.note(lines.join(\"\\n\"), \"Setup required\");\n process.exit(1);\n }\n\n const s = p.spinner();\n s.start(\"Waiting for iii-engine to be ready...\");\n\n const ready = await waitForEngine(15000);\n if (!ready) {\n const port = getRestPort();\n s.stop(\"iii-engine did not become ready within 15s\");\n\n if (startupFailure?.kind === \"engine-crashed\" || startupFailure?.kind === \"docker-crashed\") {\n p.log.error(\"The iii-engine process crashed on startup.\");\n if (startupFailure.binary) {\n p.log.info(`Binary: ${startupFailure.binary}`);\n }\n if (startupFailure.stderr) {\n p.note(startupFailure.stderr, \"engine stderr\");\n } else {\n p.log.info(\"No stderr was captured. Re-run with --verbose for more detail.\");\n }\n p.note(\n [\n \"Common causes:\",\n \" - iii-engine version mismatch — reinstall the latest binary\",\n \" (sh script on macOS/Linux, GitHub release zip on Windows)\",\n \" - Docker Desktop not running (if you're using the Docker path)\",\n \" - Port already in use (see below)\",\n \"\",\n \"See https://iii.dev/docs for current install instructions.\",\n ].join(\"\\n\"),\n \"Troubleshooting\",\n );\n } else {\n p.log.error(\"The engine process started but the REST API never responded.\");\n p.note(\n [\n `Check whether port ${port} is already bound by another process:`,\n portInUseDiagnostic(port),\n \"\",\n \"If it is, free the port or override: agentmemory --port <N>\",\n \"\",\n \"If it isn't, a firewall may be blocking 127.0.0.1:\" + port + \".\",\n \"Re-run with --verbose to see engine stderr.\",\n ].join(\"\\n\"),\n \"Troubleshooting\",\n );\n }\n process.exit(1);\n }\n\n s.stop(\"iii-engine is ready\");\n await import(\"./index.js\");\n}\n\nasync function runStatus() {\n const port = getRestPort();\n const base = `http://localhost:${port}`;\n p.intro(\"agentmemory status\");\n\n const up = await isEngineRunning();\n if (!up) {\n p.log.error(`Not running — no response on port ${port}`);\n p.log.info(\"Start with: npx @agentmemory/agentmemory\");\n process.exit(1);\n }\n\n try {\n const [healthRes, sessionsRes, graphRes, memoriesRes] = await Promise.all([\n fetch(`${base}/agentmemory/health`, { signal: AbortSignal.timeout(5000) }).then((r) => r.json()).catch(() => null),\n fetch(`${base}/agentmemory/sessions`, { signal: AbortSignal.timeout(5000) }).then((r) => r.json()).catch(() => null),\n fetch(`${base}/agentmemory/graph/stats`, { signal: AbortSignal.timeout(5000) }).then((r) => r.json()).catch(() => null),\n fetch(`${base}/agentmemory/export`, { signal: AbortSignal.timeout(5000) }).then((r) => r.json()).catch(() => null),\n ]);\n\n const h = healthRes?.health;\n const status = healthRes?.status || \"unknown\";\n const version = healthRes?.version || \"?\";\n const sessions = Array.isArray(sessionsRes?.sessions) ? sessionsRes.sessions.length : 0;\n const nodes = graphRes?.nodes || 0;\n const edges = graphRes?.edges || 0;\n const cb = healthRes?.circuitBreaker?.state || \"closed\";\n const heapMB = h?.memory ? Math.round(h.memory.heapUsed / 1048576) : 0;\n const uptime = h?.uptimeSeconds ? Math.round(h.uptimeSeconds) : 0;\n\n const obsCount = memoriesRes?.observations?.length || 0;\n const memCount = memoriesRes?.memories?.length || 0;\n const estFullTokens = obsCount * 80;\n const estInjectedTokens = Math.min(obsCount, 50) * 38;\n const tokensSaved = estFullTokens - estInjectedTokens;\n const pctSaved = estFullTokens > 0 ? Math.round((tokensSaved / estFullTokens) * 100) : 0;\n\n p.log.success(`Connected — v${version} on port ${port}`);\n\n const lines = [\n `Health: ${status === \"healthy\" ? \"✓ healthy\" : status}`,\n `Sessions: ${sessions}`,\n `Observations: ${obsCount}`,\n `Memories: ${memCount}`,\n `Graph: ${nodes} nodes, ${edges} edges`,\n `Circuit: ${cb}`,\n `Heap: ${heapMB} MB`,\n `Uptime: ${uptime}s`,\n `Viewer: http://localhost:${port + 2}`,\n ];\n\n if (obsCount > 0) {\n lines.push(\"\");\n lines.push(`Token savings: ~${tokensSaved.toLocaleString()} tokens saved (${pctSaved}% reduction)`);\n lines.push(` Full context: ~${estFullTokens.toLocaleString()} tokens`);\n lines.push(` Injected: ~${estInjectedTokens.toLocaleString()} tokens`);\n }\n\n p.note(lines.join(\"\\n\"), \"agentmemory\");\n } catch (err) {\n p.log.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n}\n\ntype DemoObservation = {\n toolName: string;\n toolInput: Record<string, string>;\n toolOutput: string;\n};\n\ntype DemoSession = {\n id: string;\n title: string;\n observations: DemoObservation[];\n};\n\ntype SearchResult = { query: string; hits: number; topTitle: string };\n\nfunction buildDemoSessions(): DemoSession[] {\n return [\n {\n id: generateId(\"demo\"),\n title: \"Session 1: JWT auth setup\",\n observations: [\n {\n toolName: \"Write\",\n toolInput: { file_path: \"src/middleware/auth.ts\" },\n toolOutput:\n \"Created JWT middleware using jose library. Tokens expire after 30 days. Chose jose over jsonwebtoken for Edge compatibility.\",\n },\n {\n toolName: \"Write\",\n toolInput: { file_path: \"test/auth.test.ts\" },\n toolOutput:\n \"Added token validation tests covering expired, malformed, and valid cases.\",\n },\n {\n toolName: \"Bash\",\n toolInput: { command: \"npm test\" },\n toolOutput: \"All 12 auth tests passing.\",\n },\n ],\n },\n {\n id: generateId(\"demo\"),\n title: \"Session 2: Database migration debugging\",\n observations: [\n {\n toolName: \"Read\",\n toolInput: { file_path: \"prisma/schema.prisma\" },\n toolOutput:\n \"Found N+1 query issue in user relations. Need to add include on posts query.\",\n },\n {\n toolName: \"Edit\",\n toolInput: { file_path: \"src/api/users.ts\" },\n toolOutput:\n \"Fixed N+1 by adding Prisma include. Query time dropped from 450ms to 28ms.\",\n },\n ],\n },\n {\n id: generateId(\"demo\"),\n title: \"Session 3: Rate limiting\",\n observations: [\n {\n toolName: \"Write\",\n toolInput: { file_path: \"src/middleware/ratelimit.ts\" },\n toolOutput:\n \"Added rate limiting middleware with 100 req/min default. Uses in-memory store for dev, Redis for prod.\",\n },\n ],\n },\n ];\n}\n\nasync function postJson<T = unknown>(\n url: string,\n body: unknown,\n timeoutMs = 5000,\n): Promise<T | null> {\n try {\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(timeoutMs),\n });\n if (!res.ok) return null;\n return (await res.json().catch(() => null)) as T | null;\n } catch {\n return null;\n }\n}\n\nasync function postJsonStrict<T = unknown>(\n url: string,\n body: unknown,\n timeoutMs = 5000,\n): Promise<T | null> {\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(timeoutMs),\n });\n if (!res.ok) {\n const errBody = await res.text().catch(() => \"\");\n const suffix = errBody ? ` — ${errBody.slice(0, 200)}` : \"\";\n throw new Error(`POST ${url} failed: ${res.status} ${res.statusText}${suffix}`);\n }\n return (await res.json().catch(() => null)) as T | null;\n}\n\nasync function seedDemoSession(\n base: string,\n project: string,\n session: DemoSession,\n): Promise<number> {\n await postJsonStrict(`${base}/agentmemory/session/start`, {\n sessionId: session.id,\n project,\n cwd: project,\n });\n\n let stored = 0;\n for (const obs of session.observations) {\n const url = `${base}/agentmemory/observe`;\n const payload = {\n hookType: \"post_tool_use\",\n sessionId: session.id,\n timestamp: new Date().toISOString(),\n data: {\n tool_name: obs.toolName,\n tool_input: obs.toolInput,\n tool_output: obs.toolOutput,\n },\n };\n\n try {\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(payload),\n signal: AbortSignal.timeout(5000),\n });\n if (res.ok) {\n stored++;\n } else {\n const body = await res.text().catch(() => \"\");\n p.log.warn(\n `observe failed for ${obs.toolName}: ${res.status} ${res.statusText}${body ? ` — ${body.slice(0, 160)}` : \"\"}`,\n );\n }\n } catch (err) {\n p.log.warn(\n `observe request failed for ${obs.toolName}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n await postJsonStrict(`${base}/agentmemory/session/end`, { sessionId: session.id });\n return stored;\n}\n\nasync function runDemoSearch(base: string, query: string): Promise<SearchResult> {\n const data = await postJson<{ results?: Array<{ title?: string }> }>(\n `${base}/agentmemory/smart-search`,\n { query, limit: 5 },\n 10000,\n );\n const items = data?.results ?? [];\n return {\n query,\n hits: items.length,\n topTitle: items[0]?.title ?? \"(no results)\",\n };\n}\n\nasync function runDemo() {\n const port = getRestPort();\n const base = `http://localhost:${port}`;\n p.intro(\"agentmemory demo\");\n\n if (!(await isEngineRunning())) {\n p.log.error(`Not running — no response on port ${port}`);\n p.log.info(\"Start the server first: npx @agentmemory/agentmemory\");\n process.exit(1);\n }\n\n const demoProject = \"/tmp/agentmemory-demo\";\n const sessions = buildDemoSessions();\n\n const sSeed = p.spinner();\n sSeed.start(\"Seeding 3 demo sessions with realistic observations...\");\n\n let totalObs = 0;\n for (const session of sessions) {\n totalObs += await seedDemoSession(base, demoProject, session);\n }\n\n sSeed.stop(`Seeded ${totalObs} observations across ${sessions.length} sessions`);\n\n const queries = [\n \"jwt auth middleware\",\n \"database performance optimization\",\n \"rate limiting\",\n ];\n\n const sQuery = p.spinner();\n sQuery.start(`Running ${queries.length} smart-search queries...`);\n\n const results: SearchResult[] = [];\n for (const query of queries) {\n results.push(await runDemoSearch(base, query));\n }\n\n sQuery.stop(\"Search complete\");\n\n const lines = [\n `Project: ${demoProject}`,\n `Sessions: ${sessions.length} seeded (${totalObs} observations)`,\n \"\",\n \"Search results:\",\n ...results.flatMap((r) => [\n ` \"${r.query}\"`,\n ` → ${r.hits} hit(s), top: ${r.topTitle.slice(0, 60)}`,\n ]),\n \"\",\n `Notice: searching \"database performance optimization\"`,\n `found the N+1 query fix — keyword matching can't do that.`,\n \"\",\n `Viewer: http://localhost:${port + 2}`,\n `Clean up with: curl -X DELETE \"${base}/agentmemory/sessions?project=${demoProject}\"`,\n ];\n\n p.note(lines.join(\"\\n\"), \"demo complete\");\n p.log.success(\"agentmemory is working. Point your agent at it and get back to coding.\");\n}\n\nfunction runCommand(\n command: string,\n commandArgs: string[],\n options: { cwd?: string; label: string; optional?: boolean } = { label: \"command\" },\n): boolean {\n const spinner = p.spinner();\n spinner.start(options.label);\n const result = spawnSync(command, commandArgs, {\n cwd: options.cwd || process.cwd(),\n stdio: \"pipe\",\n encoding: \"utf-8\",\n });\n\n if (result.status === 0) {\n spinner.stop(`${options.label} ✓`);\n return true;\n }\n\n const stderr = (result.stderr || \"\").toString().trim();\n const stdout = (result.stdout || \"\").toString().trim();\n const msg = stderr || stdout || \"unknown error\";\n\n if (options.optional) {\n spinner.stop(`${options.label} (skipped)`);\n p.log.warn(msg.slice(0, 300));\n return false;\n }\n\n spinner.stop(`${options.label} ✗`);\n p.log.error(msg.slice(0, 300));\n return false;\n}\n\nasync function runUpgrade() {\n p.intro(\"agentmemory upgrade\");\n\n const cwd = process.cwd();\n const hasPackageJson = existsSync(join(cwd, \"package.json\"));\n const hasPnpmLock = existsSync(join(cwd, \"pnpm-lock.yaml\"));\n\n const pnpmBin = whichBinary(\"pnpm\");\n const npmBin = whichBinary(\"npm\");\n const cargoBin = whichBinary(\"cargo\");\n const dockerBin = whichBinary(\"docker\");\n\n p.log.info(`Working directory: ${cwd}`);\n const requireSuccess = (ok: boolean, label: string): void => {\n if (!ok) {\n p.log.error(`Upgrade aborted: ${label} failed.`);\n process.exit(1);\n }\n };\n\n if (hasPackageJson) {\n const usePnpm = !!pnpmBin && hasPnpmLock;\n if (usePnpm && pnpmBin) {\n const installOk = runCommand(pnpmBin, [\"install\"], {\n label: \"Refreshing dependencies (pnpm install)\",\n });\n requireSuccess(installOk, \"pnpm install\");\n runCommand(pnpmBin, [\"up\", \"iii-sdk@latest\"], {\n label: \"Upgrading iii-sdk to latest\",\n optional: true,\n });\n } else if (npmBin) {\n const installOk = runCommand(npmBin, [\"install\"], {\n label: \"Refreshing dependencies (npm install)\",\n });\n requireSuccess(installOk, \"npm install\");\n runCommand(npmBin, [\"install\", \"iii-sdk@latest\"], {\n label: \"Upgrading iii-sdk to latest\",\n optional: true,\n });\n } else {\n p.log.warn(\"No package manager found (pnpm/npm). Skipping JS dependency upgrade.\");\n }\n } else {\n p.log.warn(\"No package.json in current directory. Skipping JS dependency upgrade.\");\n }\n\n if (cargoBin) {\n const upgradeEngine = await p.confirm({\n message: \"Upgrade iii-engine via cargo install --force?\",\n initialValue: true,\n });\n if (p.isCancel(upgradeEngine)) {\n p.cancel(\"Cancelled.\");\n return process.exit(0);\n }\n if (upgradeEngine === true) {\n const cargoOk = runCommand(cargoBin, [\"install\", \"iii-engine\", \"--force\"], {\n label: \"Upgrading iii-engine (cargo)\",\n });\n requireSuccess(cargoOk, \"cargo install iii-engine --force\");\n } else {\n p.log.info(\"Skipped cargo-based iii-engine upgrade.\");\n }\n } else {\n p.log.warn(\"Cargo not found. Skipping iii-engine binary upgrade.\");\n }\n\n if (dockerBin) {\n runCommand(dockerBin, [\"pull\", \"iiidev/iii:latest\"], {\n label: \"Pulling latest iii Docker image\",\n optional: true,\n });\n } else {\n p.log.info(\"Docker not found. Skipping Docker image refresh.\");\n }\n\n p.note(\n [\n \"Upgrade flow completed.\",\n \"\",\n \"Recommended next steps:\",\n \" 1) agentmemory status\",\n \" 2) npm/pnpm test\",\n \" 3) restart agentmemory process\",\n ].join(\"\\n\"),\n \"agentmemory upgrade\",\n );\n}\n\nasync function runMcp(): Promise<void> {\n await import(\"./mcp/standalone.js\");\n}\n\nconst commands: Record<string, () => Promise<void>> = {\n status: runStatus,\n demo: runDemo,\n upgrade: runUpgrade,\n mcp: runMcp,\n};\n\nconst handler = commands[args[0] ?? \"\"] ?? main;\nhandler().catch((err) => {\n p.log.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.mjs","names":["PATH_DELIMITER"],"sources":["../src/state/schema.ts","../src/cli.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\n\nexport const KV = {\n sessions: \"mem:sessions\",\n observations: (sessionId: string) => `mem:obs:${sessionId}`,\n memories: \"mem:memories\",\n summaries: \"mem:summaries\",\n config: \"mem:config\",\n metrics: \"mem:metrics\",\n health: \"mem:health\",\n embeddings: (obsId: string) => `mem:emb:${obsId}`,\n bm25Index: \"mem:index:bm25\",\n relations: \"mem:relations\",\n profiles: \"mem:profiles\",\n claudeBridge: \"mem:claude-bridge\",\n graphNodes: \"mem:graph:nodes\",\n graphEdges: \"mem:graph:edges\",\n semantic: \"mem:semantic\",\n procedural: \"mem:procedural\",\n teamShared: (teamId: string) => `mem:team:${teamId}:shared`,\n teamUsers: (teamId: string, userId: string) =>\n `mem:team:${teamId}:users:${userId}`,\n teamProfile: (teamId: string) => `mem:team:${teamId}:profile`,\n audit: \"mem:audit\",\n actions: \"mem:actions\",\n actionEdges: \"mem:action-edges\",\n leases: \"mem:leases\",\n routines: \"mem:routines\",\n routineRuns: \"mem:routine-runs\",\n signals: \"mem:signals\",\n checkpoints: \"mem:checkpoints\",\n mesh: \"mem:mesh\",\n sketches: \"mem:sketches\",\n facets: \"mem:facets\",\n sentinels: \"mem:sentinels\",\n crystals: \"mem:crystals\",\n lessons: \"mem:lessons\",\n insights: \"mem:insights\",\n graphEdgeHistory: \"mem:graph:edge-history\",\n enrichedChunks: (sessionId: string) => `mem:enriched:${sessionId}`,\n latentEmbeddings: (obsId: string) => `mem:latent:${obsId}`,\n retentionScores: \"mem:retention\",\n accessLog: \"mem:access\",\n} as const;\n\nexport const STREAM = {\n name: \"mem-live\",\n group: (sessionId: string) => sessionId,\n viewerGroup: \"viewer\",\n} as const;\n\nexport function generateId(prefix: string): string {\n const ts = Date.now().toString(36);\n const rand = crypto.randomUUID().replace(/-/g, \"\").slice(0, 12);\n return `${prefix}_${ts}_${rand}`;\n}\n\nexport function fingerprintId(prefix: string, content: string): string {\n const hash = createHash(\"sha256\").update(content).digest(\"hex\");\n return `${prefix}_${hash.slice(0, 16)}`;\n}\n\nexport function jaccardSimilarity(a: string, b: string): number {\n const setA = new Set(a.split(/\\s+/).filter((t) => t.length > 2));\n const setB = new Set(b.split(/\\s+/).filter((t) => t.length > 2));\n if (setA.size === 0 && setB.size === 0) return 1;\n if (setA.size === 0 || setB.size === 0) return 0;\n let intersection = 0;\n for (const word of setA) {\n if (setB.has(word)) intersection++;\n }\n return intersection / (setA.size + setB.size - intersection);\n}\n","#!/usr/bin/env node\n\nimport {\n spawn,\n execFileSync,\n spawnSync,\n type ChildProcess,\n} from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { join, dirname, delimiter as PATH_DELIMITER } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { platform } from \"node:os\";\nimport * as p from \"@clack/prompts\";\nimport { generateId } from \"./state/schema.js\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst args = process.argv.slice(2);\nconst IS_WINDOWS = platform() === \"win32\";\nconst IS_VERBOSE = args.includes(\"--verbose\") || args.includes(\"-v\");\n\nfunction vlog(msg: string): void {\n if (IS_VERBOSE) p.log.info(`[verbose] ${msg}`);\n}\n\nif (args.includes(\"--help\") || args.includes(\"-h\")) {\n console.log(`\nagentmemory — persistent memory for AI coding agents\n\nUsage: agentmemory [command] [options]\n\nCommands:\n (default) Start agentmemory worker\n status Show connection status, memory count, and health\n demo Seed sample sessions and show recall in action\n upgrade Upgrade local deps + iii runtime (best effort)\n mcp Start standalone MCP server (no engine required)\n import-jsonl [p] Import Claude Code JSONL transcripts (default: ~/.claude/projects)\n\nOptions:\n --help, -h Show this help\n --verbose, -v Show engine stderr and diagnostic info on startup\n --tools all|core Tool visibility (default: core = 7 tools)\n --no-engine Skip auto-starting iii-engine\n --port <N> Override REST port (default: 3111)\n\nQuick start:\n npx @agentmemory/agentmemory # start with local iii-engine or Docker\n npx @agentmemory/agentmemory status # check health\n npx @agentmemory/agentmemory demo # try it in 30 seconds (needs server running)\n npx @agentmemory/agentmemory upgrade # upgrade agentmemory + iii runtime\n npx @agentmemory/agentmemory mcp # standalone MCP server (no engine)\n npx @agentmemory/mcp # same as above (shim package)\n`);\n process.exit(0);\n}\n\nconst toolsIdx = args.indexOf(\"--tools\");\nif (toolsIdx !== -1 && args[toolsIdx + 1]) {\n process.env[\"AGENTMEMORY_TOOLS\"] = args[toolsIdx + 1];\n}\n\nconst portIdx = args.indexOf(\"--port\");\nif (portIdx !== -1 && args[portIdx + 1]) {\n process.env[\"III_REST_PORT\"] = args[portIdx + 1];\n}\n\nconst skipEngine = args.includes(\"--no-engine\");\n\nfunction getRestPort(): number {\n return parseInt(process.env[\"III_REST_PORT\"] || \"3111\", 10) || 3111;\n}\n\nasync function isEngineRunning(): Promise<boolean> {\n try {\n await fetch(`http://localhost:${getRestPort()}/`, {\n signal: AbortSignal.timeout(2000),\n });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction findIiiConfig(): string {\n const candidates = [\n join(__dirname, \"iii-config.yaml\"),\n join(__dirname, \"..\", \"iii-config.yaml\"),\n join(process.cwd(), \"iii-config.yaml\"),\n ];\n for (const c of candidates) {\n if (existsSync(c)) return c;\n }\n return \"\";\n}\n\nfunction whichBinary(name: string): string | null {\n const cmd = IS_WINDOWS ? \"where\" : \"which\";\n try {\n const out = execFileSync(cmd, [name], { encoding: \"utf-8\" });\n const first = out\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .find((line) => line.length > 0);\n return first ?? null;\n } catch {\n return null;\n }\n}\n\nfunction fallbackIiiPaths(): string[] {\n if (IS_WINDOWS) {\n const userProfile = process.env[\"USERPROFILE\"];\n if (!userProfile) return [];\n return [\n join(userProfile, \".local\", \"bin\", \"iii.exe\"),\n join(userProfile, \"bin\", \"iii.exe\"),\n ];\n }\n const home = process.env[\"HOME\"];\n if (!home) return [\"/usr/local/bin/iii\"];\n return [join(home, \".local\", \"bin\", \"iii\"), \"/usr/local/bin/iii\"];\n}\n\ntype StartupFailure = {\n kind: \"no-engine\" | \"no-docker-compose\" | \"engine-crashed\" | \"docker-crashed\";\n stderr?: string;\n binary?: string;\n};\n\nlet startupFailure: StartupFailure | null = null;\n\n// Spawn a background engine and collect any startup stderr for a short\n// window. The process is unref'd so the CLI parent can exit cleanly; we\n// only care about stderr that shows up BEFORE the health check succeeds,\n// which is what surfaces early crash/config-parse errors on all platforms.\nfunction spawnEngineBackground(\n bin: string,\n spawnArgs: string[],\n label: string,\n): ChildProcess {\n vlog(`spawn: ${bin} ${spawnArgs.join(\" \")}`);\n const child = spawn(bin, spawnArgs, {\n detached: true,\n stdio: [\"ignore\", \"ignore\", \"pipe\"],\n windowsHide: true,\n });\n const stderrChunks: Buffer[] = [];\n let stderrBytes = 0;\n const MAX_STDERR_CAPTURE = 16 * 1024;\n child.stderr?.on(\"data\", (chunk: Buffer) => {\n if (stderrBytes >= MAX_STDERR_CAPTURE) return;\n const slice = chunk.subarray(0, MAX_STDERR_CAPTURE - stderrBytes);\n stderrChunks.push(slice);\n stderrBytes += slice.length;\n });\n child.on(\"exit\", (code, signal) => {\n const abnormal =\n (code !== null && code !== 0) || (code === null && signal !== null);\n if (abnormal) {\n const stderr = Buffer.concat(stderrChunks).toString(\"utf-8\");\n startupFailure = {\n kind: label.includes(\"Docker\") ? \"docker-crashed\" : \"engine-crashed\",\n stderr:\n stderr.trim() ||\n (signal\n ? `process killed by signal ${signal}`\n : `process exited with code ${code}`),\n binary: bin,\n };\n vlog(`engine exited early: code=${code} signal=${signal}`);\n if (IS_VERBOSE && stderr.trim()) {\n p.log.error(`engine stderr:\\n${stderr}`);\n }\n }\n });\n child.unref();\n return child;\n}\n\nasync function startEngine(): Promise<boolean> {\n const configPath = findIiiConfig();\n let iiiBin = whichBinary(\"iii\");\n vlog(`iii binary: ${iiiBin ?? \"(not on PATH)\"}, config: ${configPath || \"(not found)\"}`);\n\n if (iiiBin && configPath) {\n const s = p.spinner();\n s.start(`Starting iii-engine: ${iiiBin}`);\n spawnEngineBackground(iiiBin, [\"--config\", configPath], \"iii-engine\");\n s.stop(\"iii-engine process started\");\n return true;\n }\n\n const dockerBin = whichBinary(\"docker\");\n vlog(`docker binary: ${dockerBin ?? \"(not on PATH)\"}`);\n const dockerComposeCandidates = [\n join(__dirname, \"..\", \"docker-compose.yml\"),\n join(__dirname, \"docker-compose.yml\"),\n join(process.cwd(), \"docker-compose.yml\"),\n ];\n const composeFile = dockerComposeCandidates.find((c) => existsSync(c));\n vlog(`docker-compose.yml: ${composeFile ?? \"(not found)\"}`);\n\n if (dockerBin && composeFile) {\n const s = p.spinner();\n s.start(\"Starting iii-engine via Docker...\");\n spawnEngineBackground(\n dockerBin,\n [\"compose\", \"-f\", composeFile, \"up\", \"-d\"],\n \"iii-engine via Docker\",\n );\n s.stop(\"Docker compose started\");\n return true;\n }\n\n for (const iiiPath of fallbackIiiPaths()) {\n if (existsSync(iiiPath)) {\n p.log.info(`Found iii at: ${iiiPath}`);\n process.env[\"PATH\"] = `${dirname(iiiPath)}${PATH_DELIMITER}${process.env[\"PATH\"] ?? \"\"}`;\n iiiBin = iiiPath;\n break;\n }\n }\n\n if (iiiBin && configPath) {\n const s = p.spinner();\n s.start(`Starting iii-engine: ${iiiBin}`);\n spawnEngineBackground(iiiBin, [\"--config\", configPath], \"iii-engine\");\n s.stop(\"iii-engine process started\");\n return true;\n }\n\n if (!iiiBin && (!dockerBin || !composeFile)) {\n startupFailure = { kind: \"no-engine\" };\n } else if (!composeFile && dockerBin) {\n startupFailure = { kind: \"no-docker-compose\" };\n }\n return false;\n}\n\nasync function waitForEngine(timeoutMs: number): Promise<boolean> {\n const start = Date.now();\n while (Date.now() - start < timeoutMs) {\n if (await isEngineRunning()) return true;\n await new Promise((r) => setTimeout(r, 500));\n }\n return false;\n}\n\nfunction installInstructions(): string[] {\n if (IS_WINDOWS) {\n return [\n \"agentmemory requires the `iii-engine` runtime. Pick one:\",\n \"\",\n \" A) Download the prebuilt Windows binary:\",\n \" 1. Open https://github.com/iii-hq/iii/releases/latest\",\n \" 2. Download iii-x86_64-pc-windows-msvc.zip\",\n \" (or iii-aarch64-pc-windows-msvc.zip on ARM)\",\n \" 3. Extract iii.exe and either add its folder to PATH\",\n \" or move it to %USERPROFILE%\\\\.local\\\\bin\\\\iii.exe\",\n \" 4. Re-run: npx @agentmemory/agentmemory\",\n \"\",\n \" B) Docker Desktop:\",\n \" 1. Install Docker Desktop for Windows\",\n \" 2. Start Docker Desktop (engine must be running)\",\n \" 3. Re-run: npx @agentmemory/agentmemory\",\n \"\",\n \"Or skip the engine entirely for standalone MCP:\",\n \" npx @agentmemory/agentmemory mcp\",\n ];\n }\n return [\n \"agentmemory requires the `iii-engine` runtime. Pick one:\",\n \"\",\n \" A) curl -fsSL https://install.iii.dev/iii/main/install.sh | sh\",\n \" (installs the prebuilt iii binary into ~/.local/bin/iii)\",\n \"\",\n \" B) Docker: install Docker Desktop or docker-ce, then re-run\",\n \"\",\n \"Or skip the engine entirely for standalone MCP:\",\n \" npx @agentmemory/agentmemory mcp\",\n \"\",\n \"Docs: https://iii.dev/docs\",\n ];\n}\n\nfunction portInUseDiagnostic(port: number): string {\n return IS_WINDOWS\n ? ` netstat -ano | findstr :${port}`\n : ` lsof -i :${port} # or: ss -tlnp | grep :${port}`;\n}\n\nasync function main() {\n p.intro(\"agentmemory\");\n\n if (skipEngine) {\n p.log.info(\"Skipping engine check (--no-engine)\");\n await import(\"./index.js\");\n return;\n }\n\n if (await isEngineRunning()) {\n p.log.success(\"iii-engine is running\");\n await import(\"./index.js\");\n return;\n }\n\n const started = await startEngine();\n if (!started) {\n p.log.error(\"Could not start iii-engine.\");\n const lines = installInstructions();\n if (startupFailure?.kind === \"no-docker-compose\") {\n lines.unshift(\n \"Docker is installed but docker-compose.yml is missing from this\",\n \"install. Re-install with: npm install -g @agentmemory/agentmemory\",\n \"\",\n );\n }\n p.note(lines.join(\"\\n\"), \"Setup required\");\n process.exit(1);\n }\n\n const s = p.spinner();\n s.start(\"Waiting for iii-engine to be ready...\");\n\n const ready = await waitForEngine(15000);\n if (!ready) {\n const port = getRestPort();\n s.stop(\"iii-engine did not become ready within 15s\");\n\n if (startupFailure?.kind === \"engine-crashed\" || startupFailure?.kind === \"docker-crashed\") {\n p.log.error(\"The iii-engine process crashed on startup.\");\n if (startupFailure.binary) {\n p.log.info(`Binary: ${startupFailure.binary}`);\n }\n if (startupFailure.stderr) {\n p.note(startupFailure.stderr, \"engine stderr\");\n } else {\n p.log.info(\"No stderr was captured. Re-run with --verbose for more detail.\");\n }\n p.note(\n [\n \"Common causes:\",\n \" - iii-engine version mismatch — reinstall the latest binary\",\n \" (sh script on macOS/Linux, GitHub release zip on Windows)\",\n \" - Docker Desktop not running (if you're using the Docker path)\",\n \" - Port already in use (see below)\",\n \"\",\n \"See https://iii.dev/docs for current install instructions.\",\n ].join(\"\\n\"),\n \"Troubleshooting\",\n );\n } else {\n p.log.error(\"The engine process started but the REST API never responded.\");\n p.note(\n [\n `Check whether port ${port} is already bound by another process:`,\n portInUseDiagnostic(port),\n \"\",\n \"If it is, free the port or override: agentmemory --port <N>\",\n \"\",\n \"If it isn't, a firewall may be blocking 127.0.0.1:\" + port + \".\",\n \"Re-run with --verbose to see engine stderr.\",\n ].join(\"\\n\"),\n \"Troubleshooting\",\n );\n }\n process.exit(1);\n }\n\n s.stop(\"iii-engine is ready\");\n await import(\"./index.js\");\n}\n\nasync function runStatus() {\n const port = getRestPort();\n const base = `http://localhost:${port}`;\n p.intro(\"agentmemory status\");\n\n const up = await isEngineRunning();\n if (!up) {\n p.log.error(`Not running — no response on port ${port}`);\n p.log.info(\"Start with: npx @agentmemory/agentmemory\");\n process.exit(1);\n }\n\n try {\n const [healthRes, sessionsRes, graphRes, memoriesRes] = await Promise.all([\n fetch(`${base}/agentmemory/health`, { signal: AbortSignal.timeout(5000) }).then((r) => r.json()).catch(() => null),\n fetch(`${base}/agentmemory/sessions`, { signal: AbortSignal.timeout(5000) }).then((r) => r.json()).catch(() => null),\n fetch(`${base}/agentmemory/graph/stats`, { signal: AbortSignal.timeout(5000) }).then((r) => r.json()).catch(() => null),\n fetch(`${base}/agentmemory/export`, { signal: AbortSignal.timeout(5000) }).then((r) => r.json()).catch(() => null),\n ]);\n\n const h = healthRes?.health;\n const status = healthRes?.status || \"unknown\";\n const version = healthRes?.version || \"?\";\n const sessions = Array.isArray(sessionsRes?.sessions) ? sessionsRes.sessions.length : 0;\n const nodes = graphRes?.nodes || 0;\n const edges = graphRes?.edges || 0;\n const cb = healthRes?.circuitBreaker?.state || \"closed\";\n const heapMB = h?.memory ? Math.round(h.memory.heapUsed / 1048576) : 0;\n const uptime = h?.uptimeSeconds ? Math.round(h.uptimeSeconds) : 0;\n\n const obsCount = memoriesRes?.observations?.length || 0;\n const memCount = memoriesRes?.memories?.length || 0;\n const estFullTokens = obsCount * 80;\n const estInjectedTokens = Math.min(obsCount, 50) * 38;\n const tokensSaved = estFullTokens - estInjectedTokens;\n const pctSaved = estFullTokens > 0 ? Math.round((tokensSaved / estFullTokens) * 100) : 0;\n\n p.log.success(`Connected — v${version} on port ${port}`);\n\n const lines = [\n `Health: ${status === \"healthy\" ? \"✓ healthy\" : status}`,\n `Sessions: ${sessions}`,\n `Observations: ${obsCount}`,\n `Memories: ${memCount}`,\n `Graph: ${nodes} nodes, ${edges} edges`,\n `Circuit: ${cb}`,\n `Heap: ${heapMB} MB`,\n `Uptime: ${uptime}s`,\n `Viewer: http://localhost:${port + 2}`,\n ];\n\n if (obsCount > 0) {\n lines.push(\"\");\n lines.push(`Token savings: ~${tokensSaved.toLocaleString()} tokens saved (${pctSaved}% reduction)`);\n lines.push(` Full context: ~${estFullTokens.toLocaleString()} tokens`);\n lines.push(` Injected: ~${estInjectedTokens.toLocaleString()} tokens`);\n }\n\n p.note(lines.join(\"\\n\"), \"agentmemory\");\n } catch (err) {\n p.log.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n}\n\ntype DemoObservation = {\n toolName: string;\n toolInput: Record<string, string>;\n toolOutput: string;\n};\n\ntype DemoSession = {\n id: string;\n title: string;\n observations: DemoObservation[];\n};\n\ntype SearchResult = { query: string; hits: number; topTitle: string };\n\nfunction buildDemoSessions(): DemoSession[] {\n return [\n {\n id: generateId(\"demo\"),\n title: \"Session 1: JWT auth setup\",\n observations: [\n {\n toolName: \"Write\",\n toolInput: { file_path: \"src/middleware/auth.ts\" },\n toolOutput:\n \"Created JWT middleware using jose library. Tokens expire after 30 days. Chose jose over jsonwebtoken for Edge compatibility.\",\n },\n {\n toolName: \"Write\",\n toolInput: { file_path: \"test/auth.test.ts\" },\n toolOutput:\n \"Added token validation tests covering expired, malformed, and valid cases.\",\n },\n {\n toolName: \"Bash\",\n toolInput: { command: \"npm test\" },\n toolOutput: \"All 12 auth tests passing.\",\n },\n ],\n },\n {\n id: generateId(\"demo\"),\n title: \"Session 2: Database migration debugging\",\n observations: [\n {\n toolName: \"Read\",\n toolInput: { file_path: \"prisma/schema.prisma\" },\n toolOutput:\n \"Found N+1 query issue in user relations. Need to add include on posts query.\",\n },\n {\n toolName: \"Edit\",\n toolInput: { file_path: \"src/api/users.ts\" },\n toolOutput:\n \"Fixed N+1 by adding Prisma include. Query time dropped from 450ms to 28ms.\",\n },\n ],\n },\n {\n id: generateId(\"demo\"),\n title: \"Session 3: Rate limiting\",\n observations: [\n {\n toolName: \"Write\",\n toolInput: { file_path: \"src/middleware/ratelimit.ts\" },\n toolOutput:\n \"Added rate limiting middleware with 100 req/min default. Uses in-memory store for dev, Redis for prod.\",\n },\n ],\n },\n ];\n}\n\nasync function postJson<T = unknown>(\n url: string,\n body: unknown,\n timeoutMs = 5000,\n): Promise<T | null> {\n try {\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(timeoutMs),\n });\n if (!res.ok) return null;\n return (await res.json().catch(() => null)) as T | null;\n } catch {\n return null;\n }\n}\n\nasync function postJsonStrict<T = unknown>(\n url: string,\n body: unknown,\n timeoutMs = 5000,\n): Promise<T | null> {\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(timeoutMs),\n });\n if (!res.ok) {\n const errBody = await res.text().catch(() => \"\");\n const suffix = errBody ? ` — ${errBody.slice(0, 200)}` : \"\";\n throw new Error(`POST ${url} failed: ${res.status} ${res.statusText}${suffix}`);\n }\n return (await res.json().catch(() => null)) as T | null;\n}\n\nasync function seedDemoSession(\n base: string,\n project: string,\n session: DemoSession,\n): Promise<number> {\n await postJsonStrict(`${base}/agentmemory/session/start`, {\n sessionId: session.id,\n project,\n cwd: project,\n });\n\n let stored = 0;\n for (const obs of session.observations) {\n const url = `${base}/agentmemory/observe`;\n const payload = {\n hookType: \"post_tool_use\",\n sessionId: session.id,\n timestamp: new Date().toISOString(),\n data: {\n tool_name: obs.toolName,\n tool_input: obs.toolInput,\n tool_output: obs.toolOutput,\n },\n };\n\n try {\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(payload),\n signal: AbortSignal.timeout(5000),\n });\n if (res.ok) {\n stored++;\n } else {\n const body = await res.text().catch(() => \"\");\n p.log.warn(\n `observe failed for ${obs.toolName}: ${res.status} ${res.statusText}${body ? ` — ${body.slice(0, 160)}` : \"\"}`,\n );\n }\n } catch (err) {\n p.log.warn(\n `observe request failed for ${obs.toolName}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n await postJsonStrict(`${base}/agentmemory/session/end`, { sessionId: session.id });\n return stored;\n}\n\nasync function runDemoSearch(base: string, query: string): Promise<SearchResult> {\n const data = await postJson<{ results?: Array<{ title?: string }> }>(\n `${base}/agentmemory/smart-search`,\n { query, limit: 5 },\n 10000,\n );\n const items = data?.results ?? [];\n return {\n query,\n hits: items.length,\n topTitle: items[0]?.title ?? \"(no results)\",\n };\n}\n\nasync function runDemo() {\n const port = getRestPort();\n const base = `http://localhost:${port}`;\n p.intro(\"agentmemory demo\");\n\n if (!(await isEngineRunning())) {\n p.log.error(`Not running — no response on port ${port}`);\n p.log.info(\"Start the server first: npx @agentmemory/agentmemory\");\n process.exit(1);\n }\n\n const demoProject = \"/tmp/agentmemory-demo\";\n const sessions = buildDemoSessions();\n\n const sSeed = p.spinner();\n sSeed.start(\"Seeding 3 demo sessions with realistic observations...\");\n\n let totalObs = 0;\n for (const session of sessions) {\n totalObs += await seedDemoSession(base, demoProject, session);\n }\n\n sSeed.stop(`Seeded ${totalObs} observations across ${sessions.length} sessions`);\n\n const queries = [\n \"jwt auth middleware\",\n \"database performance optimization\",\n \"rate limiting\",\n ];\n\n const sQuery = p.spinner();\n sQuery.start(`Running ${queries.length} smart-search queries...`);\n\n const results: SearchResult[] = [];\n for (const query of queries) {\n results.push(await runDemoSearch(base, query));\n }\n\n sQuery.stop(\"Search complete\");\n\n const lines = [\n `Project: ${demoProject}`,\n `Sessions: ${sessions.length} seeded (${totalObs} observations)`,\n \"\",\n \"Search results:\",\n ...results.flatMap((r) => [\n ` \"${r.query}\"`,\n ` → ${r.hits} hit(s), top: ${r.topTitle.slice(0, 60)}`,\n ]),\n \"\",\n `Notice: searching \"database performance optimization\"`,\n `found the N+1 query fix — keyword matching can't do that.`,\n \"\",\n `Viewer: http://localhost:${port + 2}`,\n `Clean up with: curl -X DELETE \"${base}/agentmemory/sessions?project=${demoProject}\"`,\n ];\n\n p.note(lines.join(\"\\n\"), \"demo complete\");\n p.log.success(\"agentmemory is working. Point your agent at it and get back to coding.\");\n}\n\nfunction runCommand(\n command: string,\n commandArgs: string[],\n options: { cwd?: string; label: string; optional?: boolean } = { label: \"command\" },\n): boolean {\n const spinner = p.spinner();\n spinner.start(options.label);\n const result = spawnSync(command, commandArgs, {\n cwd: options.cwd || process.cwd(),\n stdio: \"pipe\",\n encoding: \"utf-8\",\n });\n\n if (result.status === 0) {\n spinner.stop(`${options.label} ✓`);\n return true;\n }\n\n const stderr = (result.stderr || \"\").toString().trim();\n const stdout = (result.stdout || \"\").toString().trim();\n const msg = stderr || stdout || \"unknown error\";\n\n if (options.optional) {\n spinner.stop(`${options.label} (skipped)`);\n p.log.warn(msg.slice(0, 300));\n return false;\n }\n\n spinner.stop(`${options.label} ✗`);\n p.log.error(msg.slice(0, 300));\n return false;\n}\n\nasync function runUpgrade() {\n p.intro(\"agentmemory upgrade\");\n\n const cwd = process.cwd();\n const hasPackageJson = existsSync(join(cwd, \"package.json\"));\n const hasPnpmLock = existsSync(join(cwd, \"pnpm-lock.yaml\"));\n\n const pnpmBin = whichBinary(\"pnpm\");\n const npmBin = whichBinary(\"npm\");\n const dockerBin = whichBinary(\"docker\");\n\n p.log.info(`Working directory: ${cwd}`);\n const requireSuccess = (ok: boolean, label: string): void => {\n if (!ok) {\n p.log.error(`Upgrade aborted: ${label} failed.`);\n process.exit(1);\n }\n };\n\n if (hasPackageJson) {\n const usePnpm = !!pnpmBin && hasPnpmLock;\n if (usePnpm && pnpmBin) {\n const installOk = runCommand(pnpmBin, [\"install\"], {\n label: \"Refreshing dependencies (pnpm install)\",\n });\n requireSuccess(installOk, \"pnpm install\");\n runCommand(pnpmBin, [\"up\", \"iii-sdk@latest\"], {\n label: \"Upgrading iii-sdk to latest\",\n optional: true,\n });\n } else if (npmBin) {\n const installOk = runCommand(npmBin, [\"install\"], {\n label: \"Refreshing dependencies (npm install)\",\n });\n requireSuccess(installOk, \"npm install\");\n runCommand(npmBin, [\"install\", \"iii-sdk@latest\"], {\n label: \"Upgrading iii-sdk to latest\",\n optional: true,\n });\n } else {\n p.log.warn(\"No package manager found (pnpm/npm). Skipping JS dependency upgrade.\");\n }\n } else {\n p.log.warn(\"No package.json in current directory. Skipping JS dependency upgrade.\");\n }\n\n const shBin = whichBinary(\"sh\");\n const curlBin = whichBinary(\"curl\");\n if (shBin && curlBin) {\n const upgradeEngine = await p.confirm({\n message: \"Re-run the iii-engine install script (curl | sh)?\",\n initialValue: true,\n });\n if (p.isCancel(upgradeEngine)) {\n p.cancel(\"Cancelled.\");\n return process.exit(0);\n }\n if (upgradeEngine === true) {\n const installerOk = runCommand(\n shBin,\n [\"-c\", \"curl -fsSL https://install.iii.dev/iii/main/install.sh | sh\"],\n { label: \"Upgrading iii-engine via installer\", optional: true },\n );\n if (!installerOk) {\n p.log.warn(\n \"iii-engine installer failed. Fallbacks: Docker (`docker pull iiidev/iii:latest`) or releases at https://github.com/iii-hq/iii/releases/latest.\",\n );\n }\n } else {\n p.log.info(\"Skipped iii-engine installer.\");\n }\n } else {\n p.log.warn(\"curl or sh not found. Skipping iii-engine installer.\");\n }\n\n if (dockerBin) {\n runCommand(dockerBin, [\"pull\", \"iiidev/iii:latest\"], {\n label: \"Pulling latest iii Docker image\",\n optional: true,\n });\n } else {\n p.log.info(\"Docker not found. Skipping Docker image refresh.\");\n }\n\n p.note(\n [\n \"Upgrade flow completed.\",\n \"\",\n \"Recommended next steps:\",\n \" 1) agentmemory status\",\n \" 2) npm/pnpm test\",\n \" 3) restart agentmemory process\",\n ].join(\"\\n\"),\n \"agentmemory upgrade\",\n );\n}\n\nasync function runMcp(): Promise<void> {\n await import(\"./mcp/standalone.js\");\n}\n\nasync function runImportJsonl(): Promise<void> {\n const nonFlagArgs = args.slice(1).filter((a) => !a.startsWith(\"-\"));\n const pathArg = nonFlagArgs[0];\n const port = getRestPort();\n const base = `http://localhost:${port}`;\n\n let probeOk = false;\n let probeDetail = \"\";\n try {\n const probe = await fetch(`${base}/agentmemory/livez`, {\n signal: AbortSignal.timeout(2000),\n });\n probeOk = probe.ok;\n if (!probeOk) {\n const probeBody = await probe.text().catch(() => \"\");\n probeDetail = `reachable but unhealthy (HTTP ${probe.status}${probeBody ? `: ${probeBody.slice(0, 200)}` : \"\"})`;\n }\n } catch (err) {\n probeOk = false;\n const msg = err instanceof Error ? err.message : String(err);\n probeDetail = `unreachable (${msg})`;\n }\n if (!probeOk) {\n p.log.error(\n `agentmemory livez probe failed on port ${port}: ${probeDetail}. Start it with \\`npx @agentmemory/agentmemory\\` in another terminal, then re-run this command.`,\n );\n process.exit(1);\n }\n\n const body: Record<string, unknown> = {};\n if (pathArg) body[\"path\"] = pathArg;\n\n const headers: Record<string, string> = { \"content-type\": \"application/json\" };\n const secret = process.env[\"AGENTMEMORY_SECRET\"];\n if (secret) headers[\"authorization\"] = `Bearer ${secret}`;\n\n p.log.info(`Importing JSONL from ${pathArg || \"~/.claude/projects\"}…`);\n const spinner = p.spinner();\n spinner.start(\"scanning files\");\n\n try {\n const res = await fetch(`${base}/agentmemory/replay/import-jsonl`, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(120_000),\n });\n const text = await res.text();\n let json: {\n success?: boolean;\n error?: string;\n imported?: number;\n sessionIds?: string[];\n observations?: number;\n } = {};\n if (text.length > 0) {\n try {\n json = JSON.parse(text);\n } catch {\n spinner.stop(\"failed\");\n p.log.error(\n `server returned non-JSON response (HTTP ${res.status}): ${text.slice(0, 200)}`,\n );\n process.exit(1);\n }\n }\n if (!res.ok || json.success !== true) {\n spinner.stop(\"failed\");\n const detail =\n json.error ||\n (text.length === 0\n ? \"empty response body\"\n : json.success === undefined\n ? `HTTP ${res.status} (response missing success field)`\n : `HTTP ${res.status}`);\n if (res.status === 401) {\n p.log.error(\n `${detail}. Set AGENTMEMORY_SECRET to match the server's secret and re-run.`,\n );\n } else if (res.status === 404) {\n p.log.error(\n `${detail}. The running agentmemory server does not expose /agentmemory/replay/import-jsonl — upgrade to v0.8.13 or later.`,\n );\n } else {\n p.log.error(detail);\n }\n process.exit(1);\n }\n spinner.stop(\n `imported ${json.imported ?? 0} file(s), ${json.observations ?? 0} observation(s) across ${json.sessionIds?.length || 0} session(s)`,\n );\n if (json.sessionIds && json.sessionIds.length > 0) {\n p.log.info(`View at http://localhost:${port + 2} → Replay tab`);\n }\n } catch (err) {\n spinner.stop(\"failed\");\n if (err instanceof Error && err.name === \"TimeoutError\") {\n p.log.error(\"import timed out after 2 minutes\");\n } else {\n p.log.error(err instanceof Error ? err.message : String(err));\n }\n process.exit(1);\n }\n}\n\nconst commands: Record<string, () => Promise<void>> = {\n status: runStatus,\n demo: runDemo,\n upgrade: runUpgrade,\n mcp: runMcp,\n \"import-jsonl\": runImportJsonl,\n};\n\nconst handler = commands[args[0] ?? \"\"] ?? main;\nhandler().catch((err) => {\n p.log.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n});\n"],"mappings":"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"}
|