@askexenow/exe-os 0.9.63 → 0.9.65

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.
@@ -3621,31 +3621,43 @@ function logError(msg) {
3621
3621
  } catch {
3622
3622
  }
3623
3623
  }
3624
+ function isTruthyEnv(value) {
3625
+ return /^(1|true|yes|on)$/i.test(value ?? "");
3626
+ }
3624
3627
  function loadPgClient() {
3625
3628
  if (_pgFailed) return null;
3626
- const postgresUrl = process.env.DATABASE_URL;
3627
3629
  const configPath = path10.join(EXE_AI_DIR, "config.json");
3628
3630
  let cloudPostgresUrl;
3631
+ let configEnabled = false;
3629
3632
  try {
3630
3633
  if (existsSync10(configPath)) {
3631
3634
  const cfg = JSON.parse(readFileSync7(configPath, "utf8"));
3632
3635
  cloudPostgresUrl = cfg.cloud?.postgresUrl;
3633
- if (cfg.cloud?.syncToPostgres === false) {
3634
- _pgFailed = true;
3635
- return null;
3636
- }
3636
+ configEnabled = cfg.cloud?.syncToPostgres === true;
3637
3637
  }
3638
3638
  } catch {
3639
3639
  }
3640
- const url = postgresUrl || cloudPostgresUrl;
3640
+ const envEnabled = isTruthyEnv(process.env.EXE_CLOUD_SYNC_TO_POSTGRES);
3641
+ if (!envEnabled && !configEnabled) {
3642
+ return null;
3643
+ }
3644
+ const url = process.env.DATABASE_URL || cloudPostgresUrl;
3641
3645
  if (!url) {
3642
3646
  _pgFailed = true;
3643
3647
  return null;
3644
3648
  }
3645
3649
  if (!_pgPromise) {
3646
3650
  _pgPromise = (async () => {
3651
+ if (!process.env.DATABASE_URL) process.env.DATABASE_URL = url;
3647
3652
  const { createRequire: createRequire3 } = await import("module");
3648
3653
  const { pathToFileURL: pathToFileURL3 } = await import("url");
3654
+ const explicitPath = process.env.EXE_OS_PRISMA_CLIENT_PATH;
3655
+ if (explicitPath) {
3656
+ const mod2 = await import(pathToFileURL3(explicitPath).href);
3657
+ const Ctor2 = mod2.PrismaClient ?? mod2.default?.PrismaClient;
3658
+ if (!Ctor2) throw new Error(`No PrismaClient at ${explicitPath}`);
3659
+ return new Ctor2();
3660
+ }
3649
3661
  const exeDbRoot = process.env.EXE_DB_ROOT ?? path10.join(homedir2(), "exe-db");
3650
3662
  const req = createRequire3(path10.join(exeDbRoot, "package.json"));
3651
3663
  const entry = req.resolve("@prisma/client");
@@ -3842,6 +3854,15 @@ async function cloudSync(config) {
3842
3854
  } catch {
3843
3855
  throw new Error("[cloud-sync] Database not initialized. Call initStore() before cloudSync().");
3844
3856
  }
3857
+ try {
3858
+ const relink = await client.execute("SELECT value FROM sync_meta WHERE key = 'cloud_relink_required' LIMIT 1");
3859
+ if (String(relink.rows[0]?.value ?? "") === "1") {
3860
+ throw new Error("[cloud-sync] Paused after key rotation. Re-link/reupload cloud sync with the new recovery phrase before syncing.");
3861
+ }
3862
+ } catch (err) {
3863
+ const msg = err instanceof Error ? err.message : String(err);
3864
+ if (msg.includes("Paused after key rotation")) throw err;
3865
+ }
3845
3866
  try {
3846
3867
  const { getRawClient: getRawClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
3847
3868
  await getRawClient2().execute("PRAGMA wal_checkpoint(PASSIVE)");
@@ -1264,7 +1264,7 @@ function commandHasAnyMarker(command, markers) {
1264
1264
  function isLegacySplitPostToolCommand(command) {
1265
1265
  return commandHasAnyMarker(command, LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS);
1266
1266
  }
1267
- var EXE_HOOKS, EXE_HOOK_MANIFEST, LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS;
1267
+ var EXE_HOOKS, LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS;
1268
1268
  var init_runtime_hook_manifest = __esm({
1269
1269
  "src/adapters/runtime-hook-manifest.ts"() {
1270
1270
  "use strict";
@@ -1282,116 +1282,6 @@ var init_runtime_hook_manifest = __esm({
1282
1282
  notification: "dist/hooks/notification.js",
1283
1283
  instructionsLoaded: "dist/hooks/instructions-loaded.js"
1284
1284
  };
1285
- EXE_HOOK_MANIFEST = [
1286
- {
1287
- key: "postToolCombined",
1288
- event: "PostToolUse",
1289
- commandMarker: EXE_HOOKS.postToolCombined,
1290
- owner: "exe-os",
1291
- purpose: "Single PostToolUse entrypoint for ingestion, error recall, summaries, and bug detection.",
1292
- runtimes: ["claude", "codex", "opencode"],
1293
- checkpointRole: "none"
1294
- },
1295
- {
1296
- key: "sessionStart",
1297
- event: "SessionStart",
1298
- commandMarker: EXE_HOOKS.sessionStart,
1299
- owner: "exe-os",
1300
- purpose: "Loads agent identity, procedures, and boot context.",
1301
- runtimes: ["claude", "codex", "opencode"],
1302
- checkpointRole: "none"
1303
- },
1304
- {
1305
- key: "promptSubmit",
1306
- event: "UserPromptSubmit",
1307
- commandMarker: EXE_HOOKS.promptSubmit,
1308
- owner: "exe-os",
1309
- purpose: "Injects current tasks, pending reviews, and local context before each prompt.",
1310
- runtimes: ["claude", "codex", "opencode"],
1311
- checkpointRole: "none"
1312
- },
1313
- {
1314
- key: "heartbeat",
1315
- event: "UserPromptSubmit",
1316
- commandMarker: EXE_HOOKS.heartbeat,
1317
- owner: "exe-os",
1318
- purpose: "Lightweight heartbeat/status sidecar for Claude Code sessions.",
1319
- runtimes: ["claude"],
1320
- checkpointRole: "none"
1321
- },
1322
- {
1323
- key: "stop",
1324
- event: "Stop",
1325
- commandMarker: EXE_HOOKS.stop,
1326
- owner: "exe-os",
1327
- purpose: "Finalizes task state, capacity signals, and emergency checkpointing.",
1328
- runtimes: ["claude", "codex", "opencode"],
1329
- checkpointRole: "capacity_checkpoint"
1330
- },
1331
- {
1332
- key: "preToolUse",
1333
- event: "PreToolUse",
1334
- commandMarker: EXE_HOOKS.preToolUse,
1335
- owner: "exe-os",
1336
- purpose: "Preflight guardrails before shell/tool execution.",
1337
- runtimes: ["claude", "codex", "opencode"],
1338
- checkpointRole: "none"
1339
- },
1340
- {
1341
- key: "subagentStop",
1342
- event: "SubagentStop",
1343
- commandMarker: EXE_HOOKS.subagentStop,
1344
- owner: "exe-os",
1345
- purpose: "Captures subagent completion context.",
1346
- runtimes: ["claude"],
1347
- checkpointRole: "none"
1348
- },
1349
- {
1350
- key: "preCompact",
1351
- event: "PreCompact",
1352
- commandMarker: EXE_HOOKS.preCompact,
1353
- owner: "exe-os",
1354
- purpose: "Writes active-task snapshot and compaction recovery context.",
1355
- runtimes: ["claude"],
1356
- checkpointRole: "recovery_context"
1357
- },
1358
- {
1359
- key: "postCompact",
1360
- event: "PostCompact",
1361
- commandMarker: EXE_HOOKS.postCompact,
1362
- owner: "exe-os",
1363
- purpose: "Rehydrates recovery context after compaction.",
1364
- runtimes: ["claude"],
1365
- checkpointRole: "recovery_context"
1366
- },
1367
- {
1368
- key: "sessionEnd",
1369
- event: "SessionEnd",
1370
- commandMarker: EXE_HOOKS.sessionEnd,
1371
- owner: "exe-os",
1372
- purpose: "Stores session-end checkpoint and triages orphaned in-progress tasks.",
1373
- runtimes: ["claude"],
1374
- checkpointRole: "session_summary"
1375
- },
1376
- {
1377
- key: "notification",
1378
- event: "Notification",
1379
- commandMarker: EXE_HOOKS.notification,
1380
- owner: "exe-os",
1381
- purpose: "Captures runtime notifications and nudges.",
1382
- runtimes: ["claude"],
1383
- checkpointRole: "none"
1384
- },
1385
- {
1386
- key: "instructionsLoaded",
1387
- event: "InstructionsLoaded",
1388
- commandMarker: EXE_HOOKS.instructionsLoaded,
1389
- owner: "exe-os",
1390
- purpose: "Applies runtime instruction post-processing.",
1391
- runtimes: ["claude"],
1392
- checkpointRole: "none"
1393
- }
1394
- ];
1395
1285
  LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS = [
1396
1286
  "dist/hooks/ingest.js",
1397
1287
  "dist/hooks/error-recall.js",
@@ -3948,7 +3948,7 @@ function commandHasAnyMarker(command, markers) {
3948
3948
  function isLegacySplitPostToolCommand(command) {
3949
3949
  return commandHasAnyMarker(command, LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS);
3950
3950
  }
3951
- var EXE_HOOKS, EXE_HOOK_MANIFEST, LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS;
3951
+ var EXE_HOOKS, LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS;
3952
3952
  var init_runtime_hook_manifest = __esm({
3953
3953
  "src/adapters/runtime-hook-manifest.ts"() {
3954
3954
  "use strict";
@@ -3966,116 +3966,6 @@ var init_runtime_hook_manifest = __esm({
3966
3966
  notification: "dist/hooks/notification.js",
3967
3967
  instructionsLoaded: "dist/hooks/instructions-loaded.js"
3968
3968
  };
3969
- EXE_HOOK_MANIFEST = [
3970
- {
3971
- key: "postToolCombined",
3972
- event: "PostToolUse",
3973
- commandMarker: EXE_HOOKS.postToolCombined,
3974
- owner: "exe-os",
3975
- purpose: "Single PostToolUse entrypoint for ingestion, error recall, summaries, and bug detection.",
3976
- runtimes: ["claude", "codex", "opencode"],
3977
- checkpointRole: "none"
3978
- },
3979
- {
3980
- key: "sessionStart",
3981
- event: "SessionStart",
3982
- commandMarker: EXE_HOOKS.sessionStart,
3983
- owner: "exe-os",
3984
- purpose: "Loads agent identity, procedures, and boot context.",
3985
- runtimes: ["claude", "codex", "opencode"],
3986
- checkpointRole: "none"
3987
- },
3988
- {
3989
- key: "promptSubmit",
3990
- event: "UserPromptSubmit",
3991
- commandMarker: EXE_HOOKS.promptSubmit,
3992
- owner: "exe-os",
3993
- purpose: "Injects current tasks, pending reviews, and local context before each prompt.",
3994
- runtimes: ["claude", "codex", "opencode"],
3995
- checkpointRole: "none"
3996
- },
3997
- {
3998
- key: "heartbeat",
3999
- event: "UserPromptSubmit",
4000
- commandMarker: EXE_HOOKS.heartbeat,
4001
- owner: "exe-os",
4002
- purpose: "Lightweight heartbeat/status sidecar for Claude Code sessions.",
4003
- runtimes: ["claude"],
4004
- checkpointRole: "none"
4005
- },
4006
- {
4007
- key: "stop",
4008
- event: "Stop",
4009
- commandMarker: EXE_HOOKS.stop,
4010
- owner: "exe-os",
4011
- purpose: "Finalizes task state, capacity signals, and emergency checkpointing.",
4012
- runtimes: ["claude", "codex", "opencode"],
4013
- checkpointRole: "capacity_checkpoint"
4014
- },
4015
- {
4016
- key: "preToolUse",
4017
- event: "PreToolUse",
4018
- commandMarker: EXE_HOOKS.preToolUse,
4019
- owner: "exe-os",
4020
- purpose: "Preflight guardrails before shell/tool execution.",
4021
- runtimes: ["claude", "codex", "opencode"],
4022
- checkpointRole: "none"
4023
- },
4024
- {
4025
- key: "subagentStop",
4026
- event: "SubagentStop",
4027
- commandMarker: EXE_HOOKS.subagentStop,
4028
- owner: "exe-os",
4029
- purpose: "Captures subagent completion context.",
4030
- runtimes: ["claude"],
4031
- checkpointRole: "none"
4032
- },
4033
- {
4034
- key: "preCompact",
4035
- event: "PreCompact",
4036
- commandMarker: EXE_HOOKS.preCompact,
4037
- owner: "exe-os",
4038
- purpose: "Writes active-task snapshot and compaction recovery context.",
4039
- runtimes: ["claude"],
4040
- checkpointRole: "recovery_context"
4041
- },
4042
- {
4043
- key: "postCompact",
4044
- event: "PostCompact",
4045
- commandMarker: EXE_HOOKS.postCompact,
4046
- owner: "exe-os",
4047
- purpose: "Rehydrates recovery context after compaction.",
4048
- runtimes: ["claude"],
4049
- checkpointRole: "recovery_context"
4050
- },
4051
- {
4052
- key: "sessionEnd",
4053
- event: "SessionEnd",
4054
- commandMarker: EXE_HOOKS.sessionEnd,
4055
- owner: "exe-os",
4056
- purpose: "Stores session-end checkpoint and triages orphaned in-progress tasks.",
4057
- runtimes: ["claude"],
4058
- checkpointRole: "session_summary"
4059
- },
4060
- {
4061
- key: "notification",
4062
- event: "Notification",
4063
- commandMarker: EXE_HOOKS.notification,
4064
- owner: "exe-os",
4065
- purpose: "Captures runtime notifications and nudges.",
4066
- runtimes: ["claude"],
4067
- checkpointRole: "none"
4068
- },
4069
- {
4070
- key: "instructionsLoaded",
4071
- event: "InstructionsLoaded",
4072
- commandMarker: EXE_HOOKS.instructionsLoaded,
4073
- owner: "exe-os",
4074
- purpose: "Applies runtime instruction post-processing.",
4075
- runtimes: ["claude"],
4076
- checkpointRole: "none"
4077
- }
4078
- ];
4079
3969
  LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS = [
4080
3970
  "dist/hooks/ingest.js",
4081
3971
  "dist/hooks/error-recall.js",
@@ -3934,7 +3934,7 @@ var init_preferences = __esm({
3934
3934
  function textHasLegacySplitPostToolHook(text) {
3935
3935
  return [EXE_HOOK_FILES.ingest, EXE_HOOK_FILES.errorRecall, EXE_HOOK_FILES.ingestWorker].some((file) => text.includes(file));
3936
3936
  }
3937
- var EXE_HOOK_FILES, EXE_HOOKS, EXE_HOOK_MANIFEST;
3937
+ var EXE_HOOK_FILES;
3938
3938
  var init_runtime_hook_manifest = __esm({
3939
3939
  "src/adapters/runtime-hook-manifest.ts"() {
3940
3940
  "use strict";
@@ -3944,130 +3944,6 @@ var init_runtime_hook_manifest = __esm({
3944
3944
  errorRecall: "error-recall.js",
3945
3945
  ingestWorker: "ingest-worker.js"
3946
3946
  };
3947
- EXE_HOOKS = {
3948
- postToolCombined: "dist/hooks/post-tool-combined.js",
3949
- sessionStart: "dist/hooks/session-start.js",
3950
- promptSubmit: "dist/hooks/prompt-submit.js",
3951
- heartbeat: "dist/hooks/exe-heartbeat-hook.js",
3952
- stop: "dist/hooks/stop.js",
3953
- preToolUse: "dist/hooks/pre-tool-use.js",
3954
- subagentStop: "dist/hooks/subagent-stop.js",
3955
- preCompact: "dist/hooks/pre-compact.js",
3956
- postCompact: "dist/hooks/post-compact.js",
3957
- sessionEnd: "dist/hooks/session-end.js",
3958
- notification: "dist/hooks/notification.js",
3959
- instructionsLoaded: "dist/hooks/instructions-loaded.js"
3960
- };
3961
- EXE_HOOK_MANIFEST = [
3962
- {
3963
- key: "postToolCombined",
3964
- event: "PostToolUse",
3965
- commandMarker: EXE_HOOKS.postToolCombined,
3966
- owner: "exe-os",
3967
- purpose: "Single PostToolUse entrypoint for ingestion, error recall, summaries, and bug detection.",
3968
- runtimes: ["claude", "codex", "opencode"],
3969
- checkpointRole: "none"
3970
- },
3971
- {
3972
- key: "sessionStart",
3973
- event: "SessionStart",
3974
- commandMarker: EXE_HOOKS.sessionStart,
3975
- owner: "exe-os",
3976
- purpose: "Loads agent identity, procedures, and boot context.",
3977
- runtimes: ["claude", "codex", "opencode"],
3978
- checkpointRole: "none"
3979
- },
3980
- {
3981
- key: "promptSubmit",
3982
- event: "UserPromptSubmit",
3983
- commandMarker: EXE_HOOKS.promptSubmit,
3984
- owner: "exe-os",
3985
- purpose: "Injects current tasks, pending reviews, and local context before each prompt.",
3986
- runtimes: ["claude", "codex", "opencode"],
3987
- checkpointRole: "none"
3988
- },
3989
- {
3990
- key: "heartbeat",
3991
- event: "UserPromptSubmit",
3992
- commandMarker: EXE_HOOKS.heartbeat,
3993
- owner: "exe-os",
3994
- purpose: "Lightweight heartbeat/status sidecar for Claude Code sessions.",
3995
- runtimes: ["claude"],
3996
- checkpointRole: "none"
3997
- },
3998
- {
3999
- key: "stop",
4000
- event: "Stop",
4001
- commandMarker: EXE_HOOKS.stop,
4002
- owner: "exe-os",
4003
- purpose: "Finalizes task state, capacity signals, and emergency checkpointing.",
4004
- runtimes: ["claude", "codex", "opencode"],
4005
- checkpointRole: "capacity_checkpoint"
4006
- },
4007
- {
4008
- key: "preToolUse",
4009
- event: "PreToolUse",
4010
- commandMarker: EXE_HOOKS.preToolUse,
4011
- owner: "exe-os",
4012
- purpose: "Preflight guardrails before shell/tool execution.",
4013
- runtimes: ["claude", "codex", "opencode"],
4014
- checkpointRole: "none"
4015
- },
4016
- {
4017
- key: "subagentStop",
4018
- event: "SubagentStop",
4019
- commandMarker: EXE_HOOKS.subagentStop,
4020
- owner: "exe-os",
4021
- purpose: "Captures subagent completion context.",
4022
- runtimes: ["claude"],
4023
- checkpointRole: "none"
4024
- },
4025
- {
4026
- key: "preCompact",
4027
- event: "PreCompact",
4028
- commandMarker: EXE_HOOKS.preCompact,
4029
- owner: "exe-os",
4030
- purpose: "Writes active-task snapshot and compaction recovery context.",
4031
- runtimes: ["claude"],
4032
- checkpointRole: "recovery_context"
4033
- },
4034
- {
4035
- key: "postCompact",
4036
- event: "PostCompact",
4037
- commandMarker: EXE_HOOKS.postCompact,
4038
- owner: "exe-os",
4039
- purpose: "Rehydrates recovery context after compaction.",
4040
- runtimes: ["claude"],
4041
- checkpointRole: "recovery_context"
4042
- },
4043
- {
4044
- key: "sessionEnd",
4045
- event: "SessionEnd",
4046
- commandMarker: EXE_HOOKS.sessionEnd,
4047
- owner: "exe-os",
4048
- purpose: "Stores session-end checkpoint and triages orphaned in-progress tasks.",
4049
- runtimes: ["claude"],
4050
- checkpointRole: "session_summary"
4051
- },
4052
- {
4053
- key: "notification",
4054
- event: "Notification",
4055
- commandMarker: EXE_HOOKS.notification,
4056
- owner: "exe-os",
4057
- purpose: "Captures runtime notifications and nudges.",
4058
- runtimes: ["claude"],
4059
- checkpointRole: "none"
4060
- },
4061
- {
4062
- key: "instructionsLoaded",
4063
- event: "InstructionsLoaded",
4064
- commandMarker: EXE_HOOKS.instructionsLoaded,
4065
- owner: "exe-os",
4066
- purpose: "Applies runtime instruction post-processing.",
4067
- runtimes: ["claude"],
4068
- checkpointRole: "none"
4069
- }
4070
- ];
4071
3947
  }
4072
3948
  });
4073
3949
 
@@ -615,7 +615,7 @@ function commandHasAnyMarker(command, markers) {
615
615
  function isLegacySplitPostToolCommand(command) {
616
616
  return commandHasAnyMarker(command, LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS);
617
617
  }
618
- var EXE_HOOKS, EXE_HOOK_MANIFEST, LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS;
618
+ var EXE_HOOKS, LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS;
619
619
  var init_runtime_hook_manifest = __esm({
620
620
  "src/adapters/runtime-hook-manifest.ts"() {
621
621
  "use strict";
@@ -633,116 +633,6 @@ var init_runtime_hook_manifest = __esm({
633
633
  notification: "dist/hooks/notification.js",
634
634
  instructionsLoaded: "dist/hooks/instructions-loaded.js"
635
635
  };
636
- EXE_HOOK_MANIFEST = [
637
- {
638
- key: "postToolCombined",
639
- event: "PostToolUse",
640
- commandMarker: EXE_HOOKS.postToolCombined,
641
- owner: "exe-os",
642
- purpose: "Single PostToolUse entrypoint for ingestion, error recall, summaries, and bug detection.",
643
- runtimes: ["claude", "codex", "opencode"],
644
- checkpointRole: "none"
645
- },
646
- {
647
- key: "sessionStart",
648
- event: "SessionStart",
649
- commandMarker: EXE_HOOKS.sessionStart,
650
- owner: "exe-os",
651
- purpose: "Loads agent identity, procedures, and boot context.",
652
- runtimes: ["claude", "codex", "opencode"],
653
- checkpointRole: "none"
654
- },
655
- {
656
- key: "promptSubmit",
657
- event: "UserPromptSubmit",
658
- commandMarker: EXE_HOOKS.promptSubmit,
659
- owner: "exe-os",
660
- purpose: "Injects current tasks, pending reviews, and local context before each prompt.",
661
- runtimes: ["claude", "codex", "opencode"],
662
- checkpointRole: "none"
663
- },
664
- {
665
- key: "heartbeat",
666
- event: "UserPromptSubmit",
667
- commandMarker: EXE_HOOKS.heartbeat,
668
- owner: "exe-os",
669
- purpose: "Lightweight heartbeat/status sidecar for Claude Code sessions.",
670
- runtimes: ["claude"],
671
- checkpointRole: "none"
672
- },
673
- {
674
- key: "stop",
675
- event: "Stop",
676
- commandMarker: EXE_HOOKS.stop,
677
- owner: "exe-os",
678
- purpose: "Finalizes task state, capacity signals, and emergency checkpointing.",
679
- runtimes: ["claude", "codex", "opencode"],
680
- checkpointRole: "capacity_checkpoint"
681
- },
682
- {
683
- key: "preToolUse",
684
- event: "PreToolUse",
685
- commandMarker: EXE_HOOKS.preToolUse,
686
- owner: "exe-os",
687
- purpose: "Preflight guardrails before shell/tool execution.",
688
- runtimes: ["claude", "codex", "opencode"],
689
- checkpointRole: "none"
690
- },
691
- {
692
- key: "subagentStop",
693
- event: "SubagentStop",
694
- commandMarker: EXE_HOOKS.subagentStop,
695
- owner: "exe-os",
696
- purpose: "Captures subagent completion context.",
697
- runtimes: ["claude"],
698
- checkpointRole: "none"
699
- },
700
- {
701
- key: "preCompact",
702
- event: "PreCompact",
703
- commandMarker: EXE_HOOKS.preCompact,
704
- owner: "exe-os",
705
- purpose: "Writes active-task snapshot and compaction recovery context.",
706
- runtimes: ["claude"],
707
- checkpointRole: "recovery_context"
708
- },
709
- {
710
- key: "postCompact",
711
- event: "PostCompact",
712
- commandMarker: EXE_HOOKS.postCompact,
713
- owner: "exe-os",
714
- purpose: "Rehydrates recovery context after compaction.",
715
- runtimes: ["claude"],
716
- checkpointRole: "recovery_context"
717
- },
718
- {
719
- key: "sessionEnd",
720
- event: "SessionEnd",
721
- commandMarker: EXE_HOOKS.sessionEnd,
722
- owner: "exe-os",
723
- purpose: "Stores session-end checkpoint and triages orphaned in-progress tasks.",
724
- runtimes: ["claude"],
725
- checkpointRole: "session_summary"
726
- },
727
- {
728
- key: "notification",
729
- event: "Notification",
730
- commandMarker: EXE_HOOKS.notification,
731
- owner: "exe-os",
732
- purpose: "Captures runtime notifications and nudges.",
733
- runtimes: ["claude"],
734
- checkpointRole: "none"
735
- },
736
- {
737
- key: "instructionsLoaded",
738
- event: "InstructionsLoaded",
739
- commandMarker: EXE_HOOKS.instructionsLoaded,
740
- owner: "exe-os",
741
- purpose: "Applies runtime instruction post-processing.",
742
- runtimes: ["claude"],
743
- checkpointRole: "none"
744
- }
745
- ];
746
636
  LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS = [
747
637
  "dist/hooks/ingest.js",
748
638
  "dist/hooks/error-recall.js",
package/dist/bin/setup.js CHANGED
@@ -4544,31 +4544,43 @@ function logError(msg) {
4544
4544
  } catch {
4545
4545
  }
4546
4546
  }
4547
+ function isTruthyEnv(value) {
4548
+ return /^(1|true|yes|on)$/i.test(value ?? "");
4549
+ }
4547
4550
  function loadPgClient() {
4548
4551
  if (_pgFailed) return null;
4549
- const postgresUrl = process.env.DATABASE_URL;
4550
4552
  const configPath = path12.join(EXE_AI_DIR, "config.json");
4551
4553
  let cloudPostgresUrl;
4554
+ let configEnabled = false;
4552
4555
  try {
4553
4556
  if (existsSync12(configPath)) {
4554
4557
  const cfg = JSON.parse(readFileSync8(configPath, "utf8"));
4555
4558
  cloudPostgresUrl = cfg.cloud?.postgresUrl;
4556
- if (cfg.cloud?.syncToPostgres === false) {
4557
- _pgFailed = true;
4558
- return null;
4559
- }
4559
+ configEnabled = cfg.cloud?.syncToPostgres === true;
4560
4560
  }
4561
4561
  } catch {
4562
4562
  }
4563
- const url = postgresUrl || cloudPostgresUrl;
4563
+ const envEnabled = isTruthyEnv(process.env.EXE_CLOUD_SYNC_TO_POSTGRES);
4564
+ if (!envEnabled && !configEnabled) {
4565
+ return null;
4566
+ }
4567
+ const url = process.env.DATABASE_URL || cloudPostgresUrl;
4564
4568
  if (!url) {
4565
4569
  _pgFailed = true;
4566
4570
  return null;
4567
4571
  }
4568
4572
  if (!_pgPromise) {
4569
4573
  _pgPromise = (async () => {
4574
+ if (!process.env.DATABASE_URL) process.env.DATABASE_URL = url;
4570
4575
  const { createRequire: createRequire3 } = await import("module");
4571
4576
  const { pathToFileURL: pathToFileURL3 } = await import("url");
4577
+ const explicitPath = process.env.EXE_OS_PRISMA_CLIENT_PATH;
4578
+ if (explicitPath) {
4579
+ const mod2 = await import(pathToFileURL3(explicitPath).href);
4580
+ const Ctor2 = mod2.PrismaClient ?? mod2.default?.PrismaClient;
4581
+ if (!Ctor2) throw new Error(`No PrismaClient at ${explicitPath}`);
4582
+ return new Ctor2();
4583
+ }
4572
4584
  const exeDbRoot = process.env.EXE_DB_ROOT ?? path12.join(homedir2(), "exe-db");
4573
4585
  const req = createRequire3(path12.join(exeDbRoot, "package.json"));
4574
4586
  const entry = req.resolve("@prisma/client");
@@ -4765,6 +4777,15 @@ async function cloudSync(config) {
4765
4777
  } catch {
4766
4778
  throw new Error("[cloud-sync] Database not initialized. Call initStore() before cloudSync().");
4767
4779
  }
4780
+ try {
4781
+ const relink = await client.execute("SELECT value FROM sync_meta WHERE key = 'cloud_relink_required' LIMIT 1");
4782
+ if (String(relink.rows[0]?.value ?? "") === "1") {
4783
+ throw new Error("[cloud-sync] Paused after key rotation. Re-link/reupload cloud sync with the new recovery phrase before syncing.");
4784
+ }
4785
+ } catch (err) {
4786
+ const msg = err instanceof Error ? err.message : String(err);
4787
+ if (msg.includes("Paused after key rotation")) throw err;
4788
+ }
4768
4789
  try {
4769
4790
  const { getRawClient: getRawClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
4770
4791
  await getRawClient2().execute("PRAGMA wal_checkpoint(PASSIVE)");