@askexenow/exe-os 0.8.59 → 0.8.61

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.
package/dist/bin/cli.js CHANGED
@@ -509,12 +509,14 @@ __export(installer_exports, {
509
509
  mergeHooks: () => mergeHooks,
510
510
  registerMcpServer: () => registerMcpServer,
511
511
  resolvePackageRoot: () => resolvePackageRoot,
512
- runInstaller: () => runInstaller
512
+ runInstaller: () => runInstaller,
513
+ setupTmux: () => setupTmux
513
514
  });
514
515
  import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3, readdir } from "fs/promises";
515
- import { existsSync as existsSync4, readFileSync as readFileSync3 } from "fs";
516
+ import { existsSync as existsSync4, readFileSync as readFileSync3, writeFileSync, copyFileSync, mkdirSync as mkdirSync2 } from "fs";
516
517
  import path4 from "path";
517
518
  import os3 from "os";
519
+ import { execSync as execSync2 } from "child_process";
518
520
  import { fileURLToPath } from "url";
519
521
  function resolvePackageRoot() {
520
522
  const thisFile = fileURLToPath(import.meta.url);
@@ -961,6 +963,44 @@ async function runInstaller(homeDir) {
961
963
  exe-os installed successfully.
962
964
  `);
963
965
  }
966
+ function setupTmux(home) {
967
+ const homeDir = home ?? os3.homedir();
968
+ const exeDir = path4.join(homeDir, ".exe-os");
969
+ const exeTmuxConf = path4.join(exeDir, "tmux.conf");
970
+ const userTmuxConf = path4.join(homeDir, ".tmux.conf");
971
+ const backupPath = path4.join(homeDir, ".tmux.conf.backup");
972
+ const sourceLine = "source-file ~/.exe-os/tmux.conf";
973
+ const pkgRoot = resolvePackageRoot();
974
+ const assetPath = path4.join(pkgRoot, "dist", "assets", "tmux.conf");
975
+ if (!existsSync4(assetPath)) {
976
+ process.stderr.write(`exe-os: tmux.conf asset not found at ${assetPath} \u2014 skipping tmux setup
977
+ `);
978
+ return;
979
+ }
980
+ mkdirSync2(exeDir, { recursive: true });
981
+ copyFileSync(assetPath, exeTmuxConf);
982
+ if (existsSync4(userTmuxConf)) {
983
+ const existing = readFileSync3(userTmuxConf, "utf8");
984
+ if (!existing.includes(sourceLine)) {
985
+ if (!existsSync4(backupPath)) {
986
+ copyFileSync(userTmuxConf, backupPath);
987
+ process.stderr.write(`exe-os: backed up existing tmux config to ${backupPath}
988
+ `);
989
+ }
990
+ writeFileSync(userTmuxConf, `${sourceLine}
991
+ ${existing}`);
992
+ }
993
+ } else {
994
+ writeFileSync(userTmuxConf, `# Exe OS tmux defaults \u2014 remove this line to use your own config
995
+ ${sourceLine}
996
+ `);
997
+ }
998
+ try {
999
+ execSync2(`tmux source-file ${exeTmuxConf} 2>/dev/null`);
1000
+ } catch {
1001
+ }
1002
+ process.stderr.write("exe-os: tmux config installed\n");
1003
+ }
964
1004
  function summarizeSymlinkResults(results) {
965
1005
  if (results.length === 0) return "no employees in roster";
966
1006
  const created = results.filter((r) => r.action === "created").length;
@@ -2149,12 +2189,12 @@ __export(shard_manager_exports, {
2149
2189
  shardExists: () => shardExists
2150
2190
  });
2151
2191
  import path6 from "path";
2152
- import { existsSync as existsSync6, mkdirSync as mkdirSync2, readdirSync } from "fs";
2192
+ import { existsSync as existsSync6, mkdirSync as mkdirSync3, readdirSync } from "fs";
2153
2193
  import { createClient as createClient2 } from "@libsql/client";
2154
2194
  function initShardManager(encryptionKey) {
2155
2195
  _encryptionKey = encryptionKey;
2156
2196
  if (!existsSync6(SHARDS_DIR)) {
2157
- mkdirSync2(SHARDS_DIR, { recursive: true });
2197
+ mkdirSync3(SHARDS_DIR, { recursive: true });
2158
2198
  }
2159
2199
  _shardingEnabled = true;
2160
2200
  }
@@ -4409,8 +4449,8 @@ __export(exe_rename_exports, {
4409
4449
  main: () => main,
4410
4450
  renameEmployee: () => renameEmployee
4411
4451
  });
4412
- import { readFileSync as readFileSync5, writeFileSync, renameSync as renameSync2, unlinkSync as unlinkSync2, existsSync as existsSync8 } from "fs";
4413
- import { execSync as execSync2 } from "child_process";
4452
+ import { readFileSync as readFileSync5, writeFileSync as writeFileSync2, renameSync as renameSync2, unlinkSync as unlinkSync2, existsSync as existsSync8 } from "fs";
4453
+ import { execSync as execSync3 } from "child_process";
4414
4454
  import path9 from "path";
4415
4455
  import { homedir as homedir2 } from "os";
4416
4456
  async function renameEmployee(oldName, newName, opts = {}) {
@@ -4442,7 +4482,7 @@ async function renameEmployee(oldName, newName, opts = {}) {
4442
4482
  undo: () => {
4443
4483
  employee.name = originalName;
4444
4484
  employee.systemPrompt = originalPrompt;
4445
- writeFileSync(rosterPath, JSON.stringify(employees, null, 2) + "\n", "utf-8");
4485
+ writeFileSync2(rosterPath, JSON.stringify(employees, null, 2) + "\n", "utf-8");
4446
4486
  }
4447
4487
  });
4448
4488
  const oldIdentityPath = path9.join(identityDir, `${oldName}.md`);
@@ -4454,12 +4494,12 @@ async function renameEmployee(oldName, newName, opts = {}) {
4454
4494
  `$1${newName}`
4455
4495
  );
4456
4496
  renameSync2(oldIdentityPath, newIdentityPath);
4457
- writeFileSync(newIdentityPath, updatedContent, "utf-8");
4497
+ writeFileSync2(newIdentityPath, updatedContent, "utf-8");
4458
4498
  rollbackStack.push({
4459
4499
  description: "restore identity file",
4460
4500
  undo: () => {
4461
4501
  if (existsSync8(newIdentityPath)) {
4462
- writeFileSync(newIdentityPath, content, "utf-8");
4502
+ writeFileSync2(newIdentityPath, content, "utf-8");
4463
4503
  renameSync2(newIdentityPath, oldIdentityPath);
4464
4504
  }
4465
4505
  }
@@ -4475,7 +4515,7 @@ async function renameEmployee(oldName, newName, opts = {}) {
4475
4515
  undo: () => {
4476
4516
  if (existsSync8(newAgentPath)) {
4477
4517
  renameSync2(newAgentPath, oldAgentPath);
4478
- writeFileSync(oldAgentPath, agentContent, "utf-8");
4518
+ writeFileSync2(oldAgentPath, agentContent, "utf-8");
4479
4519
  }
4480
4520
  }
4481
4521
  });
@@ -4544,7 +4584,7 @@ async function renameEmployee(oldName, newName, opts = {}) {
4544
4584
  }
4545
4585
  function findExeBin2() {
4546
4586
  try {
4547
- return execSync2(process.platform === "win32" ? "where exe-os" : "which exe-os", { encoding: "utf8" }).trim();
4587
+ return execSync3(process.platform === "win32" ? "where exe-os" : "which exe-os", { encoding: "utf8" }).trim();
4548
4588
  } catch {
4549
4589
  return null;
4550
4590
  }
@@ -4778,7 +4818,7 @@ __export(license_exports, {
4778
4818
  stopLicenseRevalidation: () => stopLicenseRevalidation,
4779
4819
  validateLicense: () => validateLicense
4780
4820
  });
4781
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync2, existsSync as existsSync10, mkdirSync as mkdirSync3 } from "fs";
4821
+ import { readFileSync as readFileSync6, writeFileSync as writeFileSync3, existsSync as existsSync10, mkdirSync as mkdirSync4 } from "fs";
4782
4822
  import { randomUUID as randomUUID3 } from "crypto";
4783
4823
  import path11 from "path";
4784
4824
  import { jwtVerify, importSPKI } from "jose";
@@ -4807,8 +4847,8 @@ function loadDeviceId() {
4807
4847
  } catch {
4808
4848
  }
4809
4849
  const id = randomUUID3();
4810
- mkdirSync3(EXE_AI_DIR, { recursive: true });
4811
- writeFileSync2(DEVICE_ID_PATH, id, "utf8");
4850
+ mkdirSync4(EXE_AI_DIR, { recursive: true });
4851
+ writeFileSync3(DEVICE_ID_PATH, id, "utf8");
4812
4852
  return id;
4813
4853
  }
4814
4854
  function loadLicense() {
@@ -4820,8 +4860,8 @@ function loadLicense() {
4820
4860
  }
4821
4861
  }
4822
4862
  function saveLicense(apiKey) {
4823
- mkdirSync3(EXE_AI_DIR, { recursive: true });
4824
- writeFileSync2(LICENSE_PATH, apiKey.trim(), { encoding: "utf8", mode: 384 });
4863
+ mkdirSync4(EXE_AI_DIR, { recursive: true });
4864
+ writeFileSync3(LICENSE_PATH, apiKey.trim(), { encoding: "utf8", mode: 384 });
4825
4865
  }
4826
4866
  async function verifyLicenseJwt(token) {
4827
4867
  try {
@@ -4864,9 +4904,35 @@ function readCachedToken() {
4864
4904
  return null;
4865
4905
  }
4866
4906
  }
4907
+ function getRawCachedPlan() {
4908
+ try {
4909
+ const token = readCachedToken();
4910
+ if (!token) return null;
4911
+ const parts = token.split(".");
4912
+ if (parts.length !== 3) return null;
4913
+ const payload = JSON.parse(Buffer.from(parts[1], "base64url").toString());
4914
+ const plan = payload.plan ?? "free";
4915
+ const limits = PLAN_LIMITS[plan] ?? PLAN_LIMITS.free;
4916
+ process.stderr.write(
4917
+ `[license] WARN: using unverified cached plan (API unreachable, JWT expired). Plan: ${plan}
4918
+ `
4919
+ );
4920
+ return {
4921
+ valid: true,
4922
+ plan,
4923
+ email: payload.sub ?? "",
4924
+ expiresAt: payload.exp ? new Date(payload.exp * 1e3).toISOString() : null,
4925
+ deviceLimit: limits.devices,
4926
+ employeeLimit: limits.employees,
4927
+ memoryLimit: limits.memories
4928
+ };
4929
+ } catch {
4930
+ return null;
4931
+ }
4932
+ }
4867
4933
  function cacheResponse(token) {
4868
4934
  try {
4869
- writeFileSync2(CACHE_PATH, JSON.stringify({ token }), "utf8");
4935
+ writeFileSync3(CACHE_PATH, JSON.stringify({ token }), "utf8");
4870
4936
  } catch {
4871
4937
  }
4872
4938
  }
@@ -4884,6 +4950,8 @@ async function validateLicense(apiKey, deviceId) {
4884
4950
  if (data.error === "device_limit_exceeded") {
4885
4951
  const cached2 = await getCachedLicense();
4886
4952
  if (cached2) return cached2;
4953
+ const raw2 = getRawCachedPlan();
4954
+ if (raw2) return { ...raw2, valid: false };
4887
4955
  return { ...FREE_LICENSE, valid: false, plan: "free" };
4888
4956
  }
4889
4957
  if (data.token) {
@@ -4904,10 +4972,14 @@ async function validateLicense(apiKey, deviceId) {
4904
4972
  }
4905
4973
  const cached = await getCachedLicense();
4906
4974
  if (cached) return cached;
4975
+ const raw = getRawCachedPlan();
4976
+ if (raw) return raw;
4907
4977
  return { ...FREE_LICENSE, valid: false, plan: "free" };
4908
4978
  } catch {
4909
4979
  const cached = await getCachedLicense();
4910
4980
  if (cached) return cached;
4981
+ const rawFallback = getRawCachedPlan();
4982
+ if (rawFallback) return rawFallback;
4911
4983
  return { ...FREE_LICENSE, valid: false, error: "offline" };
4912
4984
  }
4913
4985
  }
@@ -5096,8 +5168,8 @@ MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEeHztAMOpR/ZMh+rWuOASjEZ54CGY
5096
5168
  -----END PUBLIC KEY-----`;
5097
5169
  LICENSE_JWT_ALG = "ES256";
5098
5170
  PLAN_LIMITS = {
5099
- free: { devices: 1, employees: 1, memories: 5e3 },
5100
- pro: { devices: 2, employees: 5, memories: 1e5 },
5171
+ free: { devices: 1, employees: 1, memories: 5e4 },
5172
+ pro: { devices: 2, employees: 5, memories: 25e4 },
5101
5173
  team: { devices: 10, employees: 20, memories: 1e6 },
5102
5174
  agency: { devices: 50, employees: 100, memories: 1e7 },
5103
5175
  enterprise: { devices: -1, employees: -1, memories: -1 }
@@ -5109,7 +5181,7 @@ MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEeHztAMOpR/ZMh+rWuOASjEZ54CGY
5109
5181
  expiresAt: null,
5110
5182
  deviceLimit: 1,
5111
5183
  employeeLimit: 1,
5112
- memoryLimit: 5e3
5184
+ memoryLimit: 5e4
5113
5185
  };
5114
5186
  CACHE_MAX_AGE_MS = 36e5;
5115
5187
  _revalTimer = null;
@@ -5125,13 +5197,13 @@ __export(identity_exports, {
5125
5197
  listIdentities: () => listIdentities,
5126
5198
  updateIdentity: () => updateIdentity
5127
5199
  });
5128
- import { existsSync as existsSync11, mkdirSync as mkdirSync4, readFileSync as readFileSync7, writeFileSync as writeFileSync3 } from "fs";
5200
+ import { existsSync as existsSync11, mkdirSync as mkdirSync5, readFileSync as readFileSync7, writeFileSync as writeFileSync4 } from "fs";
5129
5201
  import { readdirSync as readdirSync2 } from "fs";
5130
5202
  import path12 from "path";
5131
5203
  import { createHash as createHash2 } from "crypto";
5132
5204
  function ensureDir() {
5133
5205
  if (!existsSync11(IDENTITY_DIR)) {
5134
- mkdirSync4(IDENTITY_DIR, { recursive: true });
5206
+ mkdirSync5(IDENTITY_DIR, { recursive: true });
5135
5207
  }
5136
5208
  }
5137
5209
  function identityPath(agentId) {
@@ -5191,7 +5263,7 @@ async function updateIdentity(agentId, content, updatedBy) {
5191
5263
  ensureDir();
5192
5264
  const filePath = identityPath(agentId);
5193
5265
  const hash = contentHash(content);
5194
- writeFileSync3(filePath, content, "utf-8");
5266
+ writeFileSync4(filePath, content, "utf-8");
5195
5267
  try {
5196
5268
  const client = getClient();
5197
5269
  await client.execute({
@@ -5788,7 +5860,7 @@ __export(setup_wizard_exports, {
5788
5860
  validateModel: () => validateModel
5789
5861
  });
5790
5862
  import crypto3 from "crypto";
5791
- import { existsSync as existsSync12, mkdirSync as mkdirSync5, readFileSync as readFileSync8, writeFileSync as writeFileSync4, unlinkSync as unlinkSync4 } from "fs";
5863
+ import { existsSync as existsSync12, mkdirSync as mkdirSync6, readFileSync as readFileSync8, writeFileSync as writeFileSync5, unlinkSync as unlinkSync4 } from "fs";
5792
5864
  import os5 from "os";
5793
5865
  import path13 from "path";
5794
5866
  import { createInterface as createInterface2 } from "readline";
@@ -5800,8 +5872,8 @@ function loadSetupState() {
5800
5872
  }
5801
5873
  }
5802
5874
  function saveSetupState(state) {
5803
- mkdirSync5(path13.dirname(SETUP_STATE_PATH), { recursive: true });
5804
- writeFileSync4(SETUP_STATE_PATH, JSON.stringify(state, null, 2));
5875
+ mkdirSync6(path13.dirname(SETUP_STATE_PATH), { recursive: true });
5876
+ writeFileSync5(SETUP_STATE_PATH, JSON.stringify(state, null, 2));
5805
5877
  }
5806
5878
  function clearSetupState() {
5807
5879
  try {
@@ -5968,7 +6040,7 @@ async function runSetupWizard(opts = {}) {
5968
6040
  if (!projects[dir]) projects[dir] = {};
5969
6041
  projects[dir].hasTrustDialogAccepted = true;
5970
6042
  }
5971
- writeFileSync4(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
6043
+ writeFileSync5(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
5972
6044
  } catch {
5973
6045
  }
5974
6046
  state.completedSteps.push(5);
@@ -6020,9 +6092,9 @@ async function runSetupWizard(opts = {}) {
6020
6092
  const cooIdentityContent = getIdentityTemplate("coo");
6021
6093
  if (cooIdentityContent) {
6022
6094
  const cooIdPath = identityPath2(cooName);
6023
- mkdirSync5(path13.dirname(cooIdPath), { recursive: true });
6095
+ mkdirSync6(path13.dirname(cooIdPath), { recursive: true });
6024
6096
  const replaced = cooIdentityContent.replace(/agent_id:\s*exe/g, `agent_id: ${cooName}`).replace(/\$\{agent_id\}/g, cooName);
6025
- writeFileSync4(cooIdPath, replaced, "utf-8");
6097
+ writeFileSync5(cooIdPath, replaced, "utf-8");
6026
6098
  }
6027
6099
  registerBinSymlinks2(cooName);
6028
6100
  createdEmployees.push({ name: cooName, role: "COO" });
@@ -6121,9 +6193,9 @@ async function runSetupWizard(opts = {}) {
6121
6193
  const ctoIdentityContent = getIdentityTemplate("cto");
6122
6194
  if (ctoIdentityContent) {
6123
6195
  const ctoIdPath = identityPath2(ctoName);
6124
- mkdirSync5(path13.dirname(ctoIdPath), { recursive: true });
6196
+ mkdirSync6(path13.dirname(ctoIdPath), { recursive: true });
6125
6197
  const replaced = ctoIdentityContent.replace(/agent_id:\s*\w+/g, `agent_id: ${ctoName}`).replace(/\$\{agent_id\}/g, ctoName);
6126
- writeFileSync4(ctoIdPath, replaced, "utf-8");
6198
+ writeFileSync5(ctoIdPath, replaced, "utf-8");
6127
6199
  }
6128
6200
  registerBinSymlinks2(ctoName);
6129
6201
  createdEmployees.push({ name: ctoName, role: "CTO" });
@@ -6149,9 +6221,9 @@ async function runSetupWizard(opts = {}) {
6149
6221
  const cmoIdentityContent = getIdentityTemplate("cmo");
6150
6222
  if (cmoIdentityContent) {
6151
6223
  const cmoIdPath = identityPath2(cmoName);
6152
- mkdirSync5(path13.dirname(cmoIdPath), { recursive: true });
6224
+ mkdirSync6(path13.dirname(cmoIdPath), { recursive: true });
6153
6225
  const replaced = cmoIdentityContent.replace(/agent_id:\s*\w+/g, `agent_id: ${cmoName}`).replace(/\$\{agent_id\}/g, cmoName);
6154
- writeFileSync4(cmoIdPath, replaced, "utf-8");
6226
+ writeFileSync5(cmoIdPath, replaced, "utf-8");
6155
6227
  }
6156
6228
  registerBinSymlinks2(cmoName);
6157
6229
  createdEmployees.push({ name: cmoName, role: "CMO" });
@@ -6213,7 +6285,7 @@ var init_setup_wizard = __esm({
6213
6285
  });
6214
6286
 
6215
6287
  // src/lib/update-check.ts
6216
- import { execSync as execSync3 } from "child_process";
6288
+ import { execSync as execSync4 } from "child_process";
6217
6289
  import { readFileSync as readFileSync9 } from "fs";
6218
6290
  import path14 from "path";
6219
6291
  function getLocalVersion(packageRoot) {
@@ -6223,7 +6295,7 @@ function getLocalVersion(packageRoot) {
6223
6295
  }
6224
6296
  function getRemoteVersion() {
6225
6297
  try {
6226
- const output = execSync3("npm view @askexenow/exe-os version", {
6298
+ const output = execSync4("npm view @askexenow/exe-os version", {
6227
6299
  encoding: "utf-8",
6228
6300
  timeout: 15e3,
6229
6301
  stdio: ["pipe", "pipe", "pipe"]
@@ -6262,7 +6334,7 @@ __export(update_exports, {
6262
6334
  getRemoteVersion: () => getRemoteVersion,
6263
6335
  runUpdate: () => runUpdate
6264
6336
  });
6265
- import { execSync as execSync4 } from "child_process";
6337
+ import { execSync as execSync5 } from "child_process";
6266
6338
  import { createInterface as createInterface3 } from "readline";
6267
6339
  async function runUpdate(cliArgs) {
6268
6340
  const args2 = cliArgs ?? process.argv.slice(2);
@@ -6304,14 +6376,14 @@ async function runUpdate(cliArgs) {
6304
6376
  }
6305
6377
  console.log("\n\u{1F9F9} Clearing npm cache...");
6306
6378
  try {
6307
- execSync4("npm cache clean --force", { stdio: "pipe" });
6379
+ execSync5("npm cache clean --force", { stdio: "pipe" });
6308
6380
  console.log(" Done");
6309
6381
  } catch {
6310
6382
  console.log(" Skipped (non-critical)");
6311
6383
  }
6312
6384
  console.log("\u{1F4E5} Installing @askexenow/exe-os@latest...");
6313
6385
  try {
6314
- execSync4("npm install -g @askexenow/exe-os@latest", {
6386
+ execSync5("npm install -g @askexenow/exe-os@latest", {
6315
6387
  stdio: ["pipe", "pipe", "pipe"],
6316
6388
  timeout: 12e4
6317
6389
  });
@@ -6328,7 +6400,7 @@ async function runUpdate(cliArgs) {
6328
6400
  newVersion = getLocalVersion(packageRoot);
6329
6401
  } catch {
6330
6402
  try {
6331
- const out = execSync4("npm list -g @askexenow/exe-os --depth=0 2>/dev/null", { encoding: "utf8" });
6403
+ const out = execSync5("npm list -g @askexenow/exe-os --depth=0 2>/dev/null", { encoding: "utf8" });
6332
6404
  const match = out.match(/@askexenow\/exe-os@(\S+)/);
6333
6405
  newVersion = match?.[1] ?? "unknown";
6334
6406
  } catch {
@@ -12771,14 +12843,14 @@ __export(session_registry_exports, {
12771
12843
  pruneStaleSessions: () => pruneStaleSessions,
12772
12844
  registerSession: () => registerSession
12773
12845
  });
12774
- import { readFileSync as readFileSync11, writeFileSync as writeFileSync5, mkdirSync as mkdirSync6, existsSync as existsSync14 } from "fs";
12775
- import { execSync as execSync5 } from "child_process";
12846
+ import { readFileSync as readFileSync11, writeFileSync as writeFileSync6, mkdirSync as mkdirSync7, existsSync as existsSync14 } from "fs";
12847
+ import { execSync as execSync6 } from "child_process";
12776
12848
  import path15 from "path";
12777
12849
  import os6 from "os";
12778
12850
  function registerSession(entry) {
12779
12851
  const dir = path15.dirname(REGISTRY_PATH);
12780
12852
  if (!existsSync14(dir)) {
12781
- mkdirSync6(dir, { recursive: true });
12853
+ mkdirSync7(dir, { recursive: true });
12782
12854
  }
12783
12855
  const sessions = listSessions();
12784
12856
  const idx = sessions.findIndex((s) => s.windowName === entry.windowName);
@@ -12787,7 +12859,7 @@ function registerSession(entry) {
12787
12859
  } else {
12788
12860
  sessions.push(entry);
12789
12861
  }
12790
- writeFileSync5(REGISTRY_PATH, JSON.stringify(sessions, null, 2));
12862
+ writeFileSync6(REGISTRY_PATH, JSON.stringify(sessions, null, 2));
12791
12863
  }
12792
12864
  function listSessions() {
12793
12865
  try {
@@ -12802,7 +12874,7 @@ function pruneStaleSessions() {
12802
12874
  if (sessions.length === 0) return 0;
12803
12875
  let liveSessions = [];
12804
12876
  try {
12805
- liveSessions = execSync5("tmux list-sessions -F '#{session_name}' 2>/dev/null", {
12877
+ liveSessions = execSync6("tmux list-sessions -F '#{session_name}' 2>/dev/null", {
12806
12878
  encoding: "utf8"
12807
12879
  }).trim().split("\n").filter(Boolean);
12808
12880
  } catch {
@@ -12812,7 +12884,7 @@ function pruneStaleSessions() {
12812
12884
  const alive = sessions.filter((s) => liveSet.has(s.windowName));
12813
12885
  const pruned = sessions.length - alive.length;
12814
12886
  if (pruned > 0) {
12815
- writeFileSync5(REGISTRY_PATH, JSON.stringify(alive, null, 2));
12887
+ writeFileSync6(REGISTRY_PATH, JSON.stringify(alive, null, 2));
12816
12888
  }
12817
12889
  return pruned;
12818
12890
  }
@@ -12825,13 +12897,13 @@ var init_session_registry = __esm({
12825
12897
  });
12826
12898
 
12827
12899
  // src/lib/session-key.ts
12828
- import { execSync as execSync6 } from "child_process";
12900
+ import { execSync as execSync7 } from "child_process";
12829
12901
  function getSessionKey() {
12830
12902
  if (_cached) return _cached;
12831
12903
  let pid = process.ppid;
12832
12904
  for (let i = 0; i < 10; i++) {
12833
12905
  try {
12834
- const info = execSync6(`ps -p ${pid} -o ppid=,comm=`, {
12906
+ const info = execSync7(`ps -p ${pid} -o ppid=,comm=`, {
12835
12907
  encoding: "utf8",
12836
12908
  timeout: 2e3
12837
12909
  }).trim();
@@ -12975,14 +13047,14 @@ var init_transport = __esm({
12975
13047
  });
12976
13048
 
12977
13049
  // src/lib/cc-agent-support.ts
12978
- import { execSync as execSync7 } from "child_process";
13050
+ import { execSync as execSync8 } from "child_process";
12979
13051
  function _resetCcAgentSupportCache() {
12980
13052
  _cachedSupport = null;
12981
13053
  }
12982
13054
  function claudeSupportsAgentFlag() {
12983
13055
  if (_cachedSupport !== null) return _cachedSupport;
12984
13056
  try {
12985
- const helpOutput = execSync7("claude --help 2>&1", {
13057
+ const helpOutput = execSync8("claude --help 2>&1", {
12986
13058
  encoding: "utf-8",
12987
13059
  timeout: 5e3
12988
13060
  });
@@ -13025,12 +13097,12 @@ var init_provider_table = __esm({
13025
13097
  });
13026
13098
 
13027
13099
  // src/lib/intercom-queue.ts
13028
- import { readFileSync as readFileSync12, writeFileSync as writeFileSync6, renameSync as renameSync4, existsSync as existsSync15, mkdirSync as mkdirSync7 } from "fs";
13100
+ import { readFileSync as readFileSync12, writeFileSync as writeFileSync7, renameSync as renameSync4, existsSync as existsSync15, mkdirSync as mkdirSync8 } from "fs";
13029
13101
  import path16 from "path";
13030
13102
  import os7 from "os";
13031
13103
  function ensureDir2() {
13032
13104
  const dir = path16.dirname(QUEUE_PATH);
13033
- if (!existsSync15(dir)) mkdirSync7(dir, { recursive: true });
13105
+ if (!existsSync15(dir)) mkdirSync8(dir, { recursive: true });
13034
13106
  }
13035
13107
  function readQueue() {
13036
13108
  try {
@@ -13043,7 +13115,7 @@ function readQueue() {
13043
13115
  function writeQueue(queue) {
13044
13116
  ensureDir2();
13045
13117
  const tmp = `${QUEUE_PATH}.tmp`;
13046
- writeFileSync6(tmp, JSON.stringify(queue, null, 2));
13118
+ writeFileSync7(tmp, JSON.stringify(queue, null, 2));
13047
13119
  renameSync4(tmp, QUEUE_PATH);
13048
13120
  }
13049
13121
  function queueIntercom(targetSession, reason) {
@@ -13255,7 +13327,7 @@ __export(tasks_crud_exports, {
13255
13327
  });
13256
13328
  import crypto6 from "crypto";
13257
13329
  import path19 from "path";
13258
- import { execSync as execSync8 } from "child_process";
13330
+ import { execSync as execSync9 } from "child_process";
13259
13331
  import { mkdir as mkdir6, writeFile as writeFile5, appendFile } from "fs/promises";
13260
13332
  import { existsSync as existsSync18, readFileSync as readFileSync15 } from "fs";
13261
13333
  async function writeCheckpoint(input) {
@@ -13502,12 +13574,12 @@ function checkStaleCompletion(taskContext, taskCreatedAt) {
13502
13574
  if (!DELEGATION_KEYWORDS.test(taskContext)) return null;
13503
13575
  try {
13504
13576
  const since = new Date(taskCreatedAt).toISOString();
13505
- const branch = execSync8(
13577
+ const branch = execSync9(
13506
13578
  "git rev-parse --abbrev-ref HEAD 2>/dev/null",
13507
13579
  { encoding: "utf8", timeout: 3e3 }
13508
13580
  ).trim();
13509
13581
  const branchArg = branch && branch !== "HEAD" ? branch : "";
13510
- const commitCount = execSync8(
13582
+ const commitCount = execSync9(
13511
13583
  `git log --oneline --since="${since}" ${branchArg} 2>/dev/null | wc -l`,
13512
13584
  { encoding: "utf8", timeout: 5e3 }
13513
13585
  ).trim();
@@ -13961,7 +14033,7 @@ var init_tasks_chain = __esm({
13961
14033
  });
13962
14034
 
13963
14035
  // src/lib/project-name.ts
13964
- import { execSync as execSync9 } from "child_process";
14036
+ import { execSync as execSync10 } from "child_process";
13965
14037
  import path22 from "path";
13966
14038
  function getProjectName(cwd2) {
13967
14039
  const dir = cwd2 ?? process.cwd();
@@ -13969,7 +14041,7 @@ function getProjectName(cwd2) {
13969
14041
  try {
13970
14042
  let repoRoot;
13971
14043
  try {
13972
- const gitCommonDir = execSync9("git rev-parse --path-format=absolute --git-common-dir", {
14044
+ const gitCommonDir = execSync10("git rev-parse --path-format=absolute --git-common-dir", {
13973
14045
  cwd: dir,
13974
14046
  encoding: "utf8",
13975
14047
  timeout: 2e3,
@@ -13977,7 +14049,7 @@ function getProjectName(cwd2) {
13977
14049
  }).trim();
13978
14050
  repoRoot = path22.dirname(gitCommonDir);
13979
14051
  } catch {
13980
- repoRoot = execSync9("git rev-parse --show-toplevel", {
14052
+ repoRoot = execSync10("git rev-parse --show-toplevel", {
13981
14053
  cwd: dir,
13982
14054
  encoding: "utf8",
13983
14055
  timeout: 2e3,
@@ -14461,7 +14533,7 @@ __export(tasks_exports, {
14461
14533
  writeCheckpoint: () => writeCheckpoint
14462
14534
  });
14463
14535
  import path23 from "path";
14464
- import { writeFileSync as writeFileSync7, mkdirSync as mkdirSync8, unlinkSync as unlinkSync7 } from "fs";
14536
+ import { writeFileSync as writeFileSync8, mkdirSync as mkdirSync9, unlinkSync as unlinkSync7 } from "fs";
14465
14537
  async function createTask(input) {
14466
14538
  const result = await createTaskCore(input);
14467
14539
  if (!input.skipDispatch && result.status !== "blocked" && !process.env.VITEST) {
@@ -14483,8 +14555,8 @@ async function updateTask(input) {
14483
14555
  const cacheDir = path23.join(EXE_AI_DIR, "session-cache");
14484
14556
  const cachePath = path23.join(cacheDir, `current-task-${agent}.json`);
14485
14557
  if (input.status === "in_progress") {
14486
- mkdirSync8(cacheDir, { recursive: true });
14487
- writeFileSync7(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
14558
+ mkdirSync9(cacheDir, { recursive: true });
14559
+ writeFileSync8(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
14488
14560
  } else if (input.status === "done" || input.status === "blocked" || input.status === "cancelled") {
14489
14561
  try {
14490
14562
  unlinkSync7(cachePath);
@@ -14928,8 +15000,8 @@ __export(tmux_routing_exports, {
14928
15000
  spawnEmployee: () => spawnEmployee,
14929
15001
  verifyPaneAtCapacity: () => verifyPaneAtCapacity
14930
15002
  });
14931
- import { execFileSync as execFileSync3, execSync as execSync10 } from "child_process";
14932
- import { readFileSync as readFileSync16, writeFileSync as writeFileSync8, mkdirSync as mkdirSync9, existsSync as existsSync20, appendFileSync } from "fs";
15003
+ import { execFileSync as execFileSync3, execSync as execSync11 } from "child_process";
15004
+ import { readFileSync as readFileSync16, writeFileSync as writeFileSync9, mkdirSync as mkdirSync10, existsSync as existsSync20, appendFileSync } from "fs";
14933
15005
  import path24 from "path";
14934
15006
  import os9 from "os";
14935
15007
  import { fileURLToPath as fileURLToPath4 } from "url";
@@ -14947,7 +15019,7 @@ function isProcessAlive(pid) {
14947
15019
  }
14948
15020
  function acquireSpawnLock2(sessionName) {
14949
15021
  if (!existsSync20(SPAWN_LOCK_DIR)) {
14950
- mkdirSync9(SPAWN_LOCK_DIR, { recursive: true });
15022
+ mkdirSync10(SPAWN_LOCK_DIR, { recursive: true });
14951
15023
  }
14952
15024
  const lockFile = spawnLockPath(sessionName);
14953
15025
  if (existsSync20(lockFile)) {
@@ -14960,7 +15032,7 @@ function acquireSpawnLock2(sessionName) {
14960
15032
  } catch {
14961
15033
  }
14962
15034
  }
14963
- writeFileSync8(lockFile, JSON.stringify({ pid: process.pid, timestamp: Date.now() }));
15035
+ writeFileSync9(lockFile, JSON.stringify({ pid: process.pid, timestamp: Date.now() }));
14964
15036
  return true;
14965
15037
  }
14966
15038
  function releaseSpawnLock2(sessionName) {
@@ -15004,18 +15076,21 @@ function exportBehaviorsSync(agentId, projectName, sessionKey) {
15004
15076
  function getMySession() {
15005
15077
  return getTransport().getMySession();
15006
15078
  }
15079
+ function isRootSession(name) {
15080
+ return name.length > 0 && !name.includes("-");
15081
+ }
15007
15082
  function employeeSessionName(employee, exeSession, instance) {
15008
- if (!/^exe\d+$/.test(exeSession)) {
15083
+ if (!isRootSession(exeSession)) {
15009
15084
  const root = extractRootExe(exeSession);
15010
15085
  if (root) {
15011
15086
  process.stderr.write(
15012
- `[tmux-routing] WARN: exeSession="${exeSession}" is not a root exe session, using "${root}" instead
15087
+ `[tmux-routing] WARN: exeSession="${exeSession}" is not a root session, using "${root}" instead
15013
15088
  `
15014
15089
  );
15015
15090
  exeSession = root;
15016
15091
  } else {
15017
15092
  throw new Error(
15018
- `Invalid exeSession "${exeSession}" \u2014 must be a root exe session (e.g., "exe1"), not an agent session`
15093
+ `Invalid exeSession "${exeSession}" \u2014 contains a dash but no recognizable root session. Pass a root session name (e.g., "exe1", "work", "yoda1")`
15019
15094
  );
15020
15095
  }
15021
15096
  }
@@ -15023,7 +15098,7 @@ function employeeSessionName(employee, exeSession, instance) {
15023
15098
  const name = `${employee}${suffix}-${exeSession}`;
15024
15099
  if (!VALID_SESSION_NAME.test(name)) {
15025
15100
  throw new Error(
15026
- `Invalid session name "${name}" \u2014 must match {agent}-exe{N} or {agent}{instance}-exe{N}`
15101
+ `Invalid session name "${name}" \u2014 must match {agent}-{rootSession} or {agent}{instance}-{rootSession}`
15027
15102
  );
15028
15103
  }
15029
15104
  return name;
@@ -15040,11 +15115,11 @@ function extractRootExe(name) {
15040
15115
  }
15041
15116
  function registerParentExe(sessionKey, parentExe, dispatchedBy) {
15042
15117
  if (!existsSync20(SESSION_CACHE)) {
15043
- mkdirSync9(SESSION_CACHE, { recursive: true });
15118
+ mkdirSync10(SESSION_CACHE, { recursive: true });
15044
15119
  }
15045
15120
  const rootExe = extractRootExe(parentExe) ?? parentExe;
15046
15121
  const filePath = path24.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
15047
- writeFileSync8(filePath, JSON.stringify({
15122
+ writeFileSync9(filePath, JSON.stringify({
15048
15123
  parentExe: rootExe,
15049
15124
  dispatchedBy: dispatchedBy || rootExe,
15050
15125
  registeredAt: (/* @__PURE__ */ new Date()).toISOString()
@@ -15130,8 +15205,8 @@ function readDebounceState() {
15130
15205
  }
15131
15206
  function writeDebounceState(state) {
15132
15207
  try {
15133
- if (!existsSync20(SESSION_CACHE)) mkdirSync9(SESSION_CACHE, { recursive: true });
15134
- writeFileSync8(DEBOUNCE_FILE, JSON.stringify(state));
15208
+ if (!existsSync20(SESSION_CACHE)) mkdirSync10(SESSION_CACHE, { recursive: true });
15209
+ writeFileSync9(DEBOUNCE_FILE, JSON.stringify(state));
15135
15210
  } catch {
15136
15211
  }
15137
15212
  }
@@ -15266,11 +15341,11 @@ function ensureEmployee(employeeName, exeSession, projectDir, opts) {
15266
15341
  error: `Error: pass employee name ('${bare}'), not session name ('${employeeName}')`
15267
15342
  };
15268
15343
  }
15269
- if (!/^exe\d+$/.test(exeSession)) {
15344
+ if (!isRootSession(exeSession)) {
15270
15345
  const root = extractRootExe(exeSession);
15271
15346
  if (root) {
15272
15347
  process.stderr.write(
15273
- `[ensureEmployee] WARN: caller passed exeSession="${exeSession}" (not a root exe). Auto-correcting to "${root}".
15348
+ `[ensureEmployee] WARN: caller passed exeSession="${exeSession}" (not a root session). Auto-correcting to "${root}".
15274
15349
  `
15275
15350
  );
15276
15351
  exeSession = root;
@@ -15278,7 +15353,7 @@ function ensureEmployee(employeeName, exeSession, projectDir, opts) {
15278
15353
  return {
15279
15354
  status: "failed",
15280
15355
  sessionName: "",
15281
- error: `Invalid exeSession "${exeSession}" \u2014 must be a root exe session (e.g., "exe1")`
15356
+ error: `Invalid exeSession "${exeSession}" \u2014 contains a dash but no recognizable root session. Pass a root session name (e.g., "exe1", "work", "yoda1")`
15282
15357
  };
15283
15358
  }
15284
15359
  }
@@ -15323,7 +15398,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
15323
15398
  const logDir = path24.join(os9.homedir(), ".exe-os", "session-logs");
15324
15399
  const logFile = path24.join(logDir, `${instanceLabel}-${Date.now()}.log`);
15325
15400
  if (!existsSync20(logDir)) {
15326
- mkdirSync9(logDir, { recursive: true });
15401
+ mkdirSync10(logDir, { recursive: true });
15327
15402
  }
15328
15403
  transport.kill(sessionName);
15329
15404
  let cleanupSuffix = "";
@@ -15347,7 +15422,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
15347
15422
  const trustDir = opts?.cwd ?? projectDir;
15348
15423
  if (!projects[trustDir]) projects[trustDir] = {};
15349
15424
  projects[trustDir].hasTrustDialogAccepted = true;
15350
- writeFileSync8(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
15425
+ writeFileSync9(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
15351
15426
  } catch {
15352
15427
  }
15353
15428
  try {
@@ -15385,8 +15460,8 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
15385
15460
  if (changed) {
15386
15461
  perms.allow = allow;
15387
15462
  settings.permissions = perms;
15388
- mkdirSync9(projSettingsDir, { recursive: true });
15389
- writeFileSync8(settingsPath, JSON.stringify(settings, null, 2) + "\n");
15463
+ mkdirSync10(projSettingsDir, { recursive: true });
15464
+ writeFileSync9(settingsPath, JSON.stringify(settings, null, 2) + "\n");
15390
15465
  }
15391
15466
  } catch {
15392
15467
  }
@@ -15430,7 +15505,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
15430
15505
  let sessionContextFlag = "";
15431
15506
  try {
15432
15507
  const ctxDir = path24.join(os9.homedir(), ".exe-os", "session-cache");
15433
- mkdirSync9(ctxDir, { recursive: true });
15508
+ mkdirSync10(ctxDir, { recursive: true });
15434
15509
  const ctxFile = path24.join(ctxDir, `session-context-${sessionName}.md`);
15435
15510
  const ctxContent = [
15436
15511
  `## Session Context`,
@@ -15438,7 +15513,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
15438
15513
  `Your parent exe session is ${exeSession}.`,
15439
15514
  `Your employees (if any) use the -${exeSession} suffix (e.g., tom-${exeSession}).`
15440
15515
  ].join("\n");
15441
- writeFileSync8(ctxFile, ctxContent);
15516
+ writeFileSync9(ctxFile, ctxContent);
15442
15517
  sessionContextFlag = ` --append-system-prompt-file ${ctxFile}`;
15443
15518
  } catch {
15444
15519
  }
@@ -15477,7 +15552,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
15477
15552
  try {
15478
15553
  const mySession = getMySession();
15479
15554
  const dispatchInfo = path24.join(SESSION_CACHE, `dispatch-info-${sessionName}.json`);
15480
- writeFileSync8(dispatchInfo, JSON.stringify({
15555
+ writeFileSync9(dispatchInfo, JSON.stringify({
15481
15556
  dispatchedBy: mySession,
15482
15557
  rootExe: exeSession,
15483
15558
  provider: useBinSymlink ? ccProvider : useExeAgent ? opts.provider : "anthropic",
@@ -15488,7 +15563,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
15488
15563
  let booted = false;
15489
15564
  for (let i = 0; i < 30; i++) {
15490
15565
  try {
15491
- execSync10("sleep 0.5");
15566
+ execSync11("sleep 0.5");
15492
15567
  } catch {
15493
15568
  }
15494
15569
  try {
@@ -15543,7 +15618,7 @@ var init_tmux_routing = __esm({
15543
15618
  SPAWN_LOCK_DIR = path24.join(os9.homedir(), ".exe-os", "spawn-locks");
15544
15619
  SESSION_CACHE = path24.join(os9.homedir(), ".exe-os", "session-cache");
15545
15620
  BEHAVIORS_EXPORT_TIMEOUT_MS = 1e4;
15546
- VALID_SESSION_NAME = /^[a-z]+-exe\d+$|^[a-z]+\d+-exe\d+$/;
15621
+ VALID_SESSION_NAME = /^[a-z]+\d*-[a-zA-Z0-9_]+$/;
15547
15622
  VERIFY_PANE_LINES = 200;
15548
15623
  INTERCOM_DEBOUNCE_MS = 3e4;
15549
15624
  INTERCOM_LOG2 = path24.join(os9.homedir(), ".exe-os", "intercom.log");
@@ -15664,13 +15739,13 @@ __export(tmux_status_exports, {
15664
15739
  parseActivity: () => parseActivity,
15665
15740
  parseContextPercentage: () => parseContextPercentage
15666
15741
  });
15667
- import { execSync as execSync11 } from "child_process";
15742
+ import { execSync as execSync12 } from "child_process";
15668
15743
  function inTmux() {
15669
15744
  if (process.env.TMUX || process.env.TMUX_PANE) return true;
15670
15745
  const term = process.env.TERM ?? "";
15671
15746
  if (term.startsWith("tmux") || term.startsWith("screen")) return true;
15672
15747
  try {
15673
- execSync11("tmux display-message -p '#{session_name}' 2>/dev/null", {
15748
+ execSync12("tmux display-message -p '#{session_name}' 2>/dev/null", {
15674
15749
  encoding: "utf8",
15675
15750
  timeout: 2e3
15676
15751
  });
@@ -15680,12 +15755,12 @@ function inTmux() {
15680
15755
  try {
15681
15756
  let pid = process.ppid;
15682
15757
  for (let depth = 0; depth < 8 && pid > 1; depth++) {
15683
- const comm = execSync11(`ps -p ${pid} -o comm= 2>/dev/null`, {
15758
+ const comm = execSync12(`ps -p ${pid} -o comm= 2>/dev/null`, {
15684
15759
  encoding: "utf8",
15685
15760
  timeout: 1e3
15686
15761
  }).trim();
15687
15762
  if (/tmux/.test(comm)) return true;
15688
- const ppid = execSync11(`ps -p ${pid} -o ppid= 2>/dev/null`, {
15763
+ const ppid = execSync12(`ps -p ${pid} -o ppid= 2>/dev/null`, {
15689
15764
  encoding: "utf8",
15690
15765
  timeout: 1e3
15691
15766
  }).trim();
@@ -15698,7 +15773,7 @@ function inTmux() {
15698
15773
  }
15699
15774
  function listTmuxSessions() {
15700
15775
  try {
15701
- const out = execSync11("tmux list-sessions -F '#{session_name}' 2>/dev/null", {
15776
+ const out = execSync12("tmux list-sessions -F '#{session_name}' 2>/dev/null", {
15702
15777
  encoding: "utf8",
15703
15778
  timeout: 3e3
15704
15779
  });
@@ -15709,7 +15784,7 @@ function listTmuxSessions() {
15709
15784
  }
15710
15785
  function capturePaneLines(windowName, lines = 10) {
15711
15786
  try {
15712
- const out = execSync11(
15787
+ const out = execSync12(
15713
15788
  `tmux capture-pane -t ${JSON.stringify(windowName)} -p 2>/dev/null | tail -${lines}`,
15714
15789
  { encoding: "utf8", timeout: 3e3 }
15715
15790
  );
@@ -15720,7 +15795,7 @@ function capturePaneLines(windowName, lines = 10) {
15720
15795
  }
15721
15796
  function getPaneCwd(windowName) {
15722
15797
  try {
15723
- const out = execSync11(
15798
+ const out = execSync12(
15724
15799
  `tmux display-message -t ${JSON.stringify(windowName)} -p '#{pane_current_path}' 2>/dev/null`,
15725
15800
  { encoding: "utf8", timeout: 3e3 }
15726
15801
  );
@@ -15731,7 +15806,7 @@ function getPaneCwd(windowName) {
15731
15806
  }
15732
15807
  function projectFromPath(dir) {
15733
15808
  try {
15734
- const root = execSync11("git -C " + JSON.stringify(dir) + " rev-parse --show-toplevel 2>/dev/null", {
15809
+ const root = execSync12("git -C " + JSON.stringify(dir) + " rev-parse --show-toplevel 2>/dev/null", {
15735
15810
  encoding: "utf8",
15736
15811
  timeout: 3e3
15737
15812
  }).trim();
@@ -15800,7 +15875,7 @@ function getEmployeeStatuses(employeeNames) {
15800
15875
  }
15801
15876
  let paneAlive = true;
15802
15877
  try {
15803
- const paneStatus = execSync11(
15878
+ const paneStatus = execSync12(
15804
15879
  `tmux list-panes -t ${JSON.stringify(sessionName)} -F '#{pane_dead}' 2>/dev/null`,
15805
15880
  { encoding: "utf8", timeout: 3e3 }
15806
15881
  ).trim();
@@ -15990,8 +16065,8 @@ function Footer() {
15990
16065
  setSessions(allSessions.length);
15991
16066
  if (!currentSession) {
15992
16067
  try {
15993
- const { execSync: execSync13 } = await import("child_process");
15994
- const name = execSync13("tmux display-message -p '#{session_name}' 2>/dev/null", {
16068
+ const { execSync: execSync14 } = await import("child_process");
16069
+ const name = execSync14("tmux display-message -p '#{session_name}' 2>/dev/null", {
15995
16070
  encoding: "utf8",
15996
16071
  timeout: 2e3
15997
16072
  }).trim();
@@ -19315,8 +19390,8 @@ function TmuxPane({ sessionName, employeeName, employeeRole, projectName, onDeta
19315
19390
  }
19316
19391
  const capture = () => {
19317
19392
  try {
19318
- const { execSync: execSync13 } = __require("child_process");
19319
- const output = execSync13(
19393
+ const { execSync: execSync14 } = __require("child_process");
19394
+ const output = execSync14(
19320
19395
  `tmux capture-pane -t ${JSON.stringify(sessionName)} -p -e 2>/dev/null | tail -${CAPTURE_LINES}`,
19321
19396
  { encoding: "utf8", timeout: 3e3 }
19322
19397
  );
@@ -19340,8 +19415,8 @@ function TmuxPane({ sessionName, employeeName, employeeRole, projectName, onDeta
19340
19415
  if (key.return) {
19341
19416
  if (!demo && inputBuffer.trim()) {
19342
19417
  try {
19343
- const { execSync: execSync13 } = __require("child_process");
19344
- execSync13(
19418
+ const { execSync: execSync14 } = __require("child_process");
19419
+ execSync14(
19345
19420
  `tmux send-keys -t ${JSON.stringify(sessionName)} ${JSON.stringify(inputBuffer)} Enter`,
19346
19421
  { timeout: 2e3 }
19347
19422
  );
@@ -19349,8 +19424,8 @@ function TmuxPane({ sessionName, employeeName, employeeRole, projectName, onDeta
19349
19424
  }
19350
19425
  } else if (!demo) {
19351
19426
  try {
19352
- const { execSync: execSync13 } = __require("child_process");
19353
- execSync13(`tmux send-keys -t ${JSON.stringify(sessionName)} Enter`, { timeout: 2e3 });
19427
+ const { execSync: execSync14 } = __require("child_process");
19428
+ execSync14(`tmux send-keys -t ${JSON.stringify(sessionName)} Enter`, { timeout: 2e3 });
19354
19429
  } catch {
19355
19430
  }
19356
19431
  }
@@ -20025,12 +20100,12 @@ function SessionsView({
20025
20100
  return;
20026
20101
  }
20027
20102
  } else {
20028
- const { execSync: execSync13 } = await import("child_process");
20103
+ const { execSync: execSync14 } = await import("child_process");
20029
20104
  const dir = projectDir || process.cwd();
20030
- execSync13(`tmux new-session -d -s ${JSON.stringify(entry.sessionName)} -c ${JSON.stringify(dir)}`, { timeout: 5e3 });
20031
- execSync13(`tmux send-keys -t ${JSON.stringify(entry.sessionName)} "claude --dangerously-skip-permissions" Enter`, { timeout: 3e3 });
20105
+ execSync14(`tmux new-session -d -s ${JSON.stringify(entry.sessionName)} -c ${JSON.stringify(dir)}`, { timeout: 5e3 });
20106
+ execSync14(`tmux send-keys -t ${JSON.stringify(entry.sessionName)} "claude --dangerously-skip-permissions" Enter`, { timeout: 3e3 });
20032
20107
  await new Promise((r) => setTimeout(r, 3e3));
20033
- execSync13(`tmux send-keys -t ${JSON.stringify(entry.sessionName)} "/exe" Enter`, { timeout: 3e3 });
20108
+ execSync14(`tmux send-keys -t ${JSON.stringify(entry.sessionName)} "/exe" Enter`, { timeout: 3e3 });
20034
20109
  }
20035
20110
  const updated = { ...entry, status: "active", activity: "Starting...", attached: false };
20036
20111
  setViewingEmployee(updated);
@@ -20132,7 +20207,7 @@ function SessionsView({
20132
20207
  const { listSessions: listSessions2 } = await Promise.resolve().then(() => (init_session_registry(), session_registry_exports));
20133
20208
  const { listTmuxSessions: listTmuxSessions2, inTmux: inTmux2, capturePaneLines: capturePaneLines2, parseActivity: parseActivity2 } = await Promise.resolve().then(() => (init_tmux_status(), tmux_status_exports));
20134
20209
  const { loadEmployees: loadEmployees2 } = await Promise.resolve().then(() => (init_employees(), employees_exports));
20135
- const { execSync: execSync13 } = await import("child_process");
20210
+ const { execSync: execSync14 } = await import("child_process");
20136
20211
  if (!inTmux2()) {
20137
20212
  setTmuxAvailable(false);
20138
20213
  setProjects([]);
@@ -20141,7 +20216,7 @@ function SessionsView({
20141
20216
  setTmuxAvailable(true);
20142
20217
  const attachedMap = /* @__PURE__ */ new Map();
20143
20218
  try {
20144
- const out = execSync13("tmux list-sessions -F '#{session_name}:#{session_attached}' 2>/dev/null", {
20219
+ const out = execSync14("tmux list-sessions -F '#{session_name}:#{session_attached}' 2>/dev/null", {
20145
20220
  encoding: "utf8",
20146
20221
  timeout: 3e3
20147
20222
  });
@@ -21091,8 +21166,8 @@ function upsertConversation(conversations, platform, senderId, message) {
21091
21166
  async function loadGatewayConfig() {
21092
21167
  const state = { running: false, port: 3100, adapters: [], agents: [], gatewayUrl: "" };
21093
21168
  try {
21094
- const { execSync: execSync13 } = await import("child_process");
21095
- const ps = execSync13("pgrep -f exe-gateway 2>/dev/null", { encoding: "utf8", timeout: 3e3 });
21169
+ const { execSync: execSync14 } = await import("child_process");
21170
+ const ps = execSync14("pgrep -f exe-gateway 2>/dev/null", { encoding: "utf8", timeout: 3e3 });
21096
21171
  state.running = ps.trim().length > 0;
21097
21172
  } catch {
21098
21173
  state.running = false;
@@ -21569,10 +21644,10 @@ var init_Gateway = __esm({
21569
21644
  });
21570
21645
 
21571
21646
  // src/tui/utils/agent-status.ts
21572
- import { execSync as execSync12 } from "child_process";
21647
+ import { execSync as execSync13 } from "child_process";
21573
21648
  function getAgentStatus(agentId) {
21574
21649
  try {
21575
- const sessions = execSync12("tmux list-sessions -F '#{session_name}' 2>/dev/null", {
21650
+ const sessions = execSync13("tmux list-sessions -F '#{session_name}' 2>/dev/null", {
21576
21651
  encoding: "utf8",
21577
21652
  timeout: 2e3
21578
21653
  }).trim().split("\n");
@@ -21583,7 +21658,7 @@ function getAgentStatus(agentId) {
21583
21658
  return /^\d?-/.test(suffix) || /^\d+$/.test(suffix);
21584
21659
  });
21585
21660
  if (!agentSession) return { label: "offline", color: "gray" };
21586
- const pane = execSync12(`tmux capture-pane -t "${agentSession}" -p 2>/dev/null | tail -3`, {
21661
+ const pane = execSync13(`tmux capture-pane -t "${agentSession}" -p 2>/dev/null | tail -3`, {
21587
21662
  encoding: "utf8",
21588
21663
  timeout: 2e3
21589
21664
  });
@@ -22548,8 +22623,8 @@ function SettingsView({ onBack }) {
22548
22623
  };
22549
22624
  });
22550
22625
  try {
22551
- const { execSync: execSync13 } = await import("child_process");
22552
- execSync13("curl -s --max-time 1 http://localhost:11434/api/tags", { timeout: 2e3 });
22626
+ const { execSync: execSync14 } = await import("child_process");
22627
+ execSync14("curl -s --max-time 1 http://localhost:11434/api/tags", { timeout: 2e3 });
22553
22628
  providerList.push({ name: "Ollama", configured: true, detail: "localhost:11434" });
22554
22629
  } catch {
22555
22630
  providerList.push({ name: "Ollama", configured: false, detail: "not running" });
@@ -23196,7 +23271,7 @@ Unhandled rejection: ${reason}
23196
23271
  });
23197
23272
 
23198
23273
  // src/bin/cli.ts
23199
- import { existsSync as existsSync21, readFileSync as readFileSync17, writeFileSync as writeFileSync9, readdirSync as readdirSync5, rmSync } from "fs";
23274
+ import { existsSync as existsSync21, readFileSync as readFileSync17, writeFileSync as writeFileSync10, readdirSync as readdirSync5, rmSync } from "fs";
23200
23275
  import path33 from "path";
23201
23276
  import os11 from "os";
23202
23277
  var args = process.argv.slice(2);
@@ -23424,7 +23499,7 @@ async function runClaudeUninstall(flags = []) {
23424
23499
  permCount = before - settings.permissions.allow.length;
23425
23500
  }
23426
23501
  if (!dryRun) {
23427
- writeFileSync9(settingsPath, JSON.stringify(settings, null, 2) + "\n");
23502
+ writeFileSync10(settingsPath, JSON.stringify(settings, null, 2) + "\n");
23428
23503
  }
23429
23504
  log("\u2713 Removed exe-os hooks from settings.json");
23430
23505
  if (permCount > 0) log(`\u2713 Removed ${permCount} MCP permission entries`);
@@ -23453,7 +23528,7 @@ async function runClaudeUninstall(flags = []) {
23453
23528
  }
23454
23529
  if (removedMcp) {
23455
23530
  if (!dryRun) {
23456
- writeFileSync9(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
23531
+ writeFileSync10(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
23457
23532
  }
23458
23533
  log("\u2713 Removed exe-os MCP server from claude.json");
23459
23534
  removed++;
@@ -23489,7 +23564,7 @@ async function runClaudeUninstall(flags = []) {
23489
23564
  const endIdx = content.indexOf(endMarker);
23490
23565
  if (startIdx !== -1 && endIdx !== -1) {
23491
23566
  const cleaned = (content.slice(0, startIdx) + content.slice(endIdx + endMarker.length)).replace(/\n{3,}/g, "\n\n").trim() + "\n";
23492
- if (!dryRun) writeFileSync9(claudeMdPath, cleaned);
23567
+ if (!dryRun) writeFileSync10(claudeMdPath, cleaned);
23493
23568
  log("\u2713 Removed orchestration block from CLAUDE.md");
23494
23569
  removed++;
23495
23570
  }
@@ -23541,7 +23616,7 @@ async function runClaudeUninstall(flags = []) {
23541
23616
  if (pSettings.permissions.allow.length < before) changed = true;
23542
23617
  }
23543
23618
  if (changed && !dryRun) {
23544
- writeFileSync9(projSettings, JSON.stringify(pSettings, null, 2) + "\n");
23619
+ writeFileSync10(projSettings, JSON.stringify(pSettings, null, 2) + "\n");
23545
23620
  }
23546
23621
  if (changed) projectCount++;
23547
23622
  } catch {
@@ -23555,10 +23630,10 @@ async function runClaudeUninstall(flags = []) {
23555
23630
  }
23556
23631
  }
23557
23632
  try {
23558
- const { execSync: execSync13 } = await import("child_process");
23633
+ const { execSync: execSync14 } = await import("child_process");
23559
23634
  const findExeBin3 = () => {
23560
23635
  try {
23561
- return execSync13(process.platform === "win32" ? "where exe-os" : "which exe-os", { encoding: "utf8" }).trim();
23636
+ return execSync14(process.platform === "win32" ? "where exe-os" : "which exe-os", { encoding: "utf8" }).trim();
23562
23637
  } catch {
23563
23638
  return null;
23564
23639
  }