@agentmemory/agentmemory 0.9.27 → 0.9.28

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 (122) hide show
  1. package/AGENTS.md +5 -5
  2. package/README.md +97 -37
  3. package/dist/cli.d.mts.map +1 -1
  4. package/dist/cli.mjs +206 -154
  5. package/dist/cli.mjs.map +1 -1
  6. package/dist/config-ChC9EtgV.mjs +259 -0
  7. package/dist/config-ChC9EtgV.mjs.map +1 -0
  8. package/dist/{connect-bmZ5eqYN.mjs → connect-JnsJXc68.mjs} +136 -42
  9. package/dist/connect-JnsJXc68.mjs.map +1 -0
  10. package/dist/hooks/notification.mjs +2 -1
  11. package/dist/hooks/notification.mjs.map +1 -1
  12. package/dist/hooks/post-commit.mjs +2 -1
  13. package/dist/hooks/post-commit.mjs.map +1 -1
  14. package/dist/hooks/post-tool-failure.mjs +2 -1
  15. package/dist/hooks/post-tool-failure.mjs.map +1 -1
  16. package/dist/hooks/post-tool-use.mjs +2 -1
  17. package/dist/hooks/post-tool-use.mjs.map +1 -1
  18. package/dist/hooks/pre-compact.mjs +2 -1
  19. package/dist/hooks/pre-compact.mjs.map +1 -1
  20. package/dist/hooks/pre-tool-use.mjs +2 -1
  21. package/dist/hooks/pre-tool-use.mjs.map +1 -1
  22. package/dist/hooks/prompt-submit.mjs +2 -1
  23. package/dist/hooks/prompt-submit.mjs.map +1 -1
  24. package/dist/hooks/session-end.mjs +2 -1
  25. package/dist/hooks/session-end.mjs.map +1 -1
  26. package/dist/hooks/session-start.mjs +2 -1
  27. package/dist/hooks/session-start.mjs.map +1 -1
  28. package/dist/hooks/stop.mjs +2 -1
  29. package/dist/hooks/stop.mjs.map +1 -1
  30. package/dist/hooks/subagent-start.mjs +2 -1
  31. package/dist/hooks/subagent-start.mjs.map +1 -1
  32. package/dist/hooks/subagent-stop.mjs +2 -1
  33. package/dist/hooks/subagent-stop.mjs.map +1 -1
  34. package/dist/hooks/task-completed.mjs +2 -1
  35. package/dist/hooks/task-completed.mjs.map +1 -1
  36. package/dist/image-refs-BKLmp_sD.mjs +34 -0
  37. package/dist/image-refs-BKLmp_sD.mjs.map +1 -0
  38. package/dist/{image-refs-B5Zf_Djo.mjs → image-refs-C2YU7BIm.mjs} +3 -21
  39. package/dist/image-refs-C2YU7BIm.mjs.map +1 -0
  40. package/dist/index.mjs +118 -150
  41. package/dist/index.mjs.map +1 -1
  42. package/dist/{image-store-Gpo2mgM9.mjs → keyed-mutex-DTHtcZrt.mjs} +14 -11
  43. package/dist/keyed-mutex-DTHtcZrt.mjs.map +1 -0
  44. package/dist/{logger-yHTcEBAI.mjs → logger-BEB7pCI9.mjs} +1 -1
  45. package/dist/{logger-yHTcEBAI.mjs.map → logger-BEB7pCI9.mjs.map} +1 -1
  46. package/dist/{src-MOg2zKJs.mjs → src-CzgoepGU.mjs} +49 -30
  47. package/dist/src-CzgoepGU.mjs.map +1 -0
  48. package/dist/{standalone-BORXC71-.mjs → standalone-YsZFFQBM.mjs} +7 -4
  49. package/dist/standalone-YsZFFQBM.mjs.map +1 -0
  50. package/dist/standalone.d.mts.map +1 -1
  51. package/dist/standalone.mjs +6 -2
  52. package/dist/standalone.mjs.map +1 -1
  53. package/dist/{tools-registry-D8XVVPbJ.mjs → tools-registry-D3NEoe5m.mjs} +4 -256
  54. package/dist/tools-registry-D3NEoe5m.mjs.map +1 -0
  55. package/package.json +4 -1
  56. package/plugin/.claude-plugin/plugin.json +1 -1
  57. package/plugin/.codex-plugin/plugin.json +1 -1
  58. package/plugin/plugin.json +2 -2
  59. package/plugin/scripts/notification.mjs +2 -1
  60. package/plugin/scripts/notification.mjs.map +1 -1
  61. package/plugin/scripts/post-commit.mjs +2 -1
  62. package/plugin/scripts/post-commit.mjs.map +1 -1
  63. package/plugin/scripts/post-tool-failure.mjs +2 -1
  64. package/plugin/scripts/post-tool-failure.mjs.map +1 -1
  65. package/plugin/scripts/post-tool-use.mjs +2 -1
  66. package/plugin/scripts/post-tool-use.mjs.map +1 -1
  67. package/plugin/scripts/pre-compact.mjs +2 -1
  68. package/plugin/scripts/pre-compact.mjs.map +1 -1
  69. package/plugin/scripts/pre-tool-use.mjs +2 -1
  70. package/plugin/scripts/pre-tool-use.mjs.map +1 -1
  71. package/plugin/scripts/prompt-submit.mjs +2 -1
  72. package/plugin/scripts/prompt-submit.mjs.map +1 -1
  73. package/plugin/scripts/session-end.mjs +2 -1
  74. package/plugin/scripts/session-end.mjs.map +1 -1
  75. package/plugin/scripts/session-start.mjs +2 -1
  76. package/plugin/scripts/session-start.mjs.map +1 -1
  77. package/plugin/scripts/stop.mjs +2 -1
  78. package/plugin/scripts/stop.mjs.map +1 -1
  79. package/plugin/scripts/subagent-start.mjs +2 -1
  80. package/plugin/scripts/subagent-start.mjs.map +1 -1
  81. package/plugin/scripts/subagent-stop.mjs +2 -1
  82. package/plugin/scripts/subagent-stop.mjs.map +1 -1
  83. package/plugin/scripts/task-completed.mjs +2 -1
  84. package/plugin/scripts/task-completed.mjs.map +1 -1
  85. package/plugin/skills/_shared/TROUBLESHOOTING.md +38 -0
  86. package/plugin/skills/agentmemory-agents/REFERENCE.md +28 -0
  87. package/plugin/skills/agentmemory-agents/SKILL.md +34 -0
  88. package/plugin/skills/agentmemory-architecture/SKILL.md +33 -0
  89. package/plugin/skills/agentmemory-config/REFERENCE.md +42 -0
  90. package/plugin/skills/agentmemory-config/SKILL.md +37 -0
  91. package/plugin/skills/agentmemory-hooks/REFERENCE.md +20 -0
  92. package/plugin/skills/agentmemory-hooks/SKILL.md +39 -0
  93. package/plugin/skills/agentmemory-mcp-tools/REFERENCE.md +65 -0
  94. package/plugin/skills/agentmemory-mcp-tools/SKILL.md +39 -0
  95. package/plugin/skills/agentmemory-rest-api/REFERENCE.md +129 -0
  96. package/plugin/skills/agentmemory-rest-api/SKILL.md +43 -0
  97. package/plugin/skills/commit-context/EXAMPLES.md +71 -0
  98. package/plugin/skills/commit-context/SKILL.md +53 -8
  99. package/plugin/skills/commit-history/EXAMPLES.md +71 -0
  100. package/plugin/skills/commit-history/SKILL.md +51 -9
  101. package/plugin/skills/forget/EXAMPLES.md +75 -0
  102. package/plugin/skills/forget/SKILL.md +54 -14
  103. package/plugin/skills/handoff/EXAMPLES.md +56 -0
  104. package/plugin/skills/handoff/SKILL.md +56 -9
  105. package/plugin/skills/recall/EXAMPLES.md +74 -0
  106. package/plugin/skills/recall/SKILL.md +50 -11
  107. package/plugin/skills/recap/EXAMPLES.md +60 -0
  108. package/plugin/skills/recap/SKILL.md +51 -13
  109. package/plugin/skills/remember/EXAMPLES.md +67 -0
  110. package/plugin/skills/remember/SKILL.md +53 -17
  111. package/plugin/skills/session-history/EXAMPLES.md +59 -0
  112. package/plugin/skills/session-history/SKILL.md +54 -11
  113. package/plugin/skills/write-agentmemory-skill/SKILL.md +40 -0
  114. package/dist/connect-bmZ5eqYN.mjs.map +0 -1
  115. package/dist/image-refs-B5Zf_Djo.mjs.map +0 -1
  116. package/dist/image-store-Gpo2mgM9.mjs.map +0 -1
  117. package/dist/rolldown-runtime-twds-ZHy.mjs +0 -14
  118. package/dist/src-MOg2zKJs.mjs.map +0 -1
  119. package/dist/standalone-BORXC71-.mjs.map +0 -1
  120. package/dist/tools-registry-D8XVVPbJ.mjs.map +0 -1
  121. package/dist/version-9DNrRyph.mjs +0 -6
  122. package/dist/version-9DNrRyph.mjs.map +0 -1
package/dist/cli.mjs CHANGED
@@ -1,14 +1,15 @@
1
1
  #!/usr/bin/env node
2
+ import { a as runAdapter, i as resolveAdapter, r as knownAgents, t as ADAPTERS } from "./connect-JnsJXc68.mjs";
2
3
  import { i as generateId } from "./schema-CNiCWzV9.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-9DNrRyph.mjs";
4
+ import { r as setBootVerbose } from "./logger-BEB7pCI9.mjs";
5
+ import { i as VERSION, n as getAllTools, t as ESSENTIAL_TOOLS } from "./tools-registry-D3NEoe5m.mjs";
6
6
  import { execFileSync, spawn, spawnSync } from "node:child_process";
7
- import { closeSync, constants, existsSync, fsyncSync, mkdirSync, openSync, readFileSync, readdirSync, readlinkSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync, writeSync } from "node:fs";
7
+ import { appendFileSync, 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";
9
9
  import { fileURLToPath } from "node:url";
10
10
  import { homedir, platform } from "node:os";
11
11
  import * as p from "@clack/prompts";
12
+ import pc from "picocolors";
12
13
  import { copyFile, mkdir } from "node:fs/promises";
13
14
  //#region src/cli/doctor-diagnostics.ts
14
15
  /** Common placeholder values shipped in .env.example. */
@@ -436,7 +437,8 @@ const DEFAULTS = {
436
437
  skipNpxHint: false,
437
438
  skipGlobalInstall: false,
438
439
  skipConsoleInstall: false,
439
- firstRunAt: null
440
+ firstRunAt: null,
441
+ injectContextChosen: false
440
442
  };
441
443
  function prefsDir() {
442
444
  return join(homedir(), ".agentmemory");
@@ -492,95 +494,14 @@ function isFirstRun() {
492
494
  //#endregion
493
495
  //#region src/cli/onboarding.ts
494
496
  const __dirname$1 = dirname(fileURLToPath(import.meta.url));
495
- const NATIVE_AGENTS = [
496
- {
497
- value: "claude-code",
498
- label: "Claude Code",
499
- glyph: "⟁"
500
- },
501
- {
502
- value: "copilot-cli",
503
- label: "GitHub Copilot CLI",
504
- glyph: "◈"
505
- },
506
- {
507
- value: "codex",
508
- label: "Codex",
509
- glyph: "◎"
510
- },
511
- {
512
- value: "openhuman",
513
- label: "OpenHuman",
514
- glyph: "◇"
515
- },
516
- {
517
- value: "openclaw",
518
- label: "OpenClaw",
519
- glyph: "◇"
520
- },
521
- {
522
- value: "hermes",
523
- label: "Hermes",
524
- glyph: "◇"
525
- },
526
- {
527
- value: "pi",
528
- label: "Pi",
529
- glyph: "◇"
530
- },
531
- {
532
- value: "cursor",
533
- label: "Cursor",
534
- glyph: "◫"
535
- },
536
- {
537
- value: "gemini-cli",
538
- label: "Gemini CLI",
539
- glyph: "✦"
540
- }
541
- ];
542
- const MCP_AGENTS = [
543
- {
544
- value: "opencode",
545
- label: "OpenCode",
546
- glyph: "⬡"
547
- },
548
- {
549
- value: "cline",
550
- label: "Cline",
551
- glyph: "◇"
552
- },
553
- {
554
- value: "goose",
555
- label: "Goose",
556
- glyph: "◇"
557
- },
558
- {
559
- value: "kilo",
560
- label: "Kilo",
561
- glyph: "◇"
562
- },
563
- {
564
- value: "aider",
565
- label: "Aider",
566
- glyph: "◇"
567
- },
568
- {
569
- value: "claude-desktop",
570
- label: "Claude Desktop",
571
- glyph: "⟁"
572
- },
573
- {
574
- value: "windsurf",
575
- label: "Windsurf",
576
- glyph: "◇"
577
- },
578
- {
579
- value: "roo",
580
- label: "Roo",
581
- glyph: "◇"
582
- }
583
- ];
497
+ const AGENT_GLYPH = {
498
+ "claude-code": "⟁",
499
+ "copilot-cli": "◈",
500
+ codex: "◎",
501
+ cursor: "◫",
502
+ "gemini-cli": "✦",
503
+ opencode: "⬡"
504
+ };
584
505
  const PROVIDERS = [
585
506
  {
586
507
  value: "anthropic",
@@ -613,16 +534,20 @@ const PROVIDERS = [
613
534
  envKey: null
614
535
  }
615
536
  ];
537
+ const PROVIDER_COST_HINTS = {
538
+ anthropic: "rough cost: a fast Haiku-class model keeps compress/consolidate at fractions of a cent per session.",
539
+ openai: "rough cost: a mini-class model keeps compress/consolidate at fractions of a cent per session.",
540
+ gemini: "rough cost: a Flash-class model keeps compress/consolidate at fractions of a cent per session.",
541
+ openrouter: "rough cost: pick a small model; spend tracks your chosen model's per-token price.",
542
+ minimax: "rough cost: scales with the MiniMax model price per token."
543
+ };
616
544
  function buildAgentOptions() {
617
- return [...NATIVE_AGENTS.map((a) => ({
618
- value: a.value,
619
- label: `${a.glyph} ${a.label}`,
620
- hint: "native plugin"
621
- })), ...MCP_AGENTS.map((a) => ({
622
- value: a.value,
623
- label: `${a.glyph} ${a.label}`,
624
- hint: "MCP server"
625
- }))];
545
+ const options = ADAPTERS.map((a) => ({
546
+ value: a.name,
547
+ label: `${AGENT_GLYPH[a.name] ?? "◇"} ${a.displayName}`,
548
+ hint: a.category === "native" ? "native plugin" : "MCP server"
549
+ }));
550
+ return [...options.filter((o) => o.hint === "native plugin"), ...options.filter((o) => o.hint === "MCP server")];
626
551
  }
627
552
  function getInitialAgentValues(env = process.env) {
628
553
  if (env["COPILOT_CLI"] === "1" || env["COPILOT_AGENT_SESSION_ID"]) return ["copilot-cli"];
@@ -715,7 +640,12 @@ async function runOnboarding() {
715
640
  }
716
641
  const provider = providerPicked === "skip" ? null : providerPicked;
717
642
  const agents = agentsPicked ?? [];
643
+ if (provider) {
644
+ const hint = PROVIDER_COST_HINTS[provider];
645
+ if (hint) p.log.info(hint);
646
+ }
718
647
  const envPath = await seedEnvFile(provider);
648
+ await maybePromptContextInjection(envPath);
719
649
  writePrefs({
720
650
  lastAgent: agents[0] ?? null,
721
651
  lastAgents: agents,
@@ -737,6 +667,33 @@ async function runOnboarding() {
737
667
  provider
738
668
  };
739
669
  }
670
+ function enableInjectContextInEnv(envPath) {
671
+ if (!envPath || !existsSync(envPath)) return false;
672
+ try {
673
+ const current = readFileSync(envPath, "utf-8");
674
+ if (/^\s*AGENTMEMORY_INJECT_CONTEXT\s*=\s*true\b/m.test(current)) return true;
675
+ appendFileSync(envPath, `${current.length > 0 && !current.endsWith("\n") ? "\n" : ""}AGENTMEMORY_INJECT_CONTEXT=true\n`, { mode: 384 });
676
+ return true;
677
+ } catch {
678
+ return false;
679
+ }
680
+ }
681
+ async function maybePromptContextInjection(envPath) {
682
+ if (readPrefs().injectContextChosen) return;
683
+ const enable = await p.confirm({
684
+ message: "Enable automatic context injection so the agent recalls past sessions without being asked? [y/N]",
685
+ initialValue: false
686
+ });
687
+ if (p.isCancel(enable)) {
688
+ p.cancel("Setup cancelled. Re-run any time with: agentmemory --reset");
689
+ process.exit(0);
690
+ }
691
+ p.log.info("Cost note: injection spends session tokens proportional to tool-call frequency. Default is off.");
692
+ writePrefs({ injectContextChosen: true });
693
+ if (enable === true) if (enableInjectContextInEnv(envPath)) p.log.success("Context injection enabled (AGENTMEMORY_INJECT_CONTEXT=true).");
694
+ else p.log.warn("Could not update ~/.agentmemory/.env. Set AGENTMEMORY_INJECT_CONTEXT=true there to enable it.");
695
+ else p.log.info("Context injection left off. Set AGENTMEMORY_INJECT_CONTEXT=true later to enable.");
696
+ }
740
697
  async function wireSelectedAgents(agents) {
741
698
  p.note("Wire selected agents now?", "next step");
742
699
  const confirmed = await p.confirm({
@@ -809,6 +766,18 @@ async function wireSelectedAgents(agents) {
809
766
  }
810
767
  //#endregion
811
768
  //#region src/cli.ts
769
+ const c = {
770
+ url: pc.cyan,
771
+ ok: pc.green,
772
+ warn: pc.yellow,
773
+ err: pc.red,
774
+ cmd: (s) => pc.bold(pc.cyan(s)),
775
+ label: pc.bold,
776
+ dim: pc.dim,
777
+ accent: (s) => pc.bold(pc.yellow(s))
778
+ };
779
+ const ALL_TOOLS_COUNT = getAllTools().length;
780
+ const CORE_TOOLS_COUNT = getAllTools().filter((t) => ESSENTIAL_TOOLS.has(t.name)).length;
812
781
  const __dirname = dirname(fileURLToPath(import.meta.url));
813
782
  const args = process.argv.slice(2);
814
783
  const IS_WINDOWS = platform() === "win32";
@@ -840,6 +809,19 @@ function iiiReleaseUrl() {
840
809
  function vlog(msg) {
841
810
  if (IS_VERBOSE) p.log.info(`[verbose] ${msg}`);
842
811
  }
812
+ function wrapList(items, indent, width = 78) {
813
+ const lines = [];
814
+ let line = "";
815
+ for (const item of items) {
816
+ const joined = line ? `${line}, ${item}` : item;
817
+ if (line && indent + joined.length > width) {
818
+ lines.push(`${line},`);
819
+ line = item;
820
+ } else line = joined;
821
+ }
822
+ lines.push(line);
823
+ return lines.join(`\n${" ".repeat(indent)}`);
824
+ }
843
825
  if (args.includes("--help") || args.includes("-h")) {
844
826
  console.log(`
845
827
  agentmemory — persistent memory for AI coding agents
@@ -849,9 +831,8 @@ Usage: agentmemory [command] [options]
849
831
  Commands:
850
832
  (default) Start agentmemory worker
851
833
  init Copy bundled .env.example to ~/.agentmemory/.env if absent
852
- connect [agent] Wire agentmemory into an installed agent (claude-code,
853
- copilot-cli, codex, cursor, gemini-cli, openclaw,
854
- hermes, pi, openhuman).
834
+ connect [agent] Wire agentmemory into an installed agent
835
+ (${wrapList(knownAgents(), 21)}).
855
836
  No arg = interactive picker. --all wires every detected agent.
856
837
  --dry-run shows what would change. --force re-installs.
857
838
  status Show connection status, memory count, flags, and health
@@ -860,7 +841,9 @@ Commands:
860
841
  --dry-run: show what each fix would do, don't execute
861
842
  remove Cleanly uninstall agentmemory (pidfile, state, .env, binaries).
862
843
  --force: skip confirmations · --keep-data: keep memory data
863
- demo Seed sample sessions and show recall in action
844
+ demo [--serve] Seed sample sessions and show recall in action.
845
+ --serve boots the server, runs the demo, and stops it
846
+ in one command (no second terminal).
864
847
  upgrade Upgrade local deps + iii runtime (best effort)
865
848
  stop [--force] Stop the running iii-engine started by this CLI.
866
849
  --force bypasses the Docker-heuristic guard and signals
@@ -876,7 +859,7 @@ Options:
876
859
  --help, -h Show this help
877
860
  --verbose, -v Show engine stderr, boot log, and diagnostic info
878
861
  --reset Wipe ~/.agentmemory/preferences.json and re-run onboarding
879
- --tools all|core Tool visibility (default: all = 51 tools; core = 8 essentials)
862
+ --tools all|core Tool visibility (default: all = ${ALL_TOOLS_COUNT} tools; core = ${CORE_TOOLS_COUNT} essentials)
880
863
  --no-engine Skip auto-starting iii-engine
881
864
  --port <N> Override REST port (default: 3111). Streams (N+1), viewer
882
865
  (N+2), and iii engine (N+46023) auto-derive from N so a
@@ -907,7 +890,11 @@ Quick start:
907
890
  process.exit(0);
908
891
  }
909
892
  const toolsIdx = args.indexOf("--tools");
910
- if (toolsIdx !== -1 && args[toolsIdx + 1]) process.env["AGENTMEMORY_TOOLS"] = args[toolsIdx + 1];
893
+ if (toolsIdx !== -1 && args[toolsIdx + 1]) {
894
+ const toolsMode = args[toolsIdx + 1];
895
+ if (toolsMode !== "all" && toolsMode !== "core") p.log.warn(`Unknown --tools value "${toolsMode}" (valid: all, core); falling back to all.`);
896
+ process.env["AGENTMEMORY_TOOLS"] = toolsMode;
897
+ }
911
898
  const portIdx = args.indexOf("--port");
912
899
  if (portIdx !== -1 && args[portIdx + 1]) process.env["III_REST_PORT"] = args[portIdx + 1];
913
900
  const instanceIdx = args.indexOf("--instance");
@@ -1188,8 +1175,8 @@ async function maybeOfferGlobalInstall() {
1188
1175
  if (runCommand(npmBin, [
1189
1176
  "install",
1190
1177
  "-g",
1191
- `@agentmemory/agentmemory@0.9.27`
1192
- ], { label: `Installing @agentmemory/agentmemory@0.9.27 globally` })) {
1178
+ `@agentmemory/agentmemory@0.9.28`
1179
+ ], { label: `Installing @agentmemory/agentmemory@0.9.28 globally` })) {
1193
1180
  p.log.success("Installed globally. `agentmemory stop` etc. will now work in new shells.");
1194
1181
  writePrefs({ skipGlobalInstall: true });
1195
1182
  } else p.log.warn("Global install failed. Try manually: npm install -g @agentmemory/agentmemory");
@@ -1250,7 +1237,7 @@ function adoptRunningEngine() {
1250
1237
  configPath: findIiiConfig() || "",
1251
1238
  attached: true
1252
1239
  });
1253
- if (enginePid && !existingPid) p.log.info(`Attached to existing iii-engine (pid ${enginePid})`);
1240
+ if (enginePid && !existingPid) p.log.info(c.ok(`Attached to existing iii-engine (pid ${enginePid})`));
1254
1241
  } catch (err) {
1255
1242
  vlog(`adoptRunningEngine: ${err instanceof Error ? err.message : String(err)}`);
1256
1243
  }
@@ -1352,7 +1339,7 @@ function startIiiBin(iiiBin, configPath) {
1352
1339
  binPath: iiiBin
1353
1340
  });
1354
1341
  spawnEngineBackground(iiiBin, ["--config", configPath], "iii-engine");
1355
- s.stop("iii-engine process started");
1342
+ s.stop(c.ok("iii-engine process started"));
1356
1343
  return true;
1357
1344
  }
1358
1345
  function pickCompatibleIii(candidates) {
@@ -1372,7 +1359,7 @@ async function startEngine() {
1372
1359
  let iiiBin = pickCompatibleIii([pathIii, ...fallbacks]);
1373
1360
  if (iiiBin && configPath) {
1374
1361
  if (iiiBin !== pathIii) {
1375
- p.log.info(`Using iii at: ${iiiBin} (v${IIPINNED_VERSION})`);
1362
+ p.log.info(`Using iii at: ${c.dim(iiiBin)} (v${c.accent(IIPINNED_VERSION)})`);
1376
1363
  process.env["PATH"] = `${dirname(iiiBin)}${delimiter}${process.env["PATH"] ?? ""}`;
1377
1364
  }
1378
1365
  return startIiiBin(iiiBin, configPath);
@@ -1545,17 +1532,17 @@ function printReadyHint(consoleState) {
1545
1532
  const engineHost = getEngineHost();
1546
1533
  const streamUrl = `ws://${engineHost}:${getStreamPort()}`;
1547
1534
  const engineUrl = `ws://${engineHost}:${getEnginePort()}`;
1548
- const consoleLine = consoleState.kind === "installed" ? `iii console ${consoleState.binPath} (run: ${consoleState.binPath} -p <port>)` : `iii console (install: ${iiiConsoleInstallHint()})`;
1535
+ const consoleLine = consoleState.kind === "installed" ? `${c.label("iii console")} ${c.dim(consoleState.binPath)} ${c.dim(`(run: ${consoleState.binPath} -p <port>)`)}` : `${c.label("iii console")} ${c.dim(`(install: ${iiiConsoleInstallHint()})`)}`;
1549
1536
  const lines = [
1550
- `REST API ${restUrl}`,
1551
- `Viewer ${viewerUrl}`,
1552
- `Streams ${streamUrl}`,
1553
- `Engine ${engineUrl}`,
1537
+ `${c.label("REST API")} ${c.url(restUrl)}`,
1538
+ `${c.label("Viewer")} ${c.url(viewerUrl)}`,
1539
+ `${c.label("Streams")} ${c.url(streamUrl)}`,
1540
+ `${c.label("Engine")} ${c.url(engineUrl)}`,
1554
1541
  consoleLine
1555
1542
  ];
1556
- p.note(lines.join("\n"), `agentmemory v${VERSION}`);
1543
+ p.note(lines.join("\n"), `agentmemory v${c.accent(VERSION)}`);
1557
1544
  const demoCommand = isInvokedViaNpx() ? "npx @agentmemory/agentmemory demo" : "agentmemory demo";
1558
- process.stdout.write(`\nTry: ${demoCommand}\n`);
1545
+ process.stdout.write(`\n${c.dim("Try:")} ${c.cmd(demoCommand)}\n`);
1559
1546
  }
1560
1547
  async function main() {
1561
1548
  if (IS_RESET) resetPrefs();
@@ -1565,7 +1552,7 @@ async function main() {
1565
1552
  if (firstRun || IS_RESET) await runOnboarding();
1566
1553
  if (skipEngine) {
1567
1554
  if (IS_VERBOSE) p.log.info("Skipping engine check (--no-engine)");
1568
- await import("./src-MOg2zKJs.mjs");
1555
+ await import("./src-CzgoepGU.mjs");
1569
1556
  if (await waitForAgentmemoryReady(15e3)) {
1570
1557
  const consoleState = await ensureIiiConsole();
1571
1558
  await maybeOfferGlobalInstall();
@@ -1577,21 +1564,38 @@ async function main() {
1577
1564
  if (IS_VERBOSE) p.log.success("iii-engine is running");
1578
1565
  const persisted = readEngineState();
1579
1566
  const attachedBin = (persisted?.kind === "native" && persisted.binPath && existsSync(persisted.binPath) ? persisted.binPath : null) ?? whichBinary("iii") ?? fallbackIiiPaths().find((p) => existsSync(p)) ?? null;
1580
- if (attachedBin) {
1581
- const detected = iiiBinVersion(attachedBin);
1582
- if (detected && detected !== IIPINNED_VERSION) {
1583
- 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.`);
1584
- process.exit(1);
1567
+ const detected = attachedBin ? iiiBinVersion(attachedBin) : null;
1568
+ if (detected === IIPINNED_VERSION) {
1569
+ adoptRunningEngine();
1570
+ await import("./src-CzgoepGU.mjs");
1571
+ if (await waitForAgentmemoryReady(15e3)) {
1572
+ const consoleState = await ensureIiiConsole();
1573
+ await maybeOfferGlobalInstall();
1574
+ printReadyHint(consoleState);
1585
1575
  }
1576
+ return;
1586
1577
  }
1587
- adoptRunningEngine();
1588
- await import("./src-MOg2zKJs.mjs");
1589
- if (await waitForAgentmemoryReady(15e3)) {
1590
- const consoleState = await ensureIiiConsole();
1591
- await maybeOfferGlobalInstall();
1592
- printReadyHint(consoleState);
1593
- }
1594
- return;
1578
+ const detectedLabel = detected ? `v${detected}` : "an unverified version";
1579
+ const base = isInvokedViaNpx() ? "npx @agentmemory/agentmemory" : "agentmemory";
1580
+ p.log.error(`Another iii-engine (${detectedLabel}) is running on port ${getEnginePort()}, and agentmemory needs its own pinned v${IIPINNED_VERSION}.`);
1581
+ p.note([
1582
+ `agentmemory only supports iii-engine v${IIPINNED_VERSION}. It will not adopt or change the running engine (${detectedLabel}).`,
1583
+ "",
1584
+ c.label("Switch to the pinned engine in two steps:"),
1585
+ "",
1586
+ ` 1. Stop the running engine:`,
1587
+ ` ${c.cmd(`${base} stop --force`)}`,
1588
+ ` ${c.dim(`(or stop your own iii however you started it — agentmemory leaves your global iii untouched)`)}`,
1589
+ "",
1590
+ ` 2. Start agentmemory. It downloads and runs the pinned`,
1591
+ ` v${IIPINNED_VERSION} into ~/.agentmemory/bin automatically:`,
1592
+ ` ${c.cmd(base)}`,
1593
+ "",
1594
+ c.dim(`Step 2 needs no manual install. To install iii v${IIPINNED_VERSION} yourself (replaces your global iii), curl:`),
1595
+ ` ${c.cmd(III_CONSOLE_INSTALL_CMD)}`,
1596
+ ` ${c.dim("or download the release:")} ${c.url(`https://github.com/iii-hq/iii/releases/tag/iii%2Fv${IIPINNED_VERSION}`)}`
1597
+ ].join("\n"), "engine conflict");
1598
+ process.exit(1);
1595
1599
  }
1596
1600
  if (!await startEngine()) {
1597
1601
  p.log.error("Could not start iii-engine.");
@@ -1633,8 +1637,8 @@ async function main() {
1633
1637
  }
1634
1638
  process.exit(1);
1635
1639
  }
1636
- s.stop("iii-engine is ready");
1637
- await import("./src-MOg2zKJs.mjs");
1640
+ s.stop(c.ok("iii-engine is ready"));
1641
+ await import("./src-CzgoepGU.mjs");
1638
1642
  if (await waitForAgentmemoryReady(15e3)) {
1639
1643
  const consoleState = await ensureIiiConsole();
1640
1644
  await maybeOfferGlobalInstall();
@@ -1692,7 +1696,7 @@ async function runStatus() {
1692
1696
  const pctSaved = estFullTokens > 0 ? Math.round(tokensSaved / estFullTokens * 100) : 0;
1693
1697
  p.log.success(`Connected — v${version} at ${base}`);
1694
1698
  const lines = [
1695
- `Health: ${status === "healthy" ? "✓ healthy" : status}`,
1699
+ `Health: ${status === "healthy" ? pc.green("✓ healthy") : pc.yellow(status)}`,
1696
1700
  `Sessions: ${sessions}`,
1697
1701
  `Observations: ${obsCount}`,
1698
1702
  `Memories: ${memCount}`,
@@ -1700,7 +1704,7 @@ async function runStatus() {
1700
1704
  `Circuit: ${cb}`,
1701
1705
  `Heap: ${heapMB} MB`,
1702
1706
  `Uptime: ${uptime}s`,
1703
- `Viewer: ${getViewerUrl()}`
1707
+ `Viewer: ${c.url(getViewerUrl())}`
1704
1708
  ];
1705
1709
  if (obsCount > 0) {
1706
1710
  lines.push("");
@@ -1709,9 +1713,9 @@ async function runStatus() {
1709
1713
  lines.push(` Injected: ~${estInjectedTokens.toLocaleString()} tokens`);
1710
1714
  }
1711
1715
  if (flagsRes) {
1712
- const provider = flagsRes.provider === "llm" ? "✓ llm" : "✗ noop (no key)";
1713
- const embed = flagsRes.embeddingProvider === "embeddings" ? "✓ embeddings" : "bm25-only";
1714
- const flagRows = (flagsRes.flags || []).map((f) => ` ${f.enabled ? "✓" : "✗"} ${f.key.padEnd(32)} ${f.label}`);
1716
+ const provider = flagsRes.provider === "llm" ? pc.green("✓ llm") : pc.yellow("✗ noop (no key)");
1717
+ const embed = flagsRes.embeddingProvider === "embeddings" ? pc.green("✓ embeddings") : pc.dim("bm25-only");
1718
+ const flagRows = (flagsRes.flags || []).map((f) => ` ${f.enabled ? pc.green("✓") : pc.dim("✗")} ${pc.bold(f.key.padEnd(32))} ${f.label}`);
1715
1719
  lines.push("");
1716
1720
  lines.push(`Provider: ${provider}`);
1717
1721
  lines.push(`Embeddings: ${embed}`);
@@ -1732,7 +1736,7 @@ async function runStatus() {
1732
1736
  }
1733
1737
  }
1734
1738
  function formatChecks(checks) {
1735
- return checks.map((c) => `${c.ok ? "✓" : "✗"} ${c.name}${c.hint ? `\n ${c.hint}` : ""}`).join("\n");
1739
+ return checks.map((c) => `${c.ok ? pc.green("✓") : pc.red("✗")} ${c.name}${c.hint ? `\n ${c.hint}` : ""}`).join("\n");
1736
1740
  }
1737
1741
  function findLatestDebugLog(debugDir) {
1738
1742
  const latestLink = join(debugDir, "latest");
@@ -2268,15 +2272,63 @@ async function runInit() {
2268
2272
  ].join("\n"), "Next steps");
2269
2273
  p.outro(`Edit ${target} and you're set.`);
2270
2274
  }
2275
+ async function startServerForDemo() {
2276
+ if (await isAgentmemoryReady()) return async () => {};
2277
+ const startedEngine = !await isEngineRunning();
2278
+ if (startedEngine) {
2279
+ if (!await startEngine()) {
2280
+ p.log.error("Could not start iii-engine for the demo.");
2281
+ p.note(installInstructions().join("\n"), "Setup required");
2282
+ process.exit(1);
2283
+ }
2284
+ if (!await waitForEngine(15e3)) {
2285
+ p.log.error("iii-engine did not become ready within 15s.");
2286
+ process.exit(1);
2287
+ }
2288
+ }
2289
+ await import("./src-CzgoepGU.mjs");
2290
+ if (!await waitForAgentmemoryReady(15e3)) {
2291
+ p.log.error("agentmemory worker did not become ready within 15s.");
2292
+ process.exit(1);
2293
+ }
2294
+ return async () => {
2295
+ if (!startedEngine) return;
2296
+ const port = getRestPort();
2297
+ const state = readEngineState();
2298
+ if (state?.kind === "docker") {
2299
+ await stopDockerEngine(state.composeFile, port).catch(() => {});
2300
+ return;
2301
+ }
2302
+ const pids = new Set(findEnginePidsByPort(port));
2303
+ const pidfilePid = readEnginePidfile();
2304
+ if (pidfilePid) pids.add(pidfilePid);
2305
+ for (const pid of pids) await signalAndWait(pid, "SIGTERM", 3e3).catch(() => {});
2306
+ clearEnginePidfile();
2307
+ clearEngineState();
2308
+ clearWorkerPidfile();
2309
+ };
2310
+ }
2271
2311
  async function runDemo() {
2272
2312
  const port = getRestPort();
2273
2313
  const base = `http://localhost:${port}`;
2274
2314
  p.intro("agentmemory demo");
2275
- if (!await isAgentmemoryReady()) {
2315
+ const serve = args.includes("--serve");
2316
+ let teardown = async () => {};
2317
+ if (serve) teardown = await startServerForDemo();
2318
+ else if (!await isAgentmemoryReady()) {
2276
2319
  p.log.error(`agentmemory worker not reachable on port ${port} (livez probe failed). Something may be on the port but it isn't serving /agentmemory/*.`);
2277
2320
  p.log.info("Start it with: npx @agentmemory/agentmemory");
2321
+ p.log.info("Or run a one-command demo with: npx @agentmemory/agentmemory demo --serve");
2278
2322
  process.exit(1);
2279
2323
  }
2324
+ try {
2325
+ await runDemoBody(base);
2326
+ } finally {
2327
+ await teardown();
2328
+ }
2329
+ if (serve) process.exit(0);
2330
+ }
2331
+ async function runDemoBody(base) {
2280
2332
  const demoProject = "/tmp/agentmemory-demo";
2281
2333
  const sessions = buildDemoSessions();
2282
2334
  const sSeed = p.spinner();
@@ -2298,14 +2350,14 @@ async function runDemo() {
2298
2350
  `Project: ${demoProject}`,
2299
2351
  `Sessions: ${sessions.length} seeded (${totalObs} observations)`,
2300
2352
  "",
2301
- "Search results:",
2302
- ...results.flatMap((r) => [` "${r.query}"`, ` → ${r.hits} hit(s), top: ${r.topTitle.slice(0, 60)}`]),
2353
+ c.label("Search results:"),
2354
+ ...results.flatMap((r) => [` ${c.label(`"${r.query}"`)}`, ` ${c.dim("→")} ${c.ok(`${r.hits} hit(s)`)}, top: ${r.topTitle.slice(0, 60)}`]),
2303
2355
  "",
2304
- `Notice: searching "database performance optimization"`,
2305
- `found the N+1 query fix — keyword matching can't do that.`,
2356
+ c.accent(`Notice: searching "database performance optimization"`),
2357
+ c.accent(`found the N+1 query fix — keyword matching can't do that.`),
2306
2358
  "",
2307
- `Viewer: ${getViewerUrl()}`,
2308
- `Clean up with: curl -X DELETE "${base}/agentmemory/sessions?project=${demoProject}"`
2359
+ `Viewer: ${c.url(getViewerUrl())}`,
2360
+ `Clean up with: ${c.dim(`curl -X DELETE "${base}/agentmemory/sessions?project=${demoProject}"`)}`
2309
2361
  ];
2310
2362
  p.note(lines.join("\n"), "demo complete");
2311
2363
  p.log.success("agentmemory is working. Point your agent at it and get back to coding.");
@@ -2319,7 +2371,7 @@ function runCommand(command, commandArgs, options = { label: "command" }) {
2319
2371
  encoding: "utf-8"
2320
2372
  });
2321
2373
  if (result.status === 0) {
2322
- spinner.stop(`${options.label} ✓`);
2374
+ spinner.stop(`${options.label} ${pc.green("✓")}`);
2323
2375
  return true;
2324
2376
  }
2325
2377
  const stderr = (result.stderr || "").toString().trim();
@@ -2330,7 +2382,7 @@ function runCommand(command, commandArgs, options = { label: "command" }) {
2330
2382
  p.log.warn(msg.slice(0, 300));
2331
2383
  return false;
2332
2384
  }
2333
- spinner.stop(`${options.label} ✗`);
2385
+ spinner.stop(`${options.label} ${pc.red("✗")}`);
2334
2386
  p.log.error(msg.slice(0, 300));
2335
2387
  return false;
2336
2388
  }
@@ -2567,10 +2619,10 @@ async function runStop() {
2567
2619
  p.outro("Stopped. Memories persisted to disk; restart anytime with: npx @agentmemory/agentmemory");
2568
2620
  }
2569
2621
  async function runMcp() {
2570
- await import("./standalone-BORXC71-.mjs");
2622
+ await import("./standalone-YsZFFQBM.mjs");
2571
2623
  }
2572
2624
  async function runConnectCmd() {
2573
- const { runConnect } = await import("./connect-bmZ5eqYN.mjs").then((n) => n.t);
2625
+ const { runConnect } = await import("./connect-JnsJXc68.mjs").then((n) => n.n);
2574
2626
  await runConnect(args.slice(1));
2575
2627
  }
2576
2628
  async function runImportJsonl() {