@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.
- package/AGENTS.md +5 -5
- package/README.md +97 -37
- package/dist/cli.d.mts.map +1 -1
- package/dist/cli.mjs +206 -154
- package/dist/cli.mjs.map +1 -1
- package/dist/config-ChC9EtgV.mjs +259 -0
- package/dist/config-ChC9EtgV.mjs.map +1 -0
- package/dist/{connect-bmZ5eqYN.mjs → connect-JnsJXc68.mjs} +136 -42
- package/dist/connect-JnsJXc68.mjs.map +1 -0
- package/dist/hooks/notification.mjs +2 -1
- package/dist/hooks/notification.mjs.map +1 -1
- package/dist/hooks/post-commit.mjs +2 -1
- package/dist/hooks/post-commit.mjs.map +1 -1
- package/dist/hooks/post-tool-failure.mjs +2 -1
- package/dist/hooks/post-tool-failure.mjs.map +1 -1
- package/dist/hooks/post-tool-use.mjs +2 -1
- package/dist/hooks/post-tool-use.mjs.map +1 -1
- package/dist/hooks/pre-compact.mjs +2 -1
- package/dist/hooks/pre-compact.mjs.map +1 -1
- package/dist/hooks/pre-tool-use.mjs +2 -1
- package/dist/hooks/pre-tool-use.mjs.map +1 -1
- package/dist/hooks/prompt-submit.mjs +2 -1
- package/dist/hooks/prompt-submit.mjs.map +1 -1
- package/dist/hooks/session-end.mjs +2 -1
- package/dist/hooks/session-end.mjs.map +1 -1
- package/dist/hooks/session-start.mjs +2 -1
- package/dist/hooks/session-start.mjs.map +1 -1
- package/dist/hooks/stop.mjs +2 -1
- package/dist/hooks/stop.mjs.map +1 -1
- package/dist/hooks/subagent-start.mjs +2 -1
- package/dist/hooks/subagent-start.mjs.map +1 -1
- package/dist/hooks/subagent-stop.mjs +2 -1
- package/dist/hooks/subagent-stop.mjs.map +1 -1
- package/dist/hooks/task-completed.mjs +2 -1
- package/dist/hooks/task-completed.mjs.map +1 -1
- package/dist/image-refs-BKLmp_sD.mjs +34 -0
- package/dist/image-refs-BKLmp_sD.mjs.map +1 -0
- package/dist/{image-refs-B5Zf_Djo.mjs → image-refs-C2YU7BIm.mjs} +3 -21
- package/dist/image-refs-C2YU7BIm.mjs.map +1 -0
- package/dist/index.mjs +118 -150
- package/dist/index.mjs.map +1 -1
- package/dist/{image-store-Gpo2mgM9.mjs → keyed-mutex-DTHtcZrt.mjs} +14 -11
- package/dist/keyed-mutex-DTHtcZrt.mjs.map +1 -0
- package/dist/{logger-yHTcEBAI.mjs → logger-BEB7pCI9.mjs} +1 -1
- package/dist/{logger-yHTcEBAI.mjs.map → logger-BEB7pCI9.mjs.map} +1 -1
- package/dist/{src-MOg2zKJs.mjs → src-CzgoepGU.mjs} +49 -30
- package/dist/src-CzgoepGU.mjs.map +1 -0
- package/dist/{standalone-BORXC71-.mjs → standalone-YsZFFQBM.mjs} +7 -4
- package/dist/standalone-YsZFFQBM.mjs.map +1 -0
- package/dist/standalone.d.mts.map +1 -1
- package/dist/standalone.mjs +6 -2
- package/dist/standalone.mjs.map +1 -1
- package/dist/{tools-registry-D8XVVPbJ.mjs → tools-registry-D3NEoe5m.mjs} +4 -256
- package/dist/tools-registry-D3NEoe5m.mjs.map +1 -0
- package/package.json +4 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/plugin.json +2 -2
- package/plugin/scripts/notification.mjs +2 -1
- package/plugin/scripts/notification.mjs.map +1 -1
- package/plugin/scripts/post-commit.mjs +2 -1
- package/plugin/scripts/post-commit.mjs.map +1 -1
- package/plugin/scripts/post-tool-failure.mjs +2 -1
- package/plugin/scripts/post-tool-failure.mjs.map +1 -1
- package/plugin/scripts/post-tool-use.mjs +2 -1
- package/plugin/scripts/post-tool-use.mjs.map +1 -1
- package/plugin/scripts/pre-compact.mjs +2 -1
- package/plugin/scripts/pre-compact.mjs.map +1 -1
- package/plugin/scripts/pre-tool-use.mjs +2 -1
- package/plugin/scripts/pre-tool-use.mjs.map +1 -1
- package/plugin/scripts/prompt-submit.mjs +2 -1
- package/plugin/scripts/prompt-submit.mjs.map +1 -1
- package/plugin/scripts/session-end.mjs +2 -1
- package/plugin/scripts/session-end.mjs.map +1 -1
- package/plugin/scripts/session-start.mjs +2 -1
- package/plugin/scripts/session-start.mjs.map +1 -1
- package/plugin/scripts/stop.mjs +2 -1
- package/plugin/scripts/stop.mjs.map +1 -1
- package/plugin/scripts/subagent-start.mjs +2 -1
- package/plugin/scripts/subagent-start.mjs.map +1 -1
- package/plugin/scripts/subagent-stop.mjs +2 -1
- package/plugin/scripts/subagent-stop.mjs.map +1 -1
- package/plugin/scripts/task-completed.mjs +2 -1
- package/plugin/scripts/task-completed.mjs.map +1 -1
- package/plugin/skills/_shared/TROUBLESHOOTING.md +38 -0
- package/plugin/skills/agentmemory-agents/REFERENCE.md +28 -0
- package/plugin/skills/agentmemory-agents/SKILL.md +34 -0
- package/plugin/skills/agentmemory-architecture/SKILL.md +33 -0
- package/plugin/skills/agentmemory-config/REFERENCE.md +42 -0
- package/plugin/skills/agentmemory-config/SKILL.md +37 -0
- package/plugin/skills/agentmemory-hooks/REFERENCE.md +20 -0
- package/plugin/skills/agentmemory-hooks/SKILL.md +39 -0
- package/plugin/skills/agentmemory-mcp-tools/REFERENCE.md +65 -0
- package/plugin/skills/agentmemory-mcp-tools/SKILL.md +39 -0
- package/plugin/skills/agentmemory-rest-api/REFERENCE.md +129 -0
- package/plugin/skills/agentmemory-rest-api/SKILL.md +43 -0
- package/plugin/skills/commit-context/EXAMPLES.md +71 -0
- package/plugin/skills/commit-context/SKILL.md +53 -8
- package/plugin/skills/commit-history/EXAMPLES.md +71 -0
- package/plugin/skills/commit-history/SKILL.md +51 -9
- package/plugin/skills/forget/EXAMPLES.md +75 -0
- package/plugin/skills/forget/SKILL.md +54 -14
- package/plugin/skills/handoff/EXAMPLES.md +56 -0
- package/plugin/skills/handoff/SKILL.md +56 -9
- package/plugin/skills/recall/EXAMPLES.md +74 -0
- package/plugin/skills/recall/SKILL.md +50 -11
- package/plugin/skills/recap/EXAMPLES.md +60 -0
- package/plugin/skills/recap/SKILL.md +51 -13
- package/plugin/skills/remember/EXAMPLES.md +67 -0
- package/plugin/skills/remember/SKILL.md +53 -17
- package/plugin/skills/session-history/EXAMPLES.md +59 -0
- package/plugin/skills/session-history/SKILL.md +54 -11
- package/plugin/skills/write-agentmemory-skill/SKILL.md +40 -0
- package/dist/connect-bmZ5eqYN.mjs.map +0 -1
- package/dist/image-refs-B5Zf_Djo.mjs.map +0 -1
- package/dist/image-store-Gpo2mgM9.mjs.map +0 -1
- package/dist/rolldown-runtime-twds-ZHy.mjs +0 -14
- package/dist/src-MOg2zKJs.mjs.map +0 -1
- package/dist/standalone-BORXC71-.mjs.map +0 -1
- package/dist/tools-registry-D8XVVPbJ.mjs.map +0 -1
- package/dist/version-9DNrRyph.mjs +0 -6
- 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 {
|
|
4
|
-
import {
|
|
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
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
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
|
-
|
|
618
|
-
value: a.
|
|
619
|
-
label: `${a.
|
|
620
|
-
hint: "native plugin"
|
|
621
|
-
}))
|
|
622
|
-
|
|
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
|
|
853
|
-
|
|
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
|
|
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 =
|
|
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])
|
|
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.
|
|
1192
|
-
], { label: `Installing @agentmemory/agentmemory@0.9.
|
|
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" ?
|
|
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
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
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(`\
|
|
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-
|
|
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
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
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
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
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-
|
|
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
|
-
|
|
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-
|
|
2622
|
+
await import("./standalone-YsZFFQBM.mjs");
|
|
2571
2623
|
}
|
|
2572
2624
|
async function runConnectCmd() {
|
|
2573
|
-
const { runConnect } = await import("./connect-
|
|
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() {
|