@askexenow/exe-os 0.9.84 → 0.9.86

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 (82) hide show
  1. package/dist/bin/agentic-ontology-backfill.js +32 -14
  2. package/dist/bin/agentic-reflection-backfill.js +32 -14
  3. package/dist/bin/agentic-semantic-label.js +32 -14
  4. package/dist/bin/backfill-conversations.js +32 -14
  5. package/dist/bin/backfill-responses.js +32 -14
  6. package/dist/bin/backfill-vectors.js +32 -14
  7. package/dist/bin/bulk-sync-postgres.js +32 -14
  8. package/dist/bin/cleanup-stale-review-tasks.js +35 -17
  9. package/dist/bin/cli.js +224 -86
  10. package/dist/bin/exe-assign.js +32 -14
  11. package/dist/bin/exe-boot.js +57 -39
  12. package/dist/bin/exe-cloud.js +22 -4
  13. package/dist/bin/exe-dispatch.js +43 -25
  14. package/dist/bin/exe-doctor.js +22 -4
  15. package/dist/bin/exe-export-behaviors.js +32 -14
  16. package/dist/bin/exe-forget.js +32 -14
  17. package/dist/bin/exe-gateway.js +47 -29
  18. package/dist/bin/exe-heartbeat.js +37 -19
  19. package/dist/bin/exe-kill.js +36 -18
  20. package/dist/bin/exe-launch-agent.js +170 -79
  21. package/dist/bin/exe-new-employee.js +32 -0
  22. package/dist/bin/exe-pending-messages.js +35 -17
  23. package/dist/bin/exe-pending-notifications.js +35 -17
  24. package/dist/bin/exe-pending-reviews.js +37 -19
  25. package/dist/bin/exe-rename.js +34 -16
  26. package/dist/bin/exe-review.js +32 -14
  27. package/dist/bin/exe-search.js +40 -22
  28. package/dist/bin/exe-session-cleanup.js +67 -44
  29. package/dist/bin/exe-start-codex.js +39 -21
  30. package/dist/bin/exe-start-opencode.js +37 -19
  31. package/dist/bin/exe-status.js +44 -26
  32. package/dist/bin/exe-team.js +32 -14
  33. package/dist/bin/git-sweep.js +45 -27
  34. package/dist/bin/graph-backfill.js +32 -14
  35. package/dist/bin/graph-export.js +32 -14
  36. package/dist/bin/install.js +32 -0
  37. package/dist/bin/intercom-check.js +49 -31
  38. package/dist/bin/scan-tasks.js +45 -27
  39. package/dist/bin/setup.js +29 -11
  40. package/dist/bin/shard-migrate.js +32 -14
  41. package/dist/bin/stack-update.js +95 -7
  42. package/dist/bin/update.js +1 -1
  43. package/dist/gateway/index.js +47 -29
  44. package/dist/hooks/bug-report-worker.js +47 -29
  45. package/dist/hooks/codex-stop-task-finalizer.js +41 -23
  46. package/dist/hooks/commit-complete.js +46 -28
  47. package/dist/hooks/error-recall.js +44 -26
  48. package/dist/hooks/ingest-worker.js +4 -4
  49. package/dist/hooks/ingest.js +38 -20
  50. package/dist/hooks/instructions-loaded.js +32 -14
  51. package/dist/hooks/notification.js +32 -14
  52. package/dist/hooks/post-compact.js +32 -14
  53. package/dist/hooks/post-tool-combined.js +45 -27
  54. package/dist/hooks/pre-compact.js +43 -25
  55. package/dist/hooks/pre-tool-use.js +40 -22
  56. package/dist/hooks/prompt-submit.js +60 -42
  57. package/dist/hooks/session-end.js +48 -30
  58. package/dist/hooks/session-start.js +50 -32
  59. package/dist/hooks/stop.js +35 -17
  60. package/dist/hooks/subagent-stop.js +32 -14
  61. package/dist/hooks/summary-worker.js +37 -19
  62. package/dist/index.js +43 -25
  63. package/dist/lib/cloud-sync.js +32 -14
  64. package/dist/lib/database.js +22 -4
  65. package/dist/lib/db-daemon-client.js +16 -4
  66. package/dist/lib/db.js +22 -4
  67. package/dist/lib/device-registry.js +22 -4
  68. package/dist/lib/embedder.js +16 -4
  69. package/dist/lib/exe-daemon-client.js +16 -4
  70. package/dist/lib/exe-daemon.js +165 -66
  71. package/dist/lib/hybrid-search.js +40 -22
  72. package/dist/lib/schedules.js +35 -17
  73. package/dist/lib/skill-learning.js +16 -4
  74. package/dist/lib/store.js +32 -14
  75. package/dist/lib/tasks.js +16 -4
  76. package/dist/lib/tmux-routing.js +18 -6
  77. package/dist/mcp/server.js +142 -60
  78. package/dist/mcp/tools/create-task.js +18 -6
  79. package/dist/mcp/tools/update-task.js +18 -6
  80. package/dist/runtime/index.js +43 -25
  81. package/dist/tui/App.js +73 -55
  82. package/package.json +1 -1
package/dist/bin/cli.js CHANGED
@@ -1241,6 +1241,7 @@ async function registerMcpServer(packageRoot, homeDir = os6.homedir()) {
1241
1241
  `
1242
1242
  );
1243
1243
  }
1244
+ await registerExeRustMcpConfig(packageRoot, homeDir);
1244
1245
  return false;
1245
1246
  }
1246
1247
  claudeJson.mcpServers[MCP_PRIMARY_KEY] = newEntry;
@@ -1254,8 +1255,39 @@ async function registerMcpServer(packageRoot, homeDir = os6.homedir()) {
1254
1255
  `
1255
1256
  );
1256
1257
  }
1258
+ await registerExeRustMcpConfig(packageRoot, homeDir);
1257
1259
  return true;
1258
1260
  }
1261
+ async function registerExeRustMcpConfig(packageRoot, homeDir) {
1262
+ const exeDir = path7.join(homeDir, ".exe");
1263
+ const exeMcpPath = path7.join(exeDir, "mcp.json");
1264
+ await mkdir3(exeDir, { recursive: true });
1265
+ let config = { servers: {} };
1266
+ if (existsSync8(exeMcpPath)) {
1267
+ try {
1268
+ config = JSON.parse(await readFile3(exeMcpPath, "utf-8"));
1269
+ if (!config.servers) config.servers = {};
1270
+ } catch {
1271
+ config = { servers: {} };
1272
+ }
1273
+ }
1274
+ const stdioEntry = {
1275
+ command: "node",
1276
+ args: [path7.join(packageRoot, "dist", "mcp", "server.js")],
1277
+ env: {},
1278
+ shared: true
1279
+ };
1280
+ const existing = config.servers[MCP_PRIMARY_KEY];
1281
+ if (existing && JSON.stringify(existing) === JSON.stringify(stdioEntry)) {
1282
+ return;
1283
+ }
1284
+ if (config.servers[MCP_LEGACY_KEY]) {
1285
+ delete config.servers[MCP_LEGACY_KEY];
1286
+ }
1287
+ config.servers[MCP_PRIMARY_KEY] = stdioEntry;
1288
+ await writeFile3(exeMcpPath, JSON.stringify(config, null, 2) + "\n");
1289
+ process.stderr.write("exe-os: registered MCP server in ~/.exe/mcp.json (Rust runtime)\n");
1290
+ }
1259
1291
  async function cleanSettingsJsonMcp(settingsPath) {
1260
1292
  if (!existsSync8(settingsPath)) return;
1261
1293
  try {
@@ -3633,7 +3665,7 @@ __export(exe_daemon_client_exports, {
3633
3665
  });
3634
3666
  import net from "net";
3635
3667
  import os10 from "os";
3636
- import { spawn } from "child_process";
3668
+ import { spawn, execSync as execSync4 } from "child_process";
3637
3669
  import { randomUUID } from "crypto";
3638
3670
  import { existsSync as existsSync12, unlinkSync as unlinkSync3, readFileSync as readFileSync9, openSync, closeSync, statSync as statSync2 } from "fs";
3639
3671
  import path12 from "path";
@@ -3663,6 +3695,14 @@ function handleData(chunk) {
3663
3695
  }
3664
3696
  }
3665
3697
  }
3698
+ function isZombie(pid) {
3699
+ try {
3700
+ const state = execSync4(`ps -p ${pid} -o state=`, { encoding: "utf8", timeout: 2e3 }).trim();
3701
+ return state.startsWith("Z");
3702
+ } catch {
3703
+ return false;
3704
+ }
3705
+ }
3666
3706
  function cleanupStaleFiles() {
3667
3707
  if (existsSync12(PID_PATH)) {
3668
3708
  try {
@@ -3670,7 +3710,11 @@ function cleanupStaleFiles() {
3670
3710
  if (pid > 0) {
3671
3711
  try {
3672
3712
  process.kill(pid, 0);
3673
- return;
3713
+ if (!isZombie(pid)) {
3714
+ return;
3715
+ }
3716
+ process.stderr.write(`[exed-client] PID ${pid} is a zombie \u2014 cleaning up stale files
3717
+ `);
3674
3718
  } catch {
3675
3719
  }
3676
3720
  }
@@ -3698,8 +3742,8 @@ function findPackageRoot() {
3698
3742
  function getAvailableMemoryGB() {
3699
3743
  if (process.platform === "darwin") {
3700
3744
  try {
3701
- const { execSync: execSync18 } = __require("child_process");
3702
- const vmstat = execSync18("vm_stat", { encoding: "utf8" });
3745
+ const { execSync: execSync19 } = __require("child_process");
3746
+ const vmstat = execSync19("vm_stat", { encoding: "utf8" });
3703
3747
  const pageSize = 16384;
3704
3748
  const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
3705
3749
  const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
@@ -5654,6 +5698,12 @@ async function disposeDatabase() {
5654
5698
  clearInterval(_walCheckpointTimer);
5655
5699
  _walCheckpointTimer = null;
5656
5700
  }
5701
+ if (_client) {
5702
+ try {
5703
+ await _client.execute("PRAGMA wal_checkpoint(PASSIVE)");
5704
+ } catch {
5705
+ }
5706
+ }
5657
5707
  if (_daemonClient) {
5658
5708
  _daemonClient.close();
5659
5709
  _daemonClient = null;
@@ -10404,7 +10454,7 @@ import { createInterface as createInterface2 } from "readline";
10404
10454
  import { existsSync as existsSync19, statSync as statSync6, mkdirSync as mkdirSync12, copyFileSync as copyFileSync3, renameSync as renameSync4, rmSync, writeFileSync as writeFileSync12 } from "fs";
10405
10455
  import path19 from "path";
10406
10456
  import os12 from "os";
10407
- import { execSync as execSync4 } from "child_process";
10457
+ import { execSync as execSync5 } from "child_process";
10408
10458
  import { createClient as createClient3 } from "@libsql/client";
10409
10459
  function isInteractiveTerminal2() {
10410
10460
  return Boolean(process.stdin.isTTY && process.stdout.isTTY && !process.env.CI);
@@ -10435,7 +10485,7 @@ function dbSidecarPaths(dbPath) {
10435
10485
  function daemonStatus() {
10436
10486
  const pidPath = path19.join(dataDir(), "exed.pid");
10437
10487
  if (!existsSync19(pidPath)) return { pid: null, alive: false };
10438
- const pid = execSync4(`cat ${JSON.stringify(pidPath)}`, { encoding: "utf8" }).trim();
10488
+ const pid = execSync5(`cat ${JSON.stringify(pidPath)}`, { encoding: "utf8" }).trim();
10439
10489
  if (!pid) return { pid: null, alive: false };
10440
10490
  try {
10441
10491
  process.kill(Number(pid), 0);
@@ -10449,7 +10499,7 @@ async function stopDaemonIfAlive() {
10449
10499
  if (!daemon.alive || !daemon.pid) return;
10450
10500
  if (Number(daemon.pid) <= 1) {
10451
10501
  try {
10452
- execSync4("docker inspect exed >/dev/null 2>&1 && docker stop exed >/dev/null", { timeout: 3e4 });
10502
+ execSync5("docker inspect exed >/dev/null 2>&1 && docker stop exed >/dev/null", { timeout: 3e4 });
10453
10503
  return;
10454
10504
  } catch {
10455
10505
  throw new Error("Refusing to signal PID 1. Stop the exed Docker container manually, then retry.");
@@ -12918,7 +12968,7 @@ __export(session_registry_exports, {
12918
12968
  registerSession: () => registerSession
12919
12969
  });
12920
12970
  import { readFileSync as readFileSync18, writeFileSync as writeFileSync17, mkdirSync as mkdirSync17, existsSync as existsSync22 } from "fs";
12921
- import { execSync as execSync5 } from "child_process";
12971
+ import { execSync as execSync6 } from "child_process";
12922
12972
  import path25 from "path";
12923
12973
  import os14 from "os";
12924
12974
  function registerSession(entry) {
@@ -12958,7 +13008,7 @@ function pruneStaleSessions() {
12958
13008
  if (sessions.length === 0) return 0;
12959
13009
  let liveSessions = [];
12960
13010
  try {
12961
- liveSessions = execSync5("tmux list-sessions -F '#{session_name}' 2>/dev/null", {
13011
+ liveSessions = execSync6("tmux list-sessions -F '#{session_name}' 2>/dev/null", {
12962
13012
  encoding: "utf8"
12963
13013
  }).trim().split("\n").filter(Boolean);
12964
13014
  } catch {
@@ -12981,7 +13031,7 @@ var init_session_registry = __esm({
12981
13031
  });
12982
13032
 
12983
13033
  // src/lib/session-key.ts
12984
- import { execSync as execSync6 } from "child_process";
13034
+ import { execSync as execSync7 } from "child_process";
12985
13035
  function normalizeCommand(command) {
12986
13036
  const trimmed = command.trim().toLowerCase();
12987
13037
  const parts = trimmed.split(/[\\/]/);
@@ -13000,7 +13050,7 @@ function resolveRuntimeProcess() {
13000
13050
  let pid = process.ppid;
13001
13051
  for (let i = 0; i < 10; i++) {
13002
13052
  try {
13003
- const info = execSync6(`ps -p ${pid} -o ppid=,comm=`, {
13053
+ const info = execSync7(`ps -p ${pid} -o ppid=,comm=`, {
13004
13054
  encoding: "utf8",
13005
13055
  timeout: 2e3
13006
13056
  }).trim();
@@ -13174,14 +13224,14 @@ var init_transport = __esm({
13174
13224
  });
13175
13225
 
13176
13226
  // src/lib/cc-agent-support.ts
13177
- import { execSync as execSync7 } from "child_process";
13227
+ import { execSync as execSync8 } from "child_process";
13178
13228
  function _resetCcAgentSupportCache() {
13179
13229
  _cachedSupport = null;
13180
13230
  }
13181
13231
  function claudeSupportsAgentFlag() {
13182
13232
  if (_cachedSupport !== null) return _cachedSupport;
13183
13233
  try {
13184
- const helpOutput = execSync7("claude --help 2>&1", {
13234
+ const helpOutput = execSync8("claude --help 2>&1", {
13185
13235
  encoding: "utf-8",
13186
13236
  timeout: 5e3
13187
13237
  });
@@ -13558,7 +13608,7 @@ var init_session_kill_telemetry = __esm({
13558
13608
  });
13559
13609
 
13560
13610
  // src/lib/project-name.ts
13561
- import { execSync as execSync8 } from "child_process";
13611
+ import { execSync as execSync9 } from "child_process";
13562
13612
  import path29 from "path";
13563
13613
  function getProjectName(cwd2) {
13564
13614
  const dir = cwd2 ?? process.cwd();
@@ -13566,7 +13616,7 @@ function getProjectName(cwd2) {
13566
13616
  try {
13567
13617
  let repoRoot;
13568
13618
  try {
13569
- const gitCommonDir = execSync8("git rev-parse --path-format=absolute --git-common-dir", {
13619
+ const gitCommonDir = execSync9("git rev-parse --path-format=absolute --git-common-dir", {
13570
13620
  cwd: dir,
13571
13621
  encoding: "utf8",
13572
13622
  timeout: 2e3,
@@ -13574,7 +13624,7 @@ function getProjectName(cwd2) {
13574
13624
  }).trim();
13575
13625
  repoRoot = path29.dirname(gitCommonDir);
13576
13626
  } catch {
13577
- repoRoot = execSync8("git rev-parse --show-toplevel", {
13627
+ repoRoot = execSync9("git rev-parse --show-toplevel", {
13578
13628
  cwd: dir,
13579
13629
  encoding: "utf8",
13580
13630
  timeout: 2e3,
@@ -13681,7 +13731,7 @@ __export(tasks_crud_exports, {
13681
13731
  import crypto9 from "crypto";
13682
13732
  import path30 from "path";
13683
13733
  import os17 from "os";
13684
- import { execSync as execSync9 } from "child_process";
13734
+ import { execSync as execSync10 } from "child_process";
13685
13735
  import { mkdir as mkdir5, writeFile as writeFile5, appendFile } from "fs/promises";
13686
13736
  import { existsSync as existsSync26, readFileSync as readFileSync22 } from "fs";
13687
13737
  async function writeCheckpoint(input) {
@@ -14026,14 +14076,14 @@ function isTmuxSessionAlive(identifier) {
14026
14076
  if (!identifier || identifier === "unknown") return true;
14027
14077
  try {
14028
14078
  if (identifier.startsWith("%")) {
14029
- const output2 = execSync9("tmux list-panes -a -F '#{pane_id}'", {
14079
+ const output2 = execSync10("tmux list-panes -a -F '#{pane_id}'", {
14030
14080
  timeout: 2e3,
14031
14081
  encoding: "utf8",
14032
14082
  stdio: ["pipe", "pipe", "pipe"]
14033
14083
  });
14034
14084
  return output2.split("\n").some((l) => l.trim() === identifier);
14035
14085
  } else {
14036
- execSync9(`tmux has-session -t ${JSON.stringify(identifier)}`, {
14086
+ execSync10(`tmux has-session -t ${JSON.stringify(identifier)}`, {
14037
14087
  timeout: 2e3,
14038
14088
  stdio: ["pipe", "pipe", "pipe"]
14039
14089
  });
@@ -14042,7 +14092,7 @@ function isTmuxSessionAlive(identifier) {
14042
14092
  } catch {
14043
14093
  if (identifier.startsWith("%")) return true;
14044
14094
  try {
14045
- execSync9("tmux list-sessions", {
14095
+ execSync10("tmux list-sessions", {
14046
14096
  timeout: 2e3,
14047
14097
  stdio: ["pipe", "pipe", "pipe"]
14048
14098
  });
@@ -14057,12 +14107,12 @@ function checkStaleCompletion(taskContext, taskCreatedAt) {
14057
14107
  if (!DELEGATION_KEYWORDS.test(taskContext)) return null;
14058
14108
  try {
14059
14109
  const since = new Date(taskCreatedAt).toISOString();
14060
- const branch = execSync9(
14110
+ const branch = execSync10(
14061
14111
  "git rev-parse --abbrev-ref HEAD 2>/dev/null",
14062
14112
  { encoding: "utf8", timeout: 3e3 }
14063
14113
  ).trim();
14064
14114
  const branchArg = branch && branch !== "HEAD" ? branch : "";
14065
- const commitCount = execSync9(
14115
+ const commitCount = execSync10(
14066
14116
  `git log --oneline --since="${since}" ${branchArg} 2>/dev/null | wc -l`,
14067
14117
  { encoding: "utf8", timeout: 5e3 }
14068
14118
  ).trim();
@@ -15661,7 +15711,7 @@ __export(tmux_routing_exports, {
15661
15711
  spawnEmployee: () => spawnEmployee,
15662
15712
  verifyPaneAtCapacity: () => verifyPaneAtCapacity
15663
15713
  });
15664
- import { execFileSync as execFileSync3, execSync as execSync10 } from "child_process";
15714
+ import { execFileSync as execFileSync3, execSync as execSync11 } from "child_process";
15665
15715
  import { readFileSync as readFileSync23, writeFileSync as writeFileSync20, mkdirSync as mkdirSync20, existsSync as existsSync28, appendFileSync as appendFileSync2, readdirSync as readdirSync7 } from "fs";
15666
15716
  import path34 from "path";
15667
15717
  import os18 from "os";
@@ -16382,7 +16432,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
16382
16432
  let booted = false;
16383
16433
  for (let i = 0; i < 30; i++) {
16384
16434
  try {
16385
- execSync10("sleep 0.5");
16435
+ execSync11("sleep 0.5");
16386
16436
  } catch {
16387
16437
  }
16388
16438
  try {
@@ -16755,7 +16805,7 @@ __export(active_agent_exports, {
16755
16805
  writeActiveAgent: () => writeActiveAgent
16756
16806
  });
16757
16807
  import { readFileSync as readFileSync24, writeFileSync as writeFileSync21, mkdirSync as mkdirSync21, unlinkSync as unlinkSync12, readdirSync as readdirSync8 } from "fs";
16758
- import { execSync as execSync11 } from "child_process";
16808
+ import { execSync as execSync12 } from "child_process";
16759
16809
  import path35 from "path";
16760
16810
  function isNameWithOptionalInstance(candidate, baseName) {
16761
16811
  if (candidate === baseName) return true;
@@ -16849,7 +16899,7 @@ function getActiveAgent() {
16849
16899
  } catch {
16850
16900
  }
16851
16901
  try {
16852
- const sessionName = execSync11(
16902
+ const sessionName = execSync12(
16853
16903
  "tmux display-message -p '#{session_name}' 2>/dev/null",
16854
16904
  { encoding: "utf8", timeout: 2e3 }
16855
16905
  ).trim();
@@ -17574,7 +17624,7 @@ __export(exe_rename_exports, {
17574
17624
  renameEmployee: () => renameEmployee
17575
17625
  });
17576
17626
  import { readFileSync as readFileSync25, writeFileSync as writeFileSync22, renameSync as renameSync6, unlinkSync as unlinkSync13, existsSync as existsSync29 } from "fs";
17577
- import { execSync as execSync12 } from "child_process";
17627
+ import { execSync as execSync13 } from "child_process";
17578
17628
  import path36 from "path";
17579
17629
  import { homedir as homedir4 } from "os";
17580
17630
  async function renameEmployee(oldName, newName, opts = {}) {
@@ -17715,7 +17765,7 @@ function rewriteRenamedEmployeeContent(content, oldName, newName) {
17715
17765
  }
17716
17766
  function findExeBin2() {
17717
17767
  try {
17718
- return execSync12(process.platform === "win32" ? "where exe-os" : "which exe-os", { encoding: "utf8" }).trim();
17768
+ return execSync13(process.platform === "win32" ? "where exe-os" : "which exe-os", { encoding: "utf8" }).trim();
17719
17769
  } catch {
17720
17770
  return null;
17721
17771
  }
@@ -18421,7 +18471,7 @@ import {
18421
18471
  readdirSync as readdirSync9,
18422
18472
  unlinkSync as unlinkSync15
18423
18473
  } from "fs";
18424
- import { execSync as execSync13 } from "child_process";
18474
+ import { execSync as execSync14 } from "child_process";
18425
18475
  import path38 from "path";
18426
18476
  import { homedir as homedir5 } from "os";
18427
18477
  function generateSessionWrappers(packageRoot, homeDir) {
@@ -18518,12 +18568,12 @@ function writeWrapper(wrapperPath, content) {
18518
18568
  }
18519
18569
  function resolveGlobalBinDir() {
18520
18570
  try {
18521
- const exeOsPath = execSync13("command -v exe-os", { encoding: "utf8", timeout: 3e3 }).trim().split("\n")[0];
18571
+ const exeOsPath = execSync14("command -v exe-os", { encoding: "utf8", timeout: 3e3 }).trim().split("\n")[0];
18522
18572
  if (exeOsPath) return path38.dirname(exeOsPath);
18523
18573
  } catch {
18524
18574
  }
18525
18575
  try {
18526
- const prefix = execSync13("npm prefix -g", { encoding: "utf8", timeout: 3e3 }).trim();
18576
+ const prefix = execSync14("npm prefix -g", { encoding: "utf8", timeout: 3e3 }).trim();
18527
18577
  if (prefix) return path38.join(prefix, "bin");
18528
18578
  } catch {
18529
18579
  }
@@ -18630,8 +18680,8 @@ function ask3(rl, prompt) {
18630
18680
  function getAvailableMemoryGB2() {
18631
18681
  if (process.platform === "darwin") {
18632
18682
  try {
18633
- const { execSync: execSync18 } = __require("child_process");
18634
- const vmstat = execSync18("vm_stat", { encoding: "utf8" });
18683
+ const { execSync: execSync19 } = __require("child_process");
18684
+ const vmstat = execSync19("vm_stat", { encoding: "utf8" });
18635
18685
  const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
18636
18686
  const pageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : 16384;
18637
18687
  const free = vmstat.match(/Pages free:\s+(\d+)/);
@@ -19492,7 +19542,7 @@ var init_update_backup = __esm({
19492
19542
  });
19493
19543
 
19494
19544
  // src/lib/update-check.ts
19495
- import { execSync as execSync14 } from "child_process";
19545
+ import { execSync as execSync15 } from "child_process";
19496
19546
  import { readFileSync as readFileSync28 } from "fs";
19497
19547
  import path41 from "path";
19498
19548
  function getLocalVersion(packageRoot) {
@@ -19502,7 +19552,7 @@ function getLocalVersion(packageRoot) {
19502
19552
  }
19503
19553
  function getRemoteVersion() {
19504
19554
  try {
19505
- const output2 = execSync14("npm view @askexenow/exe-os version", {
19555
+ const output2 = execSync15("npm view @askexenow/exe-os version", {
19506
19556
  encoding: "utf-8",
19507
19557
  timeout: 15e3,
19508
19558
  stdio: ["pipe", "pipe", "pipe"]
@@ -19541,7 +19591,7 @@ __export(update_exports, {
19541
19591
  getRemoteVersion: () => getRemoteVersion,
19542
19592
  runUpdate: () => runUpdate
19543
19593
  });
19544
- import { execSync as execSync15 } from "child_process";
19594
+ import { execSync as execSync16 } from "child_process";
19545
19595
  import { createInterface as createInterface5 } from "readline";
19546
19596
  async function runRestore() {
19547
19597
  console.log("\n\u{1F504} Restoring from update backup...");
@@ -19552,7 +19602,7 @@ async function runRestore() {
19552
19602
  console.log(`
19553
19603
  \u{1F4E5} Reinstalling @askexenow/exe-os@${manifest.version}...`);
19554
19604
  try {
19555
- execSync15(`npm install -g @askexenow/exe-os@${manifest.version}`, {
19605
+ execSync16(`npm install -g @askexenow/exe-os@${manifest.version}`, {
19556
19606
  stdio: ["pipe", "pipe", "inherit"],
19557
19607
  timeout: 3e5
19558
19608
  });
@@ -19577,7 +19627,7 @@ async function runRestore() {
19577
19627
  }
19578
19628
  async function runUpdate(cliArgs) {
19579
19629
  const args2 = cliArgs ?? process.argv.slice(2);
19580
- const autoMode = args2.includes("--auto") || args2.includes("-y");
19630
+ const autoMode = args2.includes("--auto") || args2.includes("--yes") || args2.includes("-y");
19581
19631
  const checkOnly = args2.includes("--check");
19582
19632
  const restoreMode = args2.includes("--restore");
19583
19633
  if (restoreMode) {
@@ -19629,7 +19679,7 @@ async function runUpdate(cliArgs) {
19629
19679
  }
19630
19680
  console.log("\u{1F9F9} Clearing npm cache...");
19631
19681
  try {
19632
- execSync15("npm cache clean --force", { stdio: "pipe" });
19682
+ execSync16("npm cache clean --force", { stdio: "pipe" });
19633
19683
  console.log(" Done");
19634
19684
  } catch {
19635
19685
  console.log(" Skipped (non-critical)");
@@ -19637,7 +19687,7 @@ async function runUpdate(cliArgs) {
19637
19687
  console.log("\u{1F4E5} Installing @askexenow/exe-os@latest...");
19638
19688
  console.log(" This may take a minute...\n");
19639
19689
  try {
19640
- execSync15("npm install -g @askexenow/exe-os@latest", {
19690
+ execSync16("npm install -g @askexenow/exe-os@latest", {
19641
19691
  stdio: ["pipe", "pipe", "inherit"],
19642
19692
  timeout: 3e5
19643
19693
  });
@@ -19655,7 +19705,7 @@ async function runUpdate(cliArgs) {
19655
19705
  newVersion = getLocalVersion(packageRoot);
19656
19706
  } catch {
19657
19707
  try {
19658
- const out = execSync15("npm list -g @askexenow/exe-os --depth=0 2>/dev/null", { encoding: "utf8" });
19708
+ const out = execSync16("npm list -g @askexenow/exe-os --depth=0 2>/dev/null", { encoding: "utf8" });
19659
19709
  const match = out.match(/@askexenow\/exe-os@(\S+)/);
19660
19710
  newVersion = match?.[1] ?? "unknown";
19661
19711
  } catch {
@@ -19684,7 +19734,7 @@ async function runUpdate(cliArgs) {
19684
19734
  }
19685
19735
  console.log("\u{1F527} Re-registering MCP, hooks, wrappers, and daemon...");
19686
19736
  try {
19687
- execSync15("exe-os-install --global", {
19737
+ execSync16("exe-os-install --global", {
19688
19738
  stdio: ["pipe", "inherit", "inherit"],
19689
19739
  timeout: 3e5
19690
19740
  });
@@ -19719,7 +19769,7 @@ async function runUpdate(cliArgs) {
19719
19769
  }
19720
19770
  try {
19721
19771
  console.log("\u{1FA7A} Checking AskExe support intake...");
19722
- execSync15("exe-os support health", {
19772
+ execSync16("exe-os support health", {
19723
19773
  stdio: ["pipe", "inherit", "inherit"],
19724
19774
  timeout: 3e4
19725
19775
  });
@@ -20042,6 +20092,9 @@ function installDockerUbuntu(exec2) {
20042
20092
  function randomSecret(bytes = 32) {
20043
20093
  return randomBytes2(bytes).toString("base64url");
20044
20094
  }
20095
+ function randomHexSecret(bytes = 24) {
20096
+ return randomBytes2(bytes).toString("hex");
20097
+ }
20045
20098
  function hydrateEnv(raw, opts) {
20046
20099
  let next = raw;
20047
20100
  const license = opts.licenseKey || process.env.EXE_LICENSE_KEY || loadLicense() || "";
@@ -20051,6 +20104,8 @@ function hydrateEnv(raw, opts) {
20051
20104
  for (const [key, value] of env.entries()) {
20052
20105
  if (!/CHANGEME/.test(value)) continue;
20053
20106
  if (key === "EXE_LICENSE_KEY" && license) replacements[key] = license;
20107
+ else if (key === "MONITOR_AGENT_KEY") continue;
20108
+ else if (key === "EXE_GATEWAY_WS_RELAY_AUTH_TOKEN") replacements[key] = randomHexSecret(24);
20054
20109
  else if (key.endsWith("_PASSWORD")) replacements[key] = randomSecret(24);
20055
20110
  else if (key.endsWith("_SECRET") || key.endsWith("_TOKEN") || key.endsWith("_KEY") || key.endsWith("_SALT")) replacements[key] = value.replace(/CHANGEME[A-Z0-9_]*/g, randomSecret(32));
20056
20111
  else if (key === "EXED_MCP_TOKEN") replacements[key] = randomSecret(32);
@@ -20113,12 +20168,25 @@ function assertHostReadyForApply(report) {
20113
20168
  if (blockers.length > 0) throw new Error(`Stack host is not ready:
20114
20169
  - ${blockers.join("\n- ")}`);
20115
20170
  }
20171
+ function areStackContainersRunning(composeFile, envFile) {
20172
+ try {
20173
+ const result = spawnSync("docker", ["compose", "--file", composeFile, "--env-file", envFile, "ps", "-q"], {
20174
+ stdio: ["pipe", "pipe", "pipe"],
20175
+ timeout: 15e3
20176
+ });
20177
+ return result.status === 0 && (result.stdout?.toString().trim().length ?? 0) > 0;
20178
+ } catch {
20179
+ return false;
20180
+ }
20181
+ }
20116
20182
  async function runStackUpdate(options) {
20117
20183
  const exec2 = options.exec ?? defaultExec;
20118
20184
  const now2 = options.now ?? (() => /* @__PURE__ */ new Date());
20119
20185
  if (options.rollback) return rollbackStackUpdate(options);
20120
- const report = bootstrapStackHost({ ...options, installDocker: options.installDocker ?? !!options.yes });
20121
- if (!options.dryRun) assertHostReadyForApply(report);
20186
+ if (options.bootstrap !== false) {
20187
+ const report = bootstrapStackHost({ ...options, installDocker: options.installDocker ?? !!options.yes });
20188
+ if (!options.dryRun) assertHostReadyForApply(report);
20189
+ }
20122
20190
  const manifest = await loadStackManifest(options.manifestRef, options.fetchText, options.manifestPublicKey, options.manifestAuthToken);
20123
20191
  const envRaw = readFileSync29(options.envFile, "utf8");
20124
20192
  const plan = createStackUpdatePlan(manifest, envRaw, options.targetVersion);
@@ -20134,7 +20202,8 @@ async function runStackUpdate(options) {
20134
20202
  });
20135
20203
  const lockFile = options.lockFile ?? path42.join(path42.dirname(options.envFile), ".exe-stack-lock.json");
20136
20204
  const previousVersion = readCurrentStackVersion(lockFile);
20137
- if (options.dryRun || plan.changes.length === 0) {
20205
+ const containersRunning = plan.changes.length === 0 ? areStackContainersRunning(options.composeFile, options.envFile) : true;
20206
+ if (options.dryRun || plan.changes.length === 0 && containersRunning) {
20138
20207
  return { status: "planned", targetVersion: plan.targetVersion, changes: plan.changes, lockFile };
20139
20208
  }
20140
20209
  await postDeployAudit(options, "started", plan.targetVersion, previousVersion);
@@ -20296,7 +20365,9 @@ function defaultStackPaths() {
20296
20365
  // Packaged manifests keep cold-start installs unblocked even before update-service entitlements are provisioned.
20297
20366
  auditUrl: process.env.EXE_STACK_AUDIT_URL || (/^https?:\/\//.test(manifestRef) ? "https://update.askexe.com/v1/deploy-audits" : void 0),
20298
20367
  imageCredentialsUrl: process.env.EXE_STACK_IMAGE_CREDENTIALS_URL || (/^https?:\/\//.test(manifestRef) ? "https://update.askexe.com/v1/image-credentials" : void 0),
20299
- manifestAuthToken: process.env.EXE_STACK_UPDATE_TOKEN || process.env.EXE_LICENSE_KEY || loadLicense() || void 0,
20368
+ // License key IS the auth token for update.askexe.com no separate update token needed.
20369
+ // EXE_STACK_UPDATE_TOKEN kept as legacy fallback during migration.
20370
+ manifestAuthToken: process.env.EXE_LICENSE_KEY || loadLicense() || process.env.EXE_STACK_UPDATE_TOKEN || void 0,
20300
20371
  manifestPublicKey: loadDefaultPublicKey()
20301
20372
  };
20302
20373
  }
@@ -20322,6 +20393,7 @@ __export(stack_update_exports, {
20322
20393
  runStackUpdateCli: () => main7
20323
20394
  });
20324
20395
  import { readFileSync as readFileSync30 } from "fs";
20396
+ import { spawnSync as spawnSync2 } from "child_process";
20325
20397
  function parseArgs4(args2) {
20326
20398
  const defaults = defaultStackPaths();
20327
20399
  const opts = {
@@ -20431,9 +20503,21 @@ Options:
20431
20503
  -y, --yes Non-interactive confirmation
20432
20504
  `);
20433
20505
  }
20434
- function printChanges(changes) {
20506
+ function printChanges(changes, composeFile, envFile) {
20435
20507
  if (changes.length === 0) {
20436
- console.log("\u2705 Stack already matches target manifest.");
20508
+ const running = areCliContainersRunning(composeFile, envFile);
20509
+ if (running) {
20510
+ console.log("Stack .env matches target manifest. Checking container health...\n");
20511
+ const unhealthy = printContainerHealth(composeFile, envFile);
20512
+ if (unhealthy > 0) {
20513
+ console.log(`
20514
+ \u{1F534} ${unhealthy} service(s) unhealthy or crashlooping. Run \`docker compose logs <service>\` to diagnose.`);
20515
+ } else {
20516
+ console.log("\n\u2705 Stack already matches target manifest. All services healthy.");
20517
+ }
20518
+ } else {
20519
+ console.log("\u26A0\uFE0F Stack .env matches target manifest but containers are not running. Will start them.");
20520
+ }
20437
20521
  return;
20438
20522
  }
20439
20523
  console.log("Planned image tag changes:");
@@ -20442,6 +20526,60 @@ function printChanges(changes) {
20442
20526
  console.log(` ${c.before ?? "<unset>"} \u2192 ${c.after}`);
20443
20527
  }
20444
20528
  }
20529
+ function areCliContainersRunning(composeFile, envFile) {
20530
+ try {
20531
+ const result = spawnSync2("docker", ["compose", "--file", composeFile, "--env-file", envFile, "ps", "-q"], {
20532
+ stdio: ["pipe", "pipe", "pipe"],
20533
+ timeout: 15e3
20534
+ });
20535
+ return result.status === 0 && (result.stdout?.toString().trim().length ?? 0) > 0;
20536
+ } catch {
20537
+ return false;
20538
+ }
20539
+ }
20540
+ function getContainerHealth(composeFile, envFile) {
20541
+ try {
20542
+ const result = spawnSync2(
20543
+ "docker",
20544
+ ["compose", "--file", composeFile, "--env-file", envFile, "ps", "--format", "json"],
20545
+ { stdio: ["pipe", "pipe", "pipe"], timeout: 15e3 }
20546
+ );
20547
+ if (result.status !== 0) return [];
20548
+ const raw = result.stdout?.toString().trim() ?? "";
20549
+ if (!raw) return [];
20550
+ return raw.split("\n").filter(Boolean).map((line) => {
20551
+ try {
20552
+ const obj = JSON.parse(line);
20553
+ return {
20554
+ service: obj.Service ?? obj.Name ?? "unknown",
20555
+ state: obj.State ?? "unknown",
20556
+ health: obj.Health ?? "",
20557
+ restartCount: typeof obj.RestartCount === "number" ? obj.RestartCount : 0
20558
+ };
20559
+ } catch {
20560
+ return null;
20561
+ }
20562
+ }).filter((x) => x !== null);
20563
+ } catch {
20564
+ return [];
20565
+ }
20566
+ }
20567
+ function printContainerHealth(composeFile, envFile) {
20568
+ const containers = getContainerHealth(composeFile, envFile);
20569
+ if (containers.length === 0) return 0;
20570
+ let unhealthy = 0;
20571
+ for (const c of containers) {
20572
+ const isRestarting = c.state === "restarting" || c.restartCount > 2;
20573
+ const isUnhealthy = c.health === "unhealthy" || c.state === "dead" || c.state === "exited";
20574
+ if (isRestarting || isUnhealthy) {
20575
+ unhealthy++;
20576
+ console.log(` \u274C ${c.service}: ${c.state} (restarts: ${c.restartCount}${c.health ? `, health: ${c.health}` : ""})`);
20577
+ } else {
20578
+ console.log(` \u2705 ${c.service}: ${c.state}${c.health ? ` (${c.health})` : ""}`);
20579
+ }
20580
+ }
20581
+ return unhealthy;
20582
+ }
20445
20583
  function printBreaking(changes) {
20446
20584
  if (changes.length === 0) return;
20447
20585
  console.log("\nBreaking-change notices:");
@@ -20496,7 +20634,7 @@ async function main7(args2 = process.argv.slice(2)) {
20496
20634
  console.log(`Compose: ${opts.composeFile}`);
20497
20635
  console.log(`Env: ${opts.envFile}
20498
20636
  `);
20499
- printChanges(plan.changes);
20637
+ printChanges(plan.changes, opts.composeFile, opts.envFile);
20500
20638
  printBreaking(plan.breakingChanges);
20501
20639
  if (opts.check || opts.dryRun) return;
20502
20640
  if (!opts.yes) {
@@ -27190,13 +27328,13 @@ __export(tmux_status_exports, {
27190
27328
  parseActivity: () => parseActivity,
27191
27329
  parseContextPercentage: () => parseContextPercentage
27192
27330
  });
27193
- import { execSync as execSync16 } from "child_process";
27331
+ import { execSync as execSync17 } from "child_process";
27194
27332
  function inTmux() {
27195
27333
  if (process.env.TMUX || process.env.TMUX_PANE) return true;
27196
27334
  const term = process.env.TERM ?? "";
27197
27335
  if (term.startsWith("tmux") || term.startsWith("screen")) return true;
27198
27336
  try {
27199
- execSync16("tmux display-message -p '#{session_name}' 2>/dev/null", {
27337
+ execSync17("tmux display-message -p '#{session_name}' 2>/dev/null", {
27200
27338
  encoding: "utf8",
27201
27339
  timeout: 2e3
27202
27340
  });
@@ -27206,12 +27344,12 @@ function inTmux() {
27206
27344
  try {
27207
27345
  let pid = process.ppid;
27208
27346
  for (let depth = 0; depth < 8 && pid > 1; depth++) {
27209
- const comm = execSync16(`ps -p ${pid} -o comm= 2>/dev/null`, {
27347
+ const comm = execSync17(`ps -p ${pid} -o comm= 2>/dev/null`, {
27210
27348
  encoding: "utf8",
27211
27349
  timeout: 1e3
27212
27350
  }).trim();
27213
27351
  if (/tmux/.test(comm)) return true;
27214
- const ppid = execSync16(`ps -p ${pid} -o ppid= 2>/dev/null`, {
27352
+ const ppid = execSync17(`ps -p ${pid} -o ppid= 2>/dev/null`, {
27215
27353
  encoding: "utf8",
27216
27354
  timeout: 1e3
27217
27355
  }).trim();
@@ -27224,7 +27362,7 @@ function inTmux() {
27224
27362
  }
27225
27363
  function listTmuxSessions() {
27226
27364
  try {
27227
- const out = execSync16("tmux list-sessions -F '#{session_name}' 2>/dev/null", {
27365
+ const out = execSync17("tmux list-sessions -F '#{session_name}' 2>/dev/null", {
27228
27366
  encoding: "utf8",
27229
27367
  timeout: 3e3
27230
27368
  });
@@ -27235,7 +27373,7 @@ function listTmuxSessions() {
27235
27373
  }
27236
27374
  function capturePaneLines(windowName, lines = 10) {
27237
27375
  try {
27238
- const out = execSync16(
27376
+ const out = execSync17(
27239
27377
  `tmux capture-pane -t ${JSON.stringify(windowName)} -p 2>/dev/null | tail -${lines}`,
27240
27378
  { encoding: "utf8", timeout: 3e3 }
27241
27379
  );
@@ -27246,7 +27384,7 @@ function capturePaneLines(windowName, lines = 10) {
27246
27384
  }
27247
27385
  function getPaneCwd(windowName) {
27248
27386
  try {
27249
- const out = execSync16(
27387
+ const out = execSync17(
27250
27388
  `tmux display-message -t ${JSON.stringify(windowName)} -p '#{pane_current_path}' 2>/dev/null`,
27251
27389
  { encoding: "utf8", timeout: 3e3 }
27252
27390
  );
@@ -27257,7 +27395,7 @@ function getPaneCwd(windowName) {
27257
27395
  }
27258
27396
  function projectFromPath(dir) {
27259
27397
  try {
27260
- const root = execSync16("git -C " + JSON.stringify(dir) + " rev-parse --show-toplevel 2>/dev/null", {
27398
+ const root = execSync17("git -C " + JSON.stringify(dir) + " rev-parse --show-toplevel 2>/dev/null", {
27261
27399
  encoding: "utf8",
27262
27400
  timeout: 3e3
27263
27401
  }).trim();
@@ -27326,7 +27464,7 @@ function getEmployeeStatuses(employeeNames) {
27326
27464
  }
27327
27465
  let paneAlive = true;
27328
27466
  try {
27329
- const paneStatus = execSync16(
27467
+ const paneStatus = execSync17(
27330
27468
  `tmux list-panes -t ${JSON.stringify(sessionName)} -F '#{pane_dead}' 2>/dev/null`,
27331
27469
  { encoding: "utf8", timeout: 3e3 }
27332
27470
  ).trim();
@@ -27516,8 +27654,8 @@ function Footer() {
27516
27654
  setSessions(allSessions.length);
27517
27655
  if (!currentSession) {
27518
27656
  try {
27519
- const { execSync: execSync18 } = await import("child_process");
27520
- const name = execSync18("tmux display-message -p '#{session_name}' 2>/dev/null", {
27657
+ const { execSync: execSync19 } = await import("child_process");
27658
+ const name = execSync19("tmux display-message -p '#{session_name}' 2>/dev/null", {
27521
27659
  encoding: "utf8",
27522
27660
  timeout: 2e3
27523
27661
  }).trim();
@@ -30871,8 +31009,8 @@ function TmuxPane({ sessionName, employeeName, employeeRole, projectName, onDeta
30871
31009
  }
30872
31010
  const capture = () => {
30873
31011
  try {
30874
- const { execSync: execSync18 } = __require("child_process");
30875
- const output2 = execSync18(
31012
+ const { execSync: execSync19 } = __require("child_process");
31013
+ const output2 = execSync19(
30876
31014
  `tmux capture-pane -t ${JSON.stringify(sessionName)} -p -e 2>/dev/null | tail -${CAPTURE_LINES}`,
30877
31015
  { encoding: "utf8", timeout: 3e3 }
30878
31016
  );
@@ -30896,8 +31034,8 @@ function TmuxPane({ sessionName, employeeName, employeeRole, projectName, onDeta
30896
31034
  if (key.return) {
30897
31035
  if (!demo && inputBuffer.trim()) {
30898
31036
  try {
30899
- const { execSync: execSync18 } = __require("child_process");
30900
- execSync18(
31037
+ const { execSync: execSync19 } = __require("child_process");
31038
+ execSync19(
30901
31039
  `tmux send-keys -t ${JSON.stringify(sessionName)} ${JSON.stringify(inputBuffer)} Enter`,
30902
31040
  { timeout: 2e3 }
30903
31041
  );
@@ -30905,8 +31043,8 @@ function TmuxPane({ sessionName, employeeName, employeeRole, projectName, onDeta
30905
31043
  }
30906
31044
  } else if (!demo) {
30907
31045
  try {
30908
- const { execSync: execSync18 } = __require("child_process");
30909
- execSync18(`tmux send-keys -t ${JSON.stringify(sessionName)} Enter`, { timeout: 2e3 });
31046
+ const { execSync: execSync19 } = __require("child_process");
31047
+ execSync19(`tmux send-keys -t ${JSON.stringify(sessionName)} Enter`, { timeout: 2e3 });
30910
31048
  } catch {
30911
31049
  }
30912
31050
  }
@@ -31593,12 +31731,12 @@ function SessionsView({
31593
31731
  return;
31594
31732
  }
31595
31733
  } else {
31596
- const { execSync: execSync18 } = await import("child_process");
31734
+ const { execSync: execSync19 } = await import("child_process");
31597
31735
  const dir = projectDir || process.cwd();
31598
- execSync18(`tmux new-session -d -s ${JSON.stringify(entry.sessionName)} -c ${JSON.stringify(dir)}`, { timeout: 5e3 });
31599
- execSync18(`tmux send-keys -t ${JSON.stringify(entry.sessionName)} "claude --dangerously-skip-permissions" Enter`, { timeout: 3e3 });
31736
+ execSync19(`tmux new-session -d -s ${JSON.stringify(entry.sessionName)} -c ${JSON.stringify(dir)}`, { timeout: 5e3 });
31737
+ execSync19(`tmux send-keys -t ${JSON.stringify(entry.sessionName)} "claude --dangerously-skip-permissions" Enter`, { timeout: 3e3 });
31600
31738
  await new Promise((r) => setTimeout(r, 3e3));
31601
- execSync18(`tmux send-keys -t ${JSON.stringify(entry.sessionName)} "/exe" Enter`, { timeout: 3e3 });
31739
+ execSync19(`tmux send-keys -t ${JSON.stringify(entry.sessionName)} "/exe" Enter`, { timeout: 3e3 });
31602
31740
  }
31603
31741
  const updated = { ...entry, status: "active", activity: "Starting...", attached: false };
31604
31742
  setViewingEmployee(updated);
@@ -31701,7 +31839,7 @@ function SessionsView({
31701
31839
  const { listTmuxSessions: listTmuxSessions2, inTmux: inTmux2, capturePaneLines: capturePaneLines2, parseActivity: parseActivity2 } = await Promise.resolve().then(() => (init_tmux_status(), tmux_status_exports));
31702
31840
  const { getCoordinatorName: getCoordinatorName2, isCoordinatorRole: isCoordinatorRole2, loadEmployees: loadEmployees2 } = await Promise.resolve().then(() => (init_employees(), employees_exports));
31703
31841
  const { isExeSession: isExeSession2 } = await Promise.resolve().then(() => (init_tmux_routing(), tmux_routing_exports));
31704
- const { execSync: execSync18 } = await import("child_process");
31842
+ const { execSync: execSync19 } = await import("child_process");
31705
31843
  if (!inTmux2()) {
31706
31844
  setTmuxAvailable(false);
31707
31845
  setProjects([]);
@@ -31710,7 +31848,7 @@ function SessionsView({
31710
31848
  setTmuxAvailable(true);
31711
31849
  const attachedMap = /* @__PURE__ */ new Map();
31712
31850
  try {
31713
- const out = execSync18("tmux list-sessions -F '#{session_name}:#{session_attached}' 2>/dev/null", {
31851
+ const out = execSync19("tmux list-sessions -F '#{session_name}:#{session_attached}' 2>/dev/null", {
31714
31852
  encoding: "utf8",
31715
31853
  timeout: 3e3
31716
31854
  });
@@ -32746,8 +32884,8 @@ function upsertConversation(conversations, platform, senderId, message) {
32746
32884
  async function loadGatewayConfig() {
32747
32885
  const state = { running: false, port: 3100, adapters: [], agents: [], gatewayUrl: "" };
32748
32886
  try {
32749
- const { execSync: execSync18 } = await import("child_process");
32750
- const ps = execSync18("pgrep -f exe-gateway 2>/dev/null", { encoding: "utf8", timeout: 3e3 });
32887
+ const { execSync: execSync19 } = await import("child_process");
32888
+ const ps = execSync19("pgrep -f exe-gateway 2>/dev/null", { encoding: "utf8", timeout: 3e3 });
32751
32889
  state.running = ps.trim().length > 0;
32752
32890
  } catch {
32753
32891
  state.running = false;
@@ -33224,10 +33362,10 @@ var init_Gateway = __esm({
33224
33362
  });
33225
33363
 
33226
33364
  // src/tui/utils/agent-status.ts
33227
- import { execSync as execSync17 } from "child_process";
33365
+ import { execSync as execSync18 } from "child_process";
33228
33366
  function getAgentStatus(agentId) {
33229
33367
  try {
33230
- const sessions = execSync17("tmux list-sessions -F '#{session_name}' 2>/dev/null", {
33368
+ const sessions = execSync18("tmux list-sessions -F '#{session_name}' 2>/dev/null", {
33231
33369
  encoding: "utf8",
33232
33370
  timeout: 2e3
33233
33371
  }).trim().split("\n");
@@ -33238,7 +33376,7 @@ function getAgentStatus(agentId) {
33238
33376
  return /^\d?-/.test(suffix) || /^\d+$/.test(suffix);
33239
33377
  });
33240
33378
  if (!agentSession) return { label: "offline", color: "gray" };
33241
- const pane = execSync17(`tmux capture-pane -t "${agentSession}" -p 2>/dev/null | tail -3`, {
33379
+ const pane = execSync18(`tmux capture-pane -t "${agentSession}" -p 2>/dev/null | tail -3`, {
33242
33380
  encoding: "utf8",
33243
33381
  timeout: 2e3
33244
33382
  });
@@ -34161,8 +34299,8 @@ function SettingsView({ onBack }) {
34161
34299
  };
34162
34300
  });
34163
34301
  try {
34164
- const { execSync: execSync18 } = await import("child_process");
34165
- execSync18("curl -s --max-time 1 http://localhost:11434/api/tags", { timeout: 2e3 });
34302
+ const { execSync: execSync19 } = await import("child_process");
34303
+ execSync19("curl -s --max-time 1 http://localhost:11434/api/tags", { timeout: 2e3 });
34166
34304
  providerList.push({ name: "Ollama", configured: true, detail: "localhost:11434" });
34167
34305
  } catch {
34168
34306
  providerList.push({ name: "Ollama", configured: false, detail: "not running" });
@@ -35061,7 +35199,7 @@ __export(code_context_index_exports, {
35061
35199
  import crypto14 from "crypto";
35062
35200
  import path51 from "path";
35063
35201
  import { existsSync as existsSync36, mkdirSync as mkdirSync25, readFileSync as readFileSync32, readdirSync as readdirSync11, statSync as statSync7, writeFileSync as writeFileSync26 } from "fs";
35064
- import { spawnSync as spawnSync2 } from "child_process";
35202
+ import { spawnSync as spawnSync3 } from "child_process";
35065
35203
  function normalizeProjectRoot(projectRoot) {
35066
35204
  return path51.resolve(projectRoot || process.cwd());
35067
35205
  }
@@ -35079,7 +35217,7 @@ function getCodeContextIndexPath(projectRoot) {
35079
35217
  return path51.join(indexDir(), `${rootHash}.json`);
35080
35218
  }
35081
35219
  function currentBranch(projectRoot) {
35082
- const result = spawnSync2("git", ["branch", "--show-current"], { cwd: projectRoot, encoding: "utf8", timeout: 2e3 });
35220
+ const result = spawnSync3("git", ["branch", "--show-current"], { cwd: projectRoot, encoding: "utf8", timeout: 2e3 });
35083
35221
  const branch = result.status === 0 ? result.stdout.trim() : "";
35084
35222
  return branch || "detached-or-unknown";
35085
35223
  }
@@ -35098,12 +35236,12 @@ function listRecursive(projectRoot, dir = projectRoot, out = []) {
35098
35236
  return out;
35099
35237
  }
35100
35238
  function listCodeFiles(projectRoot, maxFiles) {
35101
- const git = spawnSync2("git", ["ls-files"], { cwd: projectRoot, encoding: "utf8", timeout: 5e3, maxBuffer: 1024 * 1024 * 16 });
35239
+ const git = spawnSync3("git", ["ls-files"], { cwd: projectRoot, encoding: "utf8", timeout: 5e3, maxBuffer: 1024 * 1024 * 16 });
35102
35240
  let files = [];
35103
35241
  if (git.status === 0 && git.stdout.trim()) {
35104
35242
  files = git.stdout.split("\n").map((s) => s.trim()).filter(Boolean);
35105
35243
  } else {
35106
- const rg = spawnSync2("rg", ["--files"], { cwd: projectRoot, encoding: "utf8", timeout: 5e3, maxBuffer: 1024 * 1024 * 16 });
35244
+ const rg = spawnSync3("rg", ["--files"], { cwd: projectRoot, encoding: "utf8", timeout: 5e3, maxBuffer: 1024 * 1024 * 16 });
35107
35245
  files = rg.status === 0 && rg.stdout.trim() ? rg.stdout.split("\n").map((s) => s.trim()).filter(Boolean) : listRecursive(projectRoot);
35108
35246
  }
35109
35247
  return files.map((file) => file.replaceAll(path51.sep, "/")).filter((file) => isChunkable(file) && !shouldIgnore(file)).slice(0, maxFiles).sort();
@@ -36961,10 +37099,10 @@ async function runClaudeUninstall(flags = []) {
36961
37099
  }
36962
37100
  }
36963
37101
  try {
36964
- const { execSync: execSync18 } = await import("child_process");
37102
+ const { execSync: execSync19 } = await import("child_process");
36965
37103
  const findExeBin3 = () => {
36966
37104
  try {
36967
- return execSync18(process.platform === "win32" ? "where exe-os" : "which exe-os", { encoding: "utf8" }).trim();
37105
+ return execSync19(process.platform === "win32" ? "where exe-os" : "which exe-os", { encoding: "utf8" }).trim();
36968
37106
  } catch {
36969
37107
  return null;
36970
37108
  }