@agentmemory/agentmemory 0.9.24 → 0.9.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/AGENTS.md +1 -1
  2. package/README.md +1 -1
  3. package/dist/cli.d.mts.map +1 -1
  4. package/dist/cli.mjs +125 -65
  5. package/dist/cli.mjs.map +1 -1
  6. package/dist/{connect-Cf9bmBqO.mjs → connect-bmZ5eqYN.mjs} +17 -56
  7. package/dist/{connect-Cf9bmBqO.mjs.map → connect-bmZ5eqYN.mjs.map} +1 -1
  8. package/dist/hooks/notification.mjs +2 -4
  9. package/dist/hooks/notification.mjs.map +1 -1
  10. package/dist/hooks/post-commit.mjs +2 -3
  11. package/dist/hooks/post-commit.mjs.map +1 -1
  12. package/dist/hooks/post-tool-failure.mjs +2 -4
  13. package/dist/hooks/post-tool-failure.mjs.map +1 -1
  14. package/dist/hooks/post-tool-use.mjs +2 -4
  15. package/dist/hooks/post-tool-use.mjs.map +1 -1
  16. package/dist/hooks/pre-compact.mjs +2 -4
  17. package/dist/hooks/pre-compact.mjs.map +1 -1
  18. package/dist/hooks/pre-tool-use.mjs +2 -2
  19. package/dist/hooks/pre-tool-use.mjs.map +1 -1
  20. package/dist/hooks/prompt-submit.mjs +2 -4
  21. package/dist/hooks/prompt-submit.mjs.map +1 -1
  22. package/dist/hooks/session-end.mjs +2 -2
  23. package/dist/hooks/session-start.mjs +2 -4
  24. package/dist/hooks/session-start.mjs.map +1 -1
  25. package/dist/hooks/stop.mjs +2 -2
  26. package/dist/hooks/subagent-start.mjs +2 -4
  27. package/dist/hooks/subagent-start.mjs.map +1 -1
  28. package/dist/hooks/subagent-stop.mjs +2 -4
  29. package/dist/hooks/subagent-stop.mjs.map +1 -1
  30. package/dist/hooks/task-completed.mjs +2 -4
  31. package/dist/hooks/task-completed.mjs.map +1 -1
  32. package/dist/image-refs-C7h9L5wx.mjs +52 -0
  33. package/dist/image-refs-C7h9L5wx.mjs.map +1 -0
  34. package/dist/{image-refs-CJS5B9Gq.mjs → image-store-Gpo2mgM9.mjs} +11 -42
  35. package/dist/image-store-Gpo2mgM9.mjs.map +1 -0
  36. package/dist/index.mjs +941 -493
  37. package/dist/index.mjs.map +1 -1
  38. package/dist/{logger-xlVlvCWX.mjs → logger-yHTcEBAI.mjs} +2 -2
  39. package/dist/{logger-xlVlvCWX.mjs.map → logger-yHTcEBAI.mjs.map} +1 -1
  40. package/dist/rolldown-runtime-twds-ZHy.mjs +14 -0
  41. package/dist/{schema-BkALl7Z_.mjs → schema-Dsr_V2Wp.mjs} +4 -4
  42. package/dist/schema-Dsr_V2Wp.mjs.map +1 -0
  43. package/dist/{src-B8J9Exum.mjs → src-fQOMXeCp.mjs} +936 -483
  44. package/dist/src-fQOMXeCp.mjs.map +1 -0
  45. package/dist/{standalone-CPfsVTBA.mjs → standalone-BzfA1zu8.mjs} +6 -10
  46. package/dist/{standalone-CPfsVTBA.mjs.map → standalone-BzfA1zu8.mjs.map} +1 -1
  47. package/dist/standalone.mjs +3 -14
  48. package/dist/standalone.mjs.map +1 -1
  49. package/dist/{tools-registry-DJizX9Az.mjs → tools-registry-Dzxv9iUu.mjs} +7 -5
  50. package/dist/tools-registry-Dzxv9iUu.mjs.map +1 -0
  51. package/dist/version-C3hZKw8n.mjs +6 -0
  52. package/dist/version-C3hZKw8n.mjs.map +1 -0
  53. package/dist/viewer/index.html +155 -9
  54. package/package.json +9 -4
  55. package/plugin/.claude-plugin/plugin.json +1 -1
  56. package/plugin/.codex-plugin/plugin.json +1 -1
  57. package/plugin/plugin.json +1 -1
  58. package/plugin/scripts/notification.mjs +2 -4
  59. package/plugin/scripts/notification.mjs.map +1 -1
  60. package/plugin/scripts/post-commit.mjs +2 -3
  61. package/plugin/scripts/post-commit.mjs.map +1 -1
  62. package/plugin/scripts/post-tool-failure.mjs +2 -4
  63. package/plugin/scripts/post-tool-failure.mjs.map +1 -1
  64. package/plugin/scripts/post-tool-use.mjs +2 -4
  65. package/plugin/scripts/post-tool-use.mjs.map +1 -1
  66. package/plugin/scripts/pre-compact.mjs +2 -4
  67. package/plugin/scripts/pre-compact.mjs.map +1 -1
  68. package/plugin/scripts/pre-tool-use.mjs +2 -2
  69. package/plugin/scripts/pre-tool-use.mjs.map +1 -1
  70. package/plugin/scripts/prompt-submit.mjs +2 -4
  71. package/plugin/scripts/prompt-submit.mjs.map +1 -1
  72. package/plugin/scripts/session-end.mjs +2 -2
  73. package/plugin/scripts/session-start.mjs +2 -4
  74. package/plugin/scripts/session-start.mjs.map +1 -1
  75. package/plugin/scripts/stop.mjs +2 -2
  76. package/plugin/scripts/subagent-start.mjs +2 -4
  77. package/plugin/scripts/subagent-start.mjs.map +1 -1
  78. package/plugin/scripts/subagent-stop.mjs +2 -4
  79. package/plugin/scripts/subagent-stop.mjs.map +1 -1
  80. package/plugin/scripts/task-completed.mjs +2 -4
  81. package/plugin/scripts/task-completed.mjs.map +1 -1
  82. package/dist/image-refs-CJS5B9Gq.mjs.map +0 -1
  83. package/dist/image-store-CdE0amb1.mjs +0 -3
  84. package/dist/schema-BkALl7Z_.mjs.map +0 -1
  85. package/dist/src-B8J9Exum.mjs.map +0 -1
  86. package/dist/tools-registry-DJizX9Az.mjs.map +0 -1
  87. package/dist/version-BWEBnKAp.mjs +0 -6
  88. package/dist/version-BWEBnKAp.mjs.map +0 -1
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
- - 125 REST endpoints
120
+ - 126 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
@@ -1429,7 +1429,7 @@ Create `~/.agentmemory/.env`:
1429
1429
 
1430
1430
  <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
1431
 
1432
- 125 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.
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.
1433
1433
 
1434
1434
  <details>
1435
1435
  <summary>Key endpoints</summary>
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.mts","names":[],"sources":["../src/cli.ts"],"mappings":";iBAgNsB,kBAAA,CAAA,GAAsB,OAAA"}
1
+ {"version":3,"file":"cli.d.mts","names":[],"sources":["../src/cli.ts"],"mappings":";iBAmNsB,kBAAA,CAAA,GAAsB,OAAA"}
package/dist/cli.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
- import { n as resolveAdapter, r as runAdapter } from "./connect-Cf9bmBqO.mjs";
3
- import { i as generateId } from "./schema-BkALl7Z_.mjs";
4
- import { r as setBootVerbose } from "./logger-xlVlvCWX.mjs";
5
- import { t as VERSION } from "./version-BWEBnKAp.mjs";
2
+ import { i as generateId } from "./schema-Dsr_V2Wp.mjs";
3
+ import { n as resolveAdapter, r as runAdapter } from "./connect-bmZ5eqYN.mjs";
4
+ import { r as setBootVerbose } from "./logger-yHTcEBAI.mjs";
5
+ import { t as VERSION } from "./version-C3hZKw8n.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";
@@ -10,7 +10,6 @@ import { fileURLToPath } from "node:url";
10
10
  import { homedir, platform } from "node:os";
11
11
  import * as p from "@clack/prompts";
12
12
  import { copyFile, mkdir } from "node:fs/promises";
13
-
14
13
  //#region src/cli/doctor-diagnostics.ts
15
14
  /** Common placeholder values shipped in .env.example. */
16
15
  const PLACEHOLDER_VALUES = new Set([
@@ -183,9 +182,9 @@ function buildDiagnostics(effects) {
183
182
  },
184
183
  {
185
184
  id: "iii-on-path-not-local-bin",
186
- message: "iii is on PATH but not in ~/.local/bin/iii (where we install).",
187
- fixPreview: "Suggest re-installing the pinned version via the installer — won't touch your PATH.",
188
- moreInfo: "agentmemory's installer writes to ~/.local/bin/iii. When a user-managed iii lives somewhere else (homebrew, cargo, $XDG_BIN) we don't auto-overwrite it. If you want our pinned build, run the installer; otherwise this is informational.",
185
+ message: "iii is on PATH but not at agentmemory's private install path.",
186
+ fixPreview: "Install the pinned version to ~/.agentmemory/bin — won't touch your PATH.",
187
+ moreInfo: "agentmemory installs its pinned engine to ~/.agentmemory/bin/iii so a user-managed iii on PATH (homebrew, cargo, manual install) stays untouched. When agentmemory needs the pin and PATH doesn't have it, it falls back to the private install. If neither exists, run the installer.",
189
188
  manualOnly: true,
190
189
  check: async () => {
191
190
  const bin = effects.findIiiBinary();
@@ -201,7 +200,7 @@ function buildDiagnostics(effects) {
201
200
  },
202
201
  fix: async () => effects.runIiiInstaller().then((r) => ({
203
202
  ok: r.ok,
204
- message: r.message ?? "Installer wrote to ~/.local/bin/iii. Your PATH wasn't modified — adjust it yourself if needed."
203
+ message: r.message ?? "Installer wrote to ~/.agentmemory/bin/iii. Your PATH wasn't modified."
205
204
  }))
206
205
  }
207
206
  ];
@@ -223,7 +222,6 @@ function dryRunPlan(ctx, results) {
223
222
  if (lines.length === 0) lines.push(`All checks passing for ${ctx.baseUrl} — no fixes to run.`);
224
223
  return lines;
225
224
  }
226
-
227
225
  //#endregion
228
226
  //#region src/cli/remove-plan.ts
229
227
  function pidfilePath(home) {
@@ -244,8 +242,14 @@ function backupsDir(home) {
244
242
  function dataDir(home) {
245
243
  return join(home, ".agentmemory", "data");
246
244
  }
247
- function localBinIii(home) {
248
- return join(home, ".local", "bin", "iii");
245
+ function iiiBinFile() {
246
+ return process.platform === "win32" ? "iii.exe" : "iii";
247
+ }
248
+ function legacyLocalBinIii(home) {
249
+ return join(home, ".local", "bin", iiiBinFile());
250
+ }
251
+ function privateIiiBin(home) {
252
+ return join(home, ".agentmemory", "bin", iiiBinFile());
249
253
  }
250
254
  function safeSize(path) {
251
255
  try {
@@ -327,16 +331,25 @@ function buildRemovePlan(ctx, options) {
327
331
  applicable: pathExists(entry.target),
328
332
  sizeBytes: safeSize(entry.target)
329
333
  });
330
- const localIii = localBinIii(home);
331
- if (pathExists(localIii)) {
334
+ const privIii = privateIiiBin(home);
335
+ if (pathExists(privIii)) plan.push({
336
+ id: "private-bin-iii",
337
+ description: `Delete ~/.agentmemory/bin/iii (agentmemory's private install)`,
338
+ path: privIii,
339
+ alwaysAsk: false,
340
+ applicable: true,
341
+ sizeBytes: safeSize(privIii)
342
+ });
343
+ const legacyIii = legacyLocalBinIii(home);
344
+ if (pathExists(legacyIii)) {
332
345
  const matches = localBinIiiVersion === pinnedVersion;
333
346
  plan.push({
334
- id: "local-bin-iii",
335
- description: matches ? `Delete ~/.local/bin/iii (matches pinned v${pinnedVersion})` : `Delete ~/.local/bin/iii (version ${localBinIiiVersion ?? "unknown"} != pinned v${pinnedVersion}) — will ask`,
336
- path: localIii,
347
+ id: "legacy-local-bin-iii",
348
+ description: matches ? `Delete ~/.local/bin/iii (legacy install location, matches pinned v${pinnedVersion})` : `Delete ~/.local/bin/iii (legacy install location, version ${localBinIiiVersion ?? "unknown"} != pinned v${pinnedVersion}) — will ask`,
349
+ path: legacyIii,
337
350
  alwaysAsk: !matches,
338
351
  applicable: true,
339
- sizeBytes: safeSize(localIii)
352
+ sizeBytes: safeSize(legacyIii)
340
353
  });
341
354
  }
342
355
  plan.push({
@@ -362,7 +375,6 @@ function humanBytes(n) {
362
375
  if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;
363
376
  return `${(n / (1024 * 1024)).toFixed(1)} MB`;
364
377
  }
365
-
366
378
  //#endregion
367
379
  //#region src/cli/splash.ts
368
380
  const IS_COLOR_TTY = !!process.stdout.isTTY && !process.env["NO_COLOR"];
@@ -413,7 +425,6 @@ function renderSplash(version) {
413
425
  else out = minimalBanner(version);
414
426
  process.stdout.write(out + "\n");
415
427
  }
416
-
417
428
  //#endregion
418
429
  //#region src/cli/preferences.ts
419
430
  const DEFAULTS = {
@@ -478,7 +489,6 @@ function isFirstRun() {
478
489
  if (!existsSync(prefsPath())) return true;
479
490
  return readPrefs().firstRunAt === null;
480
491
  }
481
-
482
492
  //#endregion
483
493
  //#region src/cli/onboarding.ts
484
494
  const __dirname$1 = dirname(fileURLToPath(import.meta.url));
@@ -797,7 +807,6 @@ async function wireSelectedAgents(agents) {
797
807
  if (summary.length === 0) summary.push("No agents were wired.");
798
808
  p.note(summary.join("\n"), "wire summary");
799
809
  }
800
-
801
810
  //#endregion
802
811
  //#region src/cli.ts
803
812
  const __dirname = dirname(fileURLToPath(import.meta.url));
@@ -877,6 +886,9 @@ Environment:
877
886
  AGENTMEMORY_USE_DOCKER=1 Prefer the bundled docker-compose path over the
878
887
  native iii-engine binary on first run.
879
888
  AGENTMEMORY_III_VERSION Override pinned iii-engine version (default ${IIPINNED_VERSION}).
889
+ AGENTMEMORY_FOLLOWUP_WINDOW_SECONDS
890
+ Window (seconds) for the smart-search follow-up diagnostic
891
+ (default 30). Long values overcount, short values undercount.
880
892
 
881
893
  Quick start:
882
894
  npx @agentmemory/agentmemory # start with local iii-engine or Docker
@@ -1002,15 +1014,29 @@ function whichBinary(name) {
1002
1014
  return null;
1003
1015
  }
1004
1016
  }
1017
+ function agentmemoryBinDir() {
1018
+ if (IS_WINDOWS) {
1019
+ const userProfile = process.env["USERPROFILE"];
1020
+ if (!userProfile) return join(homedir(), ".agentmemory", "bin");
1021
+ return join(userProfile, ".agentmemory", "bin");
1022
+ }
1023
+ return join(homedir(), ".agentmemory", "bin");
1024
+ }
1025
+ function privateIiiPath() {
1026
+ return join(agentmemoryBinDir(), IS_WINDOWS ? "iii.exe" : "iii");
1027
+ }
1005
1028
  function fallbackIiiPaths() {
1006
1029
  if (IS_WINDOWS) {
1007
1030
  const userProfile = process.env["USERPROFILE"];
1008
- if (!userProfile) return [];
1009
- return [join(userProfile, ".local", "bin", "iii.exe"), join(userProfile, "bin", "iii.exe")];
1031
+ const paths = [privateIiiPath()];
1032
+ if (userProfile) paths.push(join(userProfile, ".local", "bin", "iii.exe"), join(userProfile, "bin", "iii.exe"));
1033
+ return paths;
1010
1034
  }
1011
1035
  const home = process.env["HOME"];
1012
- if (!home) return ["/usr/local/bin/iii"];
1013
- return [join(home, ".local", "bin", "iii"), "/usr/local/bin/iii"];
1036
+ const paths = [privateIiiPath()];
1037
+ if (home) paths.push(join(home, ".local", "bin", "iii"));
1038
+ paths.push("/usr/local/bin/iii");
1039
+ return paths;
1014
1040
  }
1015
1041
  function iiiBinVersion(binPath) {
1016
1042
  try {
@@ -1028,14 +1054,18 @@ function iiiBinVersion(binPath) {
1028
1054
  return null;
1029
1055
  }
1030
1056
  }
1031
- function enforceEngineVersionPin(iiiBinPath) {
1032
- if (!iiiBinPath) return;
1057
+ function resolveCompatibleIii(iiiBinPath) {
1058
+ if (!iiiBinPath) return null;
1033
1059
  const detected = iiiBinVersion(iiiBinPath);
1034
- if (!detected || detected === IIPINNED_VERSION) return;
1035
- const asset = iiiReleaseAsset();
1036
- const downloadHint = asset ? `curl -fsSL https://github.com/iii-hq/iii/releases/download/iii/v${IIPINNED_VERSION}/${asset} | tar -xz -C ~/.local/bin` : `download v${IIPINNED_VERSION} from https://github.com/iii-hq/iii/releases/tag/iii%2Fv${IIPINNED_VERSION}`;
1037
- p.log.error(`iii-engine on PATH is v${detected} but agentmemory v${VERSION} hard-pins v${IIPINNED_VERSION}. Engine API drift causes runtime failures (e.g. state::list-not-found on v0.13.0). Downgrade with: \`${downloadHint}\`. Or set AGENTMEMORY_III_VERSION=${detected} to override at your own risk.`);
1038
- process.exit(1);
1060
+ if (detected && detected === IIPINNED_VERSION) return iiiBinPath;
1061
+ const privatePath = privateIiiPath();
1062
+ if (iiiBinPath !== privatePath && existsSync(privatePath)) {
1063
+ if (iiiBinVersion(privatePath) === IIPINNED_VERSION) {
1064
+ vlog(`iii at ${iiiBinPath} ${detected ? `v${detected} mismatches pin` : "probe failed"} v${IIPINNED_VERSION}; using private install at ${privatePath}.`);
1065
+ return privatePath;
1066
+ }
1067
+ }
1068
+ return null;
1039
1069
  }
1040
1070
  function enginePidfilePath() {
1041
1071
  return join(homedir(), ".agentmemory", "iii.pid");
@@ -1145,8 +1175,8 @@ async function maybeOfferGlobalInstall() {
1145
1175
  if (runCommand(npmBin, [
1146
1176
  "install",
1147
1177
  "-g",
1148
- `@agentmemory/agentmemory@${VERSION}`
1149
- ], { label: `Installing @agentmemory/agentmemory@${VERSION} globally` })) {
1178
+ `@agentmemory/agentmemory@0.9.25`
1179
+ ], { label: `Installing @agentmemory/agentmemory@0.9.25 globally` })) {
1150
1180
  p.log.success("Installed globally. `agentmemory stop` etc. will now work in new shells.");
1151
1181
  writePrefs({ skipGlobalInstall: true });
1152
1182
  } else p.log.warn("Global install failed. Try manually: npm install -g @agentmemory/agentmemory");
@@ -1235,8 +1265,8 @@ async function runIiiInstaller() {
1235
1265
  binPath: null
1236
1266
  };
1237
1267
  }
1238
- const binDir = join(homedir(), ".local", "bin");
1239
- const binPath = join(binDir, "iii");
1268
+ const binDir = agentmemoryBinDir();
1269
+ const binPath = privateIiiPath();
1240
1270
  if (!runCommand(shBin, ["-c", [
1241
1271
  `mkdir -p "${binDir}"`,
1242
1272
  `curl -fsSL "${releaseUrl}" | tar -xz -C "${binDir}"`,
@@ -1297,31 +1327,40 @@ function spawnEngineBackground(bin, spawnArgs, label) {
1297
1327
  return child;
1298
1328
  }
1299
1329
  function startIiiBin(iiiBin, configPath) {
1300
- enforceEngineVersionPin(iiiBin);
1301
1330
  const s = p.spinner();
1302
1331
  s.start(`Starting iii-engine: ${iiiBin}`);
1303
1332
  writeEngineState({
1304
1333
  kind: "native",
1305
- configPath
1334
+ configPath,
1335
+ binPath: iiiBin
1306
1336
  });
1307
1337
  spawnEngineBackground(iiiBin, ["--config", configPath], "iii-engine");
1308
1338
  s.stop("iii-engine process started");
1309
1339
  return true;
1310
1340
  }
1341
+ function pickCompatibleIii(candidates) {
1342
+ for (const c of candidates) {
1343
+ if (!c) continue;
1344
+ const resolved = resolveCompatibleIii(c);
1345
+ if (resolved) return resolved;
1346
+ }
1347
+ return null;
1348
+ }
1311
1349
  async function startEngine() {
1312
1350
  const configPath = findIiiConfig();
1313
- let iiiBin = whichBinary("iii");
1314
- vlog(`iii binary: ${iiiBin ?? "(not on PATH)"}, config: ${configPath || "(not found)"}`);
1315
- if (iiiBin && configPath) return startIiiBin(iiiBin, configPath);
1316
- for (const iiiPath of fallbackIiiPaths()) if (existsSync(iiiPath)) {
1317
- const v = iiiBinVersion(iiiPath);
1318
- vlog(`fallback iii at ${iiiPath} reports version: ${v ?? "unknown"}`);
1319
- p.log.info(`Found iii at: ${iiiPath}${v ? ` (v${v})` : ""}`);
1320
- process.env["PATH"] = `${dirname(iiiPath)}${delimiter}${process.env["PATH"] ?? ""}`;
1321
- iiiBin = iiiPath;
1322
- break;
1323
- }
1324
- if (iiiBin && configPath) return startIiiBin(iiiBin, configPath);
1351
+ const pathIii = whichBinary("iii");
1352
+ vlog(`iii binary: ${pathIii ?? "(not on PATH)"}, config: ${configPath || "(not found)"}`);
1353
+ const fallbacks = fallbackIiiPaths().filter((p) => existsSync(p));
1354
+ for (const f of fallbacks) vlog(`fallback iii at ${f} reports version: ${iiiBinVersion(f) ?? "unknown"}`);
1355
+ let iiiBin = pickCompatibleIii([pathIii, ...fallbacks]);
1356
+ if (iiiBin && configPath) {
1357
+ if (iiiBin !== pathIii) {
1358
+ p.log.info(`Using iii at: ${iiiBin} (v${IIPINNED_VERSION})`);
1359
+ process.env["PATH"] = `${dirname(iiiBin)}${delimiter}${process.env["PATH"] ?? ""}`;
1360
+ }
1361
+ return startIiiBin(iiiBin, configPath);
1362
+ }
1363
+ if (pathIii && !iiiBin) vlog(`iii on PATH is v${iiiBinVersion(pathIii) ?? "unknown"}, pin is v${IIPINNED_VERSION}. Will install pinned engine to ${privateIiiPath()}.`);
1325
1364
  if (!configPath) {
1326
1365
  startupFailure = { kind: "no-engine" };
1327
1366
  return false;
@@ -1337,15 +1376,20 @@ async function startEngine() {
1337
1376
  const dockerOptIn = process.env["AGENTMEMORY_USE_DOCKER"] === "1" || process.env["AGENTMEMORY_USE_DOCKER"] === "true";
1338
1377
  const interactive = !!process.stdin.isTTY && !process.env["CI"];
1339
1378
  let choice;
1379
+ const pathIiiMismatch = pathIii !== null && resolveCompatibleIii(pathIii) === null;
1340
1380
  if (dockerOptIn && dockerBin && composeFile) choice = "docker";
1341
- else if (!interactive) {
1381
+ else if (pathIiiMismatch) {
1382
+ choice = "install";
1383
+ const detected = iiiBinVersion(pathIii);
1384
+ p.log.info(`iii on PATH is v${detected ?? "unknown"} but agentmemory pins v${IIPINNED_VERSION}. Installing pinned engine to ~/.agentmemory/bin (leaves your existing iii untouched).`);
1385
+ } else if (!interactive) {
1342
1386
  choice = "install";
1343
1387
  p.log.info("Non-interactive environment detected — auto-installing iii-engine.");
1344
1388
  } else {
1345
1389
  p.log.warn(`iii-engine binary not found locally.`);
1346
1390
  const options = [{
1347
1391
  value: "install",
1348
- label: `Install iii v${IIPINNED_VERSION} to ~/.local/bin (~6MB, ~5s)`,
1392
+ label: `Install iii v${IIPINNED_VERSION} to ~/.agentmemory/bin (~6MB, ~5s)`,
1349
1393
  hint: "recommended"
1350
1394
  }];
1351
1395
  if (dockerBin && composeFile) options.push({
@@ -1441,7 +1485,7 @@ function installInstructions() {
1441
1485
  "",
1442
1486
  "Docs: https://iii.dev/docs"
1443
1487
  ];
1444
- const linuxInstall = releaseUrl ? ` A) curl -fsSL "${releaseUrl}" | tar -xz -C ~/.local/bin && chmod +x ~/.local/bin/iii` : ` A) Manual download: https://github.com/iii-hq/iii/releases/tag/iii%2Fv${IIPINNED_VERSION}`;
1488
+ const linuxInstall = releaseUrl ? ` A) mkdir -p ~/.agentmemory/bin && curl -fsSL "${releaseUrl}" | tar -xz -C ~/.agentmemory/bin && chmod +x ~/.agentmemory/bin/iii` : ` A) Manual download: https://github.com/iii-hq/iii/releases/tag/iii%2Fv${IIPINNED_VERSION}`;
1445
1489
  return [
1446
1490
  `agentmemory needs iii-engine v${IIPINNED_VERSION}. Pick one:`,
1447
1491
  "",
@@ -1504,7 +1548,7 @@ async function main() {
1504
1548
  if (firstRun || IS_RESET) await runOnboarding();
1505
1549
  if (skipEngine) {
1506
1550
  if (IS_VERBOSE) p.log.info("Skipping engine check (--no-engine)");
1507
- await import("./src-B8J9Exum.mjs");
1551
+ await import("./src-fQOMXeCp.mjs");
1508
1552
  if (await waitForAgentmemoryReady(15e3)) {
1509
1553
  const consoleState = await ensureIiiConsole();
1510
1554
  await maybeOfferGlobalInstall();
@@ -1514,9 +1558,17 @@ async function main() {
1514
1558
  }
1515
1559
  if (await isEngineRunning()) {
1516
1560
  if (IS_VERBOSE) p.log.success("iii-engine is running");
1517
- enforceEngineVersionPin(whichBinary("iii") ?? fallbackIiiPaths().find((p) => existsSync(p)) ?? null);
1561
+ const persisted = readEngineState();
1562
+ const attachedBin = (persisted?.kind === "native" && persisted.binPath && existsSync(persisted.binPath) ? persisted.binPath : null) ?? whichBinary("iii") ?? fallbackIiiPaths().find((p) => existsSync(p)) ?? null;
1563
+ if (attachedBin) {
1564
+ const detected = iiiBinVersion(attachedBin);
1565
+ if (detected && detected !== IIPINNED_VERSION) {
1566
+ p.log.error(`Attached iii-engine appears to be v${detected} (from ${attachedBin}) but agentmemory v${VERSION} hard-pins v${IIPINNED_VERSION}. Engine API drift causes runtime failures (e.g. state::list-not-found on v0.13.0+). Stop the running engine (\`agentmemory stop --force\`) and re-run \`agentmemory\` to install the pinned engine into ~/.agentmemory/bin without touching ${attachedBin}. Or set AGENTMEMORY_III_VERSION=${detected} to override at your own risk.`);
1567
+ process.exit(1);
1568
+ }
1569
+ }
1518
1570
  adoptRunningEngine();
1519
- await import("./src-B8J9Exum.mjs");
1571
+ await import("./src-fQOMXeCp.mjs");
1520
1572
  if (await waitForAgentmemoryReady(15e3)) {
1521
1573
  const consoleState = await ensureIiiConsole();
1522
1574
  await maybeOfferGlobalInstall();
@@ -1565,7 +1617,7 @@ async function main() {
1565
1617
  process.exit(1);
1566
1618
  }
1567
1619
  s.stop("iii-engine is ready");
1568
- await import("./src-B8J9Exum.mjs");
1620
+ await import("./src-fQOMXeCp.mjs");
1569
1621
  if (await waitForAgentmemoryReady(15e3)) {
1570
1622
  const consoleState = await ensureIiiConsole();
1571
1623
  await maybeOfferGlobalInstall();
@@ -1596,12 +1648,13 @@ async function runStatus() {
1596
1648
  process.exit(1);
1597
1649
  }
1598
1650
  try {
1599
- const [healthRes, sessionsRes, graphRes, memoriesRes, flagsRes] = await Promise.all([
1651
+ const [healthRes, sessionsRes, graphRes, memoriesRes, flagsRes, followupRes] = await Promise.all([
1600
1652
  apiFetch(base, "health"),
1601
1653
  apiFetch(base, "sessions"),
1602
1654
  apiFetch(base, "graph/stats"),
1603
1655
  apiFetch(base, "memories?count=true"),
1604
- apiFetch(base, "config/flags")
1656
+ apiFetch(base, "config/flags"),
1657
+ apiFetch(base, "diagnostics/followup")
1605
1658
  ]);
1606
1659
  if (typeof healthRes?.viewerPort === "number") discoveredViewerPort = healthRes.viewerPort;
1607
1660
  const h = healthRes?.health;
@@ -1648,6 +1701,13 @@ async function runStatus() {
1648
1701
  lines.push(`Flags:`);
1649
1702
  flagRows.forEach((r) => lines.push(r));
1650
1703
  }
1704
+ if (followupRes && Number.isFinite(followupRes.agentInitiatedSearches)) {
1705
+ const total = Number(followupRes.agentInitiatedSearches) || 0;
1706
+ const hits = Number(followupRes.followupWithinWindow) || 0;
1707
+ const pct = total > 0 ? Math.round(hits / total * 100) : 0;
1708
+ lines.push("");
1709
+ lines.push(`Followup rate: ${hits}/${total} (${pct}%) within ${followupRes.windowSeconds}s — directional, may overcount on refinement`);
1710
+ }
1651
1711
  p.note(lines.join("\n"), "agentmemory");
1652
1712
  } catch (err) {
1653
1713
  p.log.error(err instanceof Error ? err.message : String(err));
@@ -1720,7 +1780,7 @@ function buildDoctorEffects() {
1720
1780
  return pidAlive(pid);
1721
1781
  },
1722
1782
  findIiiBinary: () => whichBinary("iii"),
1723
- localBinIiiPath: () => join(homedir(), ".local", "bin", IS_WINDOWS ? "iii.exe" : "iii"),
1783
+ localBinIiiPath: () => privateIiiPath(),
1724
1784
  iiiBinaryVersion: (binPath) => iiiBinVersion(binPath),
1725
1785
  viewerReachable: async (timeoutMs = 2e3) => {
1726
1786
  try {
@@ -2490,10 +2550,10 @@ async function runStop() {
2490
2550
  p.outro("Stopped. Memories persisted to disk; restart anytime with: npx @agentmemory/agentmemory");
2491
2551
  }
2492
2552
  async function runMcp() {
2493
- await import("./standalone-CPfsVTBA.mjs");
2553
+ await import("./standalone-BzfA1zu8.mjs");
2494
2554
  }
2495
2555
  async function runConnectCmd() {
2496
- const { runConnect } = await import("./connect-Cf9bmBqO.mjs").then((n) => n.t);
2556
+ const { runConnect } = await import("./connect-bmZ5eqYN.mjs").then((n) => n.t);
2497
2557
  await runConnect(args.slice(1));
2498
2558
  }
2499
2559
  async function runImportJsonl() {
@@ -2610,7 +2670,7 @@ function loadConnectManifest(home) {
2610
2670
  }
2611
2671
  }
2612
2672
  function probeLocalBinIiiVersion(home) {
2613
- const path = localBinIii(home);
2673
+ const path = legacyLocalBinIii(home);
2614
2674
  if (!existsSync(path)) return null;
2615
2675
  return iiiBinVersion(path);
2616
2676
  }
@@ -2724,7 +2784,7 @@ async function runRemove() {
2724
2784
  p.log.error(err instanceof Error ? err.message : String(err));
2725
2785
  process.exit(1);
2726
2786
  });
2727
-
2728
2787
  //#endregion
2729
2788
  export { discoverViewerPort };
2789
+
2730
2790
  //# sourceMappingURL=cli.mjs.map