myagentmemory 0.4.16 → 0.5.1
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/LICENSE +1 -0
- package/README.md +78 -68
- package/dist/cli-spec.d.ts +7 -1
- package/dist/cli-spec.js +226 -12
- package/dist/cli.js +2140 -182
- package/dist/completions.js +24 -18
- package/dist/core.d.ts +42 -4
- package/dist/core.js +242 -68
- package/dist/hooks.d.ts +21 -1
- package/dist/hooks.js +382 -87
- package/dist/mcp-server.d.ts +27 -0
- package/dist/mcp-server.js +106 -0
- package/dist/plugin-bootstrap.js +6 -6
- package/dist/plugin-host.d.ts +51 -0
- package/dist/plugin-runtime.d.ts +20 -1
- package/dist/plugin-runtime.js +83 -2
- package/dist/plugin-service.d.ts +10 -4
- package/dist/plugin-service.js +83 -42
- package/dist/upgrade.d.ts +80 -0
- package/dist/upgrade.js +243 -0
- package/docs/official-plugin-bootstrap.md +30 -22
- package/package.json +24 -4
- package/scripts/install-skills.sh +1 -1
- package/skills/agent/SKILL.md +12 -2
- package/skills/claude-code/SKILL.md +17 -2
- package/skills/codex/SKILL.md +14 -2
- package/skills/cursor/SKILL.md +14 -2
- package/src/cli-spec.ts +230 -12
- package/src/completions.ts +26 -18
- package/src/core.ts +312 -123
- package/src/hooks.ts +395 -85
- package/src/plugin-bootstrap.ts +6 -6
- package/src/plugin-host.ts +53 -0
- package/src/cli.ts +0 -1271
- package/src/plugin-runtime.ts +0 -326
- package/src/plugin-service.ts +0 -628
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Upgrade orchestration for the `agent-memory` CLI and its official Pro plugin bundle.
|
|
3
|
+
*
|
|
4
|
+
* Two consumers:
|
|
5
|
+
* 1. `agent-memory upgrade` — explicit user command; checks and (optionally) installs.
|
|
6
|
+
* 2. `agent-memory hook session-start` — passive notice from a 24h-cached record.
|
|
7
|
+
*
|
|
8
|
+
* Network calls always have a hard timeout and always fail closed (upgrade is a
|
|
9
|
+
* quality-of-life feature; a flaky registry must never break the CLI).
|
|
10
|
+
*/
|
|
11
|
+
import { type SpawnOptions } from "node:child_process";
|
|
12
|
+
export type InstallManager = "bun" | "npm" | "pnpm" | "yarn" | "unknown";
|
|
13
|
+
export interface InstallMethod {
|
|
14
|
+
manager: InstallManager;
|
|
15
|
+
global: boolean;
|
|
16
|
+
/** Absolute path we think holds the current install (for diagnostics). */
|
|
17
|
+
origin: string;
|
|
18
|
+
/** Argv used to invoke the package manager (e.g. ["npm","i","-g","myagentmemory@latest"]). */
|
|
19
|
+
command: string[];
|
|
20
|
+
}
|
|
21
|
+
export interface UpgradeCache {
|
|
22
|
+
checkedAt: string;
|
|
23
|
+
cliCurrent: string;
|
|
24
|
+
cliLatest: string | null;
|
|
25
|
+
pluginCurrent: string | null;
|
|
26
|
+
pluginLatest: string | null;
|
|
27
|
+
}
|
|
28
|
+
export interface UpgradeStatus {
|
|
29
|
+
cli: {
|
|
30
|
+
current: string;
|
|
31
|
+
latest: string | null;
|
|
32
|
+
upgradeAvailable: boolean;
|
|
33
|
+
};
|
|
34
|
+
plugin: {
|
|
35
|
+
current: string | null;
|
|
36
|
+
latest: string | null;
|
|
37
|
+
upgradeAvailable: boolean;
|
|
38
|
+
};
|
|
39
|
+
checkedAt: string;
|
|
40
|
+
fromCache: boolean;
|
|
41
|
+
}
|
|
42
|
+
export declare function readUpgradeCache(): UpgradeCache | null;
|
|
43
|
+
export declare function writeUpgradeCache(record: UpgradeCache): void;
|
|
44
|
+
export declare function isCacheFresh(record: UpgradeCache | null, now?: number): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Best-effort detection of how `myagentmemory` was installed. Path signatures
|
|
47
|
+
* are heuristic but cover the common managers. On no match we fall back to
|
|
48
|
+
* `npm -g` per the user's choice ("best-effort try anyway").
|
|
49
|
+
*/
|
|
50
|
+
export declare function detectInstallMethod(location?: string): InstallMethod;
|
|
51
|
+
export interface InstallResult {
|
|
52
|
+
ok: boolean;
|
|
53
|
+
code: number | null;
|
|
54
|
+
stdout: string;
|
|
55
|
+
stderr: string;
|
|
56
|
+
command: string[];
|
|
57
|
+
}
|
|
58
|
+
export declare function runInstaller(method: InstallMethod, opts?: SpawnOptions): InstallResult;
|
|
59
|
+
/**
|
|
60
|
+
* Fire-and-forget: spawn a detached child that runs `agent-memory upgrade
|
|
61
|
+
* --check --refresh --quiet` so the next session-start has a fresh cache.
|
|
62
|
+
* Never awaits, never throws.
|
|
63
|
+
*/
|
|
64
|
+
export declare function refreshUpgradeCacheBackground(): void;
|
|
65
|
+
export interface CheckOptions {
|
|
66
|
+
cliCurrent: string;
|
|
67
|
+
pluginCurrent: string | null;
|
|
68
|
+
/** When true, do NOT hit the network — read cache only. Returns fromCache=true even on miss. */
|
|
69
|
+
cacheOnly?: boolean;
|
|
70
|
+
/** When true, force a network refresh and rewrite the cache regardless of freshness. */
|
|
71
|
+
refresh?: boolean;
|
|
72
|
+
/** Optional injected npm fetcher (used by tests). */
|
|
73
|
+
fetchCliLatest?: () => Promise<string | null>;
|
|
74
|
+
/** Optional injected plugin-latest resolver. When omitted, plugin latest is taken from pluginLatestHint. */
|
|
75
|
+
pluginLatestHint?: string | null;
|
|
76
|
+
/** Explicit signal from the bootstrap that a newer release exists even when the version number is unknown. */
|
|
77
|
+
pluginUpgradeAvailable?: boolean;
|
|
78
|
+
}
|
|
79
|
+
export declare function checkForUpgrades(opts: CheckOptions): Promise<UpgradeStatus>;
|
|
80
|
+
export declare function formatUpgradeNotice(status: UpgradeStatus): string | null;
|
package/dist/upgrade.js
ADDED
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Upgrade orchestration for the `agent-memory` CLI and its official Pro plugin bundle.
|
|
3
|
+
*
|
|
4
|
+
* Two consumers:
|
|
5
|
+
* 1. `agent-memory upgrade` — explicit user command; checks and (optionally) installs.
|
|
6
|
+
* 2. `agent-memory hook session-start` — passive notice from a 24h-cached record.
|
|
7
|
+
*
|
|
8
|
+
* Network calls always have a hard timeout and always fail closed (upgrade is a
|
|
9
|
+
* quality-of-life feature; a flaky registry must never break the CLI).
|
|
10
|
+
*/
|
|
11
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
12
|
+
import * as fs from "node:fs";
|
|
13
|
+
import * as os from "node:os";
|
|
14
|
+
import * as path from "node:path";
|
|
15
|
+
import * as url from "node:url";
|
|
16
|
+
import { getMemoryDir } from "./core.js";
|
|
17
|
+
import { compareVersions } from "./plugin-bootstrap.js";
|
|
18
|
+
const NPM_PACKAGE_NAME = "myagentmemory";
|
|
19
|
+
const NPM_LATEST_URL = `https://registry.npmjs.org/${NPM_PACKAGE_NAME}/latest`;
|
|
20
|
+
const CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24h
|
|
21
|
+
const FETCH_TIMEOUT_MS = 1_500;
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
// npm registry lookup
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
async function fetchLatestFromNpm(fetchImpl = globalThis.fetch) {
|
|
26
|
+
try {
|
|
27
|
+
const controller = new AbortController();
|
|
28
|
+
const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
|
|
29
|
+
try {
|
|
30
|
+
const response = await fetchImpl(NPM_LATEST_URL, {
|
|
31
|
+
signal: controller.signal,
|
|
32
|
+
headers: { accept: "application/json" },
|
|
33
|
+
});
|
|
34
|
+
if (!response.ok)
|
|
35
|
+
return null;
|
|
36
|
+
const body = (await response.json());
|
|
37
|
+
return typeof body.version === "string" ? body.version : null;
|
|
38
|
+
}
|
|
39
|
+
finally {
|
|
40
|
+
clearTimeout(timer);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
// Cache
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
function upgradeCachePath() {
|
|
51
|
+
return path.join(getMemoryDir(), "state", "upgrade-check.json");
|
|
52
|
+
}
|
|
53
|
+
export function readUpgradeCache() {
|
|
54
|
+
try {
|
|
55
|
+
const raw = fs.readFileSync(upgradeCachePath(), "utf-8");
|
|
56
|
+
const parsed = JSON.parse(raw);
|
|
57
|
+
if (typeof parsed.checkedAt !== "string" ||
|
|
58
|
+
typeof parsed.cliCurrent !== "string" ||
|
|
59
|
+
(parsed.cliLatest !== null && typeof parsed.cliLatest !== "string") ||
|
|
60
|
+
(parsed.pluginCurrent !== null &&
|
|
61
|
+
typeof parsed.pluginCurrent !== "string" &&
|
|
62
|
+
parsed.pluginCurrent !== undefined) ||
|
|
63
|
+
(parsed.pluginLatest !== null && typeof parsed.pluginLatest !== "string" && parsed.pluginLatest !== undefined)) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
checkedAt: parsed.checkedAt,
|
|
68
|
+
cliCurrent: parsed.cliCurrent,
|
|
69
|
+
cliLatest: parsed.cliLatest ?? null,
|
|
70
|
+
pluginCurrent: parsed.pluginCurrent ?? null,
|
|
71
|
+
pluginLatest: parsed.pluginLatest ?? null,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
export function writeUpgradeCache(record) {
|
|
79
|
+
const file = upgradeCachePath();
|
|
80
|
+
try {
|
|
81
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
82
|
+
fs.writeFileSync(file, `${JSON.stringify(record, null, 2)}\n`);
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
// Cache write failures are non-fatal.
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
export function isCacheFresh(record, now = Date.now()) {
|
|
89
|
+
if (!record)
|
|
90
|
+
return false;
|
|
91
|
+
const checked = Date.parse(record.checkedAt);
|
|
92
|
+
if (!Number.isFinite(checked))
|
|
93
|
+
return false;
|
|
94
|
+
return now - checked < CACHE_TTL_MS;
|
|
95
|
+
}
|
|
96
|
+
// ---------------------------------------------------------------------------
|
|
97
|
+
// Install-method detection
|
|
98
|
+
// ---------------------------------------------------------------------------
|
|
99
|
+
function selfInstallPath() {
|
|
100
|
+
try {
|
|
101
|
+
return url.fileURLToPath(import.meta.url);
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return process.argv[1] ?? "";
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Best-effort detection of how `myagentmemory` was installed. Path signatures
|
|
109
|
+
* are heuristic but cover the common managers. On no match we fall back to
|
|
110
|
+
* `npm -g` per the user's choice ("best-effort try anyway").
|
|
111
|
+
*/
|
|
112
|
+
export function detectInstallMethod(location = selfInstallPath()) {
|
|
113
|
+
const normalized = location.replace(/\\/g, "/");
|
|
114
|
+
const home = os.homedir().replace(/\\/g, "/");
|
|
115
|
+
const pkg = `${NPM_PACKAGE_NAME}@latest`;
|
|
116
|
+
// bun global install
|
|
117
|
+
if (normalized.includes("/.bun/install/global/") || normalized.includes("/bun/install/global/")) {
|
|
118
|
+
return { manager: "bun", global: true, origin: location, command: ["bun", "add", "-g", pkg] };
|
|
119
|
+
}
|
|
120
|
+
// pnpm global (Linux, macOS layouts)
|
|
121
|
+
if (normalized.includes("/.local/share/pnpm/global/") ||
|
|
122
|
+
normalized.includes("/Library/pnpm/global/") ||
|
|
123
|
+
normalized.includes("/AppData/Local/pnpm/global/") ||
|
|
124
|
+
normalized.includes("/pnpm-global/")) {
|
|
125
|
+
return { manager: "pnpm", global: true, origin: location, command: ["pnpm", "add", "-g", pkg] };
|
|
126
|
+
}
|
|
127
|
+
// yarn global
|
|
128
|
+
if (normalized.includes("/yarn/global/") || normalized.includes("/.config/yarn/global/")) {
|
|
129
|
+
return { manager: "yarn", global: true, origin: location, command: ["yarn", "global", "add", pkg] };
|
|
130
|
+
}
|
|
131
|
+
// npm global — common prefixes across nvm, homebrew, system node, npm-global override
|
|
132
|
+
const npmGlobalSignatures = ["/lib/node_modules/", "/npm-global/", "/.nvm/versions/node/", "/AppData/Roaming/npm/"];
|
|
133
|
+
if (npmGlobalSignatures.some((sig) => normalized.includes(sig))) {
|
|
134
|
+
return { manager: "npm", global: true, origin: location, command: ["npm", "install", "-g", pkg] };
|
|
135
|
+
}
|
|
136
|
+
// Local checkout, npx cache, or unknown — best-effort with npm -g.
|
|
137
|
+
void home;
|
|
138
|
+
return {
|
|
139
|
+
manager: "unknown",
|
|
140
|
+
global: false,
|
|
141
|
+
origin: location,
|
|
142
|
+
command: ["npm", "install", "-g", pkg],
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
export function runInstaller(method, opts = {}) {
|
|
146
|
+
const [cmd, ...args] = method.command;
|
|
147
|
+
const result = spawnSync(cmd, args, {
|
|
148
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
149
|
+
encoding: "utf-8",
|
|
150
|
+
env: process.env,
|
|
151
|
+
...opts,
|
|
152
|
+
});
|
|
153
|
+
return {
|
|
154
|
+
ok: result.status === 0,
|
|
155
|
+
code: result.status,
|
|
156
|
+
stdout: result.stdout ?? "",
|
|
157
|
+
stderr: result.stderr ?? "",
|
|
158
|
+
command: method.command,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
// ---------------------------------------------------------------------------
|
|
162
|
+
// Passive: refresh cache in background
|
|
163
|
+
// ---------------------------------------------------------------------------
|
|
164
|
+
/**
|
|
165
|
+
* Fire-and-forget: spawn a detached child that runs `agent-memory upgrade
|
|
166
|
+
* --check --refresh --quiet` so the next session-start has a fresh cache.
|
|
167
|
+
* Never awaits, never throws.
|
|
168
|
+
*/
|
|
169
|
+
export function refreshUpgradeCacheBackground() {
|
|
170
|
+
try {
|
|
171
|
+
const binary = process.argv[0];
|
|
172
|
+
const script = process.argv[1];
|
|
173
|
+
if (!binary || !script)
|
|
174
|
+
return;
|
|
175
|
+
const child = spawn(binary, [script, "upgrade", "--check", "--refresh", "--quiet", "--json"], {
|
|
176
|
+
detached: true,
|
|
177
|
+
stdio: "ignore",
|
|
178
|
+
env: { ...process.env, AGENT_MEMORY_UPGRADE_BACKGROUND: "1" },
|
|
179
|
+
});
|
|
180
|
+
child.unref();
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
// Background refresh is best-effort.
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
export async function checkForUpgrades(opts) {
|
|
187
|
+
const cached = readUpgradeCache();
|
|
188
|
+
const fresh = isCacheFresh(cached);
|
|
189
|
+
const useCache = !opts.refresh && (opts.cacheOnly || fresh);
|
|
190
|
+
let cliLatest = null;
|
|
191
|
+
let pluginLatest = null;
|
|
192
|
+
let checkedAt;
|
|
193
|
+
let fromCache = false;
|
|
194
|
+
if (useCache && cached) {
|
|
195
|
+
cliLatest = cached.cliLatest;
|
|
196
|
+
pluginLatest = opts.pluginLatestHint ?? cached.pluginLatest;
|
|
197
|
+
checkedAt = cached.checkedAt;
|
|
198
|
+
fromCache = true;
|
|
199
|
+
}
|
|
200
|
+
else if (opts.cacheOnly) {
|
|
201
|
+
// Cache miss and network is disallowed — return an empty snapshot.
|
|
202
|
+
checkedAt = new Date().toISOString();
|
|
203
|
+
fromCache = true;
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
const fetcher = opts.fetchCliLatest ?? (() => fetchLatestFromNpm());
|
|
207
|
+
cliLatest = await fetcher();
|
|
208
|
+
pluginLatest = opts.pluginLatestHint ?? null;
|
|
209
|
+
checkedAt = new Date().toISOString();
|
|
210
|
+
writeUpgradeCache({
|
|
211
|
+
checkedAt,
|
|
212
|
+
cliCurrent: opts.cliCurrent,
|
|
213
|
+
cliLatest,
|
|
214
|
+
pluginCurrent: opts.pluginCurrent,
|
|
215
|
+
pluginLatest,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
return {
|
|
219
|
+
cli: {
|
|
220
|
+
current: opts.cliCurrent,
|
|
221
|
+
latest: cliLatest,
|
|
222
|
+
upgradeAvailable: Boolean(cliLatest && compareVersions(cliLatest, opts.cliCurrent) > 0),
|
|
223
|
+
},
|
|
224
|
+
plugin: {
|
|
225
|
+
current: opts.pluginCurrent,
|
|
226
|
+
latest: pluginLatest,
|
|
227
|
+
upgradeAvailable: Boolean(opts.pluginUpgradeAvailable) ||
|
|
228
|
+
Boolean(pluginLatest && opts.pluginCurrent && compareVersions(pluginLatest, opts.pluginCurrent) > 0),
|
|
229
|
+
},
|
|
230
|
+
checkedAt,
|
|
231
|
+
fromCache,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
export function formatUpgradeNotice(status) {
|
|
235
|
+
const parts = [];
|
|
236
|
+
if (status.cli.upgradeAvailable)
|
|
237
|
+
parts.push(`CLI ${status.cli.current} → ${status.cli.latest ?? "new"}`);
|
|
238
|
+
if (status.plugin.upgradeAvailable)
|
|
239
|
+
parts.push(`Pro ${status.plugin.current ?? "?"} → ${status.plugin.latest ?? "new"}`);
|
|
240
|
+
if (!parts.length)
|
|
241
|
+
return null;
|
|
242
|
+
return `agent-memory: upgrade available (${parts.join(", ")}). Run: agent-memory upgrade`;
|
|
243
|
+
}
|
|
@@ -2,18 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
## Status
|
|
4
4
|
|
|
5
|
-
Accepted design on 2026-08-16 and revised on 2026-08-17. The public core implements host types,
|
|
5
|
+
Accepted design on 2026-08-16 and revised on 2026-08-17. The public core implements host types, anonymous preview activation, live catalog and artifact retrieval, Ed25519 release verification, bounded package validation, transactional install, bundle health checks, paid-command dispatch, and SessionStart hook dispatch. The free preview grants 20 device-local recalls and 5 device-local learning scans per local day while keeping indexing and Memory Dashboard visibility available. Account authentication, payment, renewal, and account management remain deferred.
|
|
6
6
|
|
|
7
|
-
The public `agentmemory` repository and `myagentmemory` npm package remain the free, MIT-licensed core. The public bootstrap client and host contracts are also MIT-licensed. Official commercial implementations and browser assets are built and distributed separately from the private
|
|
7
|
+
The public `agentmemory` repository and `myagentmemory` npm package remain the free, MIT-licensed core. The public bootstrap client and host contracts are also MIT-licensed. Official commercial implementations and browser assets are built and distributed separately from the private commercial workspace under their own terms. Pricing, the billing provider, device limits, offline-grace duration, and Enterprise contract terms are intentionally not decided here. The temporary beta currently uses allowlisted `*.agentmemory.paperpilot.me` service origins; changing those origins is a public-client release change.
|
|
8
8
|
|
|
9
9
|
## Decision
|
|
10
10
|
|
|
11
11
|
The public core will provide a small bootstrap and host surface for signed first-party plugins. It will not contain paid implementations, browser assets, commercial entitlement logic, or a general third-party marketplace.
|
|
12
12
|
|
|
13
|
-
The primary
|
|
13
|
+
The primary product-facing command is:
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
agent-memory
|
|
16
|
+
agent-memory pro install
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
`plugin install` is an idempotent reconcile operation:
|
|
@@ -23,11 +23,11 @@ agent-memory plugin install
|
|
|
23
23
|
| Plugin absent | Active or grace | Install the compatible signed bundle |
|
|
24
24
|
| Plugin older than the selected release | Active or grace | Upgrade atomically |
|
|
25
25
|
| Plugin current | Active or grace | Report that it is current |
|
|
26
|
-
| Any | Missing |
|
|
26
|
+
| Any | Missing | Request an anonymous free-preview entitlement and signed artifact grant |
|
|
27
27
|
| Any | Expired | Direct the user to renewal; leave core available |
|
|
28
28
|
| Incompatible bundle | Any | Leave the current version untouched and explain the required core version |
|
|
29
29
|
|
|
30
|
-
An absent plugin cannot activate itself. The public bootstrap
|
|
30
|
+
An absent plugin cannot activate itself. The public bootstrap creates a random installation identifier, obtains a server-issued free-preview policy and short-lived artifact grant, and verifies the release and artifact. A mode-0600 activation record is persisted only after the service accepts the request. After installation, the public host reconstructs the free capability policy in core code and checks required capabilities before commands and hooks. Signed long-lived paid entitlements can extend this record when authentication and payment ship.
|
|
31
31
|
|
|
32
32
|
## Ownership boundary
|
|
33
33
|
|
|
@@ -67,6 +67,12 @@ Core memory operations must continue to work when the service is unreachable, a
|
|
|
67
67
|
### Bootstrap commands
|
|
68
68
|
|
|
69
69
|
```text
|
|
70
|
+
agent-memory pro
|
|
71
|
+
agent-memory pro install
|
|
72
|
+
agent-memory pro status
|
|
73
|
+
agent-memory pro upgrade
|
|
74
|
+
agent-memory pro manage
|
|
75
|
+
|
|
70
76
|
agent-memory plugin
|
|
71
77
|
agent-memory plugin list
|
|
72
78
|
agent-memory plugin status
|
|
@@ -76,6 +82,8 @@ agent-memory plugin uninstall [--yes]
|
|
|
76
82
|
agent-memory plugin manage [--no-browser]
|
|
77
83
|
```
|
|
78
84
|
|
|
85
|
+
The `pro` namespace is the user-facing surface. The `plugin` namespace remains supported for low-level administration and compatibility.
|
|
86
|
+
|
|
79
87
|
- `plugin` with no subcommand prints a discovery summary and the next relevant command.
|
|
80
88
|
- `list` reports known official plugins and whether each is installed and available. It does not download artifacts or inspect memory.
|
|
81
89
|
- `status` is read-only. It reports the installed bundle, selected channel, compatibility, entitlement state, and update availability.
|
|
@@ -84,7 +92,7 @@ agent-memory plugin manage [--no-browser]
|
|
|
84
92
|
- `uninstall` removes executable plugin material and the active receipt. It preserves core memory, plugin state, and the permission-restricted activation credential.
|
|
85
93
|
- `manage` remains unavailable until authenticated account and billing management exists.
|
|
86
94
|
|
|
87
|
-
Installed plugins contribute top-level commands
|
|
95
|
+
Installed plugins contribute top-level commands including `recall` and `learn`; `dashboard` is a product-facing alias for the lower-level `web` command. Bootstrap command names are reserved by the core and cannot be replaced by a plugin.
|
|
88
96
|
|
|
89
97
|
The current private compatibility CLI uses `plugin install` and `plugin uninstall` for skill files only. During migration, those meanings move to `install-skills --plugin-only` and `uninstall-skills --plugin-only`; the bootstrap command names above become authoritative.
|
|
90
98
|
|
|
@@ -93,13 +101,13 @@ The current private compatibility CLI uses `plugin install` and `plugin uninstal
|
|
|
93
101
|
After a successful interactive `agent-memory init`, the core may print one informational line:
|
|
94
102
|
|
|
95
103
|
```text
|
|
96
|
-
|
|
97
|
-
Run: agent-memory
|
|
104
|
+
Core remembers what you save. Pro learns from what you do.
|
|
105
|
+
Run: agent-memory pro install
|
|
98
106
|
```
|
|
99
107
|
|
|
100
|
-
Top-level help includes
|
|
108
|
+
Top-level help includes a Pro section. Human-readable `status` may include the same recommendation while Pro is not installed. Routine `context`, `read`, `write`, `search`, and scratchpad commands never show commercial prompts.
|
|
101
109
|
|
|
102
|
-
The
|
|
110
|
+
The free preview does not open a browser or request identity. Browsers remain restricted to explicit `dashboard`, future `pro manage`, and future paid upgrade/authentication flows. Non-interactive and `--json` installs use the same anonymous access request and still fail closed when the commercial service is unavailable.
|
|
103
111
|
|
|
104
112
|
### Machine-readable output
|
|
105
113
|
|
|
@@ -133,17 +141,17 @@ Every bootstrap command supports `--json` and emits one JSON document with a ver
|
|
|
133
141
|
|
|
134
142
|
`result` is one of `not_installed`, `installed`, `upgraded`, `current`, `update_available`, `uninstalled`, `auth_required`, `renewal_required`, or `unavailable`. Failures use `ok: false` plus a stable `error.code` and redacted `error.message`. Output must never contain access tokens, download credentials, signed entitlement contents, local memory paths, or URLs containing bearer credentials.
|
|
135
143
|
|
|
136
|
-
##
|
|
144
|
+
## Anonymous free-preview flow
|
|
137
145
|
|
|
138
|
-
1. `agent-memory
|
|
139
|
-
2. The CLI
|
|
140
|
-
3.
|
|
141
|
-
4. The
|
|
142
|
-
5.
|
|
146
|
+
1. `agent-memory pro install` creates a random installation identifier locally when no activation record exists.
|
|
147
|
+
2. The CLI sends that identifier plus core, installed-bundle, platform, architecture, and release-channel fields to the private control plane. It sends no email, memory, session content, query, repository path, raw agent session identifier, IP address, or user-agent string.
|
|
148
|
+
3. The service stores the pseudonymous identifier and only the hash of a random compatibility credential, then returns a free-preview capability policy and short-lived object-bound artifact grant.
|
|
149
|
+
4. The CLI validates the explicit free policy: local indexing and Memory Dashboard access, 20 device-local recalls per day, 5 device-local learning scans per day, and no free automatic background worker.
|
|
150
|
+
5. Only then does the CLI atomically write a mode-0600 activation record.
|
|
143
151
|
6. The CLI verifies the Ed25519-signed release plus package digest and limits, imports it for health checks, and atomically activates the receipt.
|
|
144
|
-
7.
|
|
152
|
+
7. Device-local quota operations reserve before work, commit after useful work, and release on abstention or failure. A zero-result recall does not consume allowance.
|
|
145
153
|
|
|
146
|
-
|
|
154
|
+
Authentication, payment, renewal, account management, and signed paid entitlements are not implemented yet.
|
|
147
155
|
|
|
148
156
|
## Future authentication and purchase flow
|
|
149
157
|
|
|
@@ -163,12 +171,12 @@ An Enterprise administrator may pre-provision an organization entitlement or man
|
|
|
163
171
|
|
|
164
172
|
The service exposes:
|
|
165
173
|
|
|
166
|
-
- `POST /v1/plugin/access` for
|
|
167
|
-
- `POST /v1/plugin/sessions/reserve|commit|release` for
|
|
174
|
+
- `POST /v1/plugin/access` for an anonymous free-preview policy, compatibility credential, and short-lived artifact grant;
|
|
175
|
+
- `POST /v1/plugin/sessions/reserve|commit|release` for migration compatibility with activation-v2 clients;
|
|
168
176
|
- `GET /v1/plugin/releases` for an Ed25519-signed release selected from the private R2 catalog;
|
|
169
177
|
- `GET|HEAD /v1/artifacts/download` for the exact content-addressed object authorized by the bearer grant.
|
|
170
178
|
|
|
171
|
-
The access request contains
|
|
179
|
+
The access request contains a random installation identifier plus the bounded core, bundle, platform, architecture, and release-channel fields described above. Application payloads contain no email, memory content, search query, session content, path, repository name, raw agent session identifier, qmd data, IP address, or user-agent string. The activation database stores neither IP addresses nor user-agent strings. Future authenticated service responsibilities include:
|
|
172
180
|
|
|
173
181
|
- create and poll a device authorization;
|
|
174
182
|
- read the authenticated principal's effective entitlement;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "myagentmemory",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "agentmemory (agent-memory) is persistent memory for coding agents (Claude Code, OpenAI Codex, Cursor, Agent) with qmd-powered semantic search across daily logs, long-term memory, and scratchpad",
|
|
5
5
|
"main": "./dist/core.js",
|
|
6
6
|
"types": "./dist/core.d.ts",
|
|
@@ -65,9 +65,16 @@
|
|
|
65
65
|
},
|
|
66
66
|
"homepage": "https://github.com/jayzeng/agentmemory#readme",
|
|
67
67
|
"files": [
|
|
68
|
-
"src",
|
|
68
|
+
"src/core.ts",
|
|
69
|
+
"src/cli-spec.ts",
|
|
70
|
+
"src/completions.ts",
|
|
71
|
+
"src/hooks.ts",
|
|
72
|
+
"src/plugin-host.ts",
|
|
73
|
+
"src/plugin-bootstrap.ts",
|
|
69
74
|
"skills",
|
|
70
|
-
"scripts",
|
|
75
|
+
"scripts/install-skills.sh",
|
|
76
|
+
"scripts/install-skills.ps1",
|
|
77
|
+
"scripts/postinstall.cjs",
|
|
71
78
|
"dist/cli.d.ts",
|
|
72
79
|
"dist/cli.js",
|
|
73
80
|
"dist/core.d.ts",
|
|
@@ -86,6 +93,11 @@
|
|
|
86
93
|
"dist/plugin-runtime.js",
|
|
87
94
|
"dist/plugin-service.d.ts",
|
|
88
95
|
"dist/plugin-service.js",
|
|
96
|
+
|
|
97
|
+
"dist/mcp-server.d.ts",
|
|
98
|
+
"dist/mcp-server.js",
|
|
99
|
+
"dist/upgrade.d.ts",
|
|
100
|
+
"dist/upgrade.js",
|
|
89
101
|
"docs/official-plugin-bootstrap.md",
|
|
90
102
|
"README.md",
|
|
91
103
|
"LICENSE"
|
|
@@ -100,13 +112,21 @@
|
|
|
100
112
|
"build:lib": "tsc -p tsconfig.build.json",
|
|
101
113
|
"build:cli": "bun build src/cli.ts --compile --outfile dist/agent-memory --define __VERSION__=\"'$(node -p \"require('./package.json').version\")'\"",
|
|
102
114
|
"eval:feedback": "bun eval/run.ts",
|
|
115
|
+
"eval:regression": "bun eval/run.ts --dataset eval/datasets/agent-memory-regression-v1.json",
|
|
116
|
+
"eval:longmemeval": "bun eval/longmemeval.ts",
|
|
117
|
+
"eval:token-savings": "bun eval/token-savings.ts",
|
|
103
118
|
"prepare": "npm run build:lib",
|
|
104
119
|
"prepack": "npm run build:lib",
|
|
105
120
|
"lint": "biome check .",
|
|
106
121
|
"test": "bun test test/unit.test.ts",
|
|
107
122
|
"test:unit": "bun test test/unit.test.ts",
|
|
108
|
-
"test:cli": "bun test test/cli.test.ts",
|
|
123
|
+
"test:cli": "bun test test/cli.test.ts --timeout 15000",
|
|
109
124
|
"test:eval": "bun test test/eval.test.ts",
|
|
125
|
+
"test:harness": "npm run build:cli && bun test test/harness.test.ts --timeout 60000",
|
|
126
|
+
"test:token-savings": "bun test test/token-savings.test.ts",
|
|
127
|
+
"eval:harness": "bun eval/harness.ts",
|
|
128
|
+
"verify": "bash scripts/verify.sh",
|
|
129
|
+
"verify:quick": "bash scripts/verify.sh --quick",
|
|
110
130
|
"install-skills": "bash scripts/install-skills.sh"
|
|
111
131
|
},
|
|
112
132
|
"devDependencies": {
|
package/skills/agent/SKILL.md
CHANGED
|
@@ -108,6 +108,15 @@ agent-memory search --query "how we handle auth" --mode semantic # Finds related
|
|
|
108
108
|
agent-memory search --query "performance" --mode deep --limit 10 # Hybrid + reranking
|
|
109
109
|
```
|
|
110
110
|
|
|
111
|
+
`search` only looks at what you saved (daily logs, MEMORY.md, topics, scratchpad). For **prior sessions** — things you or the agent said in a past chat — use `recall`:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
agent-memory recall "deploy-to-dev label workflow" # Cross-session, verbatim events
|
|
115
|
+
agent-memory recall "auth refresh" --scope current --limit 5 # Restrict to this workspace
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
When qmd search returns no hits and AgentMemory Pro is installed, `search` automatically falls back to `recall` — but calling `recall` directly is faster and clearer when you know you want session history.
|
|
119
|
+
|
|
111
120
|
If qmd is not installed, fall back to reading files directly:
|
|
112
121
|
```bash
|
|
113
122
|
agent-memory read --target long_term
|
|
@@ -117,7 +126,7 @@ agent-memory read --target daily
|
|
|
117
126
|
### Setup
|
|
118
127
|
|
|
119
128
|
```bash
|
|
120
|
-
agent-memory
|
|
129
|
+
agent-memory setup # Idempotent: memory dir, qmd collection, skills, hooks, MCP
|
|
121
130
|
agent-memory sync # Re-index and embed all files (requires qmd)
|
|
122
131
|
agent-memory status # Show config, file counts, qmd status
|
|
123
132
|
```
|
|
@@ -174,5 +183,6 @@ Distil scans daily logs and topic notes, groups entries by their `#tags`, and ge
|
|
|
174
183
|
- Use `--target long_term` sparingly: architecture, preferences, key commands, hard-won lessons
|
|
175
184
|
- Prefer the scratchpad for any TODOs or follow-ups (persistent, cross-session tracking)
|
|
176
185
|
- Use `#tags` and `[[links]]` in content to improve search recall
|
|
177
|
-
- Use `agent-memory search` to
|
|
186
|
+
- Use `agent-memory search` to find things you saved (daily logs, MEMORY.md, topics) before starting related tasks
|
|
187
|
+
- Use `agent-memory recall "<query>"` to find things from prior chat sessions (Pro) — not the same as `search`
|
|
178
188
|
- All `agent-memory` commands are safe — they read/write only to the memory directory (`~/.agent-memory/` by default)
|
|
@@ -14,6 +14,8 @@ Pi users can choose the native extension (`pi-memory`: https://github.com/jayzen
|
|
|
14
14
|
|
|
15
15
|
!`agent-memory context --no-search 2>/dev/null`
|
|
16
16
|
|
|
17
|
+
This deliberately fetches the full layer (today's log + MEMORY.md + yesterday's log), not just the narrower "stable" layer (MEMORY.md + scratchpad only) that an installed SessionStart hook injects to keep per-turn re-injection cheap. If a hook already ran this session, you may see two context blocks — that's expected, not a bug; treat this one (the fuller one) as authoritative.
|
|
18
|
+
|
|
17
19
|
## Session Lifecycle
|
|
18
20
|
|
|
19
21
|
### On session start
|
|
@@ -28,6 +30,8 @@ Pi users can choose the native extension (`pi-memory`: https://github.com/jayzen
|
|
|
28
30
|
2. Mark completed scratchpad items as done; add new follow-ups
|
|
29
31
|
3. Only write to long-term memory if you discovered a **durable fact** that doesn't already exist there
|
|
30
32
|
|
|
33
|
+
If Claude Code's `Stop` hook is installed, you may occasionally see a reminder to do this check even if you weren't planning to stop — that's the harness backing up this step for long sessions; treat it the same as the guidance above.
|
|
34
|
+
|
|
31
35
|
## Where to Write — Decision Guide
|
|
32
36
|
|
|
33
37
|
**Default to daily. Long-term is rare.**
|
|
@@ -104,6 +108,15 @@ agent-memory search --query "how we handle auth" --mode semantic # Finds related
|
|
|
104
108
|
agent-memory search --query "performance" --mode deep --limit 10 # Hybrid + reranking
|
|
105
109
|
```
|
|
106
110
|
|
|
111
|
+
`search` only looks at what you saved (daily logs, MEMORY.md, topics, scratchpad). For **prior sessions** — things you or the agent said in a past Claude/Codex/pi chat — use `recall`:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
agent-memory recall "deploy-to-dev label workflow" # Cross-session, verbatim events
|
|
115
|
+
agent-memory recall "auth refresh" --scope current --limit 5 # Restrict to this workspace
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
When qmd search returns no hits and AgentMemory Pro is installed, `search` automatically falls back to `recall` — but calling `recall` directly is faster and clearer when you know you want session history.
|
|
119
|
+
|
|
107
120
|
If qmd is not installed, fall back to reading files directly:
|
|
108
121
|
```bash
|
|
109
122
|
agent-memory read --target long_term
|
|
@@ -113,7 +126,7 @@ agent-memory read --target daily
|
|
|
113
126
|
### Setup
|
|
114
127
|
|
|
115
128
|
```bash
|
|
116
|
-
agent-memory
|
|
129
|
+
agent-memory setup # Idempotent: memory dir, qmd collection, skills, hooks, MCP
|
|
117
130
|
agent-memory sync # Re-index and embed all files (requires qmd)
|
|
118
131
|
agent-memory status # Show config, file counts, qmd status
|
|
119
132
|
```
|
|
@@ -170,4 +183,6 @@ Distil scans daily logs and topic notes, groups entries by their `#tags`, and ge
|
|
|
170
183
|
- Use `--target long_term` sparingly: architecture, preferences, key commands, hard-won lessons
|
|
171
184
|
- Prefer the scratchpad for any TODOs or follow-ups (persistent, cross-session tracking)
|
|
172
185
|
- Use `#tags` and `[[links]]` in content to improve search recall
|
|
173
|
-
- Use `agent-memory search` to
|
|
186
|
+
- Use `agent-memory search` to find things you saved (daily logs, MEMORY.md, topics) before starting related tasks
|
|
187
|
+
- Use `agent-memory recall "<query>"` to find things from prior chat sessions (Pro) — not the same as `search`
|
|
188
|
+
- All `agent-memory` commands are safe — they read/write only to the memory directory (`~/.agent-memory/` by default)
|