@agentmemory/agentmemory 0.9.3 → 0.9.5

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 CHANGED
@@ -3,12 +3,15 @@
3
3
  </p>
4
4
 
5
5
  <p align="center">
6
- <strong>Your coding agent remembers everything. No more re-explaining.</strong><br/>
7
- Persistent memory for Claude Code, Cursor, Gemini CLI, OpenCode, and any MCP client.
6
+ <strong>
7
+ Your coding agent remembers everything. No more re-explaining.
8
+ Built on <a href="https://github.com/iii-hq/iii">iii engine</a>
9
+ </strong></br>
10
+ Persistent memory for Claude Code, Cursor, Gemini CLI, Codex CLI, pi, OpenCode, and any MCP client.
8
11
  </p>
9
12
 
10
13
  <p align="center">
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>
14
+ <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
15
  </p>
13
16
 
14
17
  <p align="center">
@@ -43,7 +46,8 @@
43
46
  <a href="#how-it-works">How It Works</a> &bull;
44
47
  <a href="#mcp-server">MCP</a> &bull;
45
48
  <a href="#real-time-viewer">Viewer</a> &bull;
46
- <a href="#iii-console--trace-level-engine-inspection">iii Console</a> &bull;
49
+ <a href="#iii-console">iii Console</a> &bull;
50
+ <a href="#powered-by-iii">Powered by iii</a> &bull;
47
51
  <a href="#configuration">Config</a> &bull;
48
52
  <a href="#api">API</a>
49
53
  </p>
@@ -341,7 +345,7 @@ Install agentmemory: run `npx @agentmemory/agentmemory` in a separate terminal t
341
345
  <summary><b>OpenClaw (paste this prompt)</b></summary>
342
346
 
343
347
  ```
344
- Install agentmemory for OpenClaw. Run `npx @agentmemory/agentmemory` in a separate terminal to start the memory server on localhost:3111. Then add this to my OpenClaw MCP config so agentmemory is available with all 50 memory tools:
348
+ Install agentmemory for OpenClaw. Run `npx @agentmemory/agentmemory` in a separate terminal to start the memory server on localhost:3111. Then add this to my OpenClaw MCP config so agentmemory is available with all 43 memory tools:
345
349
 
346
350
  {
347
351
  "mcpServers": {
@@ -352,7 +356,7 @@ Install agentmemory for OpenClaw. Run `npx @agentmemory/agentmemory` in a separa
352
356
  }
353
357
  }
354
358
 
355
- Restart OpenClaw. Verify with `curl http://localhost:3111/agentmemory/health`. Open http://localhost:3113 for the real-time viewer. For deeper 4-hook gateway integration, see integrations/openclaw in the agentmemory repo.
359
+ Restart OpenClaw. Verify with `curl http://localhost:3111/agentmemory/health`. Open http://localhost:3113 for the real-time viewer. For deeper memory-slot integration, copy `integrations/openclaw` to `~/.openclaw/extensions/agentmemory` and enable `plugins.slots.memory = "agentmemory"` in `~/.openclaw/openclaw.json`.
356
360
  ```
357
361
 
358
362
  Full guide: [`integrations/openclaw/`](integrations/openclaw/)
@@ -363,14 +367,17 @@ Full guide: [`integrations/openclaw/`](integrations/openclaw/)
363
367
  <summary><b>Hermes Agent (paste this prompt)</b></summary>
364
368
 
365
369
  ```
366
- Install agentmemory for Hermes. Run `npx @agentmemory/agentmemory` in a separate terminal to start the memory server on localhost:3111. Then add this to ~/.hermes/config.yaml so Hermes can use agentmemory as an MCP server with all 50 memory tools:
370
+ Install agentmemory for Hermes. Run `npx @agentmemory/agentmemory` in a separate terminal to start the memory server on localhost:3111. Then add this to ~/.hermes/config.yaml so Hermes can use agentmemory as an MCP server with all 43 memory tools:
367
371
 
368
372
  mcp_servers:
369
373
  agentmemory:
370
374
  command: npx
371
375
  args: ["-y", "@agentmemory/mcp"]
372
376
 
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/memory/agentmemory.
377
+ memory:
378
+ provider: agentmemory
379
+
380
+ 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
381
  ```
375
382
 
376
383
  Full guide: [`integrations/hermes/`](integrations/hermes/)
@@ -386,11 +393,12 @@ Then add the MCP config for your agent:
386
393
  | Agent | Setup |
387
394
  |---|---|
388
395
  | **Cursor** | Add to `~/.cursor/mcp.json`: `{"mcpServers": {"agentmemory": {"command": "npx", "args": ["-y", "@agentmemory/mcp"]}}}` |
389
- | **OpenClaw** | Add to MCP config: `{"mcpServers": {"agentmemory": {"command": "npx", "args": ["-y", "@agentmemory/mcp"]}}}` or use the [gateway plugin](integrations/openclaw/) |
390
- | **Gemini CLI** | `gemini mcp add agentmemory -- npx -y @agentmemory/mcp` |
391
- | **Codex CLI** | Add to `.codex/config.yaml`: `mcp_servers: {agentmemory: {command: npx, args: ["-y", "@agentmemory/mcp"]}}` |
396
+ | **OpenClaw** | Add to MCP config: `{"mcpServers": {"agentmemory": {"command": "npx", "args": ["-y", "@agentmemory/mcp"]}}}` or use the [memory plugin](integrations/openclaw/) |
397
+ | **Gemini CLI** | `gemini mcp add agentmemory npx -y @agentmemory/mcp --scope user` |
398
+ | **Codex CLI** | `codex mcp add agentmemory -- npx -y @agentmemory/mcp` or add `[mcp_servers.agentmemory]` to `.codex/config.toml` |
399
+ | **pi** | Copy [`integrations/pi`](integrations/pi/) to `~/.pi/agent/extensions/agentmemory` and restart pi |
392
400
  | **OpenCode** | Add to `opencode.json`: `{"mcp": {"agentmemory": {"type": "local", "command": ["npx", "-y", "@agentmemory/mcp"], "enabled": true}}}` |
393
- | **Hermes Agent** | Add to `~/.hermes/config.yaml` or use the [memory provider plugin](integrations/hermes/) |
401
+ | **Hermes Agent** | Add to `~/.hermes/config.yaml` with `memory.provider: agentmemory` or use the [memory provider plugin](integrations/hermes/) |
394
402
  | **Cline / Goose / Kilo Code** | Add MCP server in settings |
395
403
  | **Claude Desktop** | Add to `claude_desktop_config.json`: `{"mcpServers": {"agentmemory": {"command": "npx", "args": ["-y", "@agentmemory/mcp"]}}}` |
396
404
  | **Aider** | REST API: `curl -X POST http://localhost:3111/agentmemory/smart-search -d '{"query": "auth"}'` |
@@ -405,12 +413,15 @@ npm install && npm run build && npm start
405
413
 
406
414
  This starts agentmemory with a local `iii-engine` if `iii` is already installed, or falls back to Docker Compose if Docker is available. REST, streams, and the viewer bind to `127.0.0.1` by default.
407
415
 
408
- Install `iii-engine` manually:
416
+ Install `iii-engine` manually. **agentmemory currently pins `iii-engine` to `v0.11.2`** — `v0.11.6` introduces a new sandbox-everything-via-`iii worker add` model that agentmemory hasn't been refactored for yet. Pin lifts once the refactor lands. Override with `AGENTMEMORY_III_VERSION=<version>` if you've migrated to the sandbox model manually.
409
417
 
410
- - **macOS / Linux:** `curl -fsSL https://install.iii.dev/iii/main/install.sh | sh`
411
- - **Windows:** download `iii-x86_64-pc-windows-msvc.zip` from [iii-hq/iii releases](https://github.com/iii-hq/iii/releases/latest), extract `iii.exe`, add to PATH
418
+ - **macOS arm64:** `mkdir -p ~/.local/bin && curl -fsSL https://github.com/iii-hq/iii/releases/download/iii/v0.11.2/iii-aarch64-apple-darwin.tar.gz | tar -xz -C ~/.local/bin && chmod +x ~/.local/bin/iii`
419
+ - **macOS x64:** swap `aarch64-apple-darwin` for `x86_64-apple-darwin`
420
+ - **Linux x64:** swap for `x86_64-unknown-linux-gnu`
421
+ - **Linux arm64:** swap for `aarch64-unknown-linux-gnu`
422
+ - **Windows:** download `iii-x86_64-pc-windows-msvc.zip` from [iii-hq/iii releases v0.11.2](https://github.com/iii-hq/iii/releases/tag/iii%2Fv0.11.2), extract `iii.exe`, add to PATH
412
423
 
413
- Or use Docker (the bundled `docker-compose.yml` pulls `iiidev/iii:latest`). Full docs: [iii.dev/docs](https://iii.dev/docs).
424
+ Or use Docker (the bundled `docker-compose.yml` pulls `iiidev/iii:0.11.2`). Full docs: [iii.dev/docs](https://iii.dev/docs).
414
425
 
415
426
  ### Windows
416
427
 
@@ -419,7 +430,9 @@ agentmemory runs on Windows 10/11, but the Node.js package alone isn't enough
419
430
  **Option A — Prebuilt Windows binary (recommended):**
420
431
 
421
432
  ```powershell
422
- # 1. Open https://github.com/iii-hq/iii/releases/latest in your browser
433
+ # 1. Open https://github.com/iii-hq/iii/releases/tag/iii%2Fv0.11.2 in your browser
434
+ # (we pin to v0.11.2 until agentmemory refactors for the new sandbox
435
+ # model that engine v0.11.6+ requires)
423
436
  # 2. Download iii-x86_64-pc-windows-msvc.zip
424
437
  # (or iii-aarch64-pc-windows-msvc.zip if you're on an ARM machine)
425
438
  # 3. Extract iii.exe somewhere on PATH, or place it at:
@@ -427,6 +440,7 @@ agentmemory runs on Windows 10/11, but the Node.js package alone isn't enough
427
440
  # (agentmemory checks that location automatically)
428
441
  # 4. Verify:
429
442
  iii --version
443
+ # Should print: 0.11.2
430
444
 
431
445
  # 5. Then run agentmemory as usual:
432
446
  npx -y @agentmemory/agentmemory
@@ -506,7 +520,12 @@ PostToolUse hook fires
506
520
  -> Store raw observation
507
521
  -> LLM compress -> structured facts + concepts + narrative
508
522
  -> Vector embedding (6 providers + local)
509
- -> Index in BM25 + vector + knowledge graph
523
+ -> Index in BM25 + vector
524
+
525
+ Stop / SessionEnd hook fires
526
+ -> Summarize session
527
+ -> Knowledge graph extraction (if GRAPH_EXTRACTION_ENABLED=true)
528
+ -> Slot reflection (if SLOT_REFLECT_ENABLED=true)
510
529
 
511
530
  SessionStart hook fires
512
531
  -> Load project profile (top concepts, files, patterns)
@@ -719,41 +738,57 @@ open http://localhost:3113
719
738
 
720
739
  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'`).
721
740
 
722
- ### iii console — trace-level engine inspection
741
+ ---
742
+
743
+ <h2 id="iii-console"><picture><source media="(prefers-color-scheme: dark)" srcset="assets/tags/light/section-viewer.svg"><img src="assets/tags/section-viewer.svg" alt="iii Console" height="32" /></picture></h2>
744
+
745
+ The viewer at `:3113` shows what your agent **remembered**. The [iii console](https://iii.dev/docs/console) shows what your agent **did** — every memory op as an OpenTelemetry trace, every KV entry editable, every function invocable, every stream tappable. Two windows on the same memory: one product-shaped, one engine-shaped.
746
+
747
+ Watch a `memory_smart_search` fire and see the BM25 scan → embedding lookup → RRF fusion → reranker as a waterfall. Edit a stuck consolidation timer in the KV browser. Replay a `PostToolUse` hook with a tweaked payload. Pin the WebSocket stream and watch observations land live.
723
748
 
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.
749
+ agentmemory ships this for free because every function, trigger, state scope, and stream is an iii primitive nothing custom, nothing to instrument.
725
750
 
726
751
  <p align="center">
727
- <img src="assets/iii-console/dashboard.png" alt="iii console dashboardsystem counters, application flow, registered triggers, live WebSocket status" width="720" />
752
+ <img src="assets/iii-console/workers.png" alt="iii console Workers page connected workers including agentmemory instances with live function counts and runtime metadata" width="720" />
728
753
  <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>
754
+ <em>Workers page: every connected worker including agentmemory itself with PID, function count, runtime, and last-seen.</em>
730
755
  </p>
731
756
 
732
- **Install once:**
757
+ **Already installed.** The console ships with `iii` — no separate installer.
758
+
759
+ **Launch alongside agentmemory:**
733
760
 
734
761
  ```bash
735
- curl -fsSL https://install.iii.dev/console/main/install.sh | sh
762
+ # agentmemory viewer holds port 3113, so run the console on 3114.
763
+ # Engine REST (3111), WebSocket (3112), and bridge (49134) defaults match agentmemory.
764
+ iii console --port 3114
736
765
  ```
737
766
 
738
- **Launch alongside agentmemory:**
767
+ Then open `http://localhost:3114`. Add `--enable-flow` for the experimental architecture-graph page.
768
+
769
+ Override engine endpoints only if you've moved them:
739
770
 
740
771
  ```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
772
+ iii console --port 3114 \
773
+ --engine-port 3111 \
774
+ --ws-port 3112 \
775
+ --bridge-port 49134
743
776
  ```
744
777
 
745
- Then open `http://localhost:3114`.
746
-
747
778
  **What you can do from the console:**
748
779
 
749
780
  | Page | Use it to |
750
781
  |------|-----------|
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 storesessions, 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. |
782
+ | **Workers** | See every connected worker and its live metricsincluding the agentmemory worker itself. |
783
+ | **Functions** | Invoke any of agentmemory's functions directly with a JSON payload handy for testing `memory.recall`, `memory.consolidate`, `graph.query` without wiring a client. |
784
+ | **Triggers** | Replay HTTP, cron, event, and state triggers fire the consolidation cron manually, retry an HTTP route, emit a state change. |
785
+ | **States** | KV browser with full CRUD — sessions, memory slots, lifecycle timers, embeddings index edit values in place. |
786
+ | **Streams** | Live WebSocket monitor for memory writes, hook events, and observation updates as they flow through iii streams. |
787
+ | **Queues** | Durable queue topics + dead-letter management. Replay or drop failed embedding / compression jobs. |
755
788
  | **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. |
789
+ | **Logs** | Structured OTEL logs filtered and correlated to trace/span IDs. |
790
+ | **Config** | Runtime configuration — see exactly which workers, providers, and ports your engine is running with. |
791
+ | **Flow** | (Optional, `--enable-flow`) Interactive architecture graph of every worker, trigger, and stream. |
757
792
 
758
793
  <p align="center">
759
794
  <img src="assets/iii-console/traces-waterfall.png" alt="iii console trace waterfall view showing per-span duration" width="720" />
@@ -771,6 +806,53 @@ If you want to export to Jaeger/Honeycomb/Grafana Tempo instead, change `exporte
771
806
 
772
807
  ---
773
808
 
809
+ <h2 id="powered-by-iii"><picture><source media="(prefers-color-scheme: dark)" srcset="assets/tags/light/section-architecture.svg"><img src="assets/tags/section-architecture.svg" alt="Powered by iii" height="32" /></picture></h2>
810
+
811
+ agentmemory is **already a running [iii](https://iii.dev) instance**. Functions, triggers, KV state, streams, OTEL traces — all of it is iii primitives. You didn't install Postgres, Redis, Express, pm2, or Prometheus, because iii replaces them.
812
+
813
+ That means one more command extends agentmemory with an entire new capability.
814
+
815
+ ### Extend agentmemory with one command
816
+
817
+ ```bash
818
+ iii worker add iii-pubsub # fan memory writes out to every connected instance
819
+ iii worker add iii-cron # scheduled consolidation, decay sweeps, snapshot rotation
820
+ iii worker add iii-queue # durable retries for embedding + compression jobs
821
+ iii worker add iii-observability # OTEL traces on every memory op (default on)
822
+ iii worker add iii-sandbox # run recalled code inside an isolated microVM
823
+ iii worker add iii-database # swap in a SQL-backed state adapter
824
+ iii worker add mcp # generic MCP host alongside the agentmemory MCP
825
+ ```
826
+
827
+ Each `iii worker add` registers new functions and triggers into the same engine agentmemory is already running on. The viewer and console pick them up immediately — no reload, no new integration, no new container.
828
+
829
+ | `iii worker add` | What you get on top of agentmemory |
830
+ |---|---|
831
+ | [`iii-pubsub`](https://workers.iii.dev/workers/iii-pubsub) | Multi-instance memory: every `remember` fans out, every `search` reads the union |
832
+ | [`iii-cron`](https://workers.iii.dev/workers/iii-cron) | Scheduled lifecycle — nightly consolidation, weekly snapshots, decay on a fixed clock |
833
+ | [`iii-queue`](https://workers.iii.dev/workers/iii-queue) | Durable retries: failed embedding + compression jobs survive restart, no lost observations |
834
+ | [`iii-observability`](https://workers.iii.dev/workers/iii-observability) | OTEL traces, metrics, logs on every function — wired in `iii-config.yaml` from day one |
835
+ | [`iii-sandbox`](https://workers.iii.dev/workers/iii-sandbox) | Code that came out of `memory_recall` runs inside a throwaway VM, not your shell |
836
+ | [`iii-database`](https://workers.iii.dev/workers/iii-database) | SQL-backed state adapter when you outgrow the in-memory KV defaults |
837
+ | [`mcp`](https://workers.iii.dev/workers/mcp) | Stand up extra MCP servers next to agentmemory's, share the same engine |
838
+
839
+ Full registry: [workers.iii.dev](https://workers.iii.dev). Every worker there composes through the same primitives agentmemory uses — and the agentmemory you already have is one of them.
840
+
841
+ ### What iii replaces
842
+
843
+ | Traditional stack | agentmemory uses |
844
+ |---|---|
845
+ | Express.js / Fastify | iii HTTP Triggers |
846
+ | SQLite / Postgres + pgvector | iii KV State + in-memory vector index |
847
+ | SSE / Socket.io | iii Streams (WebSocket) |
848
+ | pm2 / systemd | iii engine worker supervision |
849
+ | Prometheus / Grafana | iii OTEL + health monitor |
850
+ | Custom plugin systems | `iii worker add <name>` |
851
+
852
+ **118 source files · ~21,800 LOC · 800 tests · 123 functions · 34 KV scopes** — all on three primitives. No `agentmemory plugin install`. The plugin system is iii itself.
853
+
854
+ ---
855
+
774
856
  <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>
775
857
 
776
858
  ### LLM Providers
@@ -907,25 +989,6 @@ Full endpoint list: [`src/triggers/api.ts`](src/triggers/api.ts)
907
989
 
908
990
  ---
909
991
 
910
- <h2 id="architecture"><picture><source media="(prefers-color-scheme: dark)" srcset="assets/tags/light/section-architecture.svg"><img src="assets/tags/section-architecture.svg" alt="Architecture" height="32" /></picture></h2>
911
-
912
- Built on [iii-engine](https://iii.dev)'s three primitives — no Express, no Postgres, no Redis.
913
-
914
- **118 source files · ~21,800 LOC · 800 tests · 123 functions · 34 KV scopes**
915
-
916
- <details>
917
- <summary>What iii-engine replaces</summary>
918
-
919
- | Traditional stack | agentmemory uses |
920
- |---|---|
921
- | Express.js / Fastify | iii HTTP Triggers |
922
- | SQLite / Postgres + pgvector | iii KV State + in-memory vector index |
923
- | SSE / Socket.io | iii Streams (WebSocket) |
924
- | pm2 / systemd | iii-engine worker management |
925
- | Prometheus / Grafana | iii OTEL + health monitor |
926
-
927
- </details>
928
-
929
992
  <h2 id="development"><picture><source media="(prefers-color-scheme: dark)" srcset="assets/tags/light/section-development.svg"><img src="assets/tags/section-development.svg" alt="Development" height="32" /></picture></h2>
930
993
 
931
994
  ```bash
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
 
@@ -81,6 +81,24 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
81
81
  const args = process.argv.slice(2);
82
82
  const IS_WINDOWS = platform() === "win32";
83
83
  const IS_VERBOSE = args.includes("--verbose") || args.includes("-v");
84
+ const IIPINNED_VERSION = process.env["AGENTMEMORY_III_VERSION"] || "0.11.2";
85
+ function iiiReleaseAsset() {
86
+ const p = platform();
87
+ const a = process.arch;
88
+ if (p === "darwin" && a === "arm64") return "iii-aarch64-apple-darwin.tar.gz";
89
+ if (p === "darwin" && a === "x64") return "iii-x86_64-apple-darwin.tar.gz";
90
+ if (p === "linux" && a === "x64") return "iii-x86_64-unknown-linux-gnu.tar.gz";
91
+ if (p === "linux" && a === "arm64") return "iii-aarch64-unknown-linux-gnu.tar.gz";
92
+ if (p === "linux" && a === "arm") return "iii-armv7-unknown-linux-gnueabihf.tar.gz";
93
+ if (p === "win32" && a === "x64") return "iii-x86_64-pc-windows-msvc.zip";
94
+ if (p === "win32" && a === "arm64") return "iii-aarch64-pc-windows-msvc.zip";
95
+ return null;
96
+ }
97
+ function iiiReleaseUrl() {
98
+ const asset = iiiReleaseAsset();
99
+ if (!asset) return null;
100
+ return `https://github.com/iii-hq/iii/releases/download/iii/v${IIPINNED_VERSION}/${asset}`;
101
+ }
84
102
  function vlog(msg) {
85
103
  if (IS_VERBOSE) p.log.info(`[verbose] ${msg}`);
86
104
  }
@@ -98,6 +116,8 @@ Commands:
98
116
  upgrade Upgrade local deps + iii runtime (best effort)
99
117
  mcp Start standalone MCP server (no engine required)
100
118
  import-jsonl [p] Import Claude Code JSONL transcripts (default: ~/.claude/projects)
119
+ --max-files <N> | --max-files=<N>: override scan cap (default 200, max 1000;
120
+ out-of-range is rejected; for trees >1000 files, batch by subdirectory)
101
121
 
102
122
  Options:
103
123
  --help, -h Show this help
@@ -286,12 +306,13 @@ async function waitForEngine(timeoutMs) {
286
306
  return false;
287
307
  }
288
308
  function installInstructions() {
309
+ const releaseUrl = iiiReleaseUrl();
289
310
  if (IS_WINDOWS) return [
290
- "agentmemory requires the `iii-engine` runtime. Pick one:",
311
+ `agentmemory requires the \`iii-engine\` runtime, pinned to v${IIPINNED_VERSION}. Pick one:`,
291
312
  "",
292
313
  " A) Download the prebuilt Windows binary:",
293
- " 1. Open https://github.com/iii-hq/iii/releases/latest",
294
- " 2. Download iii-x86_64-pc-windows-msvc.zip",
314
+ ` 1. Open https://github.com/iii-hq/iii/releases/tag/iii%2Fv${IIPINNED_VERSION}`,
315
+ ` 2. Download iii-x86_64-pc-windows-msvc.zip`,
295
316
  " (or iii-aarch64-pc-windows-msvc.zip on ARM)",
296
317
  " 3. Extract iii.exe and either add its folder to PATH",
297
318
  " or move it to %USERPROFILE%\\.local\\bin\\iii.exe",
@@ -299,24 +320,31 @@ function installInstructions() {
299
320
  "",
300
321
  " B) Docker Desktop:",
301
322
  " 1. Install Docker Desktop for Windows",
302
- " 2. Start Docker Desktop (engine must be running)",
303
- " 3. Re-run: npx @agentmemory/agentmemory",
323
+ ` 2. docker pull iiidev/iii:${IIPINNED_VERSION}`,
324
+ " 3. Start Docker Desktop (engine must be running)",
325
+ " 4. Re-run: npx @agentmemory/agentmemory",
304
326
  "",
305
327
  "Or skip the engine entirely for standalone MCP:",
306
328
  " npx @agentmemory/agentmemory mcp"
307
329
  ];
330
+ const linuxInstall = releaseUrl ? ` A) mkdir -p ~/.local/bin && curl -fsSL "${releaseUrl}" | tar -xz -C ~/.local/bin && chmod +x ~/.local/bin/iii` : ` A) Manual download from https://github.com/iii-hq/iii/releases/tag/iii%2Fv${IIPINNED_VERSION}`;
308
331
  return [
309
- "agentmemory requires the `iii-engine` runtime. Pick one:",
332
+ `agentmemory requires the \`iii-engine\` runtime, pinned to v${IIPINNED_VERSION}. Pick one:`,
310
333
  "",
311
- " A) curl -fsSL https://install.iii.dev/iii/main/install.sh | sh",
312
- " (installs the prebuilt iii binary into ~/.local/bin/iii)",
334
+ linuxInstall,
335
+ ` (installs iii v${IIPINNED_VERSION} into ~/.local/bin/iii)`,
313
336
  "",
314
- " B) Docker: install Docker Desktop or docker-ce, then re-run",
337
+ ` B) Docker: \`docker pull iiidev/iii:${IIPINNED_VERSION}\``,
315
338
  "",
316
339
  "Or skip the engine entirely for standalone MCP:",
317
340
  " npx @agentmemory/agentmemory mcp",
318
341
  "",
319
- "Docs: https://iii.dev/docs"
342
+ "Docs: https://iii.dev/docs",
343
+ `Why pinned: iii v0.11.6 introduces the new sandbox-everything model`,
344
+ `(\`iii worker add\` registration). agentmemory still uses the older`,
345
+ `iii-exec config-file worker model and needs a refactor before it`,
346
+ `runs cleanly under the new engine. Override with`,
347
+ `AGENTMEMORY_III_VERSION=<version> when you've migrated manually.`
320
348
  ];
321
349
  }
322
350
  function portInUseDiagnostic(port) {
@@ -326,12 +354,12 @@ async function main() {
326
354
  p.intro("agentmemory");
327
355
  if (skipEngine) {
328
356
  p.log.info("Skipping engine check (--no-engine)");
329
- await import("./src-3Snd7D3T.mjs");
357
+ await import("./src-xYHSzz5S.mjs");
330
358
  return;
331
359
  }
332
360
  if (await isEngineRunning()) {
333
361
  p.log.success("iii-engine is running");
334
- await import("./src-3Snd7D3T.mjs");
362
+ await import("./src-xYHSzz5S.mjs");
335
363
  return;
336
364
  }
337
365
  if (!await startEngine()) {
@@ -375,7 +403,7 @@ async function main() {
375
403
  process.exit(1);
376
404
  }
377
405
  s.stop("iii-engine is ready");
378
- await import("./src-3Snd7D3T.mjs");
406
+ await import("./src-xYHSzz5S.mjs");
379
407
  }
380
408
  async function apiFetch(base, path, timeoutMs = 5e3) {
381
409
  try {
@@ -453,6 +481,42 @@ async function runStatus() {
453
481
  function formatChecks(checks) {
454
482
  return checks.map((c) => `${c.ok ? "✓" : "✗"} ${c.name}${c.hint ? `\n ${c.hint}` : ""}`).join("\n");
455
483
  }
484
+ function findLatestDebugLog(debugDir) {
485
+ const latestLink = join(debugDir, "latest");
486
+ try {
487
+ if (existsSync(latestLink)) {
488
+ const target = readlinkSync(latestLink);
489
+ const resolved = target.startsWith("/") ? target : join(debugDir, target);
490
+ if (existsSync(resolved)) return resolved;
491
+ }
492
+ } catch {}
493
+ try {
494
+ const newest = readdirSync(debugDir).filter((f) => f.endsWith(".txt")).map((f) => ({
495
+ f,
496
+ m: statSync(join(debugDir, f)).mtimeMs
497
+ })).sort((a, b) => b.m - a.m)[0];
498
+ if (newest) return join(debugDir, newest.f);
499
+ } catch {}
500
+ }
501
+ function checkClaudeCodeHooks() {
502
+ const debugDir = join(homedir(), ".claude", "debug");
503
+ if (!existsSync(debugDir)) return { state: "no-cc-dir" };
504
+ const logPath = findLatestDebugLog(debugDir);
505
+ if (!logPath) return { state: "no-debug-log" };
506
+ let content;
507
+ try {
508
+ content = readFileSync(logPath, "utf8");
509
+ } catch {
510
+ return { state: "no-debug-log" };
511
+ }
512
+ const match = content.match(/Loaded hooks from standard location for plugin agentmemory:\s*(\S+)/);
513
+ if (match) return {
514
+ state: "loaded",
515
+ manifestPath: match[1]
516
+ };
517
+ if (content.includes("Loading hooks from plugin: agentmemory")) return { state: "loaded" };
518
+ return { state: "not-loaded" };
519
+ }
456
520
  async function runDoctor() {
457
521
  p.intro("agentmemory doctor");
458
522
  const base = getBaseUrl();
@@ -499,6 +563,28 @@ async function runDoctor() {
499
563
  ok: f.enabled,
500
564
  hint: f.enabled ? void 0 : f.enableHow
501
565
  });
566
+ const cc = checkClaudeCodeHooks();
567
+ const ccCheck = (() => {
568
+ switch (cc.state) {
569
+ case "loaded": return {
570
+ ok: true,
571
+ hint: cc.manifestPath ? `manifest: ${cc.manifestPath}` : void 0
572
+ };
573
+ case "not-loaded": return {
574
+ ok: false,
575
+ 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."
576
+ };
577
+ case "no-debug-log": return {
578
+ ok: false,
579
+ hint: "Cannot verify — no Claude Code debug log found. Run once with `claude --debug -p \"x\"`, then re-run doctor."
580
+ };
581
+ case "no-cc-dir": return;
582
+ }
583
+ })();
584
+ if (ccCheck) checks.push({
585
+ name: "Claude Code plugin hooks registered",
586
+ ...ccCheck
587
+ });
502
588
  checks.push({
503
589
  name: "Knowledge graph populated",
504
590
  ok: graphHas,
@@ -600,6 +686,8 @@ async function seedDemoSession(base, project, session) {
600
686
  const payload = {
601
687
  hookType: "post_tool_use",
602
688
  sessionId: session.id,
689
+ project,
690
+ cwd: project,
603
691
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
604
692
  data: {
605
693
  tool_name: obs.toolName,
@@ -744,14 +832,26 @@ async function runUpgrade() {
744
832
  return process.exit(0);
745
833
  }
746
834
  if (upgradeEngine === true) {
747
- if (!runCommand(shBin, ["-c", "curl -fsSL https://install.iii.dev/iii/main/install.sh | sh"], {
748
- label: "Upgrading iii-engine via installer",
749
- optional: true
750
- })) 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.");
835
+ const releaseUrl = iiiReleaseUrl();
836
+ const asset = iiiReleaseAsset();
837
+ const isZipAsset = asset?.endsWith(".zip") === true;
838
+ if (!releaseUrl) p.log.warn(`iii-engine binary not available for ${platform()}/${process.arch}. Use Docker (\`docker pull iiidev/iii:${IIPINNED_VERSION}\`) or download manually from https://github.com/iii-hq/iii/releases/tag/iii%2Fv${IIPINNED_VERSION}.`);
839
+ else if (IS_WINDOWS || isZipAsset) p.log.info(`Skipping auto-install on ${platform()} — the ${asset} asset isn't tar-compatible. Install manually:\n 1. Download ${releaseUrl}\n 2. Extract iii.exe and place it on PATH (e.g. %USERPROFILE%\\.local\\bin)\nOr use Docker: docker pull iiidev/iii:${IIPINNED_VERSION}`);
840
+ else {
841
+ const binDir = join(homedir(), ".local", "bin");
842
+ if (!runCommand(shBin, ["-c", [
843
+ `mkdir -p "${binDir}"`,
844
+ `curl -fsSL "${releaseUrl}" | tar -xz -C "${binDir}"`,
845
+ `chmod +x "${binDir}/iii"`
846
+ ].join(" && ")], {
847
+ label: `Installing iii-engine v${IIPINNED_VERSION} (pinned)`,
848
+ optional: true
849
+ })) p.log.warn(`iii-engine installer failed. Fallbacks: Docker (\`docker pull iiidev/iii:${IIPINNED_VERSION}\`) or download manually from https://github.com/iii-hq/iii/releases/tag/iii%2Fv${IIPINNED_VERSION}.`);
850
+ }
751
851
  } else p.log.info("Skipped iii-engine installer.");
752
852
  } else p.log.warn("curl or sh not found. Skipping iii-engine installer.");
753
- if (dockerBin) runCommand(dockerBin, ["pull", "iiidev/iii:latest"], {
754
- label: "Pulling latest iii Docker image",
853
+ if (dockerBin) runCommand(dockerBin, ["pull", `iiidev/iii:${IIPINNED_VERSION}`], {
854
+ label: `Pulling iii Docker image v${IIPINNED_VERSION} (pinned)`,
755
855
  optional: true
756
856
  });
757
857
  else p.log.info("Docker not found. Skipping Docker image refresh.");
@@ -765,10 +865,38 @@ async function runUpgrade() {
765
865
  ].join("\n"), "agentmemory upgrade");
766
866
  }
767
867
  async function runMcp() {
768
- await import("./standalone-BG9uPsDK.mjs");
868
+ await import("./standalone-BvKacAId.mjs");
769
869
  }
770
870
  async function runImportJsonl() {
771
- const pathArg = args.slice(1).filter((a) => !a.startsWith("-"))[0];
871
+ const VALUE_FLAGS = new Set(["--port", "--tools"]);
872
+ let maxFiles;
873
+ const tail = args.slice(1);
874
+ const positional = [];
875
+ for (let i = 0; i < tail.length; i++) {
876
+ const a = tail[i];
877
+ if (a === "--max-files") {
878
+ const raw = tail[i + 1];
879
+ const parsed = raw !== void 0 ? parseInt(raw, 10) : NaN;
880
+ if (Number.isInteger(parsed) && parsed > 0) maxFiles = parsed;
881
+ else if (raw !== void 0) p.log.warn(`Ignoring --max-files ${raw}: expected a positive integer.`);
882
+ i++;
883
+ continue;
884
+ }
885
+ if (a.startsWith("--max-files=")) {
886
+ const raw = a.slice(12);
887
+ const parsed = parseInt(raw, 10);
888
+ if (Number.isInteger(parsed) && parsed > 0) maxFiles = parsed;
889
+ else p.log.warn(`Ignoring --max-files=${raw}: expected a positive integer.`);
890
+ continue;
891
+ }
892
+ if (VALUE_FLAGS.has(a)) {
893
+ i++;
894
+ continue;
895
+ }
896
+ if (a.startsWith("-")) continue;
897
+ positional.push(a);
898
+ }
899
+ const pathArg = positional[0];
772
900
  const port = getRestPort();
773
901
  const base = `http://localhost:${port}`;
774
902
  let probeOk = false;
@@ -790,6 +918,7 @@ async function runImportJsonl() {
790
918
  }
791
919
  const body = {};
792
920
  if (pathArg) body["path"] = pathArg;
921
+ if (maxFiles !== void 0) body["maxFiles"] = maxFiles;
793
922
  const headers = { "content-type": "application/json" };
794
923
  const secret = process.env["AGENTMEMORY_SECRET"];
795
924
  if (secret) headers["authorization"] = `Bearer ${secret}`;
@@ -821,6 +950,17 @@ async function runImportJsonl() {
821
950
  process.exit(1);
822
951
  }
823
952
  spinner.stop(`imported ${json.imported ?? 0} file(s), ${json.observations ?? 0} observation(s) across ${json.sessionIds?.length || 0} session(s)`);
953
+ if (json.truncated) {
954
+ const cap = json.maxFiles ?? 200;
955
+ const upper = json.maxFilesUpperBound ?? 1e3;
956
+ const discovered = json.discovered ?? 0;
957
+ 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.`;
958
+ 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).`);
959
+ else {
960
+ const suggested = Math.min(Math.max((discovered || cap) + 100, cap * 2), upper);
961
+ p.log.warn(`${baseMsg} Re-run with --max-files=${suggested} (max ${upper}) or batch by subdirectory.`);
962
+ }
963
+ }
824
964
  if (json.sessionIds && json.sessionIds.length > 0) p.log.info(`View at ${getViewerUrl()} → Replay tab`);
825
965
  } catch (err) {
826
966
  spinner.stop("failed");