@askexenow/exe-os 0.9.8 → 0.9.9

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 (101) hide show
  1. package/dist/bin/backfill-conversations.js +222 -49
  2. package/dist/bin/backfill-responses.js +221 -48
  3. package/dist/bin/backfill-vectors.js +225 -52
  4. package/dist/bin/cleanup-stale-review-tasks.js +150 -28
  5. package/dist/bin/cli.js +1295 -856
  6. package/dist/bin/exe-agent-config.js +36 -8
  7. package/dist/bin/exe-agent.js +14 -4
  8. package/dist/bin/exe-assign.js +221 -48
  9. package/dist/bin/exe-boot.js +778 -427
  10. package/dist/bin/exe-call.js +41 -13
  11. package/dist/bin/exe-cloud.js +163 -58
  12. package/dist/bin/exe-dispatch.js +276 -139
  13. package/dist/bin/exe-doctor.js +145 -27
  14. package/dist/bin/exe-export-behaviors.js +141 -23
  15. package/dist/bin/exe-forget.js +137 -19
  16. package/dist/bin/exe-gateway.js +677 -388
  17. package/dist/bin/exe-heartbeat.js +227 -108
  18. package/dist/bin/exe-kill.js +138 -20
  19. package/dist/bin/exe-launch-agent.js +172 -39
  20. package/dist/bin/exe-link.js +291 -100
  21. package/dist/bin/exe-new-employee.js +214 -106
  22. package/dist/bin/exe-pending-messages.js +395 -33
  23. package/dist/bin/exe-pending-notifications.js +684 -99
  24. package/dist/bin/exe-pending-reviews.js +420 -74
  25. package/dist/bin/exe-rename.js +147 -49
  26. package/dist/bin/exe-review.js +138 -20
  27. package/dist/bin/exe-search.js +240 -69
  28. package/dist/bin/exe-session-cleanup.js +440 -250
  29. package/dist/bin/exe-settings.js +61 -17
  30. package/dist/bin/exe-start-codex.js +158 -39
  31. package/dist/bin/exe-start-opencode.js +157 -38
  32. package/dist/bin/exe-status.js +151 -29
  33. package/dist/bin/exe-team.js +138 -20
  34. package/dist/bin/git-sweep.js +404 -212
  35. package/dist/bin/graph-backfill.js +137 -19
  36. package/dist/bin/graph-export.js +140 -22
  37. package/dist/bin/install.js +90 -61
  38. package/dist/bin/scan-tasks.js +412 -220
  39. package/dist/bin/setup.js +564 -293
  40. package/dist/bin/shard-migrate.js +139 -21
  41. package/dist/bin/update.js +138 -49
  42. package/dist/bin/wiki-sync.js +137 -19
  43. package/dist/gateway/index.js +533 -320
  44. package/dist/hooks/bug-report-worker.js +344 -193
  45. package/dist/hooks/codex-stop-task-finalizer.js +4678 -0
  46. package/dist/hooks/commit-complete.js +402 -210
  47. package/dist/hooks/error-recall.js +245 -74
  48. package/dist/hooks/exe-heartbeat-hook.js +16 -6
  49. package/dist/hooks/ingest-worker.js +3423 -3157
  50. package/dist/hooks/ingest.js +832 -97
  51. package/dist/hooks/instructions-loaded.js +227 -54
  52. package/dist/hooks/notification.js +216 -43
  53. package/dist/hooks/post-compact.js +239 -62
  54. package/dist/hooks/pre-compact.js +408 -216
  55. package/dist/hooks/pre-tool-use.js +268 -90
  56. package/dist/hooks/prompt-ingest-worker.js +352 -102
  57. package/dist/hooks/prompt-submit.js +541 -328
  58. package/dist/hooks/response-ingest-worker.js +372 -122
  59. package/dist/hooks/session-end.js +443 -240
  60. package/dist/hooks/session-start.js +313 -127
  61. package/dist/hooks/stop.js +293 -98
  62. package/dist/hooks/subagent-stop.js +239 -62
  63. package/dist/hooks/summary-worker.js +568 -236
  64. package/dist/index.js +538 -324
  65. package/dist/lib/agent-config.js +28 -6
  66. package/dist/lib/cloud-sync.js +284 -105
  67. package/dist/lib/config.js +30 -10
  68. package/dist/lib/consolidation.js +16 -6
  69. package/dist/lib/database.js +123 -25
  70. package/dist/lib/db-daemon-client.js +73 -19
  71. package/dist/lib/db.js +123 -25
  72. package/dist/lib/device-registry.js +133 -35
  73. package/dist/lib/embedder.js +107 -32
  74. package/dist/lib/employee-templates.js +14 -4
  75. package/dist/lib/employees.js +41 -13
  76. package/dist/lib/exe-daemon-client.js +88 -22
  77. package/dist/lib/exe-daemon.js +935 -587
  78. package/dist/lib/hybrid-search.js +240 -69
  79. package/dist/lib/identity.js +18 -8
  80. package/dist/lib/license.js +133 -48
  81. package/dist/lib/messaging.js +116 -56
  82. package/dist/lib/reminders.js +14 -4
  83. package/dist/lib/schedules.js +137 -19
  84. package/dist/lib/skill-learning.js +33 -6
  85. package/dist/lib/store.js +137 -19
  86. package/dist/lib/task-router.js +14 -4
  87. package/dist/lib/tasks.js +280 -234
  88. package/dist/lib/tmux-routing.js +172 -125
  89. package/dist/lib/token-spend.js +26 -8
  90. package/dist/mcp/server.js +1326 -609
  91. package/dist/mcp/tools/complete-reminder.js +14 -4
  92. package/dist/mcp/tools/create-reminder.js +14 -4
  93. package/dist/mcp/tools/create-task.js +306 -248
  94. package/dist/mcp/tools/deactivate-behavior.js +16 -6
  95. package/dist/mcp/tools/list-reminders.js +14 -4
  96. package/dist/mcp/tools/list-tasks.js +123 -107
  97. package/dist/mcp/tools/send-message.js +75 -29
  98. package/dist/mcp/tools/update-task.js +1848 -199
  99. package/dist/runtime/index.js +441 -248
  100. package/dist/tui/App.js +761 -424
  101. package/package.json +1 -1
@@ -26,9 +26,18 @@ var init_db_retry = __esm({
26
26
  }
27
27
  });
28
28
 
29
+ // src/lib/secure-files.ts
30
+ import { chmodSync, existsSync, mkdirSync } from "fs";
31
+ import { chmod, mkdir } from "fs/promises";
32
+ var init_secure_files = __esm({
33
+ "src/lib/secure-files.ts"() {
34
+ "use strict";
35
+ }
36
+ });
37
+
29
38
  // src/lib/config.ts
30
- import { readFile, writeFile, mkdir, chmod } from "fs/promises";
31
- import { readFileSync, existsSync, renameSync } from "fs";
39
+ import { readFile, writeFile } from "fs/promises";
40
+ import { readFileSync, existsSync as existsSync2, renameSync } from "fs";
32
41
  import path from "path";
33
42
  import os from "os";
34
43
  function resolveDataDir() {
@@ -36,7 +45,7 @@ function resolveDataDir() {
36
45
  if (process.env.EXE_MEM_DIR) return process.env.EXE_MEM_DIR;
37
46
  const newDir = path.join(os.homedir(), ".exe-os");
38
47
  const legacyDir = path.join(os.homedir(), ".exe-mem");
39
- if (!existsSync(newDir) && existsSync(legacyDir)) {
48
+ if (!existsSync2(newDir) && existsSync2(legacyDir)) {
40
49
  try {
41
50
  renameSync(legacyDir, newDir);
42
51
  process.stderr.write(`[exe-os] Migrated data directory: ~/.exe-mem \u2192 ~/.exe-os
@@ -51,6 +60,7 @@ var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, LEGACY_LANCE_PATH, CURRENT_CON
51
60
  var init_config = __esm({
52
61
  "src/lib/config.ts"() {
53
62
  "use strict";
63
+ init_secure_files();
54
64
  EXE_AI_DIR = resolveDataDir();
55
65
  DB_PATH = path.join(EXE_AI_DIR, "memories.db");
56
66
  MODELS_DIR = path.join(EXE_AI_DIR, "models");
@@ -119,7 +129,7 @@ var init_config = __esm({
119
129
 
120
130
  // src/lib/employees.ts
121
131
  import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
122
- import { existsSync as existsSync2, symlinkSync, readlinkSync, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync, writeFileSync } from "fs";
132
+ import { existsSync as existsSync3, symlinkSync, readlinkSync, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync, writeFileSync } from "fs";
123
133
  import { execSync } from "child_process";
124
134
  import path2 from "path";
125
135
  import os2 from "os";
@@ -136,7 +146,7 @@ function getCoordinatorName(employees = loadEmployeesSync()) {
136
146
  return getCoordinatorEmployee(employees)?.name ?? DEFAULT_COORDINATOR_TEMPLATE_NAME;
137
147
  }
138
148
  function loadEmployeesSync(employeesPath = EMPLOYEES_PATH) {
139
- if (!existsSync2(employeesPath)) return [];
149
+ if (!existsSync3(employeesPath)) return [];
140
150
  try {
141
151
  return JSON.parse(readFileSync2(employeesPath, "utf-8"));
142
152
  } catch {
@@ -460,10 +470,10 @@ var init_runtime_table = __esm({
460
470
  });
461
471
 
462
472
  // src/lib/agent-config.ts
463
- import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, existsSync as existsSync3, mkdirSync } from "fs";
473
+ import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, existsSync as existsSync4 } from "fs";
464
474
  import path5 from "path";
465
475
  function loadAgentConfig() {
466
- if (!existsSync3(AGENT_CONFIG_PATH)) return {};
476
+ if (!existsSync4(AGENT_CONFIG_PATH)) return {};
467
477
  try {
468
478
  return JSON.parse(readFileSync3(AGENT_CONFIG_PATH, "utf-8"));
469
479
  } catch {
@@ -484,6 +494,7 @@ var init_agent_config = __esm({
484
494
  "use strict";
485
495
  init_config();
486
496
  init_runtime_table();
497
+ init_secure_files();
487
498
  AGENT_CONFIG_PATH = path5.join(EXE_AI_DIR, "agent-config.json");
488
499
  DEFAULT_MODELS = {
489
500
  claude: "claude-opus-4",
@@ -494,16 +505,16 @@ var init_agent_config = __esm({
494
505
  });
495
506
 
496
507
  // src/lib/intercom-queue.ts
497
- import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, renameSync as renameSync3, existsSync as existsSync4, mkdirSync as mkdirSync2 } from "fs";
508
+ import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, renameSync as renameSync3, existsSync as existsSync5, mkdirSync as mkdirSync2 } from "fs";
498
509
  import path6 from "path";
499
510
  import os5 from "os";
500
511
  function ensureDir() {
501
512
  const dir = path6.dirname(QUEUE_PATH);
502
- if (!existsSync4(dir)) mkdirSync2(dir, { recursive: true });
513
+ if (!existsSync5(dir)) mkdirSync2(dir, { recursive: true });
503
514
  }
504
515
  function readQueue() {
505
516
  try {
506
- if (!existsSync4(QUEUE_PATH)) return [];
517
+ if (!existsSync5(QUEUE_PATH)) return [];
507
518
  return JSON.parse(readFileSync4(QUEUE_PATH, "utf8"));
508
519
  } catch {
509
520
  return [];
@@ -543,8 +554,11 @@ var init_intercom_queue = __esm({
543
554
  });
544
555
 
545
556
  // src/lib/license.ts
546
- import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, existsSync as existsSync5, mkdirSync as mkdirSync3 } from "fs";
557
+ import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, existsSync as existsSync6, mkdirSync as mkdirSync3 } from "fs";
547
558
  import { randomUUID } from "crypto";
559
+ import { createRequire as createRequire2 } from "module";
560
+ import { pathToFileURL as pathToFileURL2 } from "url";
561
+ import os6 from "os";
548
562
  import path7 from "path";
549
563
  import { jwtVerify, importSPKI } from "jose";
550
564
  var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH;
@@ -559,7 +573,7 @@ var init_license = __esm({
559
573
  });
560
574
 
561
575
  // src/lib/plan-limits.ts
562
- import { readFileSync as readFileSync6, existsSync as existsSync6 } from "fs";
576
+ import { readFileSync as readFileSync6, existsSync as existsSync7 } from "fs";
563
577
  import path8 from "path";
564
578
  var CACHE_PATH2;
565
579
  var init_plan_limits = __esm({
@@ -575,9 +589,9 @@ var init_plan_limits = __esm({
575
589
 
576
590
  // src/lib/tmux-routing.ts
577
591
  import { execFileSync as execFileSync2, execSync as execSync4 } from "child_process";
578
- import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, existsSync as existsSync7, appendFileSync, readdirSync } from "fs";
592
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, existsSync as existsSync8, appendFileSync, readdirSync } from "fs";
579
593
  import path9 from "path";
580
- import os6 from "os";
594
+ import os7 from "os";
581
595
  import { fileURLToPath } from "url";
582
596
  function getMySession() {
583
597
  return getTransport().getMySession();
@@ -650,7 +664,7 @@ function isEmployeeAlive(sessionName) {
650
664
  }
651
665
  function readDebounceState() {
652
666
  try {
653
- if (!existsSync7(DEBOUNCE_FILE)) return {};
667
+ if (!existsSync8(DEBOUNCE_FILE)) return {};
654
668
  const raw = JSON.parse(readFileSync7(DEBOUNCE_FILE, "utf8"));
655
669
  const state = {};
656
670
  for (const [key, val] of Object.entries(raw)) {
@@ -667,7 +681,7 @@ function readDebounceState() {
667
681
  }
668
682
  function writeDebounceState(state) {
669
683
  try {
670
- if (!existsSync7(SESSION_CACHE)) mkdirSync4(SESSION_CACHE, { recursive: true });
684
+ if (!existsSync8(SESSION_CACHE)) mkdirSync4(SESSION_CACHE, { recursive: true });
671
685
  writeFileSync5(DEBOUNCE_FILE, JSON.stringify(state));
672
686
  } catch {
673
687
  }
@@ -763,7 +777,7 @@ function sendIntercom(targetSession) {
763
777
  const rawAgent = targetSession.split("-")[0] ?? targetSession;
764
778
  const agent = baseAgentName(rawAgent);
765
779
  const markerPath = path9.join(SESSION_CACHE, `current-task-${agent}.json`);
766
- if (existsSync7(markerPath)) {
780
+ if (existsSync8(markerPath)) {
767
781
  logIntercom(`SKIP \u2192 ${targetSession} (has in_progress task marker \u2014 will auto-chain)`);
768
782
  return "debounced";
769
783
  }
@@ -773,7 +787,7 @@ function sendIntercom(targetSession) {
773
787
  const rawAgent = targetSession.split("-")[0] ?? targetSession;
774
788
  const agent = baseAgentName(rawAgent);
775
789
  const taskDir = path9.join(process.cwd(), "exe", agent);
776
- if (existsSync7(taskDir)) {
790
+ if (existsSync8(taskDir)) {
777
791
  const files = readdirSync(taskDir).filter(
778
792
  (f) => f.endsWith(".md") && f !== "DONE.txt"
779
793
  );
@@ -826,21 +840,46 @@ var init_tmux_routing = __esm({
826
840
  init_intercom_queue();
827
841
  init_plan_limits();
828
842
  init_employees();
829
- SPAWN_LOCK_DIR = path9.join(os6.homedir(), ".exe-os", "spawn-locks");
830
- SESSION_CACHE = path9.join(os6.homedir(), ".exe-os", "session-cache");
843
+ SPAWN_LOCK_DIR = path9.join(os7.homedir(), ".exe-os", "spawn-locks");
844
+ SESSION_CACHE = path9.join(os7.homedir(), ".exe-os", "session-cache");
831
845
  VALID_SESSION_NAME = /^[a-z]+\d*-[a-zA-Z0-9_]+$/;
832
846
  INTERCOM_DEBOUNCE_MS = 3e4;
833
847
  CODEX_DEBOUNCE_MS = 12e4;
834
- INTERCOM_LOG2 = path9.join(os6.homedir(), ".exe-os", "intercom.log");
848
+ INTERCOM_LOG2 = path9.join(os7.homedir(), ".exe-os", "intercom.log");
835
849
  DEBOUNCE_FILE = path9.join(SESSION_CACHE, "intercom-debounce.json");
836
850
  DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
837
851
  BUSY_PATTERN = /[✻✽✶✳·].*…|Running…|• Working|• Ran |• Explored|• Called|esc to interrupt/;
838
852
  }
839
853
  });
840
854
 
855
+ // src/lib/task-scope.ts
856
+ function getCurrentSessionScope() {
857
+ try {
858
+ return resolveExeSession();
859
+ } catch {
860
+ return null;
861
+ }
862
+ }
863
+ function strictSessionScopeFilter(sessionScope, tableAlias) {
864
+ const scope = sessionScope !== void 0 ? sessionScope : getCurrentSessionScope();
865
+ if (!scope) return { sql: "", args: [] };
866
+ const col = tableAlias ? `${tableAlias}.session_scope` : "session_scope";
867
+ return {
868
+ sql: ` AND ${col} = ?`,
869
+ args: [scope]
870
+ };
871
+ }
872
+ var init_task_scope = __esm({
873
+ "src/lib/task-scope.ts"() {
874
+ "use strict";
875
+ init_tmux_routing();
876
+ }
877
+ });
878
+
841
879
  // src/lib/messaging.ts
842
880
  init_database();
843
881
  init_tmux_routing();
882
+ init_task_scope();
844
883
  import crypto from "crypto";
845
884
  function generateUlid() {
846
885
  const timestamp = Date.now().toString(36).padStart(10, "0");
@@ -855,6 +894,7 @@ function rowToMessage(row) {
855
894
  targetAgent: row.target_agent,
856
895
  targetProject: row.target_project ?? null,
857
896
  targetDevice: row.target_device,
897
+ sessionScope: row.session_scope ?? null,
858
898
  content: row.content,
859
899
  priority: row.priority ?? "normal",
860
900
  status: row.status ?? "pending",
@@ -873,15 +913,17 @@ async function sendMessage(input) {
873
913
  const id = generateUlid();
874
914
  const now = (/* @__PURE__ */ new Date()).toISOString();
875
915
  const targetDevice = input.targetDevice ?? "local";
916
+ const sessionScope = input.sessionScope === void 0 ? resolveExeSession() : input.sessionScope;
876
917
  await client.execute({
877
- sql: `INSERT INTO messages (id, from_agent, from_device, target_agent, target_project, target_device, content, priority, status, created_at)
878
- VALUES (?, ?, 'local', ?, ?, ?, ?, ?, 'pending', ?)`,
918
+ sql: `INSERT INTO messages (id, from_agent, from_device, target_agent, target_project, target_device, session_scope, content, priority, status, created_at)
919
+ VALUES (?, ?, 'local', ?, ?, ?, ?, ?, ?, 'pending', ?)`,
879
920
  args: [
880
921
  id,
881
922
  input.fromAgent,
882
923
  input.targetAgent,
883
924
  input.targetProject ?? null,
884
925
  targetDevice,
926
+ sessionScope,
885
927
  input.content,
886
928
  input.priority ?? "normal",
887
929
  now
@@ -895,9 +937,10 @@ async function sendMessage(input) {
895
937
  }
896
938
  } catch {
897
939
  }
940
+ const sentScope = strictSessionScopeFilter(sessionScope);
898
941
  const result = await client.execute({
899
- sql: "SELECT * FROM messages WHERE id = ?",
900
- args: [id]
942
+ sql: `SELECT * FROM messages WHERE id = ?${sentScope.sql}`,
943
+ args: [id, ...sentScope.args]
901
944
  });
902
945
  return rowToMessage(result.rows[0]);
903
946
  }
@@ -922,6 +965,7 @@ async function deliverCrossMachineMessage(messageId, targetDevice) {
922
965
  fromAgent: msg.fromAgent,
923
966
  targetAgent: msg.targetAgent,
924
967
  targetProject: msg.targetProject,
968
+ sessionScope: msg.sessionScope,
925
969
  content: msg.content,
926
970
  priority: msg.priority,
927
971
  createdAt: msg.createdAt
@@ -965,7 +1009,7 @@ async function deliverLocalMessage(messageId) {
965
1009
  } catch {
966
1010
  const newRetryCount = msg.retryCount + 1;
967
1011
  if (newRetryCount >= MAX_RETRIES) {
968
- await markFailed(messageId, "session unavailable after 10 retries");
1012
+ await markFailed(messageId, "session unavailable after 10 retries", msg.sessionScope);
969
1013
  } else {
970
1014
  await client.execute({
971
1015
  sql: "UPDATE messages SET retry_count = ? WHERE id = ?",
@@ -975,85 +1019,101 @@ async function deliverLocalMessage(messageId) {
975
1019
  return false;
976
1020
  }
977
1021
  }
978
- async function getPendingMessages(targetAgent) {
1022
+ async function getPendingMessages(targetAgent, sessionScope) {
979
1023
  const client = getClient();
1024
+ const scope = strictSessionScopeFilter(sessionScope);
980
1025
  const result = await client.execute({
981
1026
  sql: `SELECT * FROM messages
982
- WHERE target_agent = ? AND status IN ('pending', 'delivered')
1027
+ WHERE target_agent = ? AND status IN ('pending', 'delivered')${scope.sql}
983
1028
  ORDER BY id`,
984
- args: [targetAgent]
1029
+ args: [targetAgent, ...scope.args]
985
1030
  });
986
1031
  return result.rows.map((row) => rowToMessage(row));
987
1032
  }
988
- async function markRead(messageId) {
1033
+ async function markRead(messageId, sessionScope) {
989
1034
  const client = getClient();
1035
+ const scope = strictSessionScopeFilter(sessionScope);
990
1036
  await client.execute({
991
- sql: "UPDATE messages SET status = 'read' WHERE id = ? AND status IN ('pending', 'delivered')",
992
- args: [messageId]
1037
+ sql: `UPDATE messages SET status = 'read'
1038
+ WHERE id = ? AND status IN ('pending', 'delivered')${scope.sql}`,
1039
+ args: [messageId, ...scope.args]
993
1040
  });
994
1041
  }
995
- async function markAcknowledged(messageId) {
1042
+ async function markAcknowledged(messageId, sessionScope) {
996
1043
  const client = getClient();
1044
+ const scope = strictSessionScopeFilter(sessionScope);
997
1045
  await client.execute({
998
- sql: "UPDATE messages SET status = 'acknowledged', processed_at = ? WHERE id = ? AND status = 'read'",
999
- args: [(/* @__PURE__ */ new Date()).toISOString(), messageId]
1046
+ sql: `UPDATE messages SET status = 'acknowledged', processed_at = ?
1047
+ WHERE id = ? AND status = 'read'${scope.sql}`,
1048
+ args: [(/* @__PURE__ */ new Date()).toISOString(), messageId, ...scope.args]
1000
1049
  });
1001
1050
  }
1002
- async function markProcessed(messageId) {
1051
+ async function markProcessed(messageId, sessionScope) {
1003
1052
  const client = getClient();
1053
+ const scope = strictSessionScopeFilter(sessionScope);
1004
1054
  await client.execute({
1005
- sql: "UPDATE messages SET status = 'processed', processed_at = ? WHERE id = ?",
1006
- args: [(/* @__PURE__ */ new Date()).toISOString(), messageId]
1055
+ sql: `UPDATE messages SET status = 'processed', processed_at = ?
1056
+ WHERE id = ?${scope.sql}`,
1057
+ args: [(/* @__PURE__ */ new Date()).toISOString(), messageId, ...scope.args]
1007
1058
  });
1008
1059
  }
1009
- async function getMessageStatus(messageId) {
1060
+ async function getMessageStatus(messageId, sessionScope) {
1010
1061
  const client = getClient();
1062
+ const scope = strictSessionScopeFilter(sessionScope);
1011
1063
  const result = await client.execute({
1012
- sql: "SELECT status FROM messages WHERE id = ?",
1013
- args: [messageId]
1064
+ sql: `SELECT status FROM messages WHERE id = ?${scope.sql}`,
1065
+ args: [messageId, ...scope.args]
1014
1066
  });
1015
1067
  return result.rows[0]?.status ?? null;
1016
1068
  }
1017
- async function getUnacknowledgedMessages(targetAgent) {
1069
+ async function getUnacknowledgedMessages(targetAgent, sessionScope) {
1018
1070
  const client = getClient();
1071
+ const scope = strictSessionScopeFilter(sessionScope);
1019
1072
  const result = await client.execute({
1020
1073
  sql: `SELECT * FROM messages
1021
- WHERE target_agent = ? AND status IN ('pending', 'delivered', 'read')
1074
+ WHERE target_agent = ? AND status IN ('pending', 'delivered', 'read')${scope.sql}
1022
1075
  ORDER BY id`,
1023
- args: [targetAgent]
1076
+ args: [targetAgent, ...scope.args]
1024
1077
  });
1025
1078
  return result.rows.map((row) => rowToMessage(row));
1026
1079
  }
1027
- async function getReadMessages(targetAgent) {
1080
+ async function getReadMessages(targetAgent, sessionScope) {
1028
1081
  const client = getClient();
1082
+ const scope = strictSessionScopeFilter(sessionScope);
1029
1083
  const result = await client.execute({
1030
- sql: "SELECT * FROM messages WHERE target_agent = ? AND status = 'read' ORDER BY id",
1031
- args: [targetAgent]
1084
+ sql: `SELECT * FROM messages
1085
+ WHERE target_agent = ? AND status = 'read'${scope.sql}
1086
+ ORDER BY id`,
1087
+ args: [targetAgent, ...scope.args]
1032
1088
  });
1033
1089
  return result.rows.map((row) => rowToMessage(row));
1034
1090
  }
1035
- async function markFailed(messageId, reason) {
1091
+ async function markFailed(messageId, reason, sessionScope) {
1036
1092
  const client = getClient();
1093
+ const scope = strictSessionScopeFilter(sessionScope);
1037
1094
  await client.execute({
1038
- sql: "UPDATE messages SET status = 'failed', failed_at = ?, failure_reason = ? WHERE id = ?",
1039
- args: [(/* @__PURE__ */ new Date()).toISOString(), reason, messageId]
1095
+ sql: `UPDATE messages SET status = 'failed', failed_at = ?, failure_reason = ?
1096
+ WHERE id = ?${scope.sql}`,
1097
+ args: [(/* @__PURE__ */ new Date()).toISOString(), reason, messageId, ...scope.args]
1040
1098
  });
1041
1099
  }
1042
- async function getFailedMessages() {
1100
+ async function getFailedMessages(sessionScope) {
1043
1101
  const client = getClient();
1102
+ const scope = strictSessionScopeFilter(sessionScope);
1044
1103
  const result = await client.execute({
1045
- sql: "SELECT * FROM messages WHERE status = 'failed' ORDER BY created_at DESC",
1046
- args: []
1104
+ sql: `SELECT * FROM messages WHERE status = 'failed'${scope.sql} ORDER BY created_at DESC`,
1105
+ args: [...scope.args]
1047
1106
  });
1048
1107
  return result.rows.map((row) => rowToMessage(row));
1049
1108
  }
1050
- async function retryPendingMessages() {
1109
+ async function retryPendingMessages(sessionScope) {
1051
1110
  const client = getClient();
1111
+ const scope = strictSessionScopeFilter(sessionScope);
1052
1112
  const result = await client.execute({
1053
1113
  sql: `SELECT * FROM messages
1054
- WHERE status = 'pending' AND retry_count < ?
1114
+ WHERE status = 'pending' AND retry_count < ?${scope.sql}
1055
1115
  ORDER BY id`,
1056
- args: [MAX_RETRIES]
1116
+ args: [MAX_RETRIES, ...scope.args]
1057
1117
  });
1058
1118
  let delivered = 0;
1059
1119
  for (const row of result.rows) {
@@ -3,9 +3,18 @@ var __esm = (fn, res) => function __init() {
3
3
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
4
4
  };
5
5
 
6
+ // src/lib/secure-files.ts
7
+ import { chmodSync, existsSync, mkdirSync } from "fs";
8
+ import { chmod, mkdir } from "fs/promises";
9
+ var init_secure_files = __esm({
10
+ "src/lib/secure-files.ts"() {
11
+ "use strict";
12
+ }
13
+ });
14
+
6
15
  // src/lib/config.ts
7
- import { readFile, writeFile, mkdir, chmod } from "fs/promises";
8
- import { readFileSync, existsSync, renameSync } from "fs";
16
+ import { readFile, writeFile } from "fs/promises";
17
+ import { readFileSync, existsSync as existsSync2, renameSync } from "fs";
9
18
  import path from "path";
10
19
  import os from "os";
11
20
  function resolveDataDir() {
@@ -13,7 +22,7 @@ function resolveDataDir() {
13
22
  if (process.env.EXE_MEM_DIR) return process.env.EXE_MEM_DIR;
14
23
  const newDir = path.join(os.homedir(), ".exe-os");
15
24
  const legacyDir = path.join(os.homedir(), ".exe-mem");
16
- if (!existsSync(newDir) && existsSync(legacyDir)) {
25
+ if (!existsSync2(newDir) && existsSync2(legacyDir)) {
17
26
  try {
18
27
  renameSync(legacyDir, newDir);
19
28
  process.stderr.write(`[exe-os] Migrated data directory: ~/.exe-mem \u2192 ~/.exe-os
@@ -28,6 +37,7 @@ var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, LEGACY_LANCE_PATH, CURRENT_CON
28
37
  var init_config = __esm({
29
38
  "src/lib/config.ts"() {
30
39
  "use strict";
40
+ init_secure_files();
31
41
  EXE_AI_DIR = resolveDataDir();
32
42
  DB_PATH = path.join(EXE_AI_DIR, "memories.db");
33
43
  MODELS_DIR = path.join(EXE_AI_DIR, "models");
@@ -103,7 +113,7 @@ import { createClient } from "@libsql/client";
103
113
  // src/lib/employees.ts
104
114
  init_config();
105
115
  import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
106
- import { existsSync as existsSync2, symlinkSync, readlinkSync, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync, writeFileSync } from "fs";
116
+ import { existsSync as existsSync3, symlinkSync, readlinkSync, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync, writeFileSync } from "fs";
107
117
  import { execSync } from "child_process";
108
118
  import path2 from "path";
109
119
  import os2 from "os";