@agentmemory/agentmemory 0.9.23 → 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 +129 -66
  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 +942 -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-DvS3bhMe.mjs → src-fQOMXeCp.mjs} +937 -483
  44. package/dist/src-fQOMXeCp.mjs.map +1 -0
  45. package/dist/{standalone-DHQcPX_g.mjs → standalone-BzfA1zu8.mjs} +6 -10
  46. package/dist/{standalone-DHQcPX_g.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-DvS3bhMe.mjs.map +0 -1
  86. package/dist/tools-registry-DJizX9Az.mjs.map +0 -1
  87. package/dist/version-BPfyI4Kc.mjs +0 -6
  88. package/dist/version-BPfyI4Kc.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":";iBAwMsB,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-BPfyI4Kc.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));
@@ -806,6 +815,10 @@ const IS_WINDOWS = platform() === "win32";
806
815
  const IS_VERBOSE = args.includes("--verbose") || args.includes("-v") || process.env["AGENTMEMORY_VERBOSE"] === "1" || process.env["AGENTMEMORY_VERBOSE"] === "true";
807
816
  setBootVerbose(IS_VERBOSE);
808
817
  const IS_RESET = args.includes("--reset");
818
+ if (args.includes("--version") || args.includes("-V")) {
819
+ process.stdout.write(`${VERSION}\n`);
820
+ process.exit(0);
821
+ }
809
822
  const IIPINNED_VERSION = process.env["AGENTMEMORY_III_VERSION"] || "0.11.2";
810
823
  function iiiReleaseAsset() {
811
824
  const p = platform();
@@ -873,6 +886,9 @@ Environment:
873
886
  AGENTMEMORY_USE_DOCKER=1 Prefer the bundled docker-compose path over the
874
887
  native iii-engine binary on first run.
875
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.
876
892
 
877
893
  Quick start:
878
894
  npx @agentmemory/agentmemory # start with local iii-engine or Docker
@@ -998,15 +1014,29 @@ function whichBinary(name) {
998
1014
  return null;
999
1015
  }
1000
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
+ }
1001
1028
  function fallbackIiiPaths() {
1002
1029
  if (IS_WINDOWS) {
1003
1030
  const userProfile = process.env["USERPROFILE"];
1004
- if (!userProfile) return [];
1005
- 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;
1006
1034
  }
1007
1035
  const home = process.env["HOME"];
1008
- if (!home) return ["/usr/local/bin/iii"];
1009
- 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;
1010
1040
  }
1011
1041
  function iiiBinVersion(binPath) {
1012
1042
  try {
@@ -1024,15 +1054,18 @@ function iiiBinVersion(binPath) {
1024
1054
  return null;
1025
1055
  }
1026
1056
  }
1027
- let warnedVersionMismatch = false;
1028
- function warnIfEngineVersionMismatch(iiiBinPath) {
1029
- if (!iiiBinPath || warnedVersionMismatch) return;
1057
+ function resolveCompatibleIii(iiiBinPath) {
1058
+ if (!iiiBinPath) return null;
1030
1059
  const detected = iiiBinVersion(iiiBinPath);
1031
- if (!detected || detected === IIPINNED_VERSION) return;
1032
- warnedVersionMismatch = true;
1033
- const asset = iiiReleaseAsset();
1034
- 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}`;
1035
- p.log.warn(`iii-engine on PATH is v${detected} but agentmemory v${VERSION} pins v${IIPINNED_VERSION}. Set AGENTMEMORY_III_VERSION=${detected} to silence, or downgrade with: \`${downloadHint}\``);
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;
1036
1069
  }
1037
1070
  function enginePidfilePath() {
1038
1071
  return join(homedir(), ".agentmemory", "iii.pid");
@@ -1142,8 +1175,8 @@ async function maybeOfferGlobalInstall() {
1142
1175
  if (runCommand(npmBin, [
1143
1176
  "install",
1144
1177
  "-g",
1145
- `@agentmemory/agentmemory@${VERSION}`
1146
- ], { label: `Installing @agentmemory/agentmemory@${VERSION} globally` })) {
1178
+ `@agentmemory/agentmemory@0.9.25`
1179
+ ], { label: `Installing @agentmemory/agentmemory@0.9.25 globally` })) {
1147
1180
  p.log.success("Installed globally. `agentmemory stop` etc. will now work in new shells.");
1148
1181
  writePrefs({ skipGlobalInstall: true });
1149
1182
  } else p.log.warn("Global install failed. Try manually: npm install -g @agentmemory/agentmemory");
@@ -1232,8 +1265,8 @@ async function runIiiInstaller() {
1232
1265
  binPath: null
1233
1266
  };
1234
1267
  }
1235
- const binDir = join(homedir(), ".local", "bin");
1236
- const binPath = join(binDir, "iii");
1268
+ const binDir = agentmemoryBinDir();
1269
+ const binPath = privateIiiPath();
1237
1270
  if (!runCommand(shBin, ["-c", [
1238
1271
  `mkdir -p "${binDir}"`,
1239
1272
  `curl -fsSL "${releaseUrl}" | tar -xz -C "${binDir}"`,
@@ -1294,31 +1327,40 @@ function spawnEngineBackground(bin, spawnArgs, label) {
1294
1327
  return child;
1295
1328
  }
1296
1329
  function startIiiBin(iiiBin, configPath) {
1297
- warnIfEngineVersionMismatch(iiiBin);
1298
1330
  const s = p.spinner();
1299
1331
  s.start(`Starting iii-engine: ${iiiBin}`);
1300
1332
  writeEngineState({
1301
1333
  kind: "native",
1302
- configPath
1334
+ configPath,
1335
+ binPath: iiiBin
1303
1336
  });
1304
1337
  spawnEngineBackground(iiiBin, ["--config", configPath], "iii-engine");
1305
1338
  s.stop("iii-engine process started");
1306
1339
  return true;
1307
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
+ }
1308
1349
  async function startEngine() {
1309
1350
  const configPath = findIiiConfig();
1310
- let iiiBin = whichBinary("iii");
1311
- vlog(`iii binary: ${iiiBin ?? "(not on PATH)"}, config: ${configPath || "(not found)"}`);
1312
- if (iiiBin && configPath) return startIiiBin(iiiBin, configPath);
1313
- for (const iiiPath of fallbackIiiPaths()) if (existsSync(iiiPath)) {
1314
- const v = iiiBinVersion(iiiPath);
1315
- vlog(`fallback iii at ${iiiPath} reports version: ${v ?? "unknown"}`);
1316
- p.log.info(`Found iii at: ${iiiPath}${v ? ` (v${v})` : ""}`);
1317
- process.env["PATH"] = `${dirname(iiiPath)}${delimiter}${process.env["PATH"] ?? ""}`;
1318
- iiiBin = iiiPath;
1319
- break;
1320
- }
1321
- 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()}.`);
1322
1364
  if (!configPath) {
1323
1365
  startupFailure = { kind: "no-engine" };
1324
1366
  return false;
@@ -1334,15 +1376,20 @@ async function startEngine() {
1334
1376
  const dockerOptIn = process.env["AGENTMEMORY_USE_DOCKER"] === "1" || process.env["AGENTMEMORY_USE_DOCKER"] === "true";
1335
1377
  const interactive = !!process.stdin.isTTY && !process.env["CI"];
1336
1378
  let choice;
1379
+ const pathIiiMismatch = pathIii !== null && resolveCompatibleIii(pathIii) === null;
1337
1380
  if (dockerOptIn && dockerBin && composeFile) choice = "docker";
1338
- 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) {
1339
1386
  choice = "install";
1340
1387
  p.log.info("Non-interactive environment detected — auto-installing iii-engine.");
1341
1388
  } else {
1342
1389
  p.log.warn(`iii-engine binary not found locally.`);
1343
1390
  const options = [{
1344
1391
  value: "install",
1345
- label: `Install iii v${IIPINNED_VERSION} to ~/.local/bin (~6MB, ~5s)`,
1392
+ label: `Install iii v${IIPINNED_VERSION} to ~/.agentmemory/bin (~6MB, ~5s)`,
1346
1393
  hint: "recommended"
1347
1394
  }];
1348
1395
  if (dockerBin && composeFile) options.push({
@@ -1438,7 +1485,7 @@ function installInstructions() {
1438
1485
  "",
1439
1486
  "Docs: https://iii.dev/docs"
1440
1487
  ];
1441
- 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}`;
1442
1489
  return [
1443
1490
  `agentmemory needs iii-engine v${IIPINNED_VERSION}. Pick one:`,
1444
1491
  "",
@@ -1501,7 +1548,7 @@ async function main() {
1501
1548
  if (firstRun || IS_RESET) await runOnboarding();
1502
1549
  if (skipEngine) {
1503
1550
  if (IS_VERBOSE) p.log.info("Skipping engine check (--no-engine)");
1504
- await import("./src-DvS3bhMe.mjs");
1551
+ await import("./src-fQOMXeCp.mjs");
1505
1552
  if (await waitForAgentmemoryReady(15e3)) {
1506
1553
  const consoleState = await ensureIiiConsole();
1507
1554
  await maybeOfferGlobalInstall();
@@ -1511,9 +1558,17 @@ async function main() {
1511
1558
  }
1512
1559
  if (await isEngineRunning()) {
1513
1560
  if (IS_VERBOSE) p.log.success("iii-engine is running");
1514
- warnIfEngineVersionMismatch(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
+ }
1515
1570
  adoptRunningEngine();
1516
- await import("./src-DvS3bhMe.mjs");
1571
+ await import("./src-fQOMXeCp.mjs");
1517
1572
  if (await waitForAgentmemoryReady(15e3)) {
1518
1573
  const consoleState = await ensureIiiConsole();
1519
1574
  await maybeOfferGlobalInstall();
@@ -1562,7 +1617,7 @@ async function main() {
1562
1617
  process.exit(1);
1563
1618
  }
1564
1619
  s.stop("iii-engine is ready");
1565
- await import("./src-DvS3bhMe.mjs");
1620
+ await import("./src-fQOMXeCp.mjs");
1566
1621
  if (await waitForAgentmemoryReady(15e3)) {
1567
1622
  const consoleState = await ensureIiiConsole();
1568
1623
  await maybeOfferGlobalInstall();
@@ -1593,12 +1648,13 @@ async function runStatus() {
1593
1648
  process.exit(1);
1594
1649
  }
1595
1650
  try {
1596
- const [healthRes, sessionsRes, graphRes, memoriesRes, flagsRes] = await Promise.all([
1651
+ const [healthRes, sessionsRes, graphRes, memoriesRes, flagsRes, followupRes] = await Promise.all([
1597
1652
  apiFetch(base, "health"),
1598
1653
  apiFetch(base, "sessions"),
1599
1654
  apiFetch(base, "graph/stats"),
1600
1655
  apiFetch(base, "memories?count=true"),
1601
- apiFetch(base, "config/flags")
1656
+ apiFetch(base, "config/flags"),
1657
+ apiFetch(base, "diagnostics/followup")
1602
1658
  ]);
1603
1659
  if (typeof healthRes?.viewerPort === "number") discoveredViewerPort = healthRes.viewerPort;
1604
1660
  const h = healthRes?.health;
@@ -1645,6 +1701,13 @@ async function runStatus() {
1645
1701
  lines.push(`Flags:`);
1646
1702
  flagRows.forEach((r) => lines.push(r));
1647
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
+ }
1648
1711
  p.note(lines.join("\n"), "agentmemory");
1649
1712
  } catch (err) {
1650
1713
  p.log.error(err instanceof Error ? err.message : String(err));
@@ -1717,7 +1780,7 @@ function buildDoctorEffects() {
1717
1780
  return pidAlive(pid);
1718
1781
  },
1719
1782
  findIiiBinary: () => whichBinary("iii"),
1720
- localBinIiiPath: () => join(homedir(), ".local", "bin", IS_WINDOWS ? "iii.exe" : "iii"),
1783
+ localBinIiiPath: () => privateIiiPath(),
1721
1784
  iiiBinaryVersion: (binPath) => iiiBinVersion(binPath),
1722
1785
  viewerReachable: async (timeoutMs = 2e3) => {
1723
1786
  try {
@@ -2487,10 +2550,10 @@ async function runStop() {
2487
2550
  p.outro("Stopped. Memories persisted to disk; restart anytime with: npx @agentmemory/agentmemory");
2488
2551
  }
2489
2552
  async function runMcp() {
2490
- await import("./standalone-DHQcPX_g.mjs");
2553
+ await import("./standalone-BzfA1zu8.mjs");
2491
2554
  }
2492
2555
  async function runConnectCmd() {
2493
- const { runConnect } = await import("./connect-Cf9bmBqO.mjs").then((n) => n.t);
2556
+ const { runConnect } = await import("./connect-bmZ5eqYN.mjs").then((n) => n.t);
2494
2557
  await runConnect(args.slice(1));
2495
2558
  }
2496
2559
  async function runImportJsonl() {
@@ -2607,7 +2670,7 @@ function loadConnectManifest(home) {
2607
2670
  }
2608
2671
  }
2609
2672
  function probeLocalBinIiiVersion(home) {
2610
- const path = localBinIii(home);
2673
+ const path = legacyLocalBinIii(home);
2611
2674
  if (!existsSync(path)) return null;
2612
2675
  return iiiBinVersion(path);
2613
2676
  }
@@ -2721,7 +2784,7 @@ async function runRemove() {
2721
2784
  p.log.error(err instanceof Error ? err.message : String(err));
2722
2785
  process.exit(1);
2723
2786
  });
2724
-
2725
2787
  //#endregion
2726
2788
  export { discoverViewerPort };
2789
+
2727
2790
  //# sourceMappingURL=cli.mjs.map