@askexenow/exe-os 0.9.87 → 0.9.89

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 (102) hide show
  1. package/deploy/compose/docker-compose.yml +3 -3
  2. package/dist/bin/age-ontology-load.js +8 -2
  3. package/dist/bin/agentic-ontology-backfill.js +11 -0
  4. package/dist/bin/agentic-reflection-backfill.js +11 -0
  5. package/dist/bin/agentic-semantic-label.js +11 -0
  6. package/dist/bin/backfill-conversations.js +12 -0
  7. package/dist/bin/backfill-responses.js +12 -0
  8. package/dist/bin/backfill-vectors.js +12 -0
  9. package/dist/bin/bulk-sync-postgres.js +29 -1
  10. package/dist/bin/cc-doctor.js +3 -2
  11. package/dist/bin/cleanup-stale-review-tasks.js +12 -0
  12. package/dist/bin/cli.js +170 -15
  13. package/dist/bin/exe-agent.js +1 -0
  14. package/dist/bin/exe-assign.js +12 -0
  15. package/dist/bin/exe-boot.js +139 -4
  16. package/dist/bin/exe-call.js +2 -0
  17. package/dist/bin/exe-cloud.js +138 -3
  18. package/dist/bin/exe-dispatch.js +12 -1
  19. package/dist/bin/exe-doctor.js +12 -0
  20. package/dist/bin/exe-export-behaviors.js +11 -0
  21. package/dist/bin/exe-forget.js +12 -0
  22. package/dist/bin/exe-gateway.js +132 -35
  23. package/dist/bin/exe-healthcheck.js +2 -1
  24. package/dist/bin/exe-heartbeat.js +12 -0
  25. package/dist/bin/exe-kill.js +11 -0
  26. package/dist/bin/exe-launch-agent.js +11 -0
  27. package/dist/bin/exe-new-employee.js +4 -2
  28. package/dist/bin/exe-pending-messages.js +11 -0
  29. package/dist/bin/exe-pending-notifications.js +12 -0
  30. package/dist/bin/exe-pending-reviews.js +12 -0
  31. package/dist/bin/exe-rename.js +12 -0
  32. package/dist/bin/exe-review.js +12 -0
  33. package/dist/bin/exe-search.js +12 -0
  34. package/dist/bin/exe-session-cleanup.js +12 -1
  35. package/dist/bin/exe-settings.js +3 -0
  36. package/dist/bin/exe-start-codex.js +13 -2
  37. package/dist/bin/exe-start-opencode.js +13 -2
  38. package/dist/bin/exe-status.js +12 -0
  39. package/dist/bin/exe-team.js +12 -0
  40. package/dist/bin/git-sweep.js +12 -1
  41. package/dist/bin/graph-backfill.js +11 -0
  42. package/dist/bin/graph-export.js +11 -0
  43. package/dist/bin/graph-layer-benchmark.js +9 -1
  44. package/dist/bin/intercom-check.js +13 -1
  45. package/dist/bin/list-providers.js +1 -0
  46. package/dist/bin/postgres-agentic-reflection-backfill.js +7 -1
  47. package/dist/bin/postgres-agentic-semantic-backfill.js +7 -1
  48. package/dist/bin/registry-proxy.js +1 -0
  49. package/dist/bin/scan-tasks.js +13 -1
  50. package/dist/bin/setup.js +141 -7
  51. package/dist/bin/shard-migrate.js +11 -0
  52. package/dist/bin/stack-update.js +24 -7
  53. package/dist/bin/update.js +5 -0
  54. package/dist/gateway/index.js +12 -1
  55. package/dist/hooks/bug-report-worker.js +12 -1
  56. package/dist/hooks/codex-stop-task-finalizer.js +12 -1
  57. package/dist/hooks/commit-complete.js +12 -1
  58. package/dist/hooks/error-recall.js +11 -0
  59. package/dist/hooks/ingest.js +11 -0
  60. package/dist/hooks/instructions-loaded.js +11 -0
  61. package/dist/hooks/notification.js +11 -0
  62. package/dist/hooks/post-compact.js +11 -0
  63. package/dist/hooks/post-tool-combined.js +11 -0
  64. package/dist/hooks/pre-compact.js +12 -1
  65. package/dist/hooks/pre-tool-use.js +11 -0
  66. package/dist/hooks/prompt-submit.js +12 -1
  67. package/dist/hooks/session-end.js +12 -1
  68. package/dist/hooks/session-start.js +11 -0
  69. package/dist/hooks/stop.js +11 -0
  70. package/dist/hooks/subagent-stop.js +11 -0
  71. package/dist/hooks/summary-worker.js +137 -3
  72. package/dist/index.js +12 -1
  73. package/dist/lib/cloud-sync.js +136 -2
  74. package/dist/lib/consolidation.js +1 -0
  75. package/dist/lib/database.js +11 -0
  76. package/dist/lib/db.js +11 -0
  77. package/dist/lib/device-registry.js +11 -0
  78. package/dist/lib/employee-templates.js +1 -0
  79. package/dist/lib/exe-daemon.js +771 -49
  80. package/dist/lib/hybrid-search.js +11 -0
  81. package/dist/lib/identity.js +1 -0
  82. package/dist/lib/messaging.js +2 -1
  83. package/dist/lib/reminders.js +1 -0
  84. package/dist/lib/schedules.js +11 -0
  85. package/dist/lib/skill-learning.js +1 -0
  86. package/dist/lib/store.js +11 -0
  87. package/dist/lib/tasks.js +2 -1
  88. package/dist/lib/tmux-routing.js +2 -1
  89. package/dist/lib/token-spend.js +1 -0
  90. package/dist/lib/ws-client.js +8 -0
  91. package/dist/mcp/server.js +613 -27
  92. package/dist/mcp/tools/complete-reminder.js +1 -0
  93. package/dist/mcp/tools/create-reminder.js +1 -0
  94. package/dist/mcp/tools/create-task.js +2 -1
  95. package/dist/mcp/tools/deactivate-behavior.js +1 -0
  96. package/dist/mcp/tools/list-reminders.js +1 -0
  97. package/dist/mcp/tools/list-tasks.js +1 -0
  98. package/dist/mcp/tools/send-message.js +2 -1
  99. package/dist/mcp/tools/update-task.js +2 -1
  100. package/dist/runtime/index.js +12 -1
  101. package/dist/tui/App.js +12 -1
  102. package/package.json +2 -2
@@ -2286,6 +2286,7 @@ __export(database_exports, {
2286
2286
  isInitialized: () => isInitialized,
2287
2287
  setExternalClient: () => setExternalClient
2288
2288
  });
2289
+ import { chmodSync as chmodSync2 } from "fs";
2289
2290
  import { createClient } from "@libsql/client";
2290
2291
  async function initDatabase(config) {
2291
2292
  if (_walCheckpointTimer) {
@@ -2327,6 +2328,16 @@ async function initDatabase(config) {
2327
2328
  if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
2328
2329
  _adapterClient = await createPrismaDbAdapter(_resilientClient);
2329
2330
  }
2331
+ try {
2332
+ chmodSync2(config.dbPath, 384);
2333
+ for (const suffix of ["-wal", "-shm"]) {
2334
+ try {
2335
+ chmodSync2(config.dbPath + suffix, 384);
2336
+ } catch {
2337
+ }
2338
+ }
2339
+ } catch {
2340
+ }
2330
2341
  }
2331
2342
  function isInitialized() {
2332
2343
  return _adapterClient !== null || _client !== null;
@@ -2112,6 +2112,7 @@ __export(database_exports, {
2112
2112
  isInitialized: () => isInitialized,
2113
2113
  setExternalClient: () => setExternalClient
2114
2114
  });
2115
+ import { chmodSync as chmodSync2 } from "fs";
2115
2116
  import { createClient } from "@libsql/client";
2116
2117
  async function initDatabase(config) {
2117
2118
  if (_walCheckpointTimer) {
@@ -2153,6 +2154,16 @@ async function initDatabase(config) {
2153
2154
  if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
2154
2155
  _adapterClient = await createPrismaDbAdapter(_resilientClient);
2155
2156
  }
2157
+ try {
2158
+ chmodSync2(config.dbPath, 384);
2159
+ for (const suffix of ["-wal", "-shm"]) {
2160
+ try {
2161
+ chmodSync2(config.dbPath + suffix, 384);
2162
+ } catch {
2163
+ }
2164
+ }
2165
+ } catch {
2166
+ }
2156
2167
  }
2157
2168
  function isInitialized() {
2158
2169
  return _adapterClient !== null || _client !== null;
@@ -7323,7 +7334,7 @@ function readQueue() {
7323
7334
  function writeQueue(queue) {
7324
7335
  ensureDir();
7325
7336
  const tmp = `${QUEUE_PATH}.tmp`;
7326
- writeFileSync7(tmp, JSON.stringify(queue, null, 2));
7337
+ writeFileSync7(tmp, JSON.stringify(queue, null, 2), { mode: 384 });
7327
7338
  renameSync4(tmp, QUEUE_PATH);
7328
7339
  }
7329
7340
  function queueIntercom(targetSession, reason) {
@@ -785,7 +785,7 @@ function readQueue() {
785
785
  function writeQueue(queue) {
786
786
  ensureDir();
787
787
  const tmp = `${QUEUE_PATH}.tmp`;
788
- writeFileSync6(tmp, JSON.stringify(queue, null, 2));
788
+ writeFileSync6(tmp, JSON.stringify(queue, null, 2), { mode: 384 });
789
789
  renameSync3(tmp, QUEUE_PATH);
790
790
  }
791
791
  function queueIntercom(targetSession, reason) {
@@ -2293,6 +2293,7 @@ __export(database_exports, {
2293
2293
  isInitialized: () => isInitialized,
2294
2294
  setExternalClient: () => setExternalClient
2295
2295
  });
2296
+ import { chmodSync as chmodSync2 } from "fs";
2296
2297
  import { createClient } from "@libsql/client";
2297
2298
  async function initDatabase(config) {
2298
2299
  if (_walCheckpointTimer) {
@@ -2334,6 +2335,16 @@ async function initDatabase(config) {
2334
2335
  if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
2335
2336
  _adapterClient = await createPrismaDbAdapter(_resilientClient);
2336
2337
  }
2338
+ try {
2339
+ chmodSync2(config.dbPath, 384);
2340
+ for (const suffix of ["-wal", "-shm"]) {
2341
+ try {
2342
+ chmodSync2(config.dbPath + suffix, 384);
2343
+ } catch {
2344
+ }
2345
+ }
2346
+ } catch {
2347
+ }
2337
2348
  }
2338
2349
  function isInitialized() {
2339
2350
  return _adapterClient !== null || _client !== null;
@@ -2112,6 +2112,7 @@ __export(database_exports, {
2112
2112
  isInitialized: () => isInitialized,
2113
2113
  setExternalClient: () => setExternalClient
2114
2114
  });
2115
+ import { chmodSync as chmodSync2 } from "fs";
2115
2116
  import { createClient } from "@libsql/client";
2116
2117
  async function initDatabase(config) {
2117
2118
  if (_walCheckpointTimer) {
@@ -2153,6 +2154,16 @@ async function initDatabase(config) {
2153
2154
  if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
2154
2155
  _adapterClient = await createPrismaDbAdapter(_resilientClient);
2155
2156
  }
2157
+ try {
2158
+ chmodSync2(config.dbPath, 384);
2159
+ for (const suffix of ["-wal", "-shm"]) {
2160
+ try {
2161
+ chmodSync2(config.dbPath + suffix, 384);
2162
+ } catch {
2163
+ }
2164
+ }
2165
+ } catch {
2166
+ }
2156
2167
  }
2157
2168
  function isInitialized() {
2158
2169
  return _adapterClient !== null || _client !== null;
@@ -2034,6 +2034,7 @@ __export(database_exports, {
2034
2034
  isInitialized: () => isInitialized,
2035
2035
  setExternalClient: () => setExternalClient
2036
2036
  });
2037
+ import { chmodSync as chmodSync2 } from "fs";
2037
2038
  import { createClient } from "@libsql/client";
2038
2039
  async function initDatabase(config) {
2039
2040
  if (_walCheckpointTimer) {
@@ -2075,6 +2076,16 @@ async function initDatabase(config) {
2075
2076
  if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
2076
2077
  _adapterClient = await createPrismaDbAdapter(_resilientClient);
2077
2078
  }
2079
+ try {
2080
+ chmodSync2(config.dbPath, 384);
2081
+ for (const suffix of ["-wal", "-shm"]) {
2082
+ try {
2083
+ chmodSync2(config.dbPath + suffix, 384);
2084
+ } catch {
2085
+ }
2086
+ }
2087
+ } catch {
2088
+ }
2078
2089
  }
2079
2090
  function isInitialized() {
2080
2091
  return _adapterClient !== null || _client !== null;
@@ -2006,6 +2006,7 @@ __export(database_exports, {
2006
2006
  isInitialized: () => isInitialized,
2007
2007
  setExternalClient: () => setExternalClient
2008
2008
  });
2009
+ import { chmodSync as chmodSync2 } from "fs";
2009
2010
  import { createClient } from "@libsql/client";
2010
2011
  async function initDatabase(config) {
2011
2012
  if (_walCheckpointTimer) {
@@ -2047,6 +2048,16 @@ async function initDatabase(config) {
2047
2048
  if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
2048
2049
  _adapterClient = await createPrismaDbAdapter(_resilientClient);
2049
2050
  }
2051
+ try {
2052
+ chmodSync2(config.dbPath, 384);
2053
+ for (const suffix of ["-wal", "-shm"]) {
2054
+ try {
2055
+ chmodSync2(config.dbPath + suffix, 384);
2056
+ } catch {
2057
+ }
2058
+ }
2059
+ } catch {
2060
+ }
2050
2061
  }
2051
2062
  function isInitialized() {
2052
2063
  return _adapterClient !== null || _client !== null;
@@ -1773,6 +1773,7 @@ __export(database_exports, {
1773
1773
  isInitialized: () => isInitialized,
1774
1774
  setExternalClient: () => setExternalClient
1775
1775
  });
1776
+ import { chmodSync as chmodSync2 } from "fs";
1776
1777
  import { createClient } from "@libsql/client";
1777
1778
  async function initDatabase(config) {
1778
1779
  if (_walCheckpointTimer) {
@@ -1814,6 +1815,16 @@ async function initDatabase(config) {
1814
1815
  if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
1815
1816
  _adapterClient = await createPrismaDbAdapter(_resilientClient);
1816
1817
  }
1818
+ try {
1819
+ chmodSync2(config.dbPath, 384);
1820
+ for (const suffix of ["-wal", "-shm"]) {
1821
+ try {
1822
+ chmodSync2(config.dbPath + suffix, 384);
1823
+ } catch {
1824
+ }
1825
+ }
1826
+ } catch {
1827
+ }
1817
1828
  }
1818
1829
  function isInitialized() {
1819
1830
  return _adapterClient !== null || _client !== null;
@@ -5921,6 +5932,21 @@ var init_crdt_sync = __esm({
5921
5932
  }
5922
5933
  });
5923
5934
 
5935
+ // src/lib/pg-ssl.ts
5936
+ var pg_ssl_exports = {};
5937
+ __export(pg_ssl_exports, {
5938
+ pgSslConfig: () => pgSslConfig
5939
+ });
5940
+ function pgSslConfig() {
5941
+ if (process.env.EXE_DB_SSL_DISABLED === "true") return {};
5942
+ return { ssl: { rejectUnauthorized: process.env.EXE_DB_SSL_ALLOW_SELFSIGNED !== "true" } };
5943
+ }
5944
+ var init_pg_ssl = __esm({
5945
+ "src/lib/pg-ssl.ts"() {
5946
+ "use strict";
5947
+ }
5948
+ });
5949
+
5924
5950
  // src/lib/db-backup.ts
5925
5951
  var db_backup_exports = {};
5926
5952
  __export(db_backup_exports, {
@@ -6034,6 +6060,7 @@ __export(cloud_sync_exports, {
6034
6060
  cloudPull: () => cloudPull,
6035
6061
  cloudPullBehaviors: () => cloudPullBehaviors,
6036
6062
  cloudPullBlob: () => cloudPullBlob,
6063
+ cloudPullCodeContext: () => cloudPullCodeContext,
6037
6064
  cloudPullConversations: () => cloudPullConversations,
6038
6065
  cloudPullDocuments: () => cloudPullDocuments,
6039
6066
  cloudPullGlobalProcedures: () => cloudPullGlobalProcedures,
@@ -6043,6 +6070,7 @@ __export(cloud_sync_exports, {
6043
6070
  cloudPush: () => cloudPush,
6044
6071
  cloudPushBehaviors: () => cloudPushBehaviors,
6045
6072
  cloudPushBlob: () => cloudPushBlob,
6073
+ cloudPushCodeContext: () => cloudPushCodeContext,
6046
6074
  cloudPushConversations: () => cloudPushConversations,
6047
6075
  cloudPushDocuments: () => cloudPushDocuments,
6048
6076
  cloudPushGlobalProcedures: () => cloudPushGlobalProcedures,
@@ -6121,7 +6149,8 @@ function loadPgClient() {
6121
6149
  return new Ctor();
6122
6150
  }
6123
6151
  const { Pool } = await import("pg");
6124
- const pool = new Pool({ connectionString: process.env.DATABASE_URL });
6152
+ const { pgSslConfig: pgSslConfig2 } = await Promise.resolve().then(() => (init_pg_ssl(), pg_ssl_exports));
6153
+ const pool = new Pool({ connectionString: process.env.DATABASE_URL, ...pgSslConfig2() });
6125
6154
  return {
6126
6155
  async $queryRawUnsafe(query, ...values) {
6127
6156
  const result = await pool.query(query, values);
@@ -6666,6 +6695,17 @@ async function cloudSync(config) {
6666
6695
  } catch (err) {
6667
6696
  logError(`[cloud-sync] DB backup upload error: ${err instanceof Error ? err.message : String(err)}`);
6668
6697
  }
6698
+ let codeContextResult = { pushed: 0, pulled: 0 };
6699
+ try {
6700
+ codeContextResult.pushed = await cloudPushCodeContext(config);
6701
+ } catch (err) {
6702
+ logError(`[cloud-sync] Code context push: ${err instanceof Error ? err.message : String(err)}`);
6703
+ }
6704
+ try {
6705
+ codeContextResult.pulled = await cloudPullCodeContext(config);
6706
+ } catch (err) {
6707
+ logError(`[cloud-sync] Code context pull: ${err instanceof Error ? err.message : String(err)}`);
6708
+ }
6669
6709
  return {
6670
6710
  pushed,
6671
6711
  pulled,
@@ -6675,7 +6715,8 @@ async function cloudSync(config) {
6675
6715
  tasks: tasksResult,
6676
6716
  conversations: conversationsResult,
6677
6717
  documents: documentsResult,
6678
- roster: rosterResult
6718
+ roster: rosterResult,
6719
+ codeContext: codeContextResult
6679
6720
  };
6680
6721
  }
6681
6722
  function recordRosterDeletion(name) {
@@ -7313,7 +7354,99 @@ async function cloudPullDocuments(config) {
7313
7354
  }
7314
7355
  return { pulled };
7315
7356
  }
7316
- var LOCALHOST_PATTERNS, FETCH_TIMEOUT_MS, PUSH_BATCH_SIZE, ROSTER_LOCK_PATH, LOCK_STALE_MS, _pgPromise, _pgFailed, CLOUD_REUPLOAD_REQUIRED_MESSAGE, ROSTER_DELETIONS_PATH;
7357
+ async function cloudPushCodeContext(config) {
7358
+ assertSecureEndpoint(config.endpoint);
7359
+ if (!existsSync19(CODE_CONTEXT_DIR)) return 0;
7360
+ const files = readdirSync6(CODE_CONTEXT_DIR).filter(
7361
+ (f) => f.endsWith(".json") && !f.endsWith(".vectors.json") && !f.startsWith(".")
7362
+ );
7363
+ if (files.length === 0) return 0;
7364
+ const metaPath = path20.join(CODE_CONTEXT_DIR, ".sync-meta.json");
7365
+ let syncMeta = {};
7366
+ if (existsSync19(metaPath)) {
7367
+ try {
7368
+ syncMeta = JSON.parse(readFileSync13(metaPath, "utf-8"));
7369
+ } catch {
7370
+ }
7371
+ }
7372
+ let pushed = 0;
7373
+ for (const file of files) {
7374
+ const filePath = path20.join(CODE_CONTEXT_DIR, file);
7375
+ try {
7376
+ const stat = statSync6(filePath);
7377
+ const lastPushed = syncMeta[file] ?? 0;
7378
+ if (stat.mtimeMs <= lastPushed) continue;
7379
+ const content = readFileSync13(filePath, "utf-8");
7380
+ const header = content.substring(0, 300);
7381
+ if (header.includes("/tmp") || header.includes("/var/folders") || header.includes(".worktrees/")) continue;
7382
+ const compressed = compress(Buffer.from(content, "utf8"));
7383
+ const encrypted = encryptSyncBlob(compressed);
7384
+ const resp = await fetchWithRetry(`${config.endpoint}/sync/push-code-context`, {
7385
+ method: "POST",
7386
+ headers: {
7387
+ Authorization: `Bearer ${config.apiKey}`,
7388
+ "Content-Type": "application/json",
7389
+ "X-Device-Id": loadDeviceId()
7390
+ },
7391
+ body: JSON.stringify({ key: file, blob: encrypted })
7392
+ });
7393
+ if (resp.ok) {
7394
+ syncMeta[file] = stat.mtimeMs;
7395
+ pushed++;
7396
+ }
7397
+ } catch {
7398
+ }
7399
+ }
7400
+ if (pushed > 0) {
7401
+ try {
7402
+ writeFileSync9(metaPath, JSON.stringify(syncMeta));
7403
+ } catch {
7404
+ }
7405
+ }
7406
+ return pushed;
7407
+ }
7408
+ async function cloudPullCodeContext(config) {
7409
+ assertSecureEndpoint(config.endpoint);
7410
+ try {
7411
+ const resp = await fetchWithRetry(`${config.endpoint}/sync/pull-code-context`, {
7412
+ method: "GET",
7413
+ headers: {
7414
+ Authorization: `Bearer ${config.apiKey}`,
7415
+ "X-Device-Id": loadDeviceId()
7416
+ }
7417
+ });
7418
+ if (!resp.ok) return 0;
7419
+ const data = await resp.json();
7420
+ if (!data.indexes || data.indexes.length === 0) return 0;
7421
+ mkdirSync10(CODE_CONTEXT_DIR, { recursive: true });
7422
+ let pulled = 0;
7423
+ for (const { key, blob } of data.indexes) {
7424
+ try {
7425
+ if (key.endsWith(".vectors.json")) continue;
7426
+ const localPath = path20.join(CODE_CONTEXT_DIR, key);
7427
+ const compressed = decryptSyncBlob(blob);
7428
+ const content = decompress(compressed).toString("utf8");
7429
+ if (!existsSync19(localPath)) {
7430
+ writeFileSync9(localPath, content, "utf-8");
7431
+ pulled++;
7432
+ } else {
7433
+ const localContent = readFileSync13(localPath, "utf-8");
7434
+ if (localContent.length !== content.length) {
7435
+ writeFileSync9(localPath, content, "utf-8");
7436
+ pulled++;
7437
+ }
7438
+ }
7439
+ } catch {
7440
+ }
7441
+ }
7442
+ return pulled;
7443
+ } catch (err) {
7444
+ process.stderr.write(`[cloud-sync] Code context pull failed: ${err instanceof Error ? err.message : String(err)}
7445
+ `);
7446
+ return 0;
7447
+ }
7448
+ }
7449
+ var LOCALHOST_PATTERNS, FETCH_TIMEOUT_MS, PUSH_BATCH_SIZE, ROSTER_LOCK_PATH, LOCK_STALE_MS, _pgPromise, _pgFailed, CLOUD_REUPLOAD_REQUIRED_MESSAGE, ROSTER_DELETIONS_PATH, CODE_CONTEXT_DIR;
7317
7450
  var init_cloud_sync = __esm({
7318
7451
  "src/lib/cloud-sync.ts"() {
7319
7452
  "use strict";
@@ -7334,6 +7467,7 @@ var init_cloud_sync = __esm({
7334
7467
  _pgFailed = false;
7335
7468
  CLOUD_REUPLOAD_REQUIRED_MESSAGE = "Cloud sync is blocked because this device rotated its memory encryption key. Run `exe-os cloud reupload` first to re-upload the cloud backup with the new key.";
7336
7469
  ROSTER_DELETIONS_PATH = path20.join(EXE_AI_DIR, "roster-deletions.json");
7470
+ CODE_CONTEXT_DIR = path20.join(EXE_AI_DIR, "code-context");
7337
7471
  }
7338
7472
  });
7339
7473
 
package/dist/index.js CHANGED
@@ -1069,7 +1069,7 @@ function readQueue() {
1069
1069
  function writeQueue(queue) {
1070
1070
  ensureDir();
1071
1071
  const tmp = `${QUEUE_PATH}.tmp`;
1072
- writeFileSync4(tmp, JSON.stringify(queue, null, 2));
1072
+ writeFileSync4(tmp, JSON.stringify(queue, null, 2), { mode: 384 });
1073
1073
  renameSync3(tmp, QUEUE_PATH);
1074
1074
  }
1075
1075
  function queueIntercom(targetSession, reason) {
@@ -2511,6 +2511,7 @@ __export(database_exports, {
2511
2511
  isInitialized: () => isInitialized,
2512
2512
  setExternalClient: () => setExternalClient
2513
2513
  });
2514
+ import { chmodSync as chmodSync2 } from "fs";
2514
2515
  import { createClient } from "@libsql/client";
2515
2516
  async function initDatabase(config2) {
2516
2517
  if (_walCheckpointTimer) {
@@ -2552,6 +2553,16 @@ async function initDatabase(config2) {
2552
2553
  if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
2553
2554
  _adapterClient = await createPrismaDbAdapter(_resilientClient);
2554
2555
  }
2556
+ try {
2557
+ chmodSync2(config2.dbPath, 384);
2558
+ for (const suffix of ["-wal", "-shm"]) {
2559
+ try {
2560
+ chmodSync2(config2.dbPath + suffix, 384);
2561
+ } catch {
2562
+ }
2563
+ }
2564
+ } catch {
2565
+ }
2555
2566
  }
2556
2567
  function isInitialized() {
2557
2568
  return _adapterClient !== null || _client !== null;
@@ -1425,6 +1425,7 @@ __export(database_exports, {
1425
1425
  isInitialized: () => isInitialized,
1426
1426
  setExternalClient: () => setExternalClient
1427
1427
  });
1428
+ import { chmodSync as chmodSync2 } from "fs";
1428
1429
  import { createClient } from "@libsql/client";
1429
1430
  async function initDatabase(config) {
1430
1431
  if (_walCheckpointTimer) {
@@ -1466,6 +1467,16 @@ async function initDatabase(config) {
1466
1467
  if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
1467
1468
  _adapterClient = await createPrismaDbAdapter(_resilientClient);
1468
1469
  }
1470
+ try {
1471
+ chmodSync2(config.dbPath, 384);
1472
+ for (const suffix of ["-wal", "-shm"]) {
1473
+ try {
1474
+ chmodSync2(config.dbPath + suffix, 384);
1475
+ } catch {
1476
+ }
1477
+ }
1478
+ } catch {
1479
+ }
1469
1480
  }
1470
1481
  function isInitialized() {
1471
1482
  return _adapterClient !== null || _client !== null;
@@ -3048,6 +3059,21 @@ var init_crdt_sync = __esm({
3048
3059
  }
3049
3060
  });
3050
3061
 
3062
+ // src/lib/pg-ssl.ts
3063
+ var pg_ssl_exports = {};
3064
+ __export(pg_ssl_exports, {
3065
+ pgSslConfig: () => pgSslConfig
3066
+ });
3067
+ function pgSslConfig() {
3068
+ if (process.env.EXE_DB_SSL_DISABLED === "true") return {};
3069
+ return { ssl: { rejectUnauthorized: process.env.EXE_DB_SSL_ALLOW_SELFSIGNED !== "true" } };
3070
+ }
3071
+ var init_pg_ssl = __esm({
3072
+ "src/lib/pg-ssl.ts"() {
3073
+ "use strict";
3074
+ }
3075
+ });
3076
+
3051
3077
  // src/lib/keychain.ts
3052
3078
  var keychain_exports = {};
3053
3079
  __export(keychain_exports, {
@@ -3801,7 +3827,8 @@ function loadPgClient() {
3801
3827
  return new Ctor();
3802
3828
  }
3803
3829
  const { Pool } = await import("pg");
3804
- const pool = new Pool({ connectionString: process.env.DATABASE_URL });
3830
+ const { pgSslConfig: pgSslConfig2 } = await Promise.resolve().then(() => (init_pg_ssl(), pg_ssl_exports));
3831
+ const pool = new Pool({ connectionString: process.env.DATABASE_URL, ...pgSslConfig2() });
3805
3832
  return {
3806
3833
  async $queryRawUnsafe(query, ...values) {
3807
3834
  const result = await pool.query(query, values);
@@ -4347,6 +4374,17 @@ async function cloudSync(config) {
4347
4374
  } catch (err) {
4348
4375
  logError(`[cloud-sync] DB backup upload error: ${err instanceof Error ? err.message : String(err)}`);
4349
4376
  }
4377
+ let codeContextResult = { pushed: 0, pulled: 0 };
4378
+ try {
4379
+ codeContextResult.pushed = await cloudPushCodeContext(config);
4380
+ } catch (err) {
4381
+ logError(`[cloud-sync] Code context push: ${err instanceof Error ? err.message : String(err)}`);
4382
+ }
4383
+ try {
4384
+ codeContextResult.pulled = await cloudPullCodeContext(config);
4385
+ } catch (err) {
4386
+ logError(`[cloud-sync] Code context pull: ${err instanceof Error ? err.message : String(err)}`);
4387
+ }
4350
4388
  return {
4351
4389
  pushed,
4352
4390
  pulled,
@@ -4356,7 +4394,8 @@ async function cloudSync(config) {
4356
4394
  tasks: tasksResult,
4357
4395
  conversations: conversationsResult,
4358
4396
  documents: documentsResult,
4359
- roster: rosterResult
4397
+ roster: rosterResult,
4398
+ codeContext: codeContextResult
4360
4399
  };
4361
4400
  }
4362
4401
  var ROSTER_DELETIONS_PATH = path10.join(EXE_AI_DIR, "roster-deletions.json");
@@ -4995,6 +5034,99 @@ async function cloudPullDocuments(config) {
4995
5034
  }
4996
5035
  return { pulled };
4997
5036
  }
5037
+ var CODE_CONTEXT_DIR = path10.join(EXE_AI_DIR, "code-context");
5038
+ async function cloudPushCodeContext(config) {
5039
+ assertSecureEndpoint(config.endpoint);
5040
+ if (!existsSync10(CODE_CONTEXT_DIR)) return 0;
5041
+ const files = readdirSync2(CODE_CONTEXT_DIR).filter(
5042
+ (f) => f.endsWith(".json") && !f.endsWith(".vectors.json") && !f.startsWith(".")
5043
+ );
5044
+ if (files.length === 0) return 0;
5045
+ const metaPath = path10.join(CODE_CONTEXT_DIR, ".sync-meta.json");
5046
+ let syncMeta = {};
5047
+ if (existsSync10(metaPath)) {
5048
+ try {
5049
+ syncMeta = JSON.parse(readFileSync7(metaPath, "utf-8"));
5050
+ } catch {
5051
+ }
5052
+ }
5053
+ let pushed = 0;
5054
+ for (const file of files) {
5055
+ const filePath = path10.join(CODE_CONTEXT_DIR, file);
5056
+ try {
5057
+ const stat = statSync4(filePath);
5058
+ const lastPushed = syncMeta[file] ?? 0;
5059
+ if (stat.mtimeMs <= lastPushed) continue;
5060
+ const content = readFileSync7(filePath, "utf-8");
5061
+ const header = content.substring(0, 300);
5062
+ if (header.includes("/tmp") || header.includes("/var/folders") || header.includes(".worktrees/")) continue;
5063
+ const compressed = compress(Buffer.from(content, "utf8"));
5064
+ const encrypted = encryptSyncBlob(compressed);
5065
+ const resp = await fetchWithRetry(`${config.endpoint}/sync/push-code-context`, {
5066
+ method: "POST",
5067
+ headers: {
5068
+ Authorization: `Bearer ${config.apiKey}`,
5069
+ "Content-Type": "application/json",
5070
+ "X-Device-Id": loadDeviceId()
5071
+ },
5072
+ body: JSON.stringify({ key: file, blob: encrypted })
5073
+ });
5074
+ if (resp.ok) {
5075
+ syncMeta[file] = stat.mtimeMs;
5076
+ pushed++;
5077
+ }
5078
+ } catch {
5079
+ }
5080
+ }
5081
+ if (pushed > 0) {
5082
+ try {
5083
+ writeFileSync5(metaPath, JSON.stringify(syncMeta));
5084
+ } catch {
5085
+ }
5086
+ }
5087
+ return pushed;
5088
+ }
5089
+ async function cloudPullCodeContext(config) {
5090
+ assertSecureEndpoint(config.endpoint);
5091
+ try {
5092
+ const resp = await fetchWithRetry(`${config.endpoint}/sync/pull-code-context`, {
5093
+ method: "GET",
5094
+ headers: {
5095
+ Authorization: `Bearer ${config.apiKey}`,
5096
+ "X-Device-Id": loadDeviceId()
5097
+ }
5098
+ });
5099
+ if (!resp.ok) return 0;
5100
+ const data = await resp.json();
5101
+ if (!data.indexes || data.indexes.length === 0) return 0;
5102
+ mkdirSync5(CODE_CONTEXT_DIR, { recursive: true });
5103
+ let pulled = 0;
5104
+ for (const { key, blob } of data.indexes) {
5105
+ try {
5106
+ if (key.endsWith(".vectors.json")) continue;
5107
+ const localPath = path10.join(CODE_CONTEXT_DIR, key);
5108
+ const compressed = decryptSyncBlob(blob);
5109
+ const content = decompress(compressed).toString("utf8");
5110
+ if (!existsSync10(localPath)) {
5111
+ writeFileSync5(localPath, content, "utf-8");
5112
+ pulled++;
5113
+ } else {
5114
+ const localContent = readFileSync7(localPath, "utf-8");
5115
+ if (localContent.length !== content.length) {
5116
+ writeFileSync5(localPath, content, "utf-8");
5117
+ pulled++;
5118
+ }
5119
+ }
5120
+ } catch {
5121
+ }
5122
+ }
5123
+ return pulled;
5124
+ } catch (err) {
5125
+ process.stderr.write(`[cloud-sync] Code context pull failed: ${err instanceof Error ? err.message : String(err)}
5126
+ `);
5127
+ return 0;
5128
+ }
5129
+ }
4998
5130
  export {
4999
5131
  CLOUD_REUPLOAD_REQUIRED_MESSAGE,
5000
5132
  assertSecureEndpoint,
@@ -5003,6 +5135,7 @@ export {
5003
5135
  cloudPull,
5004
5136
  cloudPullBehaviors,
5005
5137
  cloudPullBlob,
5138
+ cloudPullCodeContext,
5006
5139
  cloudPullConversations,
5007
5140
  cloudPullDocuments,
5008
5141
  cloudPullGlobalProcedures,
@@ -5012,6 +5145,7 @@ export {
5012
5145
  cloudPush,
5013
5146
  cloudPushBehaviors,
5014
5147
  cloudPushBlob,
5148
+ cloudPushCodeContext,
5015
5149
  cloudPushConversations,
5016
5150
  cloudPushDocuments,
5017
5151
  cloudPushGlobalProcedures,
@@ -541,6 +541,7 @@ var init_database_adapter = __esm({
541
541
  });
542
542
 
543
543
  // src/lib/database.ts
544
+ import { chmodSync as chmodSync2 } from "fs";
544
545
  import { createClient } from "@libsql/client";
545
546
  var init_database = __esm({
546
547
  "src/lib/database.ts"() {
@@ -670,6 +670,7 @@ var init_db_daemon_client = __esm({
670
670
  });
671
671
 
672
672
  // src/lib/database.ts
673
+ import { chmodSync as chmodSync2 } from "fs";
673
674
  import { createClient } from "@libsql/client";
674
675
 
675
676
  // src/lib/db-retry.ts
@@ -1381,6 +1382,16 @@ async function initDatabase(config) {
1381
1382
  if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
1382
1383
  _adapterClient = await createPrismaDbAdapter(_resilientClient);
1383
1384
  }
1385
+ try {
1386
+ chmodSync2(config.dbPath, 384);
1387
+ for (const suffix of ["-wal", "-shm"]) {
1388
+ try {
1389
+ chmodSync2(config.dbPath + suffix, 384);
1390
+ } catch {
1391
+ }
1392
+ }
1393
+ } catch {
1394
+ }
1384
1395
  }
1385
1396
  function isInitialized() {
1386
1397
  return _adapterClient !== null || _client !== null;
package/dist/lib/db.js CHANGED
@@ -670,6 +670,7 @@ var init_db_daemon_client = __esm({
670
670
  });
671
671
 
672
672
  // src/lib/database.ts
673
+ import { chmodSync as chmodSync2 } from "fs";
673
674
  import { createClient } from "@libsql/client";
674
675
 
675
676
  // src/lib/db-retry.ts
@@ -1381,6 +1382,16 @@ async function initDatabase(config) {
1381
1382
  if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
1382
1383
  _adapterClient = await createPrismaDbAdapter(_resilientClient);
1383
1384
  }
1385
+ try {
1386
+ chmodSync2(config.dbPath, 384);
1387
+ for (const suffix of ["-wal", "-shm"]) {
1388
+ try {
1389
+ chmodSync2(config.dbPath + suffix, 384);
1390
+ } catch {
1391
+ }
1392
+ }
1393
+ } catch {
1394
+ }
1384
1395
  }
1385
1396
  function isInitialized() {
1386
1397
  return _adapterClient !== null || _client !== null;
@@ -1370,6 +1370,7 @@ __export(database_exports, {
1370
1370
  isInitialized: () => isInitialized,
1371
1371
  setExternalClient: () => setExternalClient
1372
1372
  });
1373
+ import { chmodSync as chmodSync2 } from "fs";
1373
1374
  import { createClient } from "@libsql/client";
1374
1375
  async function initDatabase(config) {
1375
1376
  if (_walCheckpointTimer) {
@@ -1411,6 +1412,16 @@ async function initDatabase(config) {
1411
1412
  if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
1412
1413
  _adapterClient = await createPrismaDbAdapter(_resilientClient);
1413
1414
  }
1415
+ try {
1416
+ chmodSync2(config.dbPath, 384);
1417
+ for (const suffix of ["-wal", "-shm"]) {
1418
+ try {
1419
+ chmodSync2(config.dbPath + suffix, 384);
1420
+ } catch {
1421
+ }
1422
+ }
1423
+ } catch {
1424
+ }
1414
1425
  }
1415
1426
  function isInitialized() {
1416
1427
  return _adapterClient !== null || _client !== null;