@phenx-inc/ctlsurf 0.3.7 → 0.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/out/headless/index.mjs +254 -13
  2. package/out/headless/index.mjs.map +3 -3
  3. package/out/main/index.js +130 -51
  4. package/out/preload/index.js +3 -0
  5. package/out/renderer/assets/{cssMode-DQW-brNd.js → cssMode-CYoo4t9f.js} +3 -3
  6. package/out/renderer/assets/{freemarker2-DxgOckH2.js → freemarker2--UQnPZsn.js} +1 -1
  7. package/out/renderer/assets/{handlebars-BX1Wpk_3.js → handlebars-DVDrmX0C.js} +1 -1
  8. package/out/renderer/assets/{html-t-KXioI0.js → html-D1-cXoLy.js} +1 -1
  9. package/out/renderer/assets/{htmlMode-Dya7iUjr.js → htmlMode-f5nBuprq.js} +3 -3
  10. package/out/renderer/assets/{index-D6JBcQ20.css → index-65hyKM_8.css} +16 -0
  11. package/out/renderer/assets/{index-DNqZidnO.js → index-D23nru43.js} +64 -23
  12. package/out/renderer/assets/{javascript-DZzW2adn.js → javascript-CcarFzBL.js} +2 -2
  13. package/out/renderer/assets/{jsonMode-D_Wv7XH8.js → jsonMode-BvF-xK9U.js} +3 -3
  14. package/out/renderer/assets/{liquid-BJAHAm2T.js → liquid-CHLtUKl2.js} +1 -1
  15. package/out/renderer/assets/{lspLanguageFeatures-BgMd-KJk.js → lspLanguageFeatures-B9aNeatS.js} +1 -1
  16. package/out/renderer/assets/{mdx-B6Zod3ry.js → mdx-HGDrkifZ.js} +1 -1
  17. package/out/renderer/assets/{python-Cgt13-KH.js → python-B_dPzjJ6.js} +1 -1
  18. package/out/renderer/assets/{razor-BcwFJGYS.js → razor-CHheM4ot.js} +1 -1
  19. package/out/renderer/assets/{tsMode-BTjzM6fl.js → tsMode-CdC3i1gG.js} +1 -1
  20. package/out/renderer/assets/{typescript-DZYDQEUb.js → typescript-BX6guVRK.js} +1 -1
  21. package/out/renderer/assets/{xml-CloiUoIW.js → xml-CpS-pOPE.js} +1 -1
  22. package/out/renderer/assets/{yaml-CdKdpE-z.js → yaml-Du0AjOHW.js} +1 -1
  23. package/out/renderer/index.html +2 -2
  24. package/package.json +1 -1
  25. package/src/main/bridge.ts +9 -3
  26. package/src/main/headless.ts +35 -2
  27. package/src/main/index.ts +10 -39
  28. package/src/main/orchestrator.ts +74 -1
  29. package/src/main/tui.ts +20 -8
  30. package/src/main/updateCheck.ts +40 -0
  31. package/src/preload/index.ts +6 -0
  32. package/src/renderer/App.tsx +2 -0
  33. package/src/renderer/components/AgentPicker.tsx +38 -3
  34. package/src/renderer/styles.css +16 -0
@@ -5466,6 +5466,88 @@ var require_electron = __commonJS({
5466
5466
  }
5467
5467
  });
5468
5468
 
5469
+ // package.json
5470
+ var require_package = __commonJS({
5471
+ "package.json"(exports, module) {
5472
+ module.exports = {
5473
+ name: "@phenx-inc/ctlsurf",
5474
+ version: "0.3.9",
5475
+ description: "Agent-agnostic terminal and desktop app for ctlsurf \u2014 run Claude Code, Codex, or any coding agent with live session logging and remote control",
5476
+ main: "out/main/index.js",
5477
+ bin: {
5478
+ ctlsurf: "./bin/ctlsurf-worker.js",
5479
+ "ctlsurf-worker": "./bin/ctlsurf-worker.js"
5480
+ },
5481
+ files: [
5482
+ "bin/",
5483
+ "out/",
5484
+ "resources/",
5485
+ "scripts/",
5486
+ "src/",
5487
+ "package.json",
5488
+ "electron-vite.config.ts",
5489
+ "tsconfig*.json"
5490
+ ],
5491
+ scripts: {
5492
+ dev: "electron-vite dev",
5493
+ "dev:terminal": "esbuild src/main/headless.ts --bundle --platform=node --target=node18 --format=esm --outfile=out/headless/index.mjs --external:node-pty --external:ws --sourcemap && node out/headless/index.mjs",
5494
+ build: "electron-vite build && npm run build:headless",
5495
+ "build:headless": "esbuild src/main/headless.ts --bundle --platform=node --target=node18 --format=esm --outfile=out/headless/index.mjs --external:node-pty --external:ws --sourcemap",
5496
+ prepublishOnly: "npm run build",
5497
+ preview: "electron-vite preview",
5498
+ package: "electron-builder",
5499
+ postinstall: "node-gyp rebuild --directory=node_modules/node-pty 2>/dev/null || true"
5500
+ },
5501
+ keywords: [
5502
+ "ctlsurf",
5503
+ "terminal",
5504
+ "tui",
5505
+ "coding-agent",
5506
+ "claude-code",
5507
+ "codex",
5508
+ "electron",
5509
+ "node-pty",
5510
+ "xterm"
5511
+ ],
5512
+ license: "MIT",
5513
+ engines: {
5514
+ node: ">=18"
5515
+ },
5516
+ dependencies: {
5517
+ "@monaco-editor/react": "^4.7.0",
5518
+ "@xterm/addon-fit": "^0.10.0",
5519
+ "@xterm/addon-serialize": "^0.14.0",
5520
+ "@xterm/addon-web-links": "^0.11.0",
5521
+ "@xterm/headless": "^6.0.0",
5522
+ "@xterm/xterm": "^5.5.0",
5523
+ "electron-store": "^10.0.0",
5524
+ esbuild: "^0.27.4",
5525
+ "monaco-editor": "^0.55.1",
5526
+ "node-pty": "^1.0.0",
5527
+ ws: "^8.20.0"
5528
+ },
5529
+ devDependencies: {
5530
+ "@electron/rebuild": "^4.0.3",
5531
+ "@types/node": "^22.15.0",
5532
+ "@types/react": "^19.1.0",
5533
+ "@types/react-dom": "^19.1.0",
5534
+ "@types/ws": "^8.18.1",
5535
+ "@vitejs/plugin-react": "^4.5.2",
5536
+ electron: "^35.0.0",
5537
+ "electron-builder": "^25.1.8",
5538
+ "electron-vite": "^3.1.0",
5539
+ react: "^19.1.0",
5540
+ "react-dom": "^19.1.0",
5541
+ typescript: "^5.8.3"
5542
+ },
5543
+ optionalDependencies: {
5544
+ bufferutil: "^4.1.0",
5545
+ "utf-8-validate": "^6.0.6"
5546
+ }
5547
+ };
5548
+ }
5549
+ });
5550
+
5469
5551
  // src/main/orchestrator.ts
5470
5552
  import path from "path";
5471
5553
  import fs from "fs";
@@ -5682,6 +5764,7 @@ var import_addon_serialize = __toESM(require_addon_serialize());
5682
5764
  var ConversationBridge = class {
5683
5765
  wsClient = null;
5684
5766
  sessionActive = false;
5767
+ loggingEnabled = false;
5685
5768
  inputBuffer = "";
5686
5769
  outputBuffer = "";
5687
5770
  outputFlushTimer = null;
@@ -5691,7 +5774,11 @@ var ConversationBridge = class {
5691
5774
  setWsClient(ws) {
5692
5775
  this.wsClient = ws;
5693
5776
  }
5777
+ setLoggingEnabled(enabled) {
5778
+ this.loggingEnabled = enabled;
5779
+ }
5694
5780
  startSession() {
5781
+ if (!this.loggingEnabled) return;
5695
5782
  this.clearOutputTimers();
5696
5783
  this.outputBuffer = "";
5697
5784
  this.inputBuffer = "";
@@ -5700,13 +5787,13 @@ var ConversationBridge = class {
5700
5787
  console.log("[bridge] Session started");
5701
5788
  }
5702
5789
  feedOutput(data) {
5703
- if (!this.sessionActive) return;
5790
+ if (!this.sessionActive || !this.loggingEnabled) return;
5704
5791
  this.outputBuffer += data;
5705
5792
  this.terminalCapture.write(data);
5706
5793
  this.scheduleOutputFlush();
5707
5794
  }
5708
5795
  feedInput(data) {
5709
- if (!this.sessionActive) return;
5796
+ if (!this.sessionActive || !this.loggingEnabled) return;
5710
5797
  this.inputBuffer += data;
5711
5798
  if (data.includes("\r") || data.includes("\n")) {
5712
5799
  const cleaned = cleanInput(this.inputBuffer);
@@ -5728,7 +5815,7 @@ var ConversationBridge = class {
5728
5815
  this.sendEntry("terminal_output", cleaned);
5729
5816
  }
5730
5817
  sendEntry(type, content) {
5731
- if (!this.wsClient) return;
5818
+ if (!this.wsClient || !this.loggingEnabled) return;
5732
5819
  this.wsClient.sendChatLog({
5733
5820
  ts: (/* @__PURE__ */ new Date()).toISOString(),
5734
5821
  type,
@@ -6532,6 +6619,7 @@ var DEFAULT_PROFILES = {
6532
6619
  }
6533
6620
  };
6534
6621
  var TERM_STREAM_INTERVAL_MS = 50;
6622
+ var NO_PROJECT_POLL_MS = 5e3;
6535
6623
  var Orchestrator = class {
6536
6624
  settingsDir;
6537
6625
  events;
@@ -6547,8 +6635,11 @@ var Orchestrator = class {
6547
6635
  currentCwd = null;
6548
6636
  settings = {
6549
6637
  activeProfile: "production",
6550
- profiles: { ...DEFAULT_PROFILES }
6638
+ profiles: { ...DEFAULT_PROFILES },
6639
+ logChat: false
6551
6640
  };
6641
+ noProjectPollTimer = null;
6642
+ noProjectPollCwd = null;
6552
6643
  constructor(settingsDir, events) {
6553
6644
  this.settingsDir = settingsDir;
6554
6645
  this.events = events;
@@ -6574,6 +6665,11 @@ var Orchestrator = class {
6574
6665
  events.onWorkerRegistered(data);
6575
6666
  if (!data.folder_id) {
6576
6667
  events.onWorkerStatus("no_project");
6668
+ if (this.currentCwd && data.status !== "pending_approval") {
6669
+ this.startNoProjectPolling(this.currentCwd);
6670
+ }
6671
+ } else {
6672
+ this.stopNoProjectPolling();
6577
6673
  }
6578
6674
  },
6579
6675
  onTerminalInput: (data) => {
@@ -6582,6 +6678,21 @@ var Orchestrator = class {
6582
6678
  }
6583
6679
  });
6584
6680
  this.bridge.setWsClient(this.workerWs);
6681
+ this.bridge.setLoggingEnabled(!!this.settings.logChat);
6682
+ }
6683
+ // ─── Chat logging ───────────────────────────────
6684
+ get logChatEnabled() {
6685
+ return !!this.settings.logChat;
6686
+ }
6687
+ setLogChat(enabled) {
6688
+ this.settings.logChat = enabled;
6689
+ this.saveSettings();
6690
+ this.bridge.setLoggingEnabled(enabled);
6691
+ if (!enabled) {
6692
+ this.bridge.endSession();
6693
+ } else if (this.activeTabId) {
6694
+ this.bridge.startSession();
6695
+ }
6585
6696
  }
6586
6697
  // ─── Settings ───────────────────────────────────
6587
6698
  getActiveProfile() {
@@ -6629,7 +6740,8 @@ var Orchestrator = class {
6629
6740
  baseUrl: raw.ctlsurfBaseUrl || "https://app.ctlsurf.com",
6630
6741
  dataspacePageId: raw.ctlsurfDataspacePageId || ""
6631
6742
  }
6632
- }
6743
+ },
6744
+ logChat: !!raw.logChat
6633
6745
  };
6634
6746
  this.saveSettings();
6635
6747
  log3("[settings] Migrated legacy settings to profiles");
@@ -6638,15 +6750,20 @@ var Orchestrator = class {
6638
6750
  if (!this.settings.profiles.production) {
6639
6751
  this.settings.profiles.production = { ...DEFAULT_PROFILES.production };
6640
6752
  }
6753
+ if (this.settings.logChat === void 0) {
6754
+ this.settings.logChat = false;
6755
+ }
6641
6756
  }
6642
6757
  }
6643
6758
  } catch {
6644
6759
  this.settings = {
6645
6760
  activeProfile: "production",
6646
- profiles: { ...DEFAULT_PROFILES }
6761
+ profiles: { ...DEFAULT_PROFILES },
6762
+ logChat: false
6647
6763
  };
6648
6764
  }
6649
6765
  this.applyProfile(this.getActiveProfile());
6766
+ this.bridge.setLoggingEnabled(!!this.settings.logChat);
6650
6767
  }
6651
6768
  saveSettings() {
6652
6769
  const settingsPath = path.join(this.settingsDir, "settings.json");
@@ -6776,7 +6893,9 @@ var Orchestrator = class {
6776
6893
  const t = this.tabs.get(tabId);
6777
6894
  if (t?.termStreamTimer) clearTimeout(t.termStreamTimer);
6778
6895
  });
6779
- this.bridge.startSession();
6896
+ if (this.settings.logChat) {
6897
+ this.bridge.startSession();
6898
+ }
6780
6899
  const profile = this.getActiveProfile();
6781
6900
  const shouldTrack = opts?.trackTime !== void 0 ? opts.trackTime : profile.trackTime !== false;
6782
6901
  if (shouldTrack) {
@@ -6790,6 +6909,7 @@ var Orchestrator = class {
6790
6909
  if (isCodingAgent(agent)) {
6791
6910
  this.connectWorkerWs(agent, cwd);
6792
6911
  } else {
6912
+ this.stopNoProjectPolling();
6793
6913
  this.workerWs.disconnect();
6794
6914
  this.checkProjectStatus(cwd);
6795
6915
  }
@@ -6864,12 +6984,47 @@ var Orchestrator = class {
6864
6984
  log3("[worker-ws] No API key, skipping WS connect");
6865
6985
  return;
6866
6986
  }
6987
+ this.stopNoProjectPolling();
6867
6988
  this.workerWs.connect({
6868
6989
  machine: os3.hostname(),
6869
6990
  cwd,
6870
6991
  agent: agent.name
6871
6992
  });
6872
6993
  }
6994
+ startNoProjectPolling(cwd) {
6995
+ if (this.noProjectPollTimer && this.noProjectPollCwd === cwd) return;
6996
+ this.stopNoProjectPolling();
6997
+ this.noProjectPollCwd = cwd;
6998
+ log3(`[worker-ws] Polling for project folder at ${cwd}`);
6999
+ this.noProjectPollTimer = setInterval(() => {
7000
+ void this.checkForProjectFolder(cwd);
7001
+ }, NO_PROJECT_POLL_MS);
7002
+ }
7003
+ stopNoProjectPolling() {
7004
+ if (this.noProjectPollTimer) {
7005
+ clearInterval(this.noProjectPollTimer);
7006
+ this.noProjectPollTimer = null;
7007
+ this.noProjectPollCwd = null;
7008
+ }
7009
+ }
7010
+ async checkForProjectFolder(cwd) {
7011
+ if (this.currentCwd !== cwd || !this.currentAgent) {
7012
+ this.stopNoProjectPolling();
7013
+ return;
7014
+ }
7015
+ if (!this.ctlsurfApi.getApiKey()) return;
7016
+ try {
7017
+ const folder = await this.ctlsurfApi.findFolderByPath(cwd);
7018
+ if (folder?.id && this.currentCwd === cwd && this.currentAgent) {
7019
+ log3(`[worker-ws] Project folder appeared (${folder.id}); reconnecting`);
7020
+ const agent = this.currentAgent;
7021
+ this.stopNoProjectPolling();
7022
+ this.workerWs.disconnect();
7023
+ this.connectWorkerWs(agent, cwd);
7024
+ }
7025
+ } catch {
7026
+ }
7027
+ }
6873
7028
  async checkProjectStatus(cwd) {
6874
7029
  if (!this.ctlsurfApi.getApiKey()) {
6875
7030
  this.events.onWorkerStatus("no_project");
@@ -6900,6 +7055,7 @@ var Orchestrator = class {
6900
7055
  }
6901
7056
  // ─── Shutdown ───────────────────────────────────
6902
7057
  async shutdown() {
7058
+ this.stopNoProjectPolling();
6903
7059
  this.bridge.endSession();
6904
7060
  await this.timeTracker.endAll();
6905
7061
  for (const [, tab] of this.tabs) {
@@ -7034,8 +7190,9 @@ var Tui = class {
7034
7190
  return new Promise((resolve) => {
7035
7191
  let selected = 0;
7036
7192
  let trackTime = options.initialTrackTime;
7193
+ let logChat = options.initialLogChat;
7037
7194
  const modalWidth = 44;
7038
- const modalHeight = agents.length + 4 + 2;
7195
+ const modalHeight = agents.length + 4 + 3;
7039
7196
  const startCol = Math.max(1, Math.floor((this.cols - modalWidth) / 2));
7040
7197
  const startRow = Math.max(1, Math.floor((this.rows - modalHeight) / 2));
7041
7198
  this.write(`${CSI}?1049h`);
@@ -7079,9 +7236,16 @@ var Tui = class {
7079
7236
  const trackContentLen = 2 + 3 + 1 + "Track time".length;
7080
7237
  const trackPad = " ".repeat(Math.max(0, modalWidth - 2 - trackContentLen));
7081
7238
  this.write(`${CSI}${trackRow};${startCol}H${BG_MODAL}${FG_DIM}\u2502${RESET}${BG_MODAL}${trackContent}${trackPad}${FG_DIM}\u2502${RESET}`);
7082
- const botRow = trackRow + 1;
7239
+ const logRow = trackRow + 1;
7240
+ const logCheckbox = logChat ? `${FG_GREEN}[\u2713]${RESET}${BG_MODAL}` : `${FG_DIM}[ ]${RESET}${BG_MODAL}`;
7241
+ const logLabelFg = logChat ? FG_WHITE : FG_DIM;
7242
+ const logContent = ` ${logCheckbox} ${logLabelFg}Log chat${RESET}${BG_MODAL}`;
7243
+ const logContentLen = 2 + 3 + 1 + "Log chat".length;
7244
+ const logPad = " ".repeat(Math.max(0, modalWidth - 2 - logContentLen));
7245
+ this.write(`${CSI}${logRow};${startCol}H${BG_MODAL}${FG_DIM}\u2502${RESET}${BG_MODAL}${logContent}${logPad}${FG_DIM}\u2502${RESET}`);
7246
+ const botRow = logRow + 1;
7083
7247
  this.write(`${CSI}${botRow};${startCol}H${BG_MODAL}${FG_DIM}${botBorder}${RESET}`);
7084
- const hint = "\u2191\u2193 navigate \xB7 Enter select \xB7 t track \xB7 q quit";
7248
+ const hint = "\u2191\u2193 nav \xB7 Enter \xB7 t track \xB7 l log \xB7 q quit";
7085
7249
  const hintCol = Math.max(1, Math.floor((this.cols - hint.length) / 2));
7086
7250
  this.write(`${CSI}${botRow + 2};${hintCol}H${FG_DIM}${hint}${RESET}`);
7087
7251
  };
@@ -7098,12 +7262,15 @@ var Tui = class {
7098
7262
  } else if (key === "\x1B[B" || key === "j") {
7099
7263
  selected = (selected + 1) % agents.length;
7100
7264
  drawModal();
7101
- } else if (key === "t" || key === "T" || key === " ") {
7265
+ } else if (key === "t" || key === "T") {
7102
7266
  trackTime = !trackTime;
7103
7267
  drawModal();
7268
+ } else if (key === "l" || key === "L") {
7269
+ logChat = !logChat;
7270
+ drawModal();
7104
7271
  } else if (key === "\r" || key === "\n") {
7105
7272
  cleanup();
7106
- resolve({ agentIdx: selected, trackTime });
7273
+ resolve({ agentIdx: selected, trackTime, logChat });
7107
7274
  } else if (key === "q" || key === "\x1B" || key === "") {
7108
7275
  cleanup();
7109
7276
  this.write(`${CSI}?25h`);
@@ -7170,6 +7337,50 @@ var Tui = class {
7170
7337
  }
7171
7338
  };
7172
7339
 
7340
+ // src/main/updateCheck.ts
7341
+ import https from "https";
7342
+ var NPM_PACKAGE = "@phenx-inc/ctlsurf";
7343
+ function compareSemver(a, b) {
7344
+ const pa = a.split(".").map((n) => parseInt(n, 10) || 0);
7345
+ const pb = b.split(".").map((n) => parseInt(n, 10) || 0);
7346
+ for (let i = 0; i < 3; i++) {
7347
+ const ai = pa[i] || 0;
7348
+ const bi = pb[i] || 0;
7349
+ if (ai !== bi) return ai - bi;
7350
+ }
7351
+ return 0;
7352
+ }
7353
+ function fetchLatestNpmVersion(timeoutMs = 8e3) {
7354
+ return new Promise((resolve) => {
7355
+ const url = `https://registry.npmjs.org/${encodeURIComponent(NPM_PACKAGE)}/latest`;
7356
+ const req = https.get(url, { headers: { "Accept": "application/json" } }, (res) => {
7357
+ if (res.statusCode !== 200) {
7358
+ res.resume();
7359
+ resolve(null);
7360
+ return;
7361
+ }
7362
+ let body = "";
7363
+ res.setEncoding("utf8");
7364
+ res.on("data", (chunk) => {
7365
+ body += chunk;
7366
+ });
7367
+ res.on("end", () => {
7368
+ try {
7369
+ const json = JSON.parse(body);
7370
+ resolve(typeof json?.version === "string" ? json.version : null);
7371
+ } catch {
7372
+ resolve(null);
7373
+ }
7374
+ });
7375
+ });
7376
+ req.on("error", () => resolve(null));
7377
+ req.setTimeout(timeoutMs, () => {
7378
+ req.destroy();
7379
+ resolve(null);
7380
+ });
7381
+ });
7382
+ }
7383
+
7173
7384
  // src/main/headless.ts
7174
7385
  process.stdout?.on?.("error", () => {
7175
7386
  });
@@ -7182,6 +7393,14 @@ process.on("uncaughtException", (err) => {
7182
7393
  } catch {
7183
7394
  }
7184
7395
  });
7396
+ function getCurrentVersion() {
7397
+ try {
7398
+ const pkg = require_package();
7399
+ return typeof pkg?.version === "string" ? pkg.version : "0.0.0";
7400
+ } catch {
7401
+ return "0.0.0";
7402
+ }
7403
+ }
7185
7404
  function parseArgs(argv) {
7186
7405
  const args = {
7187
7406
  agent: null,
@@ -7222,9 +7441,27 @@ function parseArgs(argv) {
7222
7441
  }
7223
7442
  return args;
7224
7443
  }
7444
+ async function checkVersionAndNotify() {
7445
+ const current = getCurrentVersion();
7446
+ const latest = await fetchLatestNpmVersion(3e3);
7447
+ if (!latest) return;
7448
+ if (compareSemver(latest, current) <= 0) return;
7449
+ const Y = "\x1B[33m";
7450
+ const G = "\x1B[32m";
7451
+ const D = "\x1B[90m";
7452
+ const R = "\x1B[0m";
7453
+ process.stdout.write(
7454
+ `
7455
+ ${Y}A new version of ctlsurf is available${R} ${D}(${current} \u2192 ${latest})${R}
7456
+ Update: ${G}npm i -g ${NPM_PACKAGE}${R}
7457
+
7458
+ `
7459
+ );
7460
+ }
7225
7461
  async function main() {
7226
7462
  const args = parseArgs(process.argv.slice(2));
7227
7463
  const settingsDir = getSettingsDir(false);
7464
+ await checkVersionAndNotify();
7228
7465
  const tui = new Tui();
7229
7466
  const agents = getBuiltinAgents();
7230
7467
  const orchestrator = new Orchestrator(settingsDir, {
@@ -7265,9 +7502,13 @@ async function main() {
7265
7502
  };
7266
7503
  } else {
7267
7504
  const initialTrackTime = orchestrator.getActiveProfile().trackTime !== false;
7268
- const picked = await tui.showAgentPicker(agents, { initialTrackTime });
7505
+ const initialLogChat = orchestrator.logChatEnabled;
7506
+ const picked = await tui.showAgentPicker(agents, { initialTrackTime, initialLogChat });
7269
7507
  agent = agents[picked.agentIdx];
7270
7508
  trackTimeOverride = picked.trackTime;
7509
+ if (picked.logChat !== orchestrator.logChatEnabled) {
7510
+ orchestrator.setLogChat(picked.logChat);
7511
+ }
7271
7512
  }
7272
7513
  tui.update({
7273
7514
  agentName: agent.name,