@agentmemory/agentmemory 0.9.25 → 0.9.27

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/AGENTS.md CHANGED
@@ -117,7 +117,7 @@ Hook scripts in `src/hooks/` are standalone Node.js scripts (no iii-sdk import).
117
117
  ## Current Stats (v0.9.16)
118
118
 
119
119
  - 53 MCP tools (8 visible by default, `AGENTMEMORY_TOOLS=all` for all)
120
- - 126 REST endpoints
120
+ - 128 REST endpoints
121
121
  - 6 MCP resources, 3 MCP prompts
122
122
  - 12 hooks, 4 skills
123
123
  - 50+ iii functions
package/README.md CHANGED
@@ -61,7 +61,7 @@
61
61
  <picture><source media="(prefers-color-scheme: dark)" srcset="assets/tags/light/stat-tools.svg"><img src="assets/tags/stat-tools.svg" alt="53 MCP tools" height="38" /></picture>
62
62
  <picture><source media="(prefers-color-scheme: dark)" srcset="assets/tags/light/stat-hooks.svg"><img src="assets/tags/stat-hooks.svg" alt="12 auto hooks" height="38" /></picture>
63
63
  <picture><source media="(prefers-color-scheme: dark)" srcset="assets/tags/light/stat-deps.svg"><img src="assets/tags/stat-deps.svg" alt="0 external DBs" height="38" /></picture>
64
- <picture><source media="(prefers-color-scheme: dark)" srcset="assets/tags/light/stat-tests.svg"><img src="assets/tags/stat-tests.svg" alt="950+ tests passing" height="38" /></picture>
64
+ <picture><source media="(prefers-color-scheme: dark)" srcset="assets/tags/light/stat-tests.svg"><img src="assets/tags/stat-tests.svg" alt="1,390+ tests passing" height="38" /></picture>
65
65
  </p>
66
66
 
67
67
  <p align="center">
@@ -226,7 +226,7 @@ You explain the same architecture every session. You re-discover the same bugs.
226
226
  npx @agentmemory/agentmemory
227
227
  ```
228
228
 
229
- > **New in v0.9.22** — Three new connect adapters (Qwen Code, Antigravity, Kiro), `AGENT_ID` multi-agent isolation with opt-in `AGENTMEMORY_AGENT_SCOPE=isolated` filtering, install ERESOLVE fixed, OpenAI thinking-model output handled, OpenCode auto-context + session creation, viewer graph settles on 1000+ nodes, 22 fixes total. Full notes in [CHANGELOG.md](CHANGELOG.md).
229
+ Latest release notes: [CHANGELOG.md](CHANGELOG.md).
230
230
 
231
231
  ---
232
232
 
@@ -242,10 +242,10 @@ npx @agentmemory/agentmemory
242
242
 
243
243
  | Adapter | P@5 | R@5 | Top-5 hit rate | p50 latency |
244
244
  |---|---|---|---|---|
245
- | **agentmemory hybrid** | **0.578** | **0.967** | **15 / 15** | 14 ms |
246
- | grep baseline | 0.267 | 0.967 | 15 / 15 | 0 ms |
245
+ | **agentmemory hybrid** | **0.240** | **1.000** | **15 / 15** | 14 ms |
246
+ | grep baseline | 0.227 | 0.967 | 15 / 15 | 0 ms |
247
247
 
248
- 100% top-5 hit rate. **2.2×** better precision than the grep baseline on identical input. Full per-type breakdown: [`docs/benchmarks/2026-05-20-coding-agent-life-v1.md`](docs/benchmarks/2026-05-20-coding-agent-life-v1.md).
248
+ 100% top-5 hit rate at the **P@5 math ceiling** for this corpus (0.240, see scorecard). Hybrid retrieves every gold session; grep misses 1 of 2 gold on the multi-session temporal query. Lift is **recall + temporal**, not aggregate precision — this benchmark is small + gold-sparse, the larger LongMemEval-S below differentiates better. Full per-type breakdown + correction note: [`docs/benchmarks/2026-05-20-coding-agent-life-v1.md`](docs/benchmarks/2026-05-20-coding-agent-life-v1.md).
249
249
 
250
250
  **LongMemEval-S** (ICLR 2025, 500 questions)
251
251
 
@@ -427,6 +427,8 @@ npx @agentmemory/agentmemory import-jsonl ~/.claude/projects/-my-project/abc123.
427
427
 
428
428
  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.
429
429
 
430
+ > **Heads-up if you rely on `import-jsonl` as your primary capture path:** Claude Code's `cleanupPeriodDays` (in `~/.claude/settings.json`, default **30**) auto-deletes JSONL transcripts older than that window from `~/.claude/projects/`. If you install agentmemory fresh on a months-old Claude Code history, anything older than 30 days is already gone before the first import. Either run `import-jsonl` on a cron, raise `cleanupPeriodDays` to something higher, or wire the auto-capture hooks (the default plugin install path) so each turn lands in agentmemory while the session is live and the JSONL cleanup stops mattering.
431
+
430
432
  ### Upgrade / Maintenance
431
433
 
432
434
  Use the maintenance command when you intentionally want to update your local runtime:
@@ -1139,7 +1141,7 @@ Full registry: [workers.iii.dev](https://workers.iii.dev). Every worker there co
1139
1141
  | Prometheus / Grafana | iii OTEL + health monitor |
1140
1142
  | Custom plugin systems | `iii worker add <name>` |
1141
1143
 
1142
- **118 source files · ~21,800 LOC · 950+ tests · 123 functions · 34 KV scopes** — all on three primitives. No `agentmemory plugin install`. The plugin system is iii itself.
1144
+ **174 source files · ~37,800 LOC · 1,390+ tests · 258 functions · 44 KV scopes** — all on three primitives. No `agentmemory plugin install`. The plugin system is iii itself.
1143
1145
 
1144
1146
  ---
1145
1147
 
@@ -1429,7 +1431,7 @@ Create `~/.agentmemory/.env`:
1429
1431
 
1430
1432
  <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>
1431
1433
 
1432
- 126 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.
1434
+ 128 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.
1433
1435
 
1434
1436
  <details>
1435
1437
  <summary>Key endpoints</summary>
@@ -1463,7 +1465,7 @@ Full endpoint list: [`src/triggers/api.ts`](src/triggers/api.ts)
1463
1465
  ```bash
1464
1466
  npm run dev # Hot reload
1465
1467
  npm run build # Production build
1466
- npm test # 950+ tests
1468
+ npm test # 1,390+ tests
1467
1469
  npm run test:integration # API tests (requires running services)
1468
1470
  ```
1469
1471
 
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.mts","names":[],"sources":["../src/cli.ts"],"mappings":";iBAmNsB,kBAAA,CAAA,GAAsB,OAAA"}
1
+ {"version":3,"file":"cli.d.mts","names":[],"sources":["../src/cli.ts"],"mappings":";iBAyOsB,kBAAA,CAAA,GAAsB,OAAA"}
package/dist/cli.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
- import { i as generateId } from "./schema-Dsr_V2Wp.mjs";
2
+ import { i as generateId } from "./schema-CNiCWzV9.mjs";
3
3
  import { n as resolveAdapter, r as runAdapter } from "./connect-bmZ5eqYN.mjs";
4
4
  import { r as setBootVerbose } from "./logger-yHTcEBAI.mjs";
5
- import { t as VERSION } from "./version-C3hZKw8n.mjs";
5
+ import { t as VERSION } from "./version-9DNrRyph.mjs";
6
6
  import { execFileSync, spawn, spawnSync } from "node:child_process";
7
7
  import { closeSync, constants, existsSync, fsyncSync, mkdirSync, openSync, readFileSync, readdirSync, readlinkSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync, writeSync } from "node:fs";
8
8
  import { delimiter, dirname, join } from "node:path";
@@ -878,7 +878,12 @@ Options:
878
878
  --reset Wipe ~/.agentmemory/preferences.json and re-run onboarding
879
879
  --tools all|core Tool visibility (default: all = 51 tools; core = 8 essentials)
880
880
  --no-engine Skip auto-starting iii-engine
881
- --port <N> Override REST port (default: 3111)
881
+ --port <N> Override REST port (default: 3111). Streams (N+1), viewer
882
+ (N+2), and iii engine (N+46023) auto-derive from N so a
883
+ single flag relocates the whole quartet.
884
+ --instance <N> Shortcut for --port (3111 + N*100) to run multiple
885
+ daemons side-by-side without env gymnastics.
886
+ --instance 1 -> 3211/3212/3213/49234, etc. (max N=50)
882
887
 
883
888
  Environment:
884
889
  AGENTMEMORY_URL Full REST base URL (e.g. http://localhost:3111).
@@ -905,6 +910,14 @@ const toolsIdx = args.indexOf("--tools");
905
910
  if (toolsIdx !== -1 && args[toolsIdx + 1]) process.env["AGENTMEMORY_TOOLS"] = args[toolsIdx + 1];
906
911
  const portIdx = args.indexOf("--port");
907
912
  if (portIdx !== -1 && args[portIdx + 1]) process.env["III_REST_PORT"] = args[portIdx + 1];
913
+ const instanceIdx = args.indexOf("--instance");
914
+ if (instanceIdx !== -1 && args[instanceIdx + 1]) {
915
+ const n = parseInt(args[instanceIdx + 1] || "", 10);
916
+ if (Number.isFinite(n) && n >= 0 && n <= 50) {
917
+ const base = 3111 + n * 100;
918
+ if (!process.env["III_REST_PORT"]) process.env["III_REST_PORT"] = String(base);
919
+ }
920
+ }
908
921
  const skipEngine = args.includes("--no-engine");
909
922
  function getRestPort() {
910
923
  const url = process.env["AGENTMEMORY_URL"];
@@ -948,7 +961,7 @@ function getViewerUrl() {
948
961
  }
949
962
  }
950
963
  function getStreamPort() {
951
- return parseInt(process.env["III_STREAM_PORT"] || "", 10) || parseInt(process.env["III_STREAMS_PORT"] || "", 10) || 3112;
964
+ return parseInt(process.env["III_STREAM_PORT"] || "", 10) || parseInt(process.env["III_STREAMS_PORT"] || "", 10) || getRestPort() + 1;
952
965
  }
953
966
  function getEnginePort() {
954
967
  const explicit = parseInt(process.env["III_ENGINE_PORT"] || "", 10);
@@ -958,7 +971,7 @@ function getEnginePort() {
958
971
  const parsed = new URL(url).port;
959
972
  if (parsed) return parseInt(parsed, 10);
960
973
  } catch {}
961
- return 49134;
974
+ return getRestPort() + 46023;
962
975
  }
963
976
  async function isEngineRunning() {
964
977
  try {
@@ -1175,8 +1188,8 @@ async function maybeOfferGlobalInstall() {
1175
1188
  if (runCommand(npmBin, [
1176
1189
  "install",
1177
1190
  "-g",
1178
- `@agentmemory/agentmemory@0.9.25`
1179
- ], { label: `Installing @agentmemory/agentmemory@0.9.25 globally` })) {
1191
+ `@agentmemory/agentmemory@0.9.27`
1192
+ ], { label: `Installing @agentmemory/agentmemory@0.9.27 globally` })) {
1180
1193
  p.log.success("Installed globally. `agentmemory stop` etc. will now work in new shells.");
1181
1194
  writePrefs({ skipGlobalInstall: true });
1182
1195
  } else p.log.warn("Global install failed. Try manually: npm install -g @agentmemory/agentmemory");
@@ -1194,7 +1207,11 @@ function detectIiiConsole() {
1194
1207
  };
1195
1208
  return { kind: "missing" };
1196
1209
  }
1197
- const III_CONSOLE_INSTALL_CMD = "curl -fsSL https://install.iii.dev/iii/main/install.sh | sh";
1210
+ const III_CONSOLE_INSTALL_CMD = `curl -fsSL https://install.iii.dev/iii/main/install.sh | VERSION=${IIPINNED_VERSION} sh`;
1211
+ function iiiConsoleInstallHint() {
1212
+ if (!IS_WINDOWS) return III_CONSOLE_INSTALL_CMD;
1213
+ return `# PowerShell:\n $env:VERSION = "${IIPINNED_VERSION}"\n iwr -useb https://install.iii.dev/iii/main/install.sh -OutFile install.sh\n bash install.sh # WSL or Git Bash required\n# Or grab the pinned release directly:\n https://github.com/iii-hq/iii/releases/tag/iii%2Fv${IIPINNED_VERSION}`;
1214
+ }
1198
1215
  async function ensureIiiConsole() {
1199
1216
  const state = detectIiiConsole();
1200
1217
  if (state.kind === "installed") return state;
@@ -1212,11 +1229,11 @@ async function ensureIiiConsole() {
1212
1229
  const shBin = whichBinary("sh");
1213
1230
  const curlBin = whichBinary("curl");
1214
1231
  if (!shBin || !curlBin) {
1215
- p.log.warn(`curl or sh not found. Install manually:\n ${III_CONSOLE_INSTALL_CMD}`);
1232
+ p.log.warn(`curl or sh not found. Install manually:\n ${iiiConsoleInstallHint()}`);
1216
1233
  return state;
1217
1234
  }
1218
1235
  if (!runCommand(shBin, ["-c", III_CONSOLE_INSTALL_CMD], { label: "Installing iii console" })) {
1219
- p.log.warn(`iii console install failed. Re-run manually:\n ${III_CONSOLE_INSTALL_CMD}`);
1236
+ p.log.warn(`iii console install failed. Re-run manually:\n ${iiiConsoleInstallHint()}`);
1220
1237
  return state;
1221
1238
  }
1222
1239
  return detectIiiConsole();
@@ -1528,7 +1545,7 @@ function printReadyHint(consoleState) {
1528
1545
  const engineHost = getEngineHost();
1529
1546
  const streamUrl = `ws://${engineHost}:${getStreamPort()}`;
1530
1547
  const engineUrl = `ws://${engineHost}:${getEnginePort()}`;
1531
- const consoleLine = consoleState.kind === "installed" ? `iii console ${consoleState.binPath} (run: ${consoleState.binPath} -p <port>)` : `iii console (install: ${III_CONSOLE_INSTALL_CMD})`;
1548
+ const consoleLine = consoleState.kind === "installed" ? `iii console ${consoleState.binPath} (run: ${consoleState.binPath} -p <port>)` : `iii console (install: ${iiiConsoleInstallHint()})`;
1532
1549
  const lines = [
1533
1550
  `REST API ${restUrl}`,
1534
1551
  `Viewer ${viewerUrl}`,
@@ -1548,7 +1565,7 @@ async function main() {
1548
1565
  if (firstRun || IS_RESET) await runOnboarding();
1549
1566
  if (skipEngine) {
1550
1567
  if (IS_VERBOSE) p.log.info("Skipping engine check (--no-engine)");
1551
- await import("./src-fQOMXeCp.mjs");
1568
+ await import("./src-MOg2zKJs.mjs");
1552
1569
  if (await waitForAgentmemoryReady(15e3)) {
1553
1570
  const consoleState = await ensureIiiConsole();
1554
1571
  await maybeOfferGlobalInstall();
@@ -1568,7 +1585,7 @@ async function main() {
1568
1585
  }
1569
1586
  }
1570
1587
  adoptRunningEngine();
1571
- await import("./src-fQOMXeCp.mjs");
1588
+ await import("./src-MOg2zKJs.mjs");
1572
1589
  if (await waitForAgentmemoryReady(15e3)) {
1573
1590
  const consoleState = await ensureIiiConsole();
1574
1591
  await maybeOfferGlobalInstall();
@@ -1595,7 +1612,7 @@ async function main() {
1595
1612
  else p.log.info("No stderr was captured. Re-run with --verbose for more detail.");
1596
1613
  p.note([
1597
1614
  "Common causes:",
1598
- " - iii-engine version mismatch — reinstall the latest binary",
1615
+ ` - iii-engine version mismatch — reinstall the pinned v${IIPINNED_VERSION} binary`,
1599
1616
  " (sh script on macOS/Linux, GitHub release zip on Windows)",
1600
1617
  " - Docker Desktop not running (if you're using the Docker path)",
1601
1618
  " - Port already in use (see below)",
@@ -1617,7 +1634,7 @@ async function main() {
1617
1634
  process.exit(1);
1618
1635
  }
1619
1636
  s.stop("iii-engine is ready");
1620
- await import("./src-fQOMXeCp.mjs");
1637
+ await import("./src-MOg2zKJs.mjs");
1621
1638
  if (await waitForAgentmemoryReady(15e3)) {
1622
1639
  const consoleState = await ensureIiiConsole();
1623
1640
  await maybeOfferGlobalInstall();
@@ -2525,19 +2542,19 @@ async function runStop() {
2525
2542
  process.exit(1);
2526
2543
  }
2527
2544
  let allStopped = true;
2528
- for (const pid of candidates) {
2545
+ for (const pid of workerCandidates) {
2529
2546
  const s = p.spinner();
2530
- s.start(`Stopping iii-engine (pid ${pid})...`);
2531
- const ok = await signalAndWait(pid, "SIGTERM", 3e3);
2532
- s.stop(ok ? `Stopped pid ${pid}` : `Failed to stop pid ${pid}`);
2547
+ s.start(`Stopping agentmemory worker (pid ${pid})... [flushing state]`);
2548
+ const ok = await signalAndWait(pid, "SIGTERM", 5e3);
2549
+ s.stop(ok ? `Stopped worker pid ${pid}` : `Failed to stop worker pid ${pid}`);
2533
2550
  if (!ok) allStopped = false;
2534
2551
  }
2535
- for (const pid of workerCandidates) {
2536
- if (candidates.has(pid)) continue;
2552
+ for (const pid of candidates) {
2553
+ if (workerCandidates.has(pid)) continue;
2537
2554
  const s = p.spinner();
2538
- s.start(`Stopping agentmemory worker (pid ${pid})...`);
2555
+ s.start(`Stopping iii-engine (pid ${pid})...`);
2539
2556
  const ok = await signalAndWait(pid, "SIGTERM", 3e3);
2540
- s.stop(ok ? `Stopped worker pid ${pid}` : `Failed to stop worker pid ${pid}`);
2557
+ s.stop(ok ? `Stopped pid ${pid}` : `Failed to stop pid ${pid}`);
2541
2558
  if (!ok) allStopped = false;
2542
2559
  }
2543
2560
  clearEnginePidfile();
@@ -2550,7 +2567,7 @@ async function runStop() {
2550
2567
  p.outro("Stopped. Memories persisted to disk; restart anytime with: npx @agentmemory/agentmemory");
2551
2568
  }
2552
2569
  async function runMcp() {
2553
- await import("./standalone-BzfA1zu8.mjs");
2570
+ await import("./standalone-BORXC71-.mjs");
2554
2571
  }
2555
2572
  async function runConnectCmd() {
2556
2573
  const { runConnect } = await import("./connect-bmZ5eqYN.mjs").then((n) => n.t);