@askexenow/exe-os 0.9.115 → 0.9.116

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/dist/bin/cleanup-stale-review-tasks.js +16 -3
  2. package/dist/bin/cli.js +31 -3
  3. package/dist/bin/exe-boot.js +31 -3
  4. package/dist/bin/exe-dispatch.js +31 -3
  5. package/dist/bin/exe-gateway.js +31 -3
  6. package/dist/bin/exe-heartbeat.js +16 -3
  7. package/dist/bin/exe-pending-messages.js +16 -3
  8. package/dist/bin/exe-pending-notifications.js +16 -3
  9. package/dist/bin/exe-pending-reviews.js +16 -3
  10. package/dist/bin/exe-session-cleanup.js +31 -3
  11. package/dist/bin/exe-status.js +16 -3
  12. package/dist/bin/git-sweep.js +31 -3
  13. package/dist/bin/intercom-check.js +31 -3
  14. package/dist/bin/scan-tasks.js +31 -3
  15. package/dist/gateway/index.js +31 -3
  16. package/dist/hooks/bug-report-worker.js +31 -3
  17. package/dist/hooks/codex-stop-task-finalizer.js +31 -3
  18. package/dist/hooks/commit-complete.js +31 -3
  19. package/dist/hooks/ingest.js +31 -3
  20. package/dist/hooks/post-compact.js +16 -3
  21. package/dist/hooks/post-tool-combined.js +16 -3
  22. package/dist/hooks/pre-compact.js +31 -3
  23. package/dist/hooks/pre-tool-use.js +16 -3
  24. package/dist/hooks/prompt-submit.js +31 -3
  25. package/dist/hooks/session-end.js +31 -3
  26. package/dist/hooks/session-start.js +16 -3
  27. package/dist/hooks/stop.js +16 -3
  28. package/dist/hooks/subagent-stop.js +16 -3
  29. package/dist/hooks/summary-worker.js +16 -3
  30. package/dist/index.js +31 -3
  31. package/dist/lib/exe-daemon.js +31 -3
  32. package/dist/lib/messaging.js +31 -3
  33. package/dist/lib/tasks.js +31 -3
  34. package/dist/lib/tmux-routing.js +31 -3
  35. package/dist/mcp/server.js +31 -3
  36. package/dist/mcp/tools/create-task.js +31 -3
  37. package/dist/mcp/tools/list-tasks.js +16 -3
  38. package/dist/mcp/tools/send-message.js +31 -3
  39. package/dist/mcp/tools/update-task.js +31 -3
  40. package/dist/runtime/index.js +31 -3
  41. package/dist/tui/App.js +31 -3
  42. package/package.json +1 -1
@@ -6556,15 +6556,28 @@ function getParentExe(sessionKey) {
6556
6556
  }
6557
6557
  }
6558
6558
  function resolveExeSession() {
6559
+ const mySession = getMySession();
6560
+ const fromSessionName = mySession ? extractRootExe(mySession) ?? null : null;
6559
6561
  if (process.env.EXE_SESSION_NAME) {
6560
6562
  const fromEnv = extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
6561
- if (fromEnv) return fromEnv;
6563
+ if (fromEnv) {
6564
+ if (!mySession) {
6565
+ return fromEnv;
6566
+ }
6567
+ if (fromSessionName && fromEnv !== fromSessionName) {
6568
+ process.stderr.write(
6569
+ `[tmux-routing] WARN: EXE_SESSION_NAME="${fromEnv}" but tmux says "${fromSessionName}". Trusting tmux, correcting env var.
6570
+ `
6571
+ );
6572
+ process.env.EXE_SESSION_NAME = fromSessionName;
6573
+ } else {
6574
+ return fromEnv;
6575
+ }
6576
+ }
6562
6577
  }
6563
- const mySession = getMySession();
6564
6578
  if (!mySession) {
6565
6579
  return null;
6566
6580
  }
6567
- const fromSessionName = extractRootExe(mySession);
6568
6581
  let candidate = null;
6569
6582
  try {
6570
6583
  const key = getSessionKey();
package/dist/bin/cli.js CHANGED
@@ -16876,15 +16876,28 @@ function getDispatchedBy(sessionKey) {
16876
16876
  }
16877
16877
  }
16878
16878
  function resolveExeSession() {
16879
+ const mySession = getMySession();
16880
+ const fromSessionName = mySession ? extractRootExe(mySession) ?? null : null;
16879
16881
  if (process.env.EXE_SESSION_NAME) {
16880
16882
  const fromEnv = extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
16881
- if (fromEnv) return fromEnv;
16883
+ if (fromEnv) {
16884
+ if (!mySession) {
16885
+ return fromEnv;
16886
+ }
16887
+ if (fromSessionName && fromEnv !== fromSessionName) {
16888
+ process.stderr.write(
16889
+ `[tmux-routing] WARN: EXE_SESSION_NAME="${fromEnv}" but tmux says "${fromSessionName}". Trusting tmux, correcting env var.
16890
+ `
16891
+ );
16892
+ process.env.EXE_SESSION_NAME = fromSessionName;
16893
+ } else {
16894
+ return fromEnv;
16895
+ }
16896
+ }
16882
16897
  }
16883
- const mySession = getMySession();
16884
16898
  if (!mySession) {
16885
16899
  return null;
16886
16900
  }
16887
- const fromSessionName = extractRootExe(mySession);
16888
16901
  let candidate = null;
16889
16902
  try {
16890
16903
  const key = getSessionKey();
@@ -17068,6 +17081,21 @@ function isExeSession(sessionName) {
17068
17081
  }
17069
17082
  function sendIntercom(targetSession) {
17070
17083
  const transport = getTransport();
17084
+ try {
17085
+ const callerScope = resolveExeSession();
17086
+ if (callerScope && isExeSession(callerScope) && targetSession.includes("-")) {
17087
+ const targetScope = extractRootExe(targetSession);
17088
+ if (targetScope && targetScope !== callerScope) {
17089
+ logIntercom(`BLOCKED \u2192 ${targetSession} (scope violation: caller=${callerScope}, target=${targetScope})`);
17090
+ process.stderr.write(
17091
+ `[intercom] BLOCKED: cross-session intercom from ${callerScope} to ${targetSession}. Session isolation enforced.
17092
+ `
17093
+ );
17094
+ return "failed";
17095
+ }
17096
+ }
17097
+ } catch {
17098
+ }
17071
17099
  if (isExeSession(targetSession)) {
17072
17100
  logIntercom(`SKIP_COORDINATOR \u2192 ${targetSession} (coordinator sessions use prompt-submit hook)`);
17073
17101
  return "skipped_exe";
@@ -9003,15 +9003,28 @@ function getDispatchedBy(sessionKey) {
9003
9003
  }
9004
9004
  }
9005
9005
  function resolveExeSession() {
9006
+ const mySession = getMySession();
9007
+ const fromSessionName = mySession ? extractRootExe(mySession) ?? null : null;
9006
9008
  if (process.env.EXE_SESSION_NAME) {
9007
9009
  const fromEnv = extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
9008
- if (fromEnv) return fromEnv;
9010
+ if (fromEnv) {
9011
+ if (!mySession) {
9012
+ return fromEnv;
9013
+ }
9014
+ if (fromSessionName && fromEnv !== fromSessionName) {
9015
+ process.stderr.write(
9016
+ `[tmux-routing] WARN: EXE_SESSION_NAME="${fromEnv}" but tmux says "${fromSessionName}". Trusting tmux, correcting env var.
9017
+ `
9018
+ );
9019
+ process.env.EXE_SESSION_NAME = fromSessionName;
9020
+ } else {
9021
+ return fromEnv;
9022
+ }
9023
+ }
9009
9024
  }
9010
- const mySession = getMySession();
9011
9025
  if (!mySession) {
9012
9026
  return null;
9013
9027
  }
9014
- const fromSessionName = extractRootExe(mySession);
9015
9028
  let candidate = null;
9016
9029
  try {
9017
9030
  const key = getSessionKey();
@@ -9195,6 +9208,21 @@ function isExeSession(sessionName) {
9195
9208
  }
9196
9209
  function sendIntercom(targetSession) {
9197
9210
  const transport = getTransport();
9211
+ try {
9212
+ const callerScope = resolveExeSession();
9213
+ if (callerScope && isExeSession(callerScope) && targetSession.includes("-")) {
9214
+ const targetScope = extractRootExe(targetSession);
9215
+ if (targetScope && targetScope !== callerScope) {
9216
+ logIntercom(`BLOCKED \u2192 ${targetSession} (scope violation: caller=${callerScope}, target=${targetScope})`);
9217
+ process.stderr.write(
9218
+ `[intercom] BLOCKED: cross-session intercom from ${callerScope} to ${targetSession}. Session isolation enforced.
9219
+ `
9220
+ );
9221
+ return "failed";
9222
+ }
9223
+ }
9224
+ } catch {
9225
+ }
9198
9226
  if (isExeSession(targetSession)) {
9199
9227
  logIntercom(`SKIP_COORDINATOR \u2192 ${targetSession} (coordinator sessions use prompt-submit hook)`);
9200
9228
  return "skipped_exe";
@@ -7524,15 +7524,28 @@ function getDispatchedBy(sessionKey) {
7524
7524
  }
7525
7525
  }
7526
7526
  function resolveExeSession() {
7527
+ const mySession = getMySession();
7528
+ const fromSessionName = mySession ? extractRootExe(mySession) ?? null : null;
7527
7529
  if (process.env.EXE_SESSION_NAME) {
7528
7530
  const fromEnv = extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
7529
- if (fromEnv) return fromEnv;
7531
+ if (fromEnv) {
7532
+ if (!mySession) {
7533
+ return fromEnv;
7534
+ }
7535
+ if (fromSessionName && fromEnv !== fromSessionName) {
7536
+ process.stderr.write(
7537
+ `[tmux-routing] WARN: EXE_SESSION_NAME="${fromEnv}" but tmux says "${fromSessionName}". Trusting tmux, correcting env var.
7538
+ `
7539
+ );
7540
+ process.env.EXE_SESSION_NAME = fromSessionName;
7541
+ } else {
7542
+ return fromEnv;
7543
+ }
7544
+ }
7530
7545
  }
7531
- const mySession = getMySession();
7532
7546
  if (!mySession) {
7533
7547
  return null;
7534
7548
  }
7535
- const fromSessionName = extractRootExe(mySession);
7536
7549
  let candidate = null;
7537
7550
  try {
7538
7551
  const key = getSessionKey();
@@ -7716,6 +7729,21 @@ function isExeSession(sessionName) {
7716
7729
  }
7717
7730
  function sendIntercom(targetSession) {
7718
7731
  const transport = getTransport();
7732
+ try {
7733
+ const callerScope = resolveExeSession();
7734
+ if (callerScope && isExeSession(callerScope) && targetSession.includes("-")) {
7735
+ const targetScope = extractRootExe(targetSession);
7736
+ if (targetScope && targetScope !== callerScope) {
7737
+ logIntercom(`BLOCKED \u2192 ${targetSession} (scope violation: caller=${callerScope}, target=${targetScope})`);
7738
+ process.stderr.write(
7739
+ `[intercom] BLOCKED: cross-session intercom from ${callerScope} to ${targetSession}. Session isolation enforced.
7740
+ `
7741
+ );
7742
+ return "failed";
7743
+ }
7744
+ }
7745
+ } catch {
7746
+ }
7719
7747
  if (isExeSession(targetSession)) {
7720
7748
  logIntercom(`SKIP_COORDINATOR \u2192 ${targetSession} (coordinator sessions use prompt-submit hook)`);
7721
7749
  return "skipped_exe";
@@ -13046,15 +13046,28 @@ function getDispatchedBy(sessionKey) {
13046
13046
  }
13047
13047
  }
13048
13048
  function resolveExeSession() {
13049
+ const mySession = getMySession();
13050
+ const fromSessionName = mySession ? extractRootExe(mySession) ?? null : null;
13049
13051
  if (process.env.EXE_SESSION_NAME) {
13050
13052
  const fromEnv = extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
13051
- if (fromEnv) return fromEnv;
13053
+ if (fromEnv) {
13054
+ if (!mySession) {
13055
+ return fromEnv;
13056
+ }
13057
+ if (fromSessionName && fromEnv !== fromSessionName) {
13058
+ process.stderr.write(
13059
+ `[tmux-routing] WARN: EXE_SESSION_NAME="${fromEnv}" but tmux says "${fromSessionName}". Trusting tmux, correcting env var.
13060
+ `
13061
+ );
13062
+ process.env.EXE_SESSION_NAME = fromSessionName;
13063
+ } else {
13064
+ return fromEnv;
13065
+ }
13066
+ }
13052
13067
  }
13053
- const mySession = getMySession();
13054
13068
  if (!mySession) {
13055
13069
  return null;
13056
13070
  }
13057
- const fromSessionName = extractRootExe(mySession);
13058
13071
  let candidate = null;
13059
13072
  try {
13060
13073
  const key = getSessionKey();
@@ -13238,6 +13251,21 @@ function isExeSession(sessionName) {
13238
13251
  }
13239
13252
  function sendIntercom(targetSession) {
13240
13253
  const transport = getTransport();
13254
+ try {
13255
+ const callerScope = resolveExeSession();
13256
+ if (callerScope && isExeSession(callerScope) && targetSession.includes("-")) {
13257
+ const targetScope = extractRootExe(targetSession);
13258
+ if (targetScope && targetScope !== callerScope) {
13259
+ logIntercom(`BLOCKED \u2192 ${targetSession} (scope violation: caller=${callerScope}, target=${targetScope})`);
13260
+ process.stderr.write(
13261
+ `[intercom] BLOCKED: cross-session intercom from ${callerScope} to ${targetSession}. Session isolation enforced.
13262
+ `
13263
+ );
13264
+ return "failed";
13265
+ }
13266
+ }
13267
+ } catch {
13268
+ }
13241
13269
  if (isExeSession(targetSession)) {
13242
13270
  logIntercom(`SKIP_COORDINATOR \u2192 ${targetSession} (coordinator sessions use prompt-submit hook)`);
13243
13271
  return "skipped_exe";
@@ -6585,15 +6585,28 @@ function getParentExe(sessionKey) {
6585
6585
  }
6586
6586
  }
6587
6587
  function resolveExeSession() {
6588
+ const mySession = getMySession();
6589
+ const fromSessionName = mySession ? extractRootExe(mySession) ?? null : null;
6588
6590
  if (process.env.EXE_SESSION_NAME) {
6589
6591
  const fromEnv = extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
6590
- if (fromEnv) return fromEnv;
6592
+ if (fromEnv) {
6593
+ if (!mySession) {
6594
+ return fromEnv;
6595
+ }
6596
+ if (fromSessionName && fromEnv !== fromSessionName) {
6597
+ process.stderr.write(
6598
+ `[tmux-routing] WARN: EXE_SESSION_NAME="${fromEnv}" but tmux says "${fromSessionName}". Trusting tmux, correcting env var.
6599
+ `
6600
+ );
6601
+ process.env.EXE_SESSION_NAME = fromSessionName;
6602
+ } else {
6603
+ return fromEnv;
6604
+ }
6605
+ }
6591
6606
  }
6592
- const mySession = getMySession();
6593
6607
  if (!mySession) {
6594
6608
  return null;
6595
6609
  }
6596
- const fromSessionName = extractRootExe(mySession);
6597
6610
  let candidate = null;
6598
6611
  try {
6599
6612
  const key = getSessionKey();
@@ -4043,15 +4043,28 @@ function getParentExe(sessionKey) {
4043
4043
  }
4044
4044
  }
4045
4045
  function resolveExeSession() {
4046
+ const mySession = getMySession();
4047
+ const fromSessionName = mySession ? extractRootExe(mySession) ?? null : null;
4046
4048
  if (process.env.EXE_SESSION_NAME) {
4047
4049
  const fromEnv = extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
4048
- if (fromEnv) return fromEnv;
4050
+ if (fromEnv) {
4051
+ if (!mySession) {
4052
+ return fromEnv;
4053
+ }
4054
+ if (fromSessionName && fromEnv !== fromSessionName) {
4055
+ process.stderr.write(
4056
+ `[tmux-routing] WARN: EXE_SESSION_NAME="${fromEnv}" but tmux says "${fromSessionName}". Trusting tmux, correcting env var.
4057
+ `
4058
+ );
4059
+ process.env.EXE_SESSION_NAME = fromSessionName;
4060
+ } else {
4061
+ return fromEnv;
4062
+ }
4063
+ }
4049
4064
  }
4050
- const mySession = getMySession();
4051
4065
  if (!mySession) {
4052
4066
  return null;
4053
4067
  }
4054
- const fromSessionName = extractRootExe(mySession);
4055
4068
  let candidate = null;
4056
4069
  try {
4057
4070
  const key = getSessionKey();
@@ -4044,15 +4044,28 @@ function getParentExe(sessionKey) {
4044
4044
  }
4045
4045
  }
4046
4046
  function resolveExeSession() {
4047
+ const mySession = getMySession();
4048
+ const fromSessionName = mySession ? extractRootExe(mySession) ?? null : null;
4047
4049
  if (process.env.EXE_SESSION_NAME) {
4048
4050
  const fromEnv = extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
4049
- if (fromEnv) return fromEnv;
4051
+ if (fromEnv) {
4052
+ if (!mySession) {
4053
+ return fromEnv;
4054
+ }
4055
+ if (fromSessionName && fromEnv !== fromSessionName) {
4056
+ process.stderr.write(
4057
+ `[tmux-routing] WARN: EXE_SESSION_NAME="${fromEnv}" but tmux says "${fromSessionName}". Trusting tmux, correcting env var.
4058
+ `
4059
+ );
4060
+ process.env.EXE_SESSION_NAME = fromSessionName;
4061
+ } else {
4062
+ return fromEnv;
4063
+ }
4064
+ }
4050
4065
  }
4051
- const mySession = getMySession();
4052
4066
  if (!mySession) {
4053
4067
  return null;
4054
4068
  }
4055
- const fromSessionName = extractRootExe(mySession);
4056
4069
  let candidate = null;
4057
4070
  try {
4058
4071
  const key = getSessionKey();
@@ -4044,15 +4044,28 @@ function getParentExe(sessionKey) {
4044
4044
  }
4045
4045
  }
4046
4046
  function resolveExeSession() {
4047
+ const mySession = getMySession();
4048
+ const fromSessionName = mySession ? extractRootExe(mySession) ?? null : null;
4047
4049
  if (process.env.EXE_SESSION_NAME) {
4048
4050
  const fromEnv = extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
4049
- if (fromEnv) return fromEnv;
4051
+ if (fromEnv) {
4052
+ if (!mySession) {
4053
+ return fromEnv;
4054
+ }
4055
+ if (fromSessionName && fromEnv !== fromSessionName) {
4056
+ process.stderr.write(
4057
+ `[tmux-routing] WARN: EXE_SESSION_NAME="${fromEnv}" but tmux says "${fromSessionName}". Trusting tmux, correcting env var.
4058
+ `
4059
+ );
4060
+ process.env.EXE_SESSION_NAME = fromSessionName;
4061
+ } else {
4062
+ return fromEnv;
4063
+ }
4064
+ }
4050
4065
  }
4051
- const mySession = getMySession();
4052
4066
  if (!mySession) {
4053
4067
  return null;
4054
4068
  }
4055
- const fromSessionName = extractRootExe(mySession);
4056
4069
  let candidate = null;
4057
4070
  try {
4058
4071
  const key = getSessionKey();
@@ -9898,15 +9898,28 @@ function getDispatchedBy(sessionKey) {
9898
9898
  }
9899
9899
  }
9900
9900
  function resolveExeSession() {
9901
+ const mySession = getMySession();
9902
+ const fromSessionName = mySession ? extractRootExe(mySession) ?? null : null;
9901
9903
  if (process.env.EXE_SESSION_NAME) {
9902
9904
  const fromEnv = extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
9903
- if (fromEnv) return fromEnv;
9905
+ if (fromEnv) {
9906
+ if (!mySession) {
9907
+ return fromEnv;
9908
+ }
9909
+ if (fromSessionName && fromEnv !== fromSessionName) {
9910
+ process.stderr.write(
9911
+ `[tmux-routing] WARN: EXE_SESSION_NAME="${fromEnv}" but tmux says "${fromSessionName}". Trusting tmux, correcting env var.
9912
+ `
9913
+ );
9914
+ process.env.EXE_SESSION_NAME = fromSessionName;
9915
+ } else {
9916
+ return fromEnv;
9917
+ }
9918
+ }
9904
9919
  }
9905
- const mySession = getMySession();
9906
9920
  if (!mySession) {
9907
9921
  return null;
9908
9922
  }
9909
- const fromSessionName = extractRootExe(mySession);
9910
9923
  let candidate = null;
9911
9924
  try {
9912
9925
  const key = getSessionKey();
@@ -10090,6 +10103,21 @@ function isExeSession(sessionName) {
10090
10103
  }
10091
10104
  function sendIntercom(targetSession) {
10092
10105
  const transport = getTransport();
10106
+ try {
10107
+ const callerScope = resolveExeSession();
10108
+ if (callerScope && isExeSession(callerScope) && targetSession.includes("-")) {
10109
+ const targetScope = extractRootExe(targetSession);
10110
+ if (targetScope && targetScope !== callerScope) {
10111
+ logIntercom(`BLOCKED \u2192 ${targetSession} (scope violation: caller=${callerScope}, target=${targetScope})`);
10112
+ process.stderr.write(
10113
+ `[intercom] BLOCKED: cross-session intercom from ${callerScope} to ${targetSession}. Session isolation enforced.
10114
+ `
10115
+ );
10116
+ return "failed";
10117
+ }
10118
+ }
10119
+ } catch {
10120
+ }
10093
10121
  if (isExeSession(targetSession)) {
10094
10122
  logIntercom(`SKIP_COORDINATOR \u2192 ${targetSession} (coordinator sessions use prompt-submit hook)`);
10095
10123
  return "skipped_exe";
@@ -6556,15 +6556,28 @@ function getParentExe(sessionKey) {
6556
6556
  }
6557
6557
  }
6558
6558
  function resolveExeSession() {
6559
+ const mySession = getMySession();
6560
+ const fromSessionName = mySession ? extractRootExe(mySession) ?? null : null;
6559
6561
  if (process.env.EXE_SESSION_NAME) {
6560
6562
  const fromEnv = extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
6561
- if (fromEnv) return fromEnv;
6563
+ if (fromEnv) {
6564
+ if (!mySession) {
6565
+ return fromEnv;
6566
+ }
6567
+ if (fromSessionName && fromEnv !== fromSessionName) {
6568
+ process.stderr.write(
6569
+ `[tmux-routing] WARN: EXE_SESSION_NAME="${fromEnv}" but tmux says "${fromSessionName}". Trusting tmux, correcting env var.
6570
+ `
6571
+ );
6572
+ process.env.EXE_SESSION_NAME = fromSessionName;
6573
+ } else {
6574
+ return fromEnv;
6575
+ }
6576
+ }
6562
6577
  }
6563
- const mySession = getMySession();
6564
6578
  if (!mySession) {
6565
6579
  return null;
6566
6580
  }
6567
- const fromSessionName = extractRootExe(mySession);
6568
6581
  let candidate = null;
6569
6582
  try {
6570
6583
  const key = getSessionKey();
@@ -7441,15 +7441,28 @@ function getDispatchedBy(sessionKey) {
7441
7441
  }
7442
7442
  }
7443
7443
  function resolveExeSession() {
7444
+ const mySession = getMySession();
7445
+ const fromSessionName = mySession ? extractRootExe(mySession) ?? null : null;
7444
7446
  if (process.env.EXE_SESSION_NAME) {
7445
7447
  const fromEnv = extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
7446
- if (fromEnv) return fromEnv;
7448
+ if (fromEnv) {
7449
+ if (!mySession) {
7450
+ return fromEnv;
7451
+ }
7452
+ if (fromSessionName && fromEnv !== fromSessionName) {
7453
+ process.stderr.write(
7454
+ `[tmux-routing] WARN: EXE_SESSION_NAME="${fromEnv}" but tmux says "${fromSessionName}". Trusting tmux, correcting env var.
7455
+ `
7456
+ );
7457
+ process.env.EXE_SESSION_NAME = fromSessionName;
7458
+ } else {
7459
+ return fromEnv;
7460
+ }
7461
+ }
7447
7462
  }
7448
- const mySession = getMySession();
7449
7463
  if (!mySession) {
7450
7464
  return null;
7451
7465
  }
7452
- const fromSessionName = extractRootExe(mySession);
7453
7466
  let candidate = null;
7454
7467
  try {
7455
7468
  const key = getSessionKey();
@@ -7633,6 +7646,21 @@ function isExeSession(sessionName) {
7633
7646
  }
7634
7647
  function sendIntercom(targetSession) {
7635
7648
  const transport = getTransport();
7649
+ try {
7650
+ const callerScope = resolveExeSession();
7651
+ if (callerScope && isExeSession(callerScope) && targetSession.includes("-")) {
7652
+ const targetScope = extractRootExe(targetSession);
7653
+ if (targetScope && targetScope !== callerScope) {
7654
+ logIntercom(`BLOCKED \u2192 ${targetSession} (scope violation: caller=${callerScope}, target=${targetScope})`);
7655
+ process.stderr.write(
7656
+ `[intercom] BLOCKED: cross-session intercom from ${callerScope} to ${targetSession}. Session isolation enforced.
7657
+ `
7658
+ );
7659
+ return "failed";
7660
+ }
7661
+ }
7662
+ } catch {
7663
+ }
7636
7664
  if (isExeSession(targetSession)) {
7637
7665
  logIntercom(`SKIP_COORDINATOR \u2192 ${targetSession} (coordinator sessions use prompt-submit hook)`);
7638
7666
  return "skipped_exe";
@@ -9550,15 +9550,28 @@ function getDispatchedBy(sessionKey) {
9550
9550
  }
9551
9551
  }
9552
9552
  function resolveExeSession() {
9553
+ const mySession = getMySession();
9554
+ const fromSessionName = mySession ? extractRootExe(mySession) ?? null : null;
9553
9555
  if (process.env.EXE_SESSION_NAME) {
9554
9556
  const fromEnv = extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
9555
- if (fromEnv) return fromEnv;
9557
+ if (fromEnv) {
9558
+ if (!mySession) {
9559
+ return fromEnv;
9560
+ }
9561
+ if (fromSessionName && fromEnv !== fromSessionName) {
9562
+ process.stderr.write(
9563
+ `[tmux-routing] WARN: EXE_SESSION_NAME="${fromEnv}" but tmux says "${fromSessionName}". Trusting tmux, correcting env var.
9564
+ `
9565
+ );
9566
+ process.env.EXE_SESSION_NAME = fromSessionName;
9567
+ } else {
9568
+ return fromEnv;
9569
+ }
9570
+ }
9556
9571
  }
9557
- const mySession = getMySession();
9558
9572
  if (!mySession) {
9559
9573
  return null;
9560
9574
  }
9561
- const fromSessionName = extractRootExe(mySession);
9562
9575
  let candidate = null;
9563
9576
  try {
9564
9577
  const key = getSessionKey();
@@ -9742,6 +9755,21 @@ function isExeSession(sessionName) {
9742
9755
  }
9743
9756
  function sendIntercom(targetSession) {
9744
9757
  const transport = getTransport();
9758
+ try {
9759
+ const callerScope = resolveExeSession();
9760
+ if (callerScope && isExeSession(callerScope) && targetSession.includes("-")) {
9761
+ const targetScope = extractRootExe(targetSession);
9762
+ if (targetScope && targetScope !== callerScope) {
9763
+ logIntercom(`BLOCKED \u2192 ${targetSession} (scope violation: caller=${callerScope}, target=${targetScope})`);
9764
+ process.stderr.write(
9765
+ `[intercom] BLOCKED: cross-session intercom from ${callerScope} to ${targetSession}. Session isolation enforced.
9766
+ `
9767
+ );
9768
+ return "failed";
9769
+ }
9770
+ }
9771
+ } catch {
9772
+ }
9745
9773
  if (isExeSession(targetSession)) {
9746
9774
  logIntercom(`SKIP_COORDINATOR \u2192 ${targetSession} (coordinator sessions use prompt-submit hook)`);
9747
9775
  return "skipped_exe";
@@ -7512,15 +7512,28 @@ function getDispatchedBy(sessionKey) {
7512
7512
  }
7513
7513
  }
7514
7514
  function resolveExeSession() {
7515
+ const mySession = getMySession();
7516
+ const fromSessionName = mySession ? extractRootExe(mySession) ?? null : null;
7515
7517
  if (process.env.EXE_SESSION_NAME) {
7516
7518
  const fromEnv = extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
7517
- if (fromEnv) return fromEnv;
7519
+ if (fromEnv) {
7520
+ if (!mySession) {
7521
+ return fromEnv;
7522
+ }
7523
+ if (fromSessionName && fromEnv !== fromSessionName) {
7524
+ process.stderr.write(
7525
+ `[tmux-routing] WARN: EXE_SESSION_NAME="${fromEnv}" but tmux says "${fromSessionName}". Trusting tmux, correcting env var.
7526
+ `
7527
+ );
7528
+ process.env.EXE_SESSION_NAME = fromSessionName;
7529
+ } else {
7530
+ return fromEnv;
7531
+ }
7532
+ }
7518
7533
  }
7519
- const mySession = getMySession();
7520
7534
  if (!mySession) {
7521
7535
  return null;
7522
7536
  }
7523
- const fromSessionName = extractRootExe(mySession);
7524
7537
  let candidate = null;
7525
7538
  try {
7526
7539
  const key = getSessionKey();
@@ -7704,6 +7717,21 @@ function isExeSession(sessionName) {
7704
7717
  }
7705
7718
  function sendIntercom(targetSession) {
7706
7719
  const transport = getTransport();
7720
+ try {
7721
+ const callerScope = resolveExeSession();
7722
+ if (callerScope && isExeSession(callerScope) && targetSession.includes("-")) {
7723
+ const targetScope = extractRootExe(targetSession);
7724
+ if (targetScope && targetScope !== callerScope) {
7725
+ logIntercom(`BLOCKED \u2192 ${targetSession} (scope violation: caller=${callerScope}, target=${targetScope})`);
7726
+ process.stderr.write(
7727
+ `[intercom] BLOCKED: cross-session intercom from ${callerScope} to ${targetSession}. Session isolation enforced.
7728
+ `
7729
+ );
7730
+ return "failed";
7731
+ }
7732
+ }
7733
+ } catch {
7734
+ }
7707
7735
  if (isExeSession(targetSession)) {
7708
7736
  logIntercom(`SKIP_COORDINATOR \u2192 ${targetSession} (coordinator sessions use prompt-submit hook)`);
7709
7737
  return "skipped_exe";
@@ -11366,15 +11366,28 @@ function getDispatchedBy(sessionKey) {
11366
11366
  }
11367
11367
  }
11368
11368
  function resolveExeSession() {
11369
+ const mySession = getMySession();
11370
+ const fromSessionName = mySession ? extractRootExe(mySession) ?? null : null;
11369
11371
  if (process.env.EXE_SESSION_NAME) {
11370
11372
  const fromEnv = extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
11371
- if (fromEnv) return fromEnv;
11373
+ if (fromEnv) {
11374
+ if (!mySession) {
11375
+ return fromEnv;
11376
+ }
11377
+ if (fromSessionName && fromEnv !== fromSessionName) {
11378
+ process.stderr.write(
11379
+ `[tmux-routing] WARN: EXE_SESSION_NAME="${fromEnv}" but tmux says "${fromSessionName}". Trusting tmux, correcting env var.
11380
+ `
11381
+ );
11382
+ process.env.EXE_SESSION_NAME = fromSessionName;
11383
+ } else {
11384
+ return fromEnv;
11385
+ }
11386
+ }
11372
11387
  }
11373
- const mySession = getMySession();
11374
11388
  if (!mySession) {
11375
11389
  return null;
11376
11390
  }
11377
- const fromSessionName = extractRootExe(mySession);
11378
11391
  let candidate = null;
11379
11392
  try {
11380
11393
  const key = getSessionKey();
@@ -11558,6 +11571,21 @@ function isExeSession(sessionName) {
11558
11571
  }
11559
11572
  function sendIntercom(targetSession) {
11560
11573
  const transport = getTransport();
11574
+ try {
11575
+ const callerScope = resolveExeSession();
11576
+ if (callerScope && isExeSession(callerScope) && targetSession.includes("-")) {
11577
+ const targetScope = extractRootExe(targetSession);
11578
+ if (targetScope && targetScope !== callerScope) {
11579
+ logIntercom(`BLOCKED \u2192 ${targetSession} (scope violation: caller=${callerScope}, target=${targetScope})`);
11580
+ process.stderr.write(
11581
+ `[intercom] BLOCKED: cross-session intercom from ${callerScope} to ${targetSession}. Session isolation enforced.
11582
+ `
11583
+ );
11584
+ return "failed";
11585
+ }
11586
+ }
11587
+ } catch {
11588
+ }
11561
11589
  if (isExeSession(targetSession)) {
11562
11590
  logIntercom(`SKIP_COORDINATOR \u2192 ${targetSession} (coordinator sessions use prompt-submit hook)`);
11563
11591
  return "skipped_exe";