@hasna/mementos 0.14.87 → 0.15.2
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/README.md +44 -9
- package/bun.lock +4 -62
- package/dist/cli/commands/info-history.d.ts.map +1 -1
- package/dist/cli/commands/info-stale.d.ts.map +1 -1
- package/dist/cli/commands/io-backup.d.ts.map +1 -1
- package/dist/cli/commands/io-export.d.ts.map +1 -1
- package/dist/cli/commands/io-restore.d.ts.map +1 -1
- package/dist/cli/commands/memory-cmd-chain.d.ts.map +1 -1
- package/dist/cli/commands/memory-cmd-crud.d.ts.map +1 -1
- package/dist/cli/commands/memory-cmd-recall.d.ts.map +1 -1
- package/dist/cli/commands/memory-cmd-search.d.ts.map +1 -1
- package/dist/cli/commands/memory-cmd-tail.d.ts.map +1 -1
- package/dist/cli/commands/memory-cmd-view.d.ts.map +1 -1
- package/dist/cli/commands/memory-cmd-when-to-use.d.ts.map +1 -1
- package/dist/cli/commands/storage.d.ts.map +1 -1
- package/dist/cli/commands/system-doctor.d.ts.map +1 -1
- package/dist/cli/commands/system-profile.d.ts.map +1 -1
- package/dist/cli/commands/system-status.d.ts +43 -0
- package/dist/cli/commands/system-status.d.ts.map +1 -0
- package/dist/cli/commands/system.d.ts.map +1 -1
- package/dist/cli/helpers.d.ts.map +1 -1
- package/dist/cli/index.js +3735 -2021
- package/dist/cli/register-all.d.ts +1 -1
- package/dist/cli/register-all.d.ts.map +1 -1
- package/dist/db/api-mode.d.ts +135 -37
- package/dist/db/api-mode.d.ts.map +1 -1
- package/dist/db/database.d.ts.map +1 -1
- package/dist/db/memories.d.ts.map +1 -1
- package/dist/db/pg-migrate.d.ts.map +1 -1
- package/dist/db/store-backend.d.ts +8 -2
- package/dist/db/store-backend.d.ts.map +1 -1
- package/dist/diagnostics/historical-project-registration-receipt.js +152 -11
- package/dist/generated/storage-kit/backend.d.ts +12 -2
- package/dist/generated/storage-kit/backend.d.ts.map +1 -1
- package/dist/generated/storage-kit/index.d.ts +1 -1
- package/dist/generated/storage-kit/index.d.ts.map +1 -1
- package/dist/generated/storage-kit/migrations.d.ts +21 -0
- package/dist/generated/storage-kit/migrations.d.ts.map +1 -1
- package/dist/generated/storage-kit/pool.d.ts +2 -5
- package/dist/generated/storage-kit/pool.d.ts.map +1 -1
- package/dist/generated/storage-kit/query.d.ts +1 -1
- package/dist/generated/storage-kit/query.d.ts.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3057 -1266
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/env.d.ts +10 -0
- package/dist/lib/env.d.ts.map +1 -0
- package/dist/lib/gatherer.d.ts.map +1 -1
- package/dist/lib/local-opt-in.d.ts +114 -0
- package/dist/lib/local-opt-in.d.ts.map +1 -0
- package/dist/lib/model-config.d.ts +1 -1
- package/dist/lib/paths.d.ts +60 -0
- package/dist/lib/paths.d.ts.map +1 -0
- package/dist/lib/profile-sync.d.ts.map +1 -1
- package/dist/lib/redact.d.ts +70 -10
- package/dist/lib/redact.d.ts.map +1 -1
- package/dist/lib/reflection.d.ts.map +1 -1
- package/dist/lib/search.d.ts.map +1 -1
- package/dist/lib/storage-sync.d.ts.map +1 -1
- package/dist/lib/sync.d.ts.map +1 -1
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +3108 -1276
- package/dist/project-registration.js +378 -153
- package/dist/sdk/index.d.ts +173 -8
- package/dist/sdk/index.d.ts.map +1 -1
- package/dist/sdk/index.js +953 -12
- package/dist/server/auth.d.ts +2 -0
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/helpers.d.ts +48 -3
- package/dist/server/helpers.d.ts.map +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +3146 -1324
- package/dist/server/routes/system-synthesis.d.ts.map +1 -1
- package/dist/storage.d.ts +18 -0
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +149 -83
- package/dist/test-support/store-isolation.d.ts +50 -11
- package/dist/test-support/store-isolation.d.ts.map +1 -1
- package/docker-entrypoint.sh +7 -0
- package/hasna.contract.json +17 -5
- package/package.json +8 -8
- package/postinstall.mjs +85 -0
- package/dashboard/bun.lock +0 -519
- package/dist/cli/brains.d.ts +0 -3
- package/dist/cli/brains.d.ts.map +0 -1
- package/dist/lib/retired-storage-mode.d.ts +0 -11
- package/dist/lib/retired-storage-mode.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-synthesis.d.ts","sourceRoot":"","sources":["../../../src/server/routes/system-synthesis.ts"],"names":[],"mappings":"AAMA,wBAAgB,6BAA6B,IAAI,IAAI,
|
|
1
|
+
{"version":3,"file":"system-synthesis.d.ts","sourceRoot":"","sources":["../../../src/server/routes/system-synthesis.ts"],"names":[],"mappings":"AAMA,wBAAgB,6BAA6B,IAAI,IAAI,CA6DpD"}
|
package/dist/storage.d.ts
CHANGED
|
@@ -247,6 +247,24 @@ export declare function getStorageStatus(): NativeStorageStatus;
|
|
|
247
247
|
export declare const getMementosStorageStatus: typeof getStorageStatus;
|
|
248
248
|
export declare function saveStorageConfig(config: StorageConfig): void;
|
|
249
249
|
export declare function getStorageConnectionString(dbName?: string): string;
|
|
250
|
+
/**
|
|
251
|
+
* Operator-only DSN resolution for the migrate commands.
|
|
252
|
+
*
|
|
253
|
+
* `storage migrate` / `migrate-pg` are deliberately-invoked operator commands
|
|
254
|
+
* (docs/CUTOVER-RUNBOOK.md §3): they run from an approved, database-reachable
|
|
255
|
+
* administrative environment — on this fleet, the ECS one-shot migrate task
|
|
256
|
+
* that holds the DSN via Secrets Manager as HASNA_MEMENTOS_DATABASE_URL, the
|
|
257
|
+
* same credential the serve task uses. The explicit `--connection-string` form
|
|
258
|
+
* was already sanctioned; this resolves the SAME configured DSN for the
|
|
259
|
+
* operator verb without forcing the value onto the command line.
|
|
260
|
+
*
|
|
261
|
+
* This is NOT the client data path. Every read/write surface (getDatabase,
|
|
262
|
+
* getCloudDatabase, storage-sync, MCP data tools) keeps the fail-closed guard
|
|
263
|
+
* in {@link getStorageConnectionString}. Only the migrate operator surfaces
|
|
264
|
+
* call this, and only they may: a DSN must already be present on the machine
|
|
265
|
+
* for the env/config form to resolve, so this adds no exfiltration surface.
|
|
266
|
+
*/
|
|
267
|
+
export declare function getStorageConnectionStringForOperator(dbName?: string): string;
|
|
250
268
|
export declare const SYNC_EXCLUDED_TABLE_PATTERNS: RegExp[];
|
|
251
269
|
export declare function isSyncExcludedTable(table: string): boolean;
|
|
252
270
|
export declare function listSqliteTables(db: DbAdapter): string[];
|
package/dist/storage.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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"}
|
package/dist/storage.js
CHANGED
|
@@ -72,16 +72,7 @@ function serverDataBackendEnvKeys(name) {
|
|
|
72
72
|
databaseUrlKeys: [`HASNA_${token}_DATABASE_URL`, `${token}_DATABASE_URL`]
|
|
73
73
|
};
|
|
74
74
|
}
|
|
75
|
-
function
|
|
76
|
-
const token = envToken(name);
|
|
77
|
-
return [
|
|
78
|
-
`HASNA_${token}_STORAGE_MODE`,
|
|
79
|
-
`HASNA_${token}_MODE`,
|
|
80
|
-
`${token}_STORAGE_MODE`,
|
|
81
|
-
`${token}_MODE`
|
|
82
|
-
];
|
|
83
|
-
}
|
|
84
|
-
function firstEnv(env, keys) {
|
|
75
|
+
function firstDatabaseUrl(env, keys) {
|
|
85
76
|
for (const key of keys) {
|
|
86
77
|
const value = ownString(env, key)?.trim();
|
|
87
78
|
if (value)
|
|
@@ -89,23 +80,8 @@ function firstEnv(env, keys) {
|
|
|
89
80
|
}
|
|
90
81
|
return null;
|
|
91
82
|
}
|
|
92
|
-
function firstDefinedEnvKey(env, keys) {
|
|
93
|
-
for (const key of keys) {
|
|
94
|
-
if (Object.hasOwn(env, key) && env[key] !== undefined)
|
|
95
|
-
return key;
|
|
96
|
-
}
|
|
97
|
-
return null;
|
|
98
|
-
}
|
|
99
|
-
function assertNoLegacyStorageMode(name, env = process.env) {
|
|
100
|
-
const legacyKey = firstDefinedEnvKey(env, legacyModeKeys(name));
|
|
101
|
-
if (!legacyKey)
|
|
102
|
-
return;
|
|
103
|
-
const canonicalDatabaseUrl = serverDataBackendEnvKeys(name).databaseUrlKeys[0];
|
|
104
|
-
throw new Error(`${legacyKey} was removed. Delete the storage-mode variable; ` + `set ${canonicalDatabaseUrl} to select the postgresql server backend, ` + `or leave it unset for sqlite.`);
|
|
105
|
-
}
|
|
106
83
|
function resolveServerDataBackend(name, env = process.env) {
|
|
107
|
-
|
|
108
|
-
const databaseUrl = firstEnv(env, serverDataBackendEnvKeys(name).databaseUrlKeys);
|
|
84
|
+
const databaseUrl = firstDatabaseUrl(env, serverDataBackendEnvKeys(name).databaseUrlKeys);
|
|
109
85
|
if (!databaseUrl) {
|
|
110
86
|
return {
|
|
111
87
|
backend: "sqlite",
|
|
@@ -122,41 +98,125 @@ function resolveServerDataBackend(name, env = process.env) {
|
|
|
122
98
|
};
|
|
123
99
|
}
|
|
124
100
|
function resolveDatabaseUrl(name, env = process.env) {
|
|
125
|
-
|
|
126
|
-
const hit = firstEnv(env, serverDataBackendEnvKeys(name).databaseUrlKeys);
|
|
127
|
-
return hit?.value ?? null;
|
|
101
|
+
return firstDatabaseUrl(env, serverDataBackendEnvKeys(name).databaseUrlKeys)?.value ?? null;
|
|
128
102
|
}
|
|
129
103
|
var init_backend = () => {};
|
|
130
104
|
|
|
131
|
-
// src/lib/
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
105
|
+
// src/lib/paths.ts
|
|
106
|
+
import { existsSync } from "fs";
|
|
107
|
+
import { homedir } from "os";
|
|
108
|
+
import { join, resolve } from "path";
|
|
109
|
+
import { homedir as pathsResolverHomedir } from "os";
|
|
110
|
+
import { join as pathsResolverJoin } from "path";
|
|
111
|
+
function pathsResolverAssertApp(app) {
|
|
112
|
+
if (typeof app !== "string" || app.length === 0) {
|
|
113
|
+
throw new TypeError("paths: app must be a non-empty string");
|
|
114
|
+
}
|
|
115
|
+
if (!PATHS_RESOLVER_APP_SLUG_RE.test(app)) {
|
|
116
|
+
throw new TypeError(`paths: invalid app slug "${app}" \u2014 expected lowercase kebab-case ([a-z0-9]+(-[a-z0-9]+)*)`);
|
|
136
117
|
}
|
|
137
|
-
return null;
|
|
138
118
|
}
|
|
139
|
-
function
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
119
|
+
function pathsResolverAssertKind(kind) {
|
|
120
|
+
if (!Object.keys(PATHS_RESOLVER_KIND_ENV).includes(kind)) {
|
|
121
|
+
throw new TypeError(`paths: invalid path kind "${kind}" \u2014 expected one of ${Object.keys(PATHS_RESOLVER_KIND_ENV).join(", ")}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function pathsResolverBaseDir(kind, options) {
|
|
125
|
+
pathsResolverAssertKind(kind);
|
|
126
|
+
const env = options.env ?? process.env;
|
|
127
|
+
const override = env[PATHS_RESOLVER_KIND_ENV[kind]];
|
|
128
|
+
if (typeof override === "string" && override.length > 0)
|
|
129
|
+
return override;
|
|
130
|
+
const home = options.home ?? pathsResolverHomedir();
|
|
131
|
+
const platform = options.platform ?? process.platform;
|
|
132
|
+
if (platform === "darwin") {
|
|
133
|
+
switch (kind) {
|
|
134
|
+
case "data":
|
|
135
|
+
return pathsResolverJoin(home, "Library", "Application Support", "Hasna");
|
|
136
|
+
case "cache":
|
|
137
|
+
return pathsResolverJoin(home, "Library", "Caches", "Hasna");
|
|
138
|
+
case "state":
|
|
139
|
+
return pathsResolverJoin(home, "Library", "Logs", "Hasna");
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
switch (kind) {
|
|
143
|
+
case "data":
|
|
144
|
+
return pathsResolverJoin(home, ".local", "share", "hasna");
|
|
145
|
+
case "state":
|
|
146
|
+
return pathsResolverJoin(home, ".local", "state", "hasna");
|
|
147
|
+
case "cache":
|
|
148
|
+
return pathsResolverJoin(home, ".cache", "hasna");
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
function pathsResolverResolve(kind, options) {
|
|
152
|
+
pathsResolverAssertApp(options.app);
|
|
153
|
+
const appSegment = options.internal === true ? pathsResolverJoin("internal", options.app) : options.app;
|
|
154
|
+
return pathsResolverJoin(pathsResolverBaseDir(kind, options), appSegment);
|
|
155
|
+
}
|
|
156
|
+
function dataDir(options) {
|
|
157
|
+
return pathsResolverResolve("data", options);
|
|
158
|
+
}
|
|
159
|
+
function effectiveHome() {
|
|
160
|
+
return process.env["HOME"] || process.env["USERPROFILE"] || homedir() || "/tmp";
|
|
161
|
+
}
|
|
162
|
+
function legacyDataRoot() {
|
|
163
|
+
return join(effectiveHome(), ".hasna", "mementos");
|
|
164
|
+
}
|
|
165
|
+
function resolverDataRoot() {
|
|
166
|
+
return dataDir({
|
|
167
|
+
app: "mementos",
|
|
168
|
+
home: process.env["HOME"] || process.env["USERPROFILE"] || undefined
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
function adoptResolverDataRoot(resolved, env = process.env) {
|
|
172
|
+
const dataOverride = env.HASNA_DATA_HOME;
|
|
173
|
+
if (typeof dataOverride === "string" && dataOverride.trim().length > 0)
|
|
174
|
+
return true;
|
|
175
|
+
return existsSync(join(resolved, "mementos.db"));
|
|
176
|
+
}
|
|
177
|
+
function exactDataRoot() {
|
|
178
|
+
for (const key of ["HASNA_MEMENTOS_HOME", "MEMENTOS_HOME"]) {
|
|
179
|
+
const dir = process.env[key]?.trim();
|
|
180
|
+
if (dir)
|
|
181
|
+
return resolve(dir);
|
|
182
|
+
}
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
function getDataRoot() {
|
|
186
|
+
const exact = exactDataRoot();
|
|
187
|
+
if (exact)
|
|
188
|
+
return exact;
|
|
189
|
+
const resolved = resolverDataRoot();
|
|
190
|
+
return adoptResolverDataRoot(resolved) ? resolve(resolved) : resolve(legacyDataRoot());
|
|
191
|
+
}
|
|
192
|
+
var PATHS_RESOLVER_KIND_ENV, PATHS_RESOLVER_APP_SLUG_RE;
|
|
193
|
+
var init_paths = __esm(() => {
|
|
194
|
+
PATHS_RESOLVER_KIND_ENV = {
|
|
195
|
+
data: "HASNA_DATA_HOME",
|
|
196
|
+
state: "HASNA_STATE_HOME",
|
|
197
|
+
cache: "HASNA_CACHE_HOME"
|
|
198
|
+
};
|
|
199
|
+
PATHS_RESOLVER_APP_SLUG_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
// src/lib/env.ts
|
|
203
|
+
var alias = (canonical, legacy) => process.env[canonical] ?? process.env[legacy], env;
|
|
204
|
+
var init_env = __esm(() => {
|
|
205
|
+
env = {
|
|
206
|
+
apiKey: () => alias("HASNA_MEMENTOS_API_KEY", "MEMENTOS_API_KEY"),
|
|
207
|
+
defaultScope: () => alias("HASNA_MEMENTOS_DEFAULT_SCOPE", "MEMENTOS_DEFAULT_SCOPE"),
|
|
208
|
+
defaultCategory: () => alias("HASNA_MEMENTOS_DEFAULT_CATEGORY", "MEMENTOS_DEFAULT_CATEGORY"),
|
|
209
|
+
defaultImportance: () => alias("HASNA_MEMENTOS_DEFAULT_IMPORTANCE", "MEMENTOS_DEFAULT_IMPORTANCE"),
|
|
210
|
+
pgsyncQueryTimeoutMs: () => alias("HASNA_MEMENTOS_PGSYNC_QUERY_TIMEOUT_MS", "MEMENTOS_PGSYNC_QUERY_TIMEOUT_MS"),
|
|
211
|
+
reflectProvider: () => alias("HASNA_MEMENTOS_REFLECT_PROVIDER", "MEMENTOS_REFLECT_PROVIDER"),
|
|
212
|
+
reflectModel: () => alias("HASNA_MEMENTOS_REFLECT_MODEL", "MEMENTOS_REFLECT_MODEL")
|
|
213
|
+
};
|
|
153
214
|
});
|
|
154
215
|
|
|
155
216
|
// src/storage.ts
|
|
156
217
|
import { Database } from "bun:sqlite";
|
|
157
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
158
|
-
import {
|
|
159
|
-
import { join } from "path";
|
|
218
|
+
import { existsSync as existsSync2, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
219
|
+
import { join as join2 } from "path";
|
|
160
220
|
import { fileURLToPath } from "url";
|
|
161
221
|
import { Worker } from "worker_threads";
|
|
162
222
|
import pg from "pg";
|
|
@@ -181,6 +241,7 @@ class SqliteAdapter {
|
|
|
181
241
|
db;
|
|
182
242
|
constructor(path) {
|
|
183
243
|
this.db = new Database(path, { create: true });
|
|
244
|
+
this.db.exec("PRAGMA busy_timeout = 5000");
|
|
184
245
|
this.db.exec("PRAGMA journal_mode = WAL");
|
|
185
246
|
this.db.exec("PRAGMA foreign_keys = ON");
|
|
186
247
|
}
|
|
@@ -415,7 +476,7 @@ function readEnv(name) {
|
|
|
415
476
|
return value ? value : null;
|
|
416
477
|
}
|
|
417
478
|
function readConfigFile() {
|
|
418
|
-
if (!
|
|
479
|
+
if (!existsSync2(STORAGE_CONFIG_PATH)) {
|
|
419
480
|
return {};
|
|
420
481
|
}
|
|
421
482
|
try {
|
|
@@ -431,9 +492,9 @@ function getConfigPath() {
|
|
|
431
492
|
return STORAGE_CONFIG_PATH;
|
|
432
493
|
}
|
|
433
494
|
function getStorageDatabaseEnv() {
|
|
434
|
-
for (const
|
|
435
|
-
if (readEnv(
|
|
436
|
-
return
|
|
495
|
+
for (const env2 of DATABASE_ENV_NAMES) {
|
|
496
|
+
if (readEnv(env2.name))
|
|
497
|
+
return env2;
|
|
437
498
|
}
|
|
438
499
|
return null;
|
|
439
500
|
}
|
|
@@ -443,20 +504,19 @@ function getStorageEnvName(key) {
|
|
|
443
504
|
return readEnv(canonical) || !readEnv(fallback) ? canonical : fallback;
|
|
444
505
|
}
|
|
445
506
|
function getStorageDatabaseUrl() {
|
|
446
|
-
const
|
|
447
|
-
return
|
|
507
|
+
const env2 = getStorageDatabaseEnv();
|
|
508
|
+
return env2 ? readEnv(env2.name) : null;
|
|
448
509
|
}
|
|
449
510
|
function getStorageDatabaseEnvName() {
|
|
450
511
|
return getStorageEnvName("databaseUrl");
|
|
451
512
|
}
|
|
452
|
-
function getStorageBackend(
|
|
453
|
-
return resolveServerDataBackend("mementos",
|
|
513
|
+
function getStorageBackend(env2 = process.env) {
|
|
514
|
+
return resolveServerDataBackend("mementos", env2).backend;
|
|
454
515
|
}
|
|
455
|
-
function getStorageBackendDatabaseUrl(
|
|
456
|
-
return resolveDatabaseUrl("mementos",
|
|
516
|
+
function getStorageBackendDatabaseUrl(env2 = process.env) {
|
|
517
|
+
return resolveDatabaseUrl("mementos", env2);
|
|
457
518
|
}
|
|
458
519
|
function getStorageConfig() {
|
|
459
|
-
assertNoLegacyStorageMode2();
|
|
460
520
|
const fileConfig = readConfigFile();
|
|
461
521
|
const merged = {
|
|
462
522
|
...DEFAULT_STORAGE_CONFIG,
|
|
@@ -543,14 +603,14 @@ function storageEnvStatus(key) {
|
|
|
543
603
|
};
|
|
544
604
|
}
|
|
545
605
|
function postgresBackendStatus(config) {
|
|
546
|
-
const
|
|
547
|
-
const envUrl =
|
|
548
|
-
if (
|
|
606
|
+
const env2 = getStorageDatabaseEnv();
|
|
607
|
+
const envUrl = env2 ? readEnv(env2.name) : null;
|
|
608
|
+
if (env2 && envUrl) {
|
|
549
609
|
const validation = validatePostgresConnectionString(envUrl);
|
|
550
610
|
return {
|
|
551
611
|
configured: validation.ok,
|
|
552
612
|
source: "env",
|
|
553
|
-
env_name:
|
|
613
|
+
env_name: env2.name,
|
|
554
614
|
redacted_url: validation.redacted_url,
|
|
555
615
|
missing: [],
|
|
556
616
|
issues: validation.issues,
|
|
@@ -596,7 +656,6 @@ function getSafeStorageConfigSummary(config = getStorageConfig()) {
|
|
|
596
656
|
};
|
|
597
657
|
}
|
|
598
658
|
function getStorageStatus() {
|
|
599
|
-
assertNoLegacyStorageMode2();
|
|
600
659
|
const config = getStorageConfig();
|
|
601
660
|
const backend = getStorageBackend();
|
|
602
661
|
const postgresRequested = backend === "postgresql";
|
|
@@ -677,11 +736,7 @@ function saveStorageConfig(config) {
|
|
|
677
736
|
function getConfiguredConnectionString() {
|
|
678
737
|
return getStorageDatabaseUrl() ?? undefined;
|
|
679
738
|
}
|
|
680
|
-
function
|
|
681
|
-
assertNoLegacyStorageMode2();
|
|
682
|
-
if (!isServerContext()) {
|
|
683
|
-
throw new Error("Refusing to construct an RDS Postgres DSN outside the mementos-serve server. " + "The raw database DSN is NEVER distributed to client machines. " + "Clients must use the HTTP API: set HASNA_MEMENTOS_API_URL and " + "HASNA_MEMENTOS_API_KEY (and unset HASNA_MEMENTOS_DATABASE_URL).");
|
|
684
|
-
}
|
|
739
|
+
function resolveConfiguredConnectionString(dbName) {
|
|
685
740
|
const envConnectionString = getConfiguredConnectionString();
|
|
686
741
|
if (envConnectionString) {
|
|
687
742
|
const validation = validatePostgresConnectionString(envConnectionString);
|
|
@@ -700,7 +755,7 @@ function getStorageConnectionString(dbName = "mementos") {
|
|
|
700
755
|
missing.push("storage.rds.username");
|
|
701
756
|
}
|
|
702
757
|
if (missing.length > 0) {
|
|
703
|
-
throw new Error(`Remote storage database is not configured. Missing ${missing.join(", ")}. Set HASNA_MEMENTOS_DATABASE_URL or configure
|
|
758
|
+
throw new Error(`Remote storage database is not configured. Missing ${missing.join(", ")}. Set HASNA_MEMENTOS_DATABASE_URL or configure ${STORAGE_CONFIG_PATH}.`);
|
|
704
759
|
}
|
|
705
760
|
const password = process.env[password_env];
|
|
706
761
|
if (!password) {
|
|
@@ -709,6 +764,15 @@ function getStorageConnectionString(dbName = "mementos") {
|
|
|
709
764
|
const sslParam = ssl ? "?sslmode=require" : "";
|
|
710
765
|
return `postgres://${username}:${encodeURIComponent(password)}@${host}:${port}/${dbName}${sslParam}`;
|
|
711
766
|
}
|
|
767
|
+
function getStorageConnectionString(dbName = "mementos") {
|
|
768
|
+
if (!isServerContext()) {
|
|
769
|
+
throw new Error("Refusing to construct an RDS Postgres DSN outside the mementos-serve server. " + "The raw database DSN is NEVER distributed to client machines. " + "Clients must use the HTTP API: set HASNA_MEMENTOS_API_URL and " + "HASNA_MEMENTOS_API_KEY (and unset HASNA_MEMENTOS_DATABASE_URL).");
|
|
770
|
+
}
|
|
771
|
+
return resolveConfiguredConnectionString(dbName);
|
|
772
|
+
}
|
|
773
|
+
function getStorageConnectionStringForOperator(dbName = "mementos") {
|
|
774
|
+
return resolveConfiguredConnectionString(dbName);
|
|
775
|
+
}
|
|
712
776
|
function isSyncExcludedTable(table) {
|
|
713
777
|
return SYNC_EXCLUDED_TABLE_PATTERNS.some((pattern) => pattern.test(table));
|
|
714
778
|
}
|
|
@@ -877,7 +941,8 @@ CREATE TABLE IF NOT EXISTS _sync_meta (
|
|
|
877
941
|
)`;
|
|
878
942
|
var init_storage = __esm(() => {
|
|
879
943
|
init_backend();
|
|
880
|
-
|
|
944
|
+
init_paths();
|
|
945
|
+
init_env();
|
|
881
946
|
PgSyncPool = class PgSyncPool {
|
|
882
947
|
worker;
|
|
883
948
|
status;
|
|
@@ -887,7 +952,7 @@ var init_storage = __esm(() => {
|
|
|
887
952
|
generation = 0;
|
|
888
953
|
static DATA_BYTES = 128 * 1024 * 1024;
|
|
889
954
|
static queryTimeoutMs() {
|
|
890
|
-
const raw =
|
|
955
|
+
const raw = env.pgsyncQueryTimeoutMs()?.trim();
|
|
891
956
|
const parsed = raw ? Number(raw) : Number.NaN;
|
|
892
957
|
return Number.isFinite(parsed) && parsed > 0 ? parsed : 60000;
|
|
893
958
|
}
|
|
@@ -895,12 +960,12 @@ var init_storage = __esm(() => {
|
|
|
895
960
|
const ext = import.meta.url.endsWith(".ts") ? ".ts" : ".js";
|
|
896
961
|
const here = fileURLToPath(new URL(".", import.meta.url));
|
|
897
962
|
const candidates = [
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
963
|
+
join2(here, `pg-sync-worker${ext}`),
|
|
964
|
+
join2(here, "..", `pg-sync-worker${ext}`),
|
|
965
|
+
join2(here, "..", "..", `pg-sync-worker${ext}`)
|
|
901
966
|
];
|
|
902
967
|
for (const candidate of candidates) {
|
|
903
|
-
if (
|
|
968
|
+
if (existsSync2(candidate))
|
|
904
969
|
return candidate;
|
|
905
970
|
}
|
|
906
971
|
return candidates[0];
|
|
@@ -988,7 +1053,7 @@ var init_storage = __esm(() => {
|
|
|
988
1053
|
MEMENTOS_STORAGE_FALLBACK_ENV = {
|
|
989
1054
|
databaseUrl: "MEMENTOS_DATABASE_URL"
|
|
990
1055
|
};
|
|
991
|
-
LOCAL_DATA_DIR =
|
|
1056
|
+
LOCAL_DATA_DIR = getDataRoot();
|
|
992
1057
|
DEFAULT_STORAGE_CONFIG = {
|
|
993
1058
|
rds: {
|
|
994
1059
|
host: "",
|
|
@@ -1003,8 +1068,8 @@ var init_storage = __esm(() => {
|
|
|
1003
1068
|
schedule_minutes: 0
|
|
1004
1069
|
}
|
|
1005
1070
|
};
|
|
1006
|
-
STORAGE_CONFIG_DIR =
|
|
1007
|
-
STORAGE_CONFIG_PATH =
|
|
1071
|
+
STORAGE_CONFIG_DIR = join2(LOCAL_DATA_DIR, "storage");
|
|
1072
|
+
STORAGE_CONFIG_PATH = join2(STORAGE_CONFIG_DIR, "config.json");
|
|
1008
1073
|
DATABASE_ENV_NAMES = [
|
|
1009
1074
|
{ name: MEMENTOS_STORAGE_ENV.databaseUrl, deprecated: false },
|
|
1010
1075
|
{ name: MEMENTOS_STORAGE_FALLBACK_ENV.databaseUrl, deprecated: false }
|
|
@@ -1051,6 +1116,7 @@ export {
|
|
|
1051
1116
|
getStorageDatabaseUrl,
|
|
1052
1117
|
getStorageDatabaseEnvName,
|
|
1053
1118
|
getStorageDatabaseEnv,
|
|
1119
|
+
getStorageConnectionStringForOperator,
|
|
1054
1120
|
getStorageConnectionString,
|
|
1055
1121
|
getStorageConfig,
|
|
1056
1122
|
getStorageBackendDatabaseUrl,
|
|
@@ -1,21 +1,54 @@
|
|
|
1
1
|
import type { StoreBackendReport } from "../db/store-backend.js";
|
|
2
2
|
/**
|
|
3
|
-
* Every env var that can
|
|
4
|
-
*
|
|
5
|
-
* retyped, so adding a selector in
|
|
6
|
-
* automatically widens what the harnesses neutralize.
|
|
3
|
+
* Every env var that can point this client at a store shared with other
|
|
4
|
+
* people, derived from the resolver's own exported key lists rather than
|
|
5
|
+
* retyped, so adding a selector in @hasna/contracts (or a deliberate tier
|
|
6
|
+
* here) automatically widens what the harnesses neutralize.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* Blanking them is NO LONGER SUFFICIENT ON ITS OWN, and that is the whole
|
|
9
|
+
* reason the local opt-in below is defaulted on. Since the credential chain
|
|
10
|
+
* moved into @hasna/contracts (hasna/apps#1720) a key can also arrive from the
|
|
11
|
+
* machine's login Keychain or from `~/.hasna/mementos/config/credentials`,
|
|
12
|
+
* neither of which an env dictionary can blank. What makes a fixture
|
|
13
|
+
* physically unable to reach the hosted authority is therefore the pair: these
|
|
14
|
+
* variables deleted, AND the local opt-in, which the resolver is never
|
|
15
|
+
* consulted past — so no Keychain item and no credential file is ever read.
|
|
12
16
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
17
|
+
* The legacy unprefixed `MEMENTOS_*` spellings are the resolver's silent alias
|
|
18
|
+
* fallback for one release; they are scrubbed here for the same reason the
|
|
19
|
+
* canonical names are.
|
|
15
20
|
*/
|
|
16
21
|
export declare const STORE_SELECTOR_ENV_KEYS: readonly string[];
|
|
22
|
+
/**
|
|
23
|
+
* Routing variables that select a store *kind* rather than a shared
|
|
24
|
+
* destination; LOCAL_ONLY entries are pinned rather than scrubbed and exempt
|
|
25
|
+
* from the coverage assertion:
|
|
26
|
+
*
|
|
27
|
+
* - `HASNA_MEMENTOS_LOCAL` / `MEMENTOS_LOCAL` — the explicit unhosted
|
|
28
|
+
* opt-in; local-intent envs default it on, remote-intent envs may set it
|
|
29
|
+
* to "" to exercise the fail-closed arm. It is answered BEFORE the
|
|
30
|
+
* resolver runs, so a scrubbed test environment physically cannot read the
|
|
31
|
+
* Keychain or a credentials file.
|
|
32
|
+
* - the `*_DB_PATH` keys are the precedence-1 explicit local SQLite file.
|
|
33
|
+
* - `HASNA_STATION` pins WHICH Keychain account the resolver asks for — a
|
|
34
|
+
* name no item can exist under, so the Keychain tier is reliably EMPTY on
|
|
35
|
+
* a developer Mac and on CI alike.
|
|
36
|
+
*/
|
|
37
|
+
export declare const LOCAL_ONLY_STORE_ENV_KEYS: readonly string[];
|
|
38
|
+
/**
|
|
39
|
+
* The retired storage-mode variables, from the resolver's own list. The
|
|
40
|
+
* resolver never reads them — they are inert — but a test env DELETES them so
|
|
41
|
+
* a test can never depend on a stale fragment from the host environment. They
|
|
42
|
+
* are listed here so scrub coverage treats them as handled.
|
|
43
|
+
*/
|
|
44
|
+
export declare const REMOVED_STORE_ENV_KEYS: readonly string[];
|
|
45
|
+
/**
|
|
46
|
+
* The Keychain account a test environment pins, chosen so that no item can
|
|
47
|
+
* exist under it (see LOCAL_ONLY_STORE_ENV_KEYS).
|
|
48
|
+
*/
|
|
49
|
+
export declare const MEMENTOS_TEST_KEYCHAIN_ACCOUNT = "mementos-test-fixture-no-such-station";
|
|
17
50
|
/** The two env vars that point the CLI at a specific SQLite file. */
|
|
18
|
-
export declare const DB_PATH_ENV_KEYS: readonly [
|
|
51
|
+
export declare const DB_PATH_ENV_KEYS: readonly string[];
|
|
19
52
|
export interface IsolatedStoreEnvOptions {
|
|
20
53
|
/**
|
|
21
54
|
* Extra vars to set in the child, applied last. Harnesses use this to blank
|
|
@@ -73,6 +106,12 @@ export declare function stubApiEnv(baseUrl: string, options?: StubApiEnvOptions)
|
|
|
73
106
|
* @param apiKey never a real credential
|
|
74
107
|
*/
|
|
75
108
|
export declare function cloudSelectingEnv(baseUrl: string, apiKey?: string): Record<string, string>;
|
|
109
|
+
/**
|
|
110
|
+
* The ambient env with the local-intent defaults applied ON TOP of the scrub
|
|
111
|
+
* (used by the `bun test` preload and by in-process suites that must be able
|
|
112
|
+
* to reach the hosted arm deliberately).
|
|
113
|
+
*/
|
|
114
|
+
export declare function localMementosTestEnv(extra?: Record<string, string>): Record<string, string>;
|
|
76
115
|
/** LLM provider keys most harnesses blank so no test can make a billed call. */
|
|
77
116
|
export declare const LLM_PROVIDER_ENV_KEYS: readonly ["ANTHROPIC_API_KEY", "OPENAI_API_KEY", "CEREBRAS_API_KEY", "XAI_API_KEY"];
|
|
78
117
|
/** `{ ANTHROPIC_API_KEY: "", ... }` — pass as `extra` to blank LLM providers. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store-isolation.d.ts","sourceRoot":"","sources":["../../src/test-support/store-isolation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"store-isolation.d.ts","sourceRoot":"","sources":["../../src/test-support/store-isolation.ts"],"names":[],"mappings":"AA+DA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AASjE;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,uBAAuB,EAAE,SAAS,MAAM,EAUpD,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,yBAAyB,EAAE,SAAS,MAAM,EAKtD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,EAAE,SAAS,MAAM,EAAoC,CAAC;AAEzF;;;GAGG;AACH,eAAO,MAAM,8BAA8B,0CAA0C,CAAC;AAStF,qEAAqE;AACrE,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAA8B,CAAC;AAE7E,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,uBAA4B,GACpC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAKxB;AAUD,MAAM,WAAW,iBAAiB;IAChC,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAWnG;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,MAAM,SAAmB,GACxB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOxB;AAUD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAK/F;AAED,gFAAgF;AAChF,eAAO,MAAM,qBAAqB,qFAKxB,CAAC;AAEX,iFAAiF;AACjF,wBAAgB,mBAAmB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAE5D;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC3B,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,kBAAkB,CAAC,CAuD7B;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,SAA0B,GAAG,IAAI,CAQ9F"}
|
package/docker-entrypoint.sh
CHANGED
|
@@ -32,10 +32,17 @@ esac
|
|
|
32
32
|
export HASNA_MEMENTOS_API_SIGNING_KEY="${HASNA_MEMENTOS_API_SIGNING_KEY:-${API_KEY_SIGNING_SECRET}}"
|
|
33
33
|
|
|
34
34
|
# Map published bin names to their dist entrypoints.
|
|
35
|
+
# mementos-deploy is the deploy-lane marker command: the deploy workflow
|
|
36
|
+
# (deploy-mementos.yml) registers every managed task definition with
|
|
37
|
+
# command=["mementos-deploy"], and preflight verifies the stable baseline by
|
|
38
|
+
# that marker. It runs the web server exactly like mementos-serve — without
|
|
39
|
+
# this mapping the deployed task would fall through to the fallback branch and
|
|
40
|
+
# exec a binary named mementos-deploy that does not exist (O15-05020).
|
|
35
41
|
cmd="${1:-mementos-serve}"
|
|
36
42
|
[ "$#" -gt 0 ] && shift || true
|
|
37
43
|
case "$cmd" in
|
|
38
44
|
mementos-serve) set -- bun /app/dist/server/index.js "$@" ;;
|
|
45
|
+
mementos-deploy) set -- bun /app/dist/server/index.js "$@" ;;
|
|
39
46
|
mementos-mcp) set -- bun /app/dist/mcp/index.js "$@" ;;
|
|
40
47
|
mementos) set -- bun /app/dist/cli/index.js "$@" ;;
|
|
41
48
|
bun|/*) set -- "$cmd" "$@" ;;
|
package/hasna.contract.json
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
"name": "mementos",
|
|
5
5
|
"class": "cli-with-store",
|
|
6
6
|
"contractVersion": "v1",
|
|
7
|
-
"kitVersion": "0.
|
|
8
|
-
"description": "Universal memory system for AI agents — CLI, MCP server, REST API, and TypeScript SDK over one SQLite or PostgreSQL store.
|
|
7
|
+
"kitVersion": "1.0.2",
|
|
8
|
+
"description": "Universal memory system for AI agents — CLI, MCP server, REST API, and TypeScript SDK over one SQLite or PostgreSQL store. Hosted clients (CLI, MCP server, ./sdk) resolve their credential and authority through the @hasna/contracts client chain, fresh per call; the on-box SQLite store is reachable only by the explicit local opt-ins (HASNA_MEMENTOS_DB_PATH / HASNA_MEMENTOS_LOCAL). mementos-serve reads PostgreSQL selected by HASNA_MEMENTOS_DATABASE_URL. The data backend is the only runtime switch; retired storage-mode variables are inert.",
|
|
9
9
|
"bins": [
|
|
10
10
|
"mementos",
|
|
11
11
|
"mementos-mcp",
|
|
@@ -21,9 +21,21 @@
|
|
|
21
21
|
"status": "supported",
|
|
22
22
|
"bin": "mementos-serve",
|
|
23
23
|
"authMode": "api-key",
|
|
24
|
-
"health": {
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
"health": {
|
|
25
|
+
"method": "GET",
|
|
26
|
+
"path": "/health",
|
|
27
|
+
"public": true
|
|
28
|
+
},
|
|
29
|
+
"readiness": {
|
|
30
|
+
"method": "GET",
|
|
31
|
+
"path": "/ready",
|
|
32
|
+
"public": true
|
|
33
|
+
},
|
|
34
|
+
"version": {
|
|
35
|
+
"method": "GET",
|
|
36
|
+
"path": "/version",
|
|
37
|
+
"public": true
|
|
38
|
+
},
|
|
27
39
|
"apiBasePath": "/v1",
|
|
28
40
|
"openApiPath": "/v1/openapi.json"
|
|
29
41
|
},
|