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.
@@ -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;
@@ -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, loopback email 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 plan grants a configurable number of agent sessions per normalized email and UTC day; durable account authentication, payment, renewal, and account management remain deferred.
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 `agent-memory-plugin` 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.
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 user command is:
13
+ The primary product-facing command is:
14
14
 
15
15
  ```bash
16
- agent-memory plugin install
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 | Start loopback email activation in an interactive terminal |
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 collects an email locally, obtains a server-issued usage credential and short-lived artifact grant, and verifies the release and artifact. The credential is persisted only after the service accepts activation. After installation, the public host reconstructs the free account-metered capability policy in core code and checks required capabilities before commands and hooks. Signed long-lived entitlements can extend this credential when authentication and payment ship.
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 such as `recall`, `learn`, `worker`, and `web`. Bootstrap command names are reserved by the core and cannot be replaced by a plugin.
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
- Optional: AgentMemory Pro adds session recall and a local Web Console.
97
- Run: agent-memory plugin install
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 an `Optional official plugins` section. Human-readable `status` may include the same recommendation while no official plugin is installed. Routine `context`, `read`, `write`, `search`, and scratchpad commands never show commercial prompts.
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 core must not open a browser during package installation, `init`, `help`, `status`, or any normal memory operation. A browser may open only after an explicit interactive `plugin install`. `--no-browser`, non-interactive execution, and `--json` fail closed with `auth_required` when no activation record exists.
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
- ## Free activation flow
144
+ ## Anonymous free-preview flow
137
145
 
138
- 1. `agent-memory plugin install` starts an HTTP server bound to `127.0.0.1` on an ephemeral port.
139
- 2. The CLI prints and opens a nonce-bearing local URL. The page accepts one email address with bounded input, an exact Host and nonce path, same-origin browser request validation, restrictive response headers, and a five-minute deadline.
140
- 3. Submission returns a completion page but does not create a local credential yet.
141
- 4. The waiting CLI sends the email plus core, installed-bundle, platform, architecture, release-channel, and consent-version fields to the private control plane. Its activation database stores none of the user's memory, session content, queries, repository paths, raw agent session identifiers, IP address, or user-agent string.
142
- 5. The service normalizes the email, stores only a hash of a random usage credential, and returns the credential, a free account-metered entitlement, and a short-lived object-bound artifact grant. Only then does the CLI atomically write a mode-0600 activation record.
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. Each paid SessionStart hook reserves one opaque operation against the email's UTC-day allowance, commits after useful hook work, and releases on failure. Exhaustion skips paid hook work without affecting public-core context.
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
- Email ownership is not verified in this free flow. Authentication, payment, renewal, account management, and signed paid entitlements are not implemented yet.
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 a free account-metered entitlement, a usage credential, and a short-lived artifact grant;
167
- - `POST /v1/plugin/sessions/reserve|commit|release` for atomic daily allowance enforcement;
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 the submitted email plus the bounded core, bundle, platform, architecture, release-channel, and consent-version fields described above. Session metering sends only a random operation ID and bearer credential; D1 associates those values with a normalized email and UTC-day counter. Application payloads contain no 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:
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.4.16",
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": {
@@ -110,4 +110,4 @@ else
110
110
  echo " $AGENT_MEMORY_BIN"
111
111
  fi
112
112
  echo ""
113
- echo "Initialize memory: agent-memory init"
113
+ echo "Finish setup: agent-memory setup"
@@ -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 init # Create dirs, detect qmd, setup collection
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 recall past work before starting related tasks
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 init # Create dirs, detect qmd, setup collection
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 recall past work before starting related tasks
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)