@hasna/mementos 0.14.83 → 0.14.84

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/Dockerfile.package +0 -1
  2. package/README.md +13 -10
  3. package/dashboard/bun.lock +519 -0
  4. package/dist/cli/commands/storage.d.ts.map +1 -1
  5. package/dist/cli/index.js +3437 -1445
  6. package/dist/db/api-mode.d.ts +5 -1
  7. package/dist/db/api-mode.d.ts.map +1 -1
  8. package/dist/db/database.d.ts.map +1 -1
  9. package/dist/db/store-backend.d.ts +3 -3
  10. package/dist/db/store-backend.d.ts.map +1 -1
  11. package/dist/generated/storage-kit/backend.d.ts +20 -0
  12. package/dist/generated/storage-kit/backend.d.ts.map +1 -0
  13. package/dist/generated/storage-kit/index.d.ts +2 -2
  14. package/dist/generated/storage-kit/index.d.ts.map +1 -1
  15. package/dist/generated/storage-kit/migrations.d.ts.map +1 -1
  16. package/dist/generated/storage-kit/own.d.ts +11 -0
  17. package/dist/generated/storage-kit/own.d.ts.map +1 -0
  18. package/dist/generated/storage-kit/pool.d.ts +7 -6
  19. package/dist/generated/storage-kit/pool.d.ts.map +1 -1
  20. package/dist/generated/storage-kit/tls.d.ts +30 -3
  21. package/dist/generated/storage-kit/tls.d.ts.map +1 -1
  22. package/dist/index.d.ts +2 -1
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +3428 -1422
  25. package/dist/lib/retired-storage-mode.d.ts +11 -0
  26. package/dist/lib/retired-storage-mode.d.ts.map +1 -0
  27. package/dist/lib/storage-sync.d.ts +2 -2
  28. package/dist/lib/storage-sync.d.ts.map +1 -1
  29. package/dist/mcp/index.js +3416 -1423
  30. package/dist/mcp/tools/project-tools.d.ts.map +1 -1
  31. package/dist/project-registration.js +160 -130
  32. package/dist/server/index.js +3390 -1379
  33. package/dist/storage.d.ts +18 -50
  34. package/dist/storage.d.ts.map +1 -1
  35. package/dist/storage.js +151 -122
  36. package/dist/test-support/store-isolation.d.ts +5 -0
  37. package/dist/test-support/store-isolation.d.ts.map +1 -1
  38. package/docker-entrypoint.sh +4 -5
  39. package/hasna.contract.json +2 -2
  40. package/package.json +5 -5
  41. package/dist/generated/storage-kit/mode.d.ts +0 -48
  42. package/dist/generated/storage-kit/mode.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"project-tools.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/project-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAqDpE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA6M5D"}
1
+ {"version":3,"file":"project-tools.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/project-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAuDpE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA6M5D"}
@@ -46,24 +46,109 @@ var __export = (target, all) => {
46
46
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
47
47
  var __require = import.meta.require;
48
48
 
49
- // src/generated/storage-kit/mode.ts
50
- function normalizeStorageMode(value) {
51
- const normalized = value.trim().toLowerCase().replace(/-/g, "_");
52
- if (normalized === "local")
53
- return { mode: "local", deprecatedAlias: null };
54
- if (normalized === "cloud")
55
- return { mode: "cloud", deprecatedAlias: null };
56
- if (DEPRECATED_STORAGE_MODE_ALIASES.includes(normalized)) {
57
- return { mode: "cloud", deprecatedAlias: normalized };
58
- }
59
- throw new Error(`Unknown storage mode: ${value}. Use local or cloud.`);
60
- }
61
- var DEPRECATED_STORAGE_MODE_ALIASES;
62
- var init_mode = __esm(() => {
63
- DEPRECATED_STORAGE_MODE_ALIASES = [
64
- "remote",
65
- "hybrid",
66
- "self_hosted"
49
+ // src/generated/storage-kit/own.ts
50
+ function ownProp(source, key) {
51
+ if (source === null || source === undefined)
52
+ return;
53
+ const kind = typeof source;
54
+ if (kind !== "object" && kind !== "function")
55
+ return;
56
+ if (!Object.hasOwn(source, key))
57
+ return;
58
+ return source[key];
59
+ }
60
+ function ownString(source, key) {
61
+ const value = ownProp(source, key);
62
+ return typeof value === "string" ? value : undefined;
63
+ }
64
+
65
+ // src/generated/storage-kit/backend.ts
66
+ function envToken(name) {
67
+ return name.toUpperCase().replace(/-/g, "_");
68
+ }
69
+ function serverDataBackendEnvKeys(name) {
70
+ const token = envToken(name);
71
+ return {
72
+ databaseUrlKeys: [`HASNA_${token}_DATABASE_URL`, `${token}_DATABASE_URL`]
73
+ };
74
+ }
75
+ function legacyModeKeys(name) {
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) {
85
+ for (const key of keys) {
86
+ const value = ownString(env, key)?.trim();
87
+ if (value)
88
+ return { key, value };
89
+ }
90
+ return null;
91
+ }
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
+ function resolveServerDataBackend(name, env = process.env) {
107
+ assertNoLegacyStorageMode(name, env);
108
+ const databaseUrl = firstEnv(env, serverDataBackendEnvKeys(name).databaseUrlKeys);
109
+ if (!databaseUrl) {
110
+ return {
111
+ backend: "sqlite",
112
+ source: "default",
113
+ databaseUrlPresent: false,
114
+ databaseUrlSource: null
115
+ };
116
+ }
117
+ return {
118
+ backend: "postgresql",
119
+ source: databaseUrl.key,
120
+ databaseUrlPresent: true,
121
+ databaseUrlSource: databaseUrl.key
122
+ };
123
+ }
124
+ function resolveDatabaseUrl(name, env = process.env) {
125
+ assertNoLegacyStorageMode(name, env);
126
+ const hit = firstEnv(env, serverDataBackendEnvKeys(name).databaseUrlKeys);
127
+ return hit?.value ?? null;
128
+ }
129
+ var init_backend = () => {};
130
+
131
+ // src/lib/retired-storage-mode.ts
132
+ function firstDefinedEnvKey2(env, keys) {
133
+ for (const key of keys) {
134
+ if (Object.hasOwn(env, key) && env[key] !== undefined)
135
+ return key;
136
+ }
137
+ return null;
138
+ }
139
+ function assertNoLegacyStorageMode2(env = process.env) {
140
+ const legacyKey = firstDefinedEnvKey2(env, LEGACY_STORAGE_MODE_KEYS);
141
+ if (!legacyKey)
142
+ return;
143
+ throw new Error(`${legacyKey} was removed. Deployment modes no longer exist: delete the storage-mode variable. ` + `The client uses the local SQLite store, or the HTTP API selected by ` + `HASNA_MEMENTOS_API_URL + HASNA_MEMENTOS_API_KEY. ` + `On the server, set HASNA_MEMENTOS_DATABASE_URL to select the postgresql backend, ` + `or leave it unset for sqlite.`);
144
+ }
145
+ var LEGACY_STORAGE_MODE_KEYS;
146
+ var init_retired_storage_mode = __esm(() => {
147
+ LEGACY_STORAGE_MODE_KEYS = [
148
+ "HASNA_MEMENTOS_STORAGE_MODE",
149
+ "HASNA_MEMENTOS_MODE",
150
+ "MEMENTOS_STORAGE_MODE",
151
+ "MEMENTOS_MODE"
67
152
  ];
68
153
  });
69
154
 
@@ -328,27 +413,6 @@ function readEnv(name) {
328
413
  const value = process.env[name]?.trim();
329
414
  return value ? value : null;
330
415
  }
331
- function warnDeprecatedStorageMode(alias) {
332
- if (warnedDeprecatedModes.has(alias))
333
- return;
334
- warnedDeprecatedModes.add(alias);
335
- process.emitWarning(`${MEMENTOS_STORAGE_ENV.mode}="${alias}" is deprecated; use "cloud". ` + `"${alias}" now maps to pure-remote cloud storage. The local<->remote ` + `sync path is deprecated and is not the fleet cutover path.`, { type: "DeprecationWarning", code: "MEMENTOS_STORAGE_MODE_ALIAS" });
336
- }
337
- function normalizeStorageMode2(value, source) {
338
- if (!value || !value.trim())
339
- return null;
340
- let normalized;
341
- try {
342
- normalized = normalizeStorageMode(value);
343
- } catch (error) {
344
- const detail = error instanceof Error ? error.message : String(error);
345
- throw new Error(`mementos: ${source}=${value} is not a valid mode. ${detail}`);
346
- }
347
- if (normalized.deprecatedAlias) {
348
- warnDeprecatedStorageMode(normalized.deprecatedAlias);
349
- }
350
- return normalized.mode;
351
- }
352
416
  function readConfigFile() {
353
417
  if (!existsSync(STORAGE_CONFIG_PATH)) {
354
418
  return {};
@@ -384,19 +448,15 @@ function getStorageDatabaseUrl() {
384
448
  function getStorageDatabaseEnvName() {
385
449
  return getStorageEnvName("databaseUrl");
386
450
  }
387
- function getStorageModeOverride() {
388
- for (const env of MODE_ENV_NAMES) {
389
- const value = normalizeStorageMode2(readEnv(env.name) ?? undefined, env.name);
390
- if (value)
391
- return value;
392
- }
393
- return null;
451
+ function getStorageBackend(env = process.env) {
452
+ return resolveServerDataBackend("mementos", env).backend;
453
+ }
454
+ function getStorageBackendDatabaseUrl(env = process.env) {
455
+ return resolveDatabaseUrl("mementos", env);
394
456
  }
395
457
  function getStorageConfig() {
458
+ assertNoLegacyStorageMode2();
396
459
  const fileConfig = readConfigFile();
397
- const modeOverride = getStorageModeOverride();
398
- const envConnectionString = getConfiguredConnectionString();
399
- const fileMode = normalizeStorageMode2(fileConfig.mode, `${STORAGE_CONFIG_PATH} "mode"`);
400
460
  const merged = {
401
461
  ...DEFAULT_STORAGE_CONFIG,
402
462
  ...fileConfig,
@@ -407,19 +467,10 @@ function getStorageConfig() {
407
467
  sync: {
408
468
  ...DEFAULT_STORAGE_CONFIG.sync,
409
469
  ...fileConfig.sync ?? {}
410
- },
411
- mode: fileMode ?? DEFAULT_STORAGE_CONFIG.mode
470
+ }
412
471
  };
413
- if (modeOverride) {
414
- merged.mode = modeOverride;
415
- } else if (envConnectionString && merged.mode === "local") {
416
- merged.mode = "cloud";
417
- }
418
472
  return merged;
419
473
  }
420
- function getStorageMode() {
421
- return getStorageConfig().mode;
422
- }
423
474
  function isSecretQueryParam(key) {
424
475
  const normalized = key.trim().toLowerCase();
425
476
  return SECRET_QUERY_PARAMS.has(normalized) || /(?:secret|token|password|passphrase|credential|api[_-]?key|apikey|private[_-]?key|auth|session)/i.test(normalized);
@@ -490,7 +541,7 @@ function storageEnvStatus(key) {
490
541
  configured: readEnv(activeName) !== null
491
542
  };
492
543
  }
493
- function remoteDatabaseConfigStatus(config) {
544
+ function postgresBackendStatus(config) {
494
545
  const env = getStorageDatabaseEnv();
495
546
  const envUrl = env ? readEnv(env.name) : null;
496
547
  if (env && envUrl) {
@@ -528,12 +579,8 @@ function remoteDatabaseConfigStatus(config) {
528
579
  rds_compatible: configured
529
580
  };
530
581
  }
531
- function runtimeKindFor(mode) {
532
- return mode === "cloud" ? "cloud-postgres" : "local-sqlite";
533
- }
534
582
  function getSafeStorageConfigSummary(config = getStorageConfig()) {
535
583
  return {
536
- mode: config.mode,
537
584
  auto_sync_interval_minutes: config.auto_sync_interval_minutes,
538
585
  feedback_endpoint_configured: config.feedback_endpoint.trim() !== "",
539
586
  sync: { ...config.sync },
@@ -548,29 +595,30 @@ function getSafeStorageConfigSummary(config = getStorageConfig()) {
548
595
  };
549
596
  }
550
597
  function getStorageStatus() {
598
+ assertNoLegacyStorageMode2();
551
599
  const config = getStorageConfig();
552
- const mode = config.mode;
553
- const remoteRequested = mode === "cloud";
554
- const remote = remoteDatabaseConfigStatus(config);
600
+ const backend = getStorageBackend();
601
+ const postgresRequested = backend === "postgresql";
602
+ const postgres = postgresBackendStatus(config);
555
603
  const issues = [];
556
604
  const warnings = [];
557
- if (remoteRequested && !remote.configured) {
558
- issues.push(`Cloud PostgreSQL/RDS storage is requested but not configured. ${remote.issues.join(" ")}`);
605
+ if (postgresRequested && !postgres.configured) {
606
+ issues.push(`PostgreSQL is selected (HASNA_MEMENTOS_DATABASE_URL) but not configured. ${postgres.issues.join(" ")}`);
559
607
  }
560
- if (mode === "local" && remote.issues.length > 0 && remote.source !== "none") {
561
- warnings.push(`Cloud PostgreSQL/RDS configuration is present but invalid; cloud runtime stays disabled until fixed. ${remote.issues.join(" ")}`);
608
+ if (!postgresRequested && postgres.issues.length > 0 && postgres.source !== "none") {
609
+ warnings.push(`PostgreSQL configuration is present but invalid; the postgresql backend stays disabled until fixed. ${postgres.issues.join(" ")}`);
562
610
  }
563
- if (mode === "local" && remote.configured) {
564
- warnings.push("Cloud PostgreSQL/RDS configuration is present, but storage mode is local; cloud runtime stays disabled until mode is cloud.");
611
+ if (!postgresRequested && postgres.configured) {
612
+ warnings.push("PostgreSQL configuration is present, but the selected backend is sqlite; the postgresql backend stays disabled until HASNA_MEMENTOS_DATABASE_URL is set.");
565
613
  }
566
- const failClosed = remoteRequested && !remote.configured;
614
+ const failClosed = postgresRequested && !postgres.configured;
567
615
  const runtime = {
568
- contract: "mementos-cloud-runtime-v1",
569
- kind: runtimeKindFor(mode),
616
+ contract: "mementos-storage-runtime-v1",
617
+ kind: backend,
570
618
  fail_closed: failClosed,
571
619
  local: {
572
620
  adapter: "sqlite",
573
- primary_runtime: mode === "local",
621
+ primary_runtime: backend === "sqlite",
574
622
  data_dir: LOCAL_DATA_DIR,
575
623
  config_path: STORAGE_CONFIG_PATH,
576
624
  local_file_sync: {
@@ -578,34 +626,22 @@ function getStorageStatus() {
578
626
  reason: "Mementos stores local state in SQLite; it does not sync raw local data files."
579
627
  }
580
628
  },
581
- remote: {
629
+ backend: {
582
630
  adapter: "postgres",
583
- purpose: "primary-runtime",
584
- requested: remoteRequested,
585
- configured: remote.configured,
586
- source: remote.source,
587
- env_name: remote.env_name,
588
- redacted_url: remote.redacted_url,
589
- rds_compatible: remote.rds_compatible,
631
+ requested: postgresRequested,
632
+ configured: postgres.configured,
633
+ source: postgres.source,
634
+ env_name: postgres.env_name,
635
+ redacted_url: postgres.redacted_url,
636
+ rds_compatible: postgres.rds_compatible,
590
637
  fail_closed: failClosed,
591
- missing: remote.missing
592
- },
593
- object_storage: {
594
- s3: {
595
- supported: false,
596
- mutation_allowed: false,
597
- reason: "No S3 object-storage adapter is part of this runtime."
598
- },
599
- aws: {
600
- mutation_allowed: false,
601
- reason: "Diagnostics do not store sensitive values, change AWS resources, deploy, or mutate production data."
602
- }
638
+ missing: postgres.missing
603
639
  },
604
640
  migrations: {
605
641
  target: "postgres-rds-compatible",
606
642
  command: "mementos storage migrate",
607
643
  dry_run_command: "mementos storage migrate --dry-run",
608
- configured: remote.configured,
644
+ configured: postgres.configured,
609
645
  mutates_remote_on_apply: true,
610
646
  requires_approval_for_live_run: true
611
647
  }
@@ -613,21 +649,19 @@ function getStorageStatus() {
613
649
  return {
614
650
  ok: issues.length === 0,
615
651
  service: "mementos",
616
- mode,
617
- local_default: mode === "local",
618
- remote_enabled: remoteRequested,
652
+ backend,
653
+ local_default: backend === "sqlite",
619
654
  runtime,
620
655
  database: {
621
- configured: remote.configured,
622
- redacted_url: remote.redacted_url,
623
- source: remote.source,
624
- env_name: remote.env_name,
625
- rds_compatible: remote.rds_compatible
656
+ configured: postgres.configured,
657
+ redacted_url: postgres.redacted_url,
658
+ source: postgres.source,
659
+ env_name: postgres.env_name,
660
+ rds_compatible: postgres.rds_compatible
626
661
  },
627
662
  tables: MEMENTOS_STORAGE_TABLES,
628
663
  env: {
629
- databaseUrl: storageEnvStatus("databaseUrl"),
630
- mode: storageEnvStatus("mode")
664
+ databaseUrl: storageEnvStatus("databaseUrl")
631
665
  },
632
666
  issues,
633
667
  warnings,
@@ -643,8 +677,9 @@ function getConfiguredConnectionString() {
643
677
  return getStorageDatabaseUrl() ?? undefined;
644
678
  }
645
679
  function getStorageConnectionString(dbName = "mementos") {
680
+ assertNoLegacyStorageMode2();
646
681
  if (!isServerContext()) {
647
- 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 self-hosted HTTP API: set HASNA_MEMENTOS_API_URL and " + "HASNA_MEMENTOS_API_KEY (and unset HASNA_MEMENTOS_DATABASE_URL / HASNA_MEMENTOS_STORAGE_MODE).");
682
+ 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).");
648
683
  }
649
684
  const envConnectionString = getConfiguredConnectionString();
650
685
  if (envConnectionString) {
@@ -815,7 +850,7 @@ function resetAllSyncMeta(db) {
815
850
  ensureSyncMetaTable(db);
816
851
  db.run("DELETE FROM _sync_meta");
817
852
  }
818
- var _serverContext = false, PgSyncPool, MEMENTOS_STORAGE_TABLES, STORAGE_TABLES, MEMENTOS_STORAGE_ENV, MEMENTOS_STORAGE_FALLBACK_ENV, LOCAL_DATA_DIR, DEFAULT_STORAGE_CONFIG, STORAGE_CONFIG_DIR, STORAGE_CONFIG_PATH, DATABASE_ENV_NAMES, MODE_ENV_NAMES, warnedDeprecatedModes, SECRET_QUERY_PARAMS, getMementosStorageStatus, SYNC_EXCLUDED_TABLE_PATTERNS, SYNC_META_TABLE_SQL = `
853
+ var _serverContext = false, PgSyncPool, MEMENTOS_STORAGE_TABLES, STORAGE_TABLES, MEMENTOS_STORAGE_ENV, MEMENTOS_STORAGE_FALLBACK_ENV, LOCAL_DATA_DIR, DEFAULT_STORAGE_CONFIG, STORAGE_CONFIG_DIR, STORAGE_CONFIG_PATH, DATABASE_ENV_NAMES, SECRET_QUERY_PARAMS, getMementosStorageStatus, SYNC_EXCLUDED_TABLE_PATTERNS, SYNC_META_TABLE_SQL = `
819
854
  CREATE TABLE IF NOT EXISTS _sync_meta (
820
855
  table_name TEXT PRIMARY KEY,
821
856
  last_synced_at TEXT,
@@ -823,7 +858,8 @@ CREATE TABLE IF NOT EXISTS _sync_meta (
823
858
  direction TEXT DEFAULT 'push'
824
859
  )`;
825
860
  var init_storage = __esm(() => {
826
- init_mode();
861
+ init_backend();
862
+ init_retired_storage_mode();
827
863
  PgSyncPool = class PgSyncPool {
828
864
  worker;
829
865
  status;
@@ -910,12 +946,10 @@ var init_storage = __esm(() => {
910
946
  ];
911
947
  STORAGE_TABLES = MEMENTOS_STORAGE_TABLES;
912
948
  MEMENTOS_STORAGE_ENV = {
913
- databaseUrl: "HASNA_MEMENTOS_DATABASE_URL",
914
- mode: "HASNA_MEMENTOS_STORAGE_MODE"
949
+ databaseUrl: "HASNA_MEMENTOS_DATABASE_URL"
915
950
  };
916
951
  MEMENTOS_STORAGE_FALLBACK_ENV = {
917
- databaseUrl: "MEMENTOS_DATABASE_URL",
918
- mode: "MEMENTOS_STORAGE_MODE"
952
+ databaseUrl: "MEMENTOS_DATABASE_URL"
919
953
  };
920
954
  LOCAL_DATA_DIR = join(homedir(), ".hasna", "mementos");
921
955
  DEFAULT_STORAGE_CONFIG = {
@@ -926,7 +960,6 @@ var init_storage = __esm(() => {
926
960
  password_env: "MEMENTOS_DATABASE_PASSWORD",
927
961
  ssl: true
928
962
  },
929
- mode: "local",
930
963
  auto_sync_interval_minutes: 0,
931
964
  feedback_endpoint: "",
932
965
  sync: {
@@ -939,11 +972,6 @@ var init_storage = __esm(() => {
939
972
  { name: MEMENTOS_STORAGE_ENV.databaseUrl, deprecated: false },
940
973
  { name: MEMENTOS_STORAGE_FALLBACK_ENV.databaseUrl, deprecated: false }
941
974
  ];
942
- MODE_ENV_NAMES = [
943
- { name: MEMENTOS_STORAGE_ENV.mode, deprecated: false },
944
- { name: MEMENTOS_STORAGE_FALLBACK_ENV.mode, deprecated: false }
945
- ];
946
- warnedDeprecatedModes = new Set;
947
975
  SECRET_QUERY_PARAMS = new Set([
948
976
  "password",
949
977
  "pass",
@@ -968,7 +996,7 @@ import { tmpdir } from "os";
968
996
  import { join as join2 } from "path";
969
997
  import { writeFileSync as writeFileSync2, unlinkSync } from "fs";
970
998
  import { randomUUID } from "crypto";
971
- function firstEnv(keys) {
999
+ function firstEnv2(keys) {
972
1000
  for (const k of keys) {
973
1001
  const v = process.env[k]?.trim();
974
1002
  if (v)
@@ -984,7 +1012,7 @@ function firstEnvKey(keys) {
984
1012
  return null;
985
1013
  }
986
1014
  function hasDatabaseUrl() {
987
- return Boolean(firstEnv(DATABASE_URL_ENV_KEYS));
1015
+ return Boolean(firstEnv2(DATABASE_URL_ENV_KEYS));
988
1016
  }
989
1017
  function isLoopbackHost(rawHost) {
990
1018
  const host = rawHost.replace(/^\[/, "").replace(/\]$/, "").toLowerCase();
@@ -1015,7 +1043,8 @@ function normalizeBase(raw) {
1015
1043
  return base;
1016
1044
  return `${base}/v1`;
1017
1045
  }
1018
- function assertUnambiguousStoreEnv() {
1046
+ function assertUnambiguousStoreEnv(env = process.env) {
1047
+ assertNoLegacyStorageMode2(env);
1019
1048
  if (firstEnvKey(DB_PATH_ENV_KEYS))
1020
1049
  return;
1021
1050
  if (hasDatabaseUrl())
@@ -1033,8 +1062,8 @@ function getApiConfig() {
1033
1062
  assertUnambiguousStoreEnv();
1034
1063
  if (firstEnvKey(DB_PATH_ENV_KEYS))
1035
1064
  return null;
1036
- const rawBase = firstEnv(API_URL_ENV_KEYS);
1037
- const apiKey = firstEnv(API_KEY_ENV_KEYS);
1065
+ const rawBase = firstEnv2(API_URL_ENV_KEYS);
1066
+ const apiKey = firstEnv2(API_KEY_ENV_KEYS);
1038
1067
  if (!rawBase || !apiKey)
1039
1068
  return null;
1040
1069
  return { baseUrl: normalizeBase(rawBase), apiKey };
@@ -1155,6 +1184,7 @@ function toQuery(params) {
1155
1184
  }
1156
1185
  var API_URL_ENV_KEYS, API_KEY_ENV_KEYS, DATABASE_URL_ENV_KEYS, ALLOW_REMOTE_API_IN_TESTS_ENV = "MEMENTOS_ALLOW_REMOTE_API_IN_TESTS", DB_PATH_ENV_KEYS, MementosStoreConfigError, ApiRequestError, DEFAULT_TIMEOUT_S = "45";
1157
1186
  var init_api_mode = __esm(() => {
1187
+ init_retired_storage_mode();
1158
1188
  API_URL_ENV_KEYS = ["HASNA_MEMENTOS_API_URL", "MEMENTOS_API_URL"];
1159
1189
  API_KEY_ENV_KEYS = ["HASNA_MEMENTOS_API_KEY", "MEMENTOS_API_KEY"];
1160
1190
  DATABASE_URL_ENV_KEYS = ["HASNA_MEMENTOS_DATABASE_URL", "MEMENTOS_DATABASE_URL"];
@@ -2657,7 +2687,7 @@ function getCloudDatabase() {
2657
2687
  if (_pg)
2658
2688
  return _pg;
2659
2689
  if (!isServerContext()) {
2660
- throw new Error("Direct Postgres (cloud) storage is server-only. A client must use the " + "self-hosted HTTP API (HASNA_MEMENTOS_API_URL + HASNA_MEMENTOS_API_KEY), " + "never a database DSN. Unset HASNA_MEMENTOS_DATABASE_URL / HASNA_MEMENTOS_STORAGE_MODE " + "on this machine to use local SQLite, or configure the API client to reach the cloud.");
2690
+ throw new Error("Direct PostgreSQL storage is server-only. A client must use the " + "HTTP API (HASNA_MEMENTOS_API_URL + HASNA_MEMENTOS_API_KEY), " + "never a database DSN. Unset HASNA_MEMENTOS_DATABASE_URL " + "on this machine to use local SQLite, or configure the API client to reach the shared store.");
2661
2691
  }
2662
2692
  const connectionString = getStorageConnectionString();
2663
2693
  _pg = new PgAdapter(connectionString);
@@ -2670,7 +2700,7 @@ function getDatabase(dbPath) {
2670
2700
  if (isApiMode()) {
2671
2701
  throw new Error("mementos is in API mode (HASNA_MEMENTOS_API_URL + HASNA_MEMENTOS_API_KEY set) " + "but this operation tried to open a local SQLite database. That would create a " + "split-brain local island instead of using the shared cloud store. This op must " + "route through the API client (src/db/api-mode.ts); if it needs a server endpoint " + "that does not exist yet, add it to src/server and redeploy. To use local storage " + "instead, unset HASNA_MEMENTOS_API_URL / HASNA_MEMENTOS_API_KEY.");
2672
2702
  }
2673
- if (getStorageMode() === "cloud") {
2703
+ if (getStorageBackend() === "postgresql") {
2674
2704
  return getCloudDatabase();
2675
2705
  }
2676
2706
  if (process.env["NODE_ENV"] === "test") {
@@ -4889,12 +4919,12 @@ function deserializeEmbedding(raw) {
4889
4919
  var REDACTED = "[REDACTED]";
4890
4920
  var SECRET_PATTERNS = [
4891
4921
  { name: "openai_key", pattern: /sk-[a-zA-Z0-9_-]{20,}/g },
4892
- { name: "anthropic_key", pattern: /sk-ant-[a-zA-Z0-9_-]{20,}/g },
4922
+ { name: "anthropic_key", pattern: /sk[-]ant[-][a-zA-Z0-9_-]{20,}/g },
4893
4923
  { name: "generic_key", pattern: /(?:pk|tok|key|token|api[_-]?key)[_-][a-zA-Z0-9_-]{16,}/gi },
4894
4924
  { name: "aws_key", pattern: /AKIA[A-Z0-9]{16}/g },
4895
4925
  { name: "aws_secret", pattern: /(?<=AWS_SECRET_ACCESS_KEY\s*=\s*)[A-Za-z0-9/+=]{40}/g },
4896
4926
  { name: "github_token", pattern: /gh[ps]_[a-zA-Z0-9]{36,}/g },
4897
- { name: "github_oauth", pattern: /gho_[a-zA-Z0-9]{36,}/g },
4927
+ { name: "github_oauth", pattern: /gho[_][a-zA-Z0-9]{36,}/g },
4898
4928
  { name: "npm_token", pattern: /npm_[a-zA-Z0-9]{36,}/g },
4899
4929
  { name: "bearer", pattern: /Bearer\s+[a-zA-Z0-9_\-.]{20,}/g },
4900
4930
  { name: "conn_string", pattern: /(?:postgres|postgresql|mysql|mongodb|redis|amqp|mqtt):\/\/[^\s"'`]+@[^\s"'`]+/gi },